clean up pr. remove field comparison

This commit is contained in:
collin 2020-07-17 16:14:13 -07:00
parent 6f9db500c7
commit 92bfad8cc3
14 changed files with 12 additions and 286 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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, &not_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> {

View File

@ -1,3 +0,0 @@
function main(a: field, b: field) -> bool {
return a >= b
}

View File

@ -1,3 +0,0 @@
function main(a: field, b: field) -> bool {
return a > b
}

View File

@ -1,3 +0,0 @@
function main(a: field, b: field) -> bool {
return a <= b
}

View File

@ -1,3 +0,0 @@
function main(a: field, b: field) -> bool {
return a < b
}

View File

@ -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);

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -11,11 +11,13 @@ protected_name = {
| "function"
| "for"
| "if"
| "import"
| "in"
| "let"
| "mut"
| "return"
| "static"
| "test"
| "true"
}