From 3de414eb16b649a34f261cd31db1934344f44c73 Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Tue, 24 Jan 2023 22:06:41 -0800 Subject: [PATCH 1/2] Add code to generate field-from-bits gadget. --- circuit/tests/field.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/circuit/tests/field.rs b/circuit/tests/field.rs index 8b22f20967..3456c1b129 100644 --- a/circuit/tests/field.rs +++ b/circuit/tests/field.rs @@ -26,7 +26,7 @@ extern crate snarkvm_circuit; #[cfg(test)] mod field { use snarkvm_circuit::Boolean; - use snarkvm_circuit_environment::{Circuit, Inject, Inverse, Mode, SquareRoot}; + use snarkvm_circuit_environment::{Circuit, FromBits, Inject, Inverse, Mode, SquareRoot}; use snarkvm_circuit_types::{Compare, DivUnchecked, Double, Equal, Field, Pow, Square, Ternary}; use snarkvm_console_types_field::{Field as ConsoleField, One, Zero}; @@ -107,6 +107,21 @@ mod field { println!("{}", output); } + #[test] + fn from_bits_le() { + let mut bits = vec![]; + for _i in 0..256 { + bits.push(Boolean::::new(Mode::Private, false)); + } + let _candidate = Field::::from_bits_le(&bits); + + // print Circuit to JSON in console + let circuit_json = Circuit::json(); + let output = serde_json::to_string_pretty(&circuit_json).unwrap(); + println!("// from_bits_le"); + println!("{}", output); + } + #[test] fn inverse() { let a = Field::::new(Mode::Private, ConsoleField::zero()); From 8bcd83bc378e89eb123f9605504d4f4041eb20f5 Mon Sep 17 00:00:00 2001 From: Alessandro Coglio Date: Sat, 28 Jan 2023 21:03:07 -0800 Subject: [PATCH 2/2] Add a test related to field from bits. This is actually to test the constraint subsystem that checks whether the integer value of the bits is not above a known constant value, which for this field operation is the prime minus one, but this test tries that with a smaller number that has some ones as the least significant bits. This confirms what can be inferred by looking at the code, namely that the least significant one bits are skipped, and constraints start only at the first zero bit; furthermore, the first constraint is slightly different than the subsequent ones. --- circuit/tests/field.rs | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/circuit/tests/field.rs b/circuit/tests/field.rs index 3456c1b129..0eac8ee5fc 100644 --- a/circuit/tests/field.rs +++ b/circuit/tests/field.rs @@ -25,8 +25,9 @@ extern crate snarkvm_circuit; #[cfg(test)] mod field { - use snarkvm_circuit::Boolean; - use snarkvm_circuit_environment::{Circuit, FromBits, Inject, Inverse, Mode, SquareRoot}; + use std::ops::{BitAnd, BitOr}; + use snarkvm_circuit::{Boolean, Itertools}; + use snarkvm_circuit_environment::{Circuit, Environment, FromBits, Inject, Inverse, Mode, SquareRoot}; use snarkvm_circuit_types::{Compare, DivUnchecked, Double, Equal, Field, Pow, Square, Ternary}; use snarkvm_console_types_field::{Field as ConsoleField, One, Zero}; @@ -122,6 +123,28 @@ mod field { println!("{}", output); } + #[test] + fn from_bits_le_diff_const() { + let mut bits = vec![]; + for _i in 0..10 { + bits.push(Boolean::::new(Mode::Private, false)); + } + let mut constant = vec![true, true, true, false, false, false, true, true, false, true]; + let is_lte = !constant.iter().zip_eq(bits).fold( + Boolean::constant(false), + |rest_is_less, (this, that)| { + if *this { that.bitand(&rest_is_less) } else { that.bitor(&rest_is_less) } + } + ); + Circuit::assert(is_lte); + + // print Circuit to JSON in console + let circuit_json = Circuit::json(); + let output = serde_json::to_string_pretty(&circuit_json).unwrap(); + println!("// from_bits_le"); + println!("{}", output); + } + #[test] fn inverse() { let a = Field::::new(Mode::Private, ConsoleField::zero());