mirror of
https://github.com/AleoHQ/leo.git
synced 2024-09-11 15:05:33 +03:00
clean up pr. remove field comparison
This commit is contained in:
parent
6f9db500c7
commit
92bfad8cc3
@ -20,9 +20,6 @@ pub fn evaluate_ge<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
num_1.greater_than_or_equal(unique_namespace, &num_2)
|
||||
}
|
||||
(ConstrainedValue::Field(field_1), ConstrainedValue::Field(field_2)) => {
|
||||
field_1.greater_than_or_equal(unique_namespace, &field_2)
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||
return evaluate_ge(&mut unique_namespace, val_1, val_2, span);
|
||||
|
@ -20,9 +20,6 @@ pub fn evaluate_gt<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
num_1.greater_than(unique_namespace, &num_2)
|
||||
}
|
||||
(ConstrainedValue::Field(field_1), ConstrainedValue::Field(field_2)) => {
|
||||
field_1.greater_than(unique_namespace, &field_2)
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||
return evaluate_gt(&mut unique_namespace, val_1, val_2, span);
|
||||
|
@ -20,9 +20,6 @@ pub fn evaluate_le<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
num_1.less_than_or_equal(unique_namespace, &num_2)
|
||||
}
|
||||
(ConstrainedValue::Field(field_1), ConstrainedValue::Field(field_2)) => {
|
||||
field_1.less_than_or_equal(unique_namespace, &field_2)
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||
return evaluate_le(&mut unique_namespace, val_1, val_2, span);
|
||||
|
@ -20,9 +20,6 @@ pub fn evaluate_lt<F: Field + PrimeField, G: GroupType<F>, CS: ConstraintSystem<
|
||||
(ConstrainedValue::Integer(num_1), ConstrainedValue::Integer(num_2)) => {
|
||||
num_1.less_than(unique_namespace, &num_2)
|
||||
}
|
||||
(ConstrainedValue::Field(field_1), ConstrainedValue::Field(field_2)) => {
|
||||
field_1.less_than(unique_namespace, &field_2)
|
||||
}
|
||||
(ConstrainedValue::Unresolved(string), val_2) => {
|
||||
let val_1 = ConstrainedValue::from_other(string, &val_2, span.clone())?;
|
||||
return evaluate_lt(&mut unique_namespace, val_1, val_2, span);
|
||||
|
@ -1,7 +1,6 @@
|
||||
//! A data type that represents a field value
|
||||
|
||||
use crate::errors::FieldError;
|
||||
use leo_gadgets::bits::{ComparatorGadget, EvaluateLtGadget};
|
||||
use leo_types::Span;
|
||||
|
||||
use snarkos_errors::gadgets::SynthesisError;
|
||||
@ -21,7 +20,6 @@ use snarkos_models::{
|
||||
},
|
||||
},
|
||||
};
|
||||
use snarkos_utilities::BigInteger;
|
||||
|
||||
use std::{borrow::Borrow, cmp::Ordering};
|
||||
|
||||
@ -215,72 +213,6 @@ 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> {
|
||||
// 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::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)
|
||||
}
|
||||
}
|
||||
|
||||
impl<F: Field + PrimeField> ComparatorGadget<F> for FieldType<F> {}
|
||||
|
||||
impl<F: Field + PrimeField> EqGadget<F> for FieldType<F> {}
|
||||
|
||||
impl<F: Field + PrimeField> ConditionalEqGadget<F> for FieldType<F> {
|
||||
|
@ -1,3 +0,0 @@
|
||||
function main(a: field, b: field) -> bool {
|
||||
return a >= b
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
function main(a: field, b: field) -> bool {
|
||||
return a > b
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
function main(a: field, b: field) -> bool {
|
||||
return a <= b
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
function main(a: field, b: field) -> bool {
|
||||
return a < b
|
||||
}
|
@ -297,192 +297,6 @@ fn test_eq() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] // fix comparators before uncommenting
|
||||
fn test_ge() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..10 {
|
||||
let r1: Fq = rng.gen();
|
||||
let r2: Fq = rng.gen();
|
||||
|
||||
let mut r1_buf = Vec::new();
|
||||
let mut r2_buf = Vec::new();
|
||||
|
||||
r1.write(&mut r1_buf).unwrap();
|
||||
r2.write(&mut r2_buf).unwrap();
|
||||
|
||||
let r1_bigint = BigUint::from_bytes_le(&r1_buf);
|
||||
let r2_bigint = BigUint::from_bytes_le(&r2_buf);
|
||||
|
||||
// test equal
|
||||
|
||||
let bytes = include_bytes!("ge.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
||||
]);
|
||||
|
||||
output_true(program);
|
||||
|
||||
// test greater than or equals
|
||||
|
||||
let result = r1.ge(&r2);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
||||
Some(InputValue::Field(r2_bigint.to_str_radix(10))),
|
||||
]);
|
||||
|
||||
output_expected_boolean(program, result)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] // fix comparators before uncommenting
|
||||
fn test_gt() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..10 {
|
||||
let r1: Fq = rng.gen();
|
||||
let r2: Fq = rng.gen();
|
||||
|
||||
let mut r1_buf = Vec::new();
|
||||
let mut r2_buf = Vec::new();
|
||||
|
||||
r1.write(&mut r1_buf).unwrap();
|
||||
r2.write(&mut r2_buf).unwrap();
|
||||
|
||||
let r1_bigint = BigUint::from_bytes_le(&r1_buf);
|
||||
let r2_bigint = BigUint::from_bytes_le(&r2_buf);
|
||||
|
||||
// test equal
|
||||
|
||||
let bytes = include_bytes!("gt.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
||||
]);
|
||||
|
||||
output_true(program);
|
||||
|
||||
// test greater than
|
||||
|
||||
let result = r1.gt(&r2);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
||||
Some(InputValue::Field(r2_bigint.to_str_radix(10))),
|
||||
]);
|
||||
|
||||
output_expected_boolean(program, result)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] // fix comparators before uncommenting
|
||||
fn test_le() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
for _ in 0..10 {
|
||||
let r1: Fq = rng.gen();
|
||||
let r2: Fq = rng.gen();
|
||||
|
||||
let mut r1_buf = Vec::new();
|
||||
let mut r2_buf = Vec::new();
|
||||
|
||||
r1.write(&mut r1_buf).unwrap();
|
||||
r2.write(&mut r2_buf).unwrap();
|
||||
|
||||
let r1_bigint = BigUint::from_bytes_le(&r1_buf);
|
||||
let r2_bigint = BigUint::from_bytes_le(&r2_buf);
|
||||
|
||||
// test equal
|
||||
let bytes = include_bytes!("le.leo");
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
||||
]);
|
||||
|
||||
output_true(program);
|
||||
|
||||
// test less than or equals
|
||||
|
||||
let result = r1.le(&r2);
|
||||
|
||||
let mut program = parse_program(bytes).unwrap();
|
||||
|
||||
program.set_inputs(vec![
|
||||
Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
||||
Some(InputValue::Field(r2_bigint.to_str_radix(10))),
|
||||
]);
|
||||
|
||||
output_expected_boolean(program, result)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore] // fix comparators before uncommenting
|
||||
fn test_lt() {
|
||||
// let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
||||
// for _ in 0..10 {
|
||||
// let r1: Fq = rng.gen();
|
||||
// let r2: Fq = rng.gen();
|
||||
|
||||
// let r1 = Fq::zero() - &Fq::one();
|
||||
// let r2 = Fq::zero();
|
||||
//
|
||||
// let mut r1_buf = Vec::new();
|
||||
// let mut r2_buf = Vec::new();
|
||||
//
|
||||
// r1.write(&mut r1_buf).unwrap();
|
||||
// r2.write(&mut r2_buf).unwrap();
|
||||
//
|
||||
// let r1_bigint = BigUint::from_bytes_le(&r1_buf);
|
||||
// let r2_bigint = BigUint::from_bytes_le(&r2_buf);
|
||||
//
|
||||
// println!("r1 `{}`", r1_bigint);
|
||||
// println!("r2 `{}`", r2_bigint);
|
||||
//
|
||||
//
|
||||
// // test equal
|
||||
// let bytes = include_bytes!("lt.leo");
|
||||
// let mut program = parse_program(bytes).unwrap();
|
||||
//
|
||||
// program.set_inputs(vec![
|
||||
// Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
||||
// Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
||||
// ]);
|
||||
//
|
||||
// // println!("{} < {}", r1, r1);
|
||||
// output_false(program);
|
||||
//
|
||||
// // test greater than
|
||||
//
|
||||
// let result = r1.lt(&r2);
|
||||
//
|
||||
// let mut program = parse_program(bytes).unwrap();
|
||||
//
|
||||
// program.set_inputs(vec![
|
||||
// Some(InputValue::Field(r1_bigint.to_str_radix(10))),
|
||||
// Some(InputValue::Field(r2_bigint.to_str_radix(10))),
|
||||
// ]);
|
||||
//
|
||||
// output_expected_boolean(program, result)
|
||||
// }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_assert_eq_pass() {
|
||||
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
||||
|
@ -5,6 +5,7 @@ use snarkos_models::{
|
||||
};
|
||||
|
||||
/// Single bit binary adder with carry bit
|
||||
/// https://en.wikipedia.org/wiki/Adder_(electronics)#Full_adder
|
||||
/// sum = (a XOR b) XOR carry
|
||||
/// carry = a AND b OR carry AND (a XOR b)
|
||||
/// Returns (sum, carry)
|
||||
|
@ -113,11 +113,10 @@ macro_rules! div_int_impl {
|
||||
let mut q = zero.clone();
|
||||
let mut r = zero.clone();
|
||||
|
||||
for (i, bit) in a.bits.iter().rev().enumerate() {
|
||||
if i == 0 {
|
||||
// skip the sign bit
|
||||
continue;
|
||||
}
|
||||
let mut index = <$gadget as Int>::SIZE - 1 as usize;
|
||||
let mut bit_value = (1 as <$gadget as Int>::IntegerType) << ((index - 1) as <$gadget as Int>::IntegerType);
|
||||
|
||||
for (i, bit) in a.bits.iter().rev().enumerate().skip(1) {
|
||||
|
||||
// Left shift remainder by 1
|
||||
r = r.add(
|
||||
@ -157,12 +156,14 @@ macro_rules! div_int_impl {
|
||||
&r
|
||||
)?;
|
||||
|
||||
let index = <$gadget as Int>::SIZE - 1 - i as usize;
|
||||
let bit_value = (1 as <$gadget as Int>::IntegerType) << (index as <$gadget as Int>::IntegerType);
|
||||
index = index - 1;
|
||||
|
||||
let mut q_new = q.clone();
|
||||
q_new.bits[index] = true_bit.clone();
|
||||
q_new.value = Some(q_new.value.unwrap() + bit_value);
|
||||
|
||||
bit_value = (bit_value >> 1);
|
||||
|
||||
q = Self::conditionally_select(
|
||||
&mut cs.ns(|| format!("set_bit_or_same_{}", i)),
|
||||
&can_sub,
|
||||
|
@ -55,7 +55,7 @@ macro_rules! cmp_gadget_impl {
|
||||
// evaluate a <= b
|
||||
let less_or_equal = Boolean::or(cs.ns(|| format!("less or equal [{}]", i)), &less, &equal)?;
|
||||
|
||||
// select the current result if it is the first bit difference
|
||||
// If `all_equal` is `true`, sets `result` to `less_or_equal`. Else, sets `result` to `result`.
|
||||
result = Boolean::conditionally_select(cs.ns(|| format!("select bit [{}]", i)), &all_equal, &less_or_equal, &result)?;
|
||||
|
||||
// keep track of equal bits
|
||||
|
@ -11,11 +11,13 @@ protected_name = {
|
||||
| "function"
|
||||
| "for"
|
||||
| "if"
|
||||
| "import"
|
||||
| "in"
|
||||
| "let"
|
||||
| "mut"
|
||||
| "return"
|
||||
| "static"
|
||||
| "test"
|
||||
| "true"
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user