mirror of
https://github.com/AleoHQ/leo.git
synced 2024-11-29 22:36:05 +03:00
fix field comparator
This commit is contained in:
parent
d542a9716b
commit
8f397a3382
@ -16,6 +16,8 @@ snarkos-errors = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", rev = "c7a56
|
||||
snarkos-gadgets = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", rev = "c7a56d9", default-features = false }
|
||||
snarkos-models = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", rev = "c7a56d9", default-features = false }
|
||||
snarkos-objects = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", rev = "c7a56d9", default-features = false }
|
||||
snarkos-utilities = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", rev = "c7a56d9" }
|
||||
|
||||
|
||||
bincode = { version = "1.0" }
|
||||
hex = { version = "0.4.2" }
|
||||
@ -25,5 +27,3 @@ rand = { version = "0.7" }
|
||||
sha2 = { version = "0.9" }
|
||||
thiserror = { version = "1.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
snarkos-utilities = { git = "ssh://git@github.com/AleoHQ/snarkOS.git", rev = "c7a56d9" }
|
||||
|
@ -21,6 +21,8 @@ use snarkos_models::{
|
||||
},
|
||||
},
|
||||
};
|
||||
use snarkos_utilities::BigInteger;
|
||||
|
||||
use std::{borrow::Borrow, cmp::Ordering};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -213,26 +215,67 @@ impl<F: Field + PrimeField> EvaluateEqGadget<F> for FieldType<F> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if any bit is true
|
||||
fn not_all_zeros<F: Field + PrimeField, CS: ConstraintSystem<F>>(
|
||||
bits: &[Boolean],
|
||||
mut cs: CS,
|
||||
) -> Result<Boolean, SynthesisError> {
|
||||
let mut result = Boolean::constant(false);
|
||||
|
||||
for (i, b) in bits.iter().enumerate() {
|
||||
result = Boolean::or(cs.ns(|| format!("result or bit [{}]", i)), &result, b)?;
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Returns true if A < B
|
||||
impl<F: Field + PrimeField> EvaluateLtGadget<F> for FieldType<F> {
|
||||
/*
|
||||
packed(alpha) = 2^n + B - A
|
||||
not_all_zeros = \bigvee_{i=0}^{n-1} alpha_i
|
||||
if B - A > 0, then 2^n + B - A > 2^n,
|
||||
so alpha_n = 1 and not_all_zeros = 1
|
||||
if B - A = 0, then 2^n + B - A = 2^n,
|
||||
so alpha_n = 1 and not_all_zeros = 0
|
||||
if B - A < 0, then 2^n + B - A \in {0, 1, \ldots, 2^n-1},
|
||||
so alpha_n = 0
|
||||
therefore less_than = alpha_n * not_all_zeros
|
||||
*/
|
||||
fn less_than<CS: ConstraintSystem<F>>(&self, mut cs: CS, other: &Self) -> Result<Boolean, SynthesisError> {
|
||||
match (self, other) {
|
||||
(FieldType::Constant(first), FieldType::Constant(second)) => Ok(Boolean::constant(first.lt(second))),
|
||||
(FieldType::Allocated(allocated), FieldType::Constant(constant))
|
||||
| (FieldType::Constant(constant), FieldType::Allocated(allocated)) => {
|
||||
let bool_option = allocated.value.map(|f| f.lt(constant));
|
||||
|
||||
Boolean::alloc(&mut cs.ns(|| "less than"), || {
|
||||
bool_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})
|
||||
// B - A
|
||||
let alpha: FpGadget<F> = match (self, other) {
|
||||
(FieldType::Constant(a), FieldType::Constant(b)) => {
|
||||
let cmp = a < b;
|
||||
return Ok(Boolean::constant(cmp));
|
||||
}
|
||||
(FieldType::Allocated(first), FieldType::Allocated(second)) => {
|
||||
let bool_option = first.value.and_then(|a| second.value.map(|b| a.lt(&b)));
|
||||
|
||||
Boolean::alloc(&mut cs.ns(|| "less than"), || {
|
||||
bool_option.ok_or(SynthesisError::AssignmentMissing)
|
||||
})
|
||||
(FieldType::Constant(a), FieldType::Allocated(b)) => b.sub_constant(cs.ns(|| "alpha"), &a)?,
|
||||
(FieldType::Allocated(a), FieldType::Constant(b)) => {
|
||||
let a_neg = a.negate(cs.ns(|| "a neg"))?;
|
||||
a_neg.add_constant(cs.ns(|| "alpha"), &b)?
|
||||
}
|
||||
}
|
||||
(FieldType::Allocated(a), FieldType::Allocated(b)) => b.sub(cs.ns(|| "alpha"), a)?,
|
||||
};
|
||||
|
||||
// not_all_zeros = \bigvee_{i=0}^{n-1} alpha_i
|
||||
let alpha_bits = alpha.to_bits(cs.ns(|| "alpha to bits"))?;
|
||||
let not_all_zeroes = not_all_zeros(&alpha_bits, cs.ns(|| "not all zeroes"))?;
|
||||
|
||||
// 2^n
|
||||
let n = F::size_in_bits() - 1;
|
||||
let mut base_big_int = F::BigInt::from(1u64);
|
||||
base_big_int.muln(n as u32);
|
||||
let base = F::from_repr(base_big_int);
|
||||
|
||||
// packed(alpha) = 2^n + B - A
|
||||
let packed_alpha = alpha.add_constant(cs.ns(|| "packed alpha"), &base)?;
|
||||
|
||||
// less_than = alpha_n * not_all_zeros
|
||||
let packed_alpha_bits = packed_alpha.to_bits(cs.ns(|| "packed alpha to bits"))?;
|
||||
let alpha_n = packed_alpha_bits.first().unwrap();
|
||||
let result = Boolean::and(cs.ns(|| "alpha_n and not all zeroes"), alpha_n, ¬_all_zeroes)?;
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user