Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement to_radix #587

Merged
merged 14 commits into from
Jan 11, 2023
36 changes: 10 additions & 26 deletions crates/acir/src/circuit/gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ impl Gate {
Gate::Directive(Directive::Truncate { .. }) => "truncate",
Gate::Directive(Directive::Quotient { .. }) => "quotient",
Gate::Directive(Directive::Oddrange { .. }) => "odd_range",
Gate::Directive(Directive::Split { .. }) => "split",
Gate::Directive(Directive::ToBytes { .. }) => "to_bytes",
Gate::Directive(Directive::ToRadix { .. }) => "to_radix",
Gate::GadgetCall(g) => g.name.name(),
}
}
Expand Down Expand Up @@ -78,9 +77,9 @@ impl std::fmt::Debug for Gate {
Gate::Directive(Directive::Truncate { a, b, c: _c, bit_size }) => {
write!(
f,
"Truncate: x{} is x{} truncated to {} bits",
"Truncate: x{} is {} truncated to {} bits",
b.witness_index(),
a.witness_index(),
a,
bit_size
)
}
Expand Down Expand Up @@ -120,20 +119,12 @@ impl std::fmt::Debug for Gate {
Gate::And(g) => write!(f, "{:?}", g),
Gate::Xor(g) => write!(f, "{:?}", g),
Gate::GadgetCall(g) => write!(f, "{:?}", g),
Gate::Directive(Directive::Split { a, b, bit_size: _ }) => {
write!(
f,
"Split: {} into x{}...x{}",
a,
b.first().unwrap().witness_index(),
b.last().unwrap().witness_index(),
)
}
Gate::Directive(Directive::ToBytes { a, b, byte_size: _ }) => {
Gate::Directive(Directive::ToRadix { a, b, radix }) => {
write!(
f,
"To Bytes: {} into x{}...x{}",
"To Radix: {} into base {}; x{}...x{}",
a,
radix,
b.first().unwrap().witness_index(),
b.last().unwrap().witness_index(),
)
Expand Down Expand Up @@ -162,7 +153,7 @@ pub enum Directive {

//Reduces the value of a modulo 2^bit_size and stores the result in b: a= c*2^bit_size + b
Truncate {
a: Witness,
a: Expression,
b: Witness,
c: Witness,
bit_size: u32,
Expand All @@ -176,18 +167,11 @@ pub enum Directive {
bit_size: u32,
},

//bit decomposition of a: a=\sum b[i]*2^i
Split {
a: Expression,
b: Vec<Witness>,
bit_size: u32,
},

//byte decomposition of a: a=\sum b[i]*2^i where b is a byte array
ToBytes {
//decomposition of a: a=\sum b[i]*radix^i where b is an array of witnesses < radix
ToRadix {
a: Expression,
b: Vec<Witness>,
byte_size: u32,
radix: u32,
},
}

Expand Down
2 changes: 1 addition & 1 deletion crates/acir/src/circuit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub struct PublicInputs(pub Vec<Witness>);
impl PublicInputs {
/// Returns the witness index of each public input
pub fn indices(&self) -> Vec<u32> {
self.0.iter().map(|witness| witness.witness_index() as u32).collect()
self.0.iter().map(|witness| witness.witness_index()).collect()
}

pub fn contains(&self, index: usize) -> bool {
Expand Down
6 changes: 5 additions & 1 deletion crates/acir/src/fallback/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ pub fn split(
g.linear_combinations.push((-two_pow, w));
two_pow = FieldElement::from(2_i128) * two_pow;
}
new_gates.push(Gate::Directive(Directive::Split { a: gate, b: bit_vector.clone(), bit_size }));
new_gates.push(Gate::Directive(Directive::ToRadix {
a: gate,
b: bit_vector.clone(),
radix: 2,
}));
new_gates.extend(intermediate_gates);
g.sort();
new_gates.push(Gate::Arithmetic(g));
Expand Down
18 changes: 0 additions & 18 deletions crates/acir/src/opcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ pub enum OPCODE {
HashToField,
EcdsaSecp256k1,
FixedBaseScalarMul,
ToBits,
ToBytes,
}

impl std::fmt::Display for OPCODE {
Expand All @@ -35,8 +33,6 @@ impl OPCODE {
OPCODE::HashToField => 6,
OPCODE::EcdsaSecp256k1 => 7,
OPCODE::FixedBaseScalarMul => 8,
OPCODE::ToBits => 9,
OPCODE::ToBytes => 10,
}
}
pub fn name(&self) -> &str {
Expand All @@ -50,8 +46,6 @@ impl OPCODE {
OPCODE::HashToField => "hash_to_field",
OPCODE::EcdsaSecp256k1 => "ecdsa_secp256k1",
OPCODE::FixedBaseScalarMul => "fixed_base_scalar_mul",
OPCODE::ToBits => "to_bits",
OPCODE::ToBytes => "to_bytes",
}
}
pub fn lookup(op_name: &str) -> Option<OPCODE> {
Expand All @@ -64,8 +58,6 @@ impl OPCODE {
"hash_to_field" => Some(OPCODE::HashToField),
"ecdsa_secp256k1" => Some(OPCODE::EcdsaSecp256k1),
"fixed_base_scalar_mul" => Some(OPCODE::FixedBaseScalarMul),
"to_bits" => Some(OPCODE::ToBits),
"to_bytes" => Some(OPCODE::ToBytes),
_ => None,
}
}
Expand Down Expand Up @@ -118,16 +110,6 @@ impl OPCODE {
input_size: InputSize::Fixed(1),
output_size: OutputSize(2),
},
OPCODE::ToBits => GadgetDefinition {
name: self.name().into(),
input_size: InputSize::Fixed(2),
output_size: OutputSize(1),
},
OPCODE::ToBytes => GadgetDefinition {
name: self.name().into(),
input_size: InputSize::Fixed(2),
output_size: OutputSize(1),
},
}
}
}
Expand Down
75 changes: 28 additions & 47 deletions crates/acvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,62 +133,43 @@ pub trait PartialWitnessGenerator {
_ => true,
}
}
Directive::Truncate { a, b, c, bit_size } => match initial_witness.get(a) {
Some(val_a) => {
let pow: BigUint = BigUint::one() << bit_size;

let int_a = BigUint::from_bytes_be(&val_a.to_bytes());
let int_b: BigUint = &int_a % &pow;
let int_c: BigUint = (&int_a - &int_b) / &pow;

initial_witness.insert(
*b,
FieldElement::from_be_bytes_reduce(&int_b.to_bytes_be()),
);
initial_witness.insert(
*c,
FieldElement::from_be_bytes_reduce(&int_c.to_bytes_be()),
);
false
}
_ => true,
},
Directive::Split { a, b, bit_size } => {
Directive::Truncate { a, b, c, bit_size } => {
match Self::get_value(a, initial_witness) {
Some(val_a) => {
let a_big = BigUint::from_bytes_be(&val_a.to_bytes());
for i in 0..*bit_size {
let j = i as usize;
let v = if a_big.bit(j as u64) {
FieldElement::one()
} else {
FieldElement::zero()
};
match initial_witness.entry(b[j]) {
std::collections::btree_map::Entry::Vacant(e) => {
e.insert(v);
}
std::collections::btree_map::Entry::Occupied(e) => {
if e.get() != &v {
return GateResolution::UnsatisfiedConstrain;
}
}
}
}
let pow: BigUint = BigUint::one() << bit_size;

let int_a = BigUint::from_bytes_be(&val_a.to_bytes());
let int_b: BigUint = &int_a % &pow;
let int_c: BigUint = (&int_a - &int_b) / &pow;

initial_witness.insert(
*b,
FieldElement::from_be_bytes_reduce(&int_b.to_bytes_be()),
);
initial_witness.insert(
*c,
FieldElement::from_be_bytes_reduce(&int_c.to_bytes_be()),
);
false
}
_ => true,
}
}
Directive::ToBytes { a, b, byte_size } => {
Directive::ToRadix { a, b, radix } => {
match Self::get_value(a, initial_witness) {
Some(val_a) => {
let mut a_bytes = val_a.to_bytes();
a_bytes.reverse();
for i in 0..*byte_size {
let i_usize = i as usize;
let v = FieldElement::from_be_bytes_reduce(&[a_bytes[i_usize]]);
match initial_witness.entry(b[i_usize]) {
let a_big = BigUint::from_bytes_be(&val_a.to_bytes());
let a_dec = a_big.to_radix_le(*radix);
if b.len() < a_dec.len() {
return GateResolution::UnsatisfiedConstrain;
}
for i in 0..b.len() {
let v = if i < a_dec.len() {
FieldElement::from_be_bytes_reduce(&[a_dec[i]])
} else {
FieldElement::zero()
};
match initial_witness.entry(b[i]) {
std::collections::btree_map::Entry::Vacant(e) => {
e.insert(v);
}
Expand Down
2 changes: 1 addition & 1 deletion crates/fm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ impl FileManager {

let dir = self.path(anchor).to_path_buf();

candidate_files.push(dir.join(&format!("{}.{}", mod_name, FILE_EXTENSION)));
candidate_files.push(dir.join(format!("{}.{}", mod_name, FILE_EXTENSION)));

for candidate in candidate_files.iter() {
if let Some(file_id) = self.add_file(candidate, FileType::Normal) {
Expand Down
2 changes: 1 addition & 1 deletion crates/nargo/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,5 @@ fn main() {
let stdlib_src_dir = Path::new("../../noir_stdlib/");
rerun_if_stdlib_changes(stdlib_src_dir);
let target = dirs::config_dir().unwrap().join("noir-lang").join("std");
copy(stdlib_src_dir, &target).unwrap();
copy(stdlib_src_dir, target).unwrap();
}
Loading