From 62fd553e9130fd8b106124ea567ada8c38986bf1 Mon Sep 17 00:00:00 2001 From: dark64 Date: Wed, 1 Dec 2021 17:05:56 +0100 Subject: [PATCH 01/21] add missing case in zir propagation --- zokrates_core/src/flatten/mod.rs | 12 ++++--- .../src/static_analysis/zir_propagation.rs | 35 +++++++++++++++++++ zokrates_core/src/zir/mod.rs | 3 ++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index a8b2c68c..4b1338a6 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -459,7 +459,9 @@ impl<'ast, T: Field> Flattener<'ast, T> { let condition_id = self.use_sym(); statements_flattened.push(FlatStatement::Definition(condition_id, condition_flat)); - self.condition_cache.insert(condition, condition_id); + if !condition.is_constant() { + self.condition_cache.insert(condition, condition_id); + } let (consequence, alternative) = if self.config.isolate_branches { let mut consequence_statements = vec![]; @@ -754,9 +756,11 @@ impl<'ast, T: Field> Flattener<'ast, T> { statements_flattened: &mut FlatStatements, expression: BooleanExpression<'ast, T>, ) -> FlatExpression { - // check the cache - if let Some(c) = self.condition_cache.get(&expression) { - return (*c).into(); + if !expression.is_constant() { + // check the cache + if let Some(c) = self.condition_cache.get(&expression) { + return (*c).into(); + } } match expression { diff --git a/zokrates_core/src/static_analysis/zir_propagation.rs b/zokrates_core/src/static_analysis/zir_propagation.rs index 8971b2c1..7c29fd37 100644 --- a/zokrates_core/src/static_analysis/zir_propagation.rs +++ b/zokrates_core/src/static_analysis/zir_propagation.rs @@ -76,6 +76,41 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { } } } + ZirStatement::IfElse(e, consequence, alternative) => { + match self.fold_boolean_expression(e)? { + BooleanExpression::Value(true) => Ok(consequence + .into_iter() + .map(|s| self.fold_statement(s)) + .collect::, _>>()? + .into_iter() + .flatten() + .collect()), + BooleanExpression::Value(false) => Ok(alternative + .into_iter() + .map(|s| self.fold_statement(s)) + .collect::, _>>()? + .into_iter() + .flatten() + .collect()), + e => Ok(vec![ZirStatement::IfElse( + e, + consequence + .into_iter() + .map(|s| self.fold_statement(s)) + .collect::, _>>()? + .into_iter() + .flatten() + .collect(), + alternative + .into_iter() + .map(|s| self.fold_statement(s)) + .collect::, _>>()? + .into_iter() + .flatten() + .collect(), + )]), + } + } ZirStatement::MultipleDefinition(assignees, list) => { for a in &assignees { self.constants.remove(&a.id); diff --git a/zokrates_core/src/zir/mod.rs b/zokrates_core/src/zir/mod.rs index 9978ed14..5d621b28 100644 --- a/zokrates_core/src/zir/mod.rs +++ b/zokrates_core/src/zir/mod.rs @@ -364,6 +364,9 @@ impl<'ast, T> BooleanExpression<'ast, T> { current: vec![self], } } + pub fn is_constant(&self) -> bool { + matches!(self, BooleanExpression::Value(_)) + } } // Downcasts From bc427597a4fceed9c3f7572241a1ec377c18f1bd Mon Sep 17 00:00:00 2001 From: schaeff Date: Thu, 2 Dec 2021 18:29:56 +0100 Subject: [PATCH 02/21] use arkff in zokrates_field --- Cargo.lock | 13 ++ zokrates_core/src/ir/expression.rs | 4 +- zokrates_field/Cargo.toml | 4 +- zokrates_field/src/bls12_377.rs | 5 +- zokrates_field/src/bls12_381.rs | 5 +- zokrates_field/src/bn128.rs | 199 +++++++----------- zokrates_field/src/bw6_761.rs | 7 +- zokrates_field/src/lib.rs | 310 +++++++++++++++-------------- 8 files changed, 270 insertions(+), 277 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 41db65de..b56a8b3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,6 +67,17 @@ dependencies = [ "ark-std", ] +[[package]] +name = "ark-bls12-381" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e1c2ad76c4f725520440b981df3ce2d635f2baa1122750c757c0cf0f3d4b74" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + [[package]] name = "ark-bn254" version = "0.2.0" @@ -2483,10 +2494,12 @@ name = "zokrates_field" version = "0.4.0" dependencies = [ "ark-bls12-377", + "ark-bls12-381", "ark-bn254", "ark-bw6-761", "ark-ec", "ark-ff", + "ark-serialize", "bellman_ce", "bincode", "lazy_static", diff --git a/zokrates_core/src/ir/expression.rs b/zokrates_core/src/ir/expression.rs index 57ec2753..77069a4d 100644 --- a/zokrates_core/src/ir/expression.rs +++ b/zokrates_core/src/ir/expression.rs @@ -259,10 +259,8 @@ impl Mul<&T> for LinComb { impl Div<&T> for LinComb { type Output = LinComb; - // Clippy warns about multiplication in a method named div. It's okay, here, since we multiply with the inverse. - #[allow(clippy::suspicious_arithmetic_impl)] fn div(self, scalar: &T) -> LinComb { - self * &scalar.inverse_mul().unwrap() + self * &T::one().div(scalar) } } diff --git a/zokrates_field/Cargo.toml b/zokrates_field/Cargo.toml index cea2f9ec..7c26729b 100644 --- a/zokrates_field/Cargo.toml +++ b/zokrates_field/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [features] default = ["ark", "bellman"] -ark = ["ark-ff", "ark-ec", "ark-bn254", "ark-bls12-377", "ark-bw6-761"] +ark = ["ark-ff", "ark-ec", "ark-bn254", "ark-bls12-381", "ark-bls12-377", "ark-bw6-761", "ark-serialize"] bellman = ["bellman_ce"] [dependencies] @@ -27,7 +27,9 @@ ark-ff = { version = "^0.2.0", default-features = false, optional = true } ark-ec = { version = "^0.2.0", default-features = false, optional = true } ark-bn254 = { version = "^0.2.0", features = ["curve"], default-features = false, optional = true } ark-bls12-377 = { version = "^0.2.0", features = ["curve"], default-features = false, optional = true } +ark-bls12-381 = { version = "^0.2.0", features = ["curve"], default-features = false, optional = true } ark-bw6-761 = { version = "^0.2.0", default-features = false, optional = true } +ark-serialize = { version = "^0.2.0", default-features = false, optional = true } [dev-dependencies] rand = "0.4" diff --git a/zokrates_field/src/bls12_377.rs b/zokrates_field/src/bls12_377.rs index 08045dcb..54e4f4f1 100644 --- a/zokrates_field/src/bls12_377.rs +++ b/zokrates_field/src/bls12_377.rs @@ -1,6 +1,9 @@ +use ark_bls12_377::Bls12_377; + prime_field!( b"8444461749428370424248824938781546531375899335154063827935233455917409239041", - "bls12_377" + "bls12_377", + Bls12_377 ); #[cfg(feature = "ark")] diff --git a/zokrates_field/src/bls12_381.rs b/zokrates_field/src/bls12_381.rs index 25f4e827..e76dbc0b 100644 --- a/zokrates_field/src/bls12_381.rs +++ b/zokrates_field/src/bls12_381.rs @@ -1,6 +1,9 @@ +use ark_bls12_381::Bls12_381; + prime_field!( b"52435875175126190479447740508185965837690552500527637822603658699938581184513", - "bls12_381" + "bls12_381", + Bls12_381 ); #[cfg(feature = "bellman")] diff --git a/zokrates_field/src/bn128.rs b/zokrates_field/src/bn128.rs index b7bf2ea2..54c08a7a 100644 --- a/zokrates_field/src/bn128.rs +++ b/zokrates_field/src/bn128.rs @@ -1,6 +1,9 @@ +use ark_bn254::Bn254; + prime_field!( b"21888242871839275222246405745257275088548364400416034343698204186575808495617", - "bn128" + "bn128", + Bn254 ); #[cfg(feature = "bellman")] @@ -8,9 +11,6 @@ use bellman_ce::pairing::bn256::{Bn256, Fq2}; #[cfg(feature = "bellman")] bellman_extensions!(Bn256, Fq2); -#[cfg(feature = "ark")] -use ark_bn254::Bn254; -#[cfg(feature = "ark")] ark_extensions!(Bn254); #[cfg(test)] @@ -37,157 +37,155 @@ mod tests { ); } - #[test] - fn positive_number() { - assert_eq!( - "1234245612".parse::().unwrap(), - FieldPrime::from("1234245612").value - ); - } + // #[test] + // fn positive_number() { + // assert_eq!( + // "1234245612".parse::().unwrap(), + // FieldPrime::from("1234245612").value + // ); + // } - #[test] - fn negative_number() { - assert_eq!( - P.checked_sub(&"12".parse::().unwrap()).unwrap(), - FieldPrime::from("-12").value - ); - } + // #[test] + // fn negative_number() { + // assert_eq!( + // P.checked_sub(&"12".parse::().unwrap()).unwrap(), + // FieldPrime::from("-12").value + // ); + // } #[test] fn addition() { assert_eq!( - "65484493".parse::().unwrap(), - (FieldPrime::from("65416358") + FieldPrime::from("68135")).value + FieldPrime::from("65484493"), + FieldPrime::from("65416358") + FieldPrime::from("68135") ); assert_eq!( - "65484493".parse::().unwrap(), - (FieldPrime::from("65416358") + &FieldPrime::from("68135")).value + FieldPrime::from("65484493"), + FieldPrime::from("65416358") + &FieldPrime::from("68135") ); } #[test] fn addition_negative_small() { assert_eq!( - "3".parse::().unwrap(), - (FieldPrime::from("5") + FieldPrime::from("-2")).value + FieldPrime::from("3"), + FieldPrime::from("5") + FieldPrime::from(-2) ); assert_eq!( - "3".parse::().unwrap(), - (FieldPrime::from("5") + &FieldPrime::from("-2")).value + FieldPrime::from("3"), + FieldPrime::from("5") + &FieldPrime::from(-2) ); } #[test] fn addition_negative() { assert_eq!( - "65348223".parse::().unwrap(), - (FieldPrime::from("65416358") + FieldPrime::from("-68135")).value + FieldPrime::from("65348223"), + FieldPrime::from("65416358") + FieldPrime::from(-68135) ); assert_eq!( - "65348223".parse::().unwrap(), - (FieldPrime::from("65416358") + &FieldPrime::from("-68135")).value + FieldPrime::from("65348223"), + FieldPrime::from("65416358") + &FieldPrime::from(-68135) ); } #[test] fn subtraction() { assert_eq!( - "65348223".parse::().unwrap(), - (FieldPrime::from("65416358") - FieldPrime::from("68135")).value + FieldPrime::from("65348223"), + FieldPrime::from("65416358") - FieldPrime::from("68135") ); assert_eq!( - "65348223".parse::().unwrap(), - (FieldPrime::from("65416358") - &FieldPrime::from("68135")).value + FieldPrime::from("65348223"), + FieldPrime::from("65416358") - &FieldPrime::from("68135") ); } #[test] fn subtraction_negative() { assert_eq!( - "65484493".parse::().unwrap(), - (FieldPrime::from("65416358") - FieldPrime::from("-68135")).value + FieldPrime::from("65484493"), + FieldPrime::from("65416358") - FieldPrime::from(-68135) ); assert_eq!( - "65484493".parse::().unwrap(), - (FieldPrime::from("65416358") - &FieldPrime::from("-68135")).value + FieldPrime::from("65484493"), + FieldPrime::from("65416358") - &FieldPrime::from(-68135) ); } #[test] fn subtraction_overflow() { assert_eq!( - "21888242871839275222246405745257275088548364400416034343698204186575743147394" - .parse::() - .unwrap(), - (FieldPrime::from("68135") - FieldPrime::from("65416358")).value + FieldPrime::from( + "21888242871839275222246405745257275088548364400416034343698204186575743147394" + ), + FieldPrime::from("68135") - FieldPrime::from("65416358") ); assert_eq!( - "21888242871839275222246405745257275088548364400416034343698204186575743147394" - .parse::() - .unwrap(), - (FieldPrime::from("68135") - &FieldPrime::from("65416358")).value + FieldPrime::from( + "21888242871839275222246405745257275088548364400416034343698204186575743147394" + ), + FieldPrime::from("68135") - &FieldPrime::from("65416358") ); } #[test] fn multiplication() { assert_eq!( - "13472".parse::().unwrap(), - (FieldPrime::from("32") * FieldPrime::from("421")).value + FieldPrime::from("13472"), + FieldPrime::from("32") * FieldPrime::from("421") ); assert_eq!( - "13472".parse::().unwrap(), - (FieldPrime::from("32") * &FieldPrime::from("421")).value + FieldPrime::from("13472"), + FieldPrime::from("32") * &FieldPrime::from("421") ); } #[test] fn multiplication_negative() { assert_eq!( - "21888242871839275222246405745257275088548364400416034343698204186575808014369" - .parse::() - .unwrap(), - (FieldPrime::from("54") * FieldPrime::from("-8912")).value + FieldPrime::from( + "21888242871839275222246405745257275088548364400416034343698204186575808014369" + ), + FieldPrime::from("54") * FieldPrime::from(-8912) ); assert_eq!( - "21888242871839275222246405745257275088548364400416034343698204186575808014369" - .parse::() - .unwrap(), - (FieldPrime::from("54") * &FieldPrime::from("-8912")).value + FieldPrime::from( + "21888242871839275222246405745257275088548364400416034343698204186575808014369" + ), + FieldPrime::from("54") * &FieldPrime::from(-8912) ); } #[test] fn multiplication_two_negative() { assert_eq!( - "648".parse::().unwrap(), - (FieldPrime::from("-54") * FieldPrime::from("-12")).value + FieldPrime::from("648"), + FieldPrime::from(-54) * FieldPrime::from(-12) ); assert_eq!( - "648".parse::().unwrap(), - (FieldPrime::from("-54") * &FieldPrime::from("-12")).value + FieldPrime::from("648"), + FieldPrime::from(-54) * &FieldPrime::from(-12) ); } #[test] fn multiplication_overflow() { assert_eq!( - "6042471409729479866150380306128222617399890671095126975526159292198160466142" - .parse::() - .unwrap(), - (FieldPrime::from( + FieldPrime::from( + "6042471409729479866150380306128222617399890671095126975526159292198160466142" + ), + FieldPrime::from( "21888242871839225222246405785257275088694311157297823662689037894645225727" - ) * FieldPrime::from("218882428715392752222464057432572755886923")) - .value + ) * FieldPrime::from("218882428715392752222464057432572755886923") ); assert_eq!( - "6042471409729479866150380306128222617399890671095126975526159292198160466142" - .parse::() - .unwrap(), - (FieldPrime::from( + FieldPrime::from( + "6042471409729479866150380306128222617399890671095126975526159292198160466142" + ), + FieldPrime::from( "21888242871839225222246405785257275088694311157297823662689037894645225727" - ) * &FieldPrime::from("218882428715392752222464057432572755886923")) - .value + ) * &FieldPrime::from("218882428715392752222464057432572755886923") ); } @@ -218,8 +216,8 @@ mod tests { #[test] fn pow_usize() { assert_eq!( - "614787626176508399616".parse::().unwrap(), - (FieldPrime::from("54").pow(12)).value + FieldPrime::from("614787626176508399616"), + FieldPrime::from("54").pow(12) ); } @@ -233,6 +231,7 @@ mod tests { #[test] fn serde_json_ser_deser() { let serialized = serde_json::to_string(&FieldPrime::from("11")).unwrap(); + println!("{}", serialized); let deserialized = serde_json::from_str(&serialized).unwrap(); assert_eq!(FieldPrime::from("11"), deserialized); } @@ -293,54 +292,6 @@ mod tests { ); } - #[test] - fn test_extended_euclid() { - assert_eq!( - ( - ToBigInt::to_bigint(&1).unwrap(), - ToBigInt::to_bigint(&-9).unwrap(), - ToBigInt::to_bigint(&47).unwrap() - ), - extended_euclid( - &ToBigInt::to_bigint(&120).unwrap(), - &ToBigInt::to_bigint(&23).unwrap() - ) - ); - assert_eq!( - ( - ToBigInt::to_bigint(&2).unwrap(), - ToBigInt::to_bigint(&2).unwrap(), - ToBigInt::to_bigint(&-11).unwrap() - ), - extended_euclid( - &ToBigInt::to_bigint(&122).unwrap(), - &ToBigInt::to_bigint(&22).unwrap() - ) - ); - assert_eq!( - ( - ToBigInt::to_bigint(&2).unwrap(), - ToBigInt::to_bigint(&-9).unwrap(), - ToBigInt::to_bigint(&47).unwrap() - ), - extended_euclid( - &ToBigInt::to_bigint(&240).unwrap(), - &ToBigInt::to_bigint(&46).unwrap() - ) - ); - let (b, s, _) = extended_euclid(&ToBigInt::to_bigint(&253).unwrap(), &*P); - assert_eq!(b, BigInt::one()); - let s_field = FieldPrime { - value: &s - s.div_floor(&*P) * &*P, - }; - assert_eq!( - FieldPrime::from( - "12717674712096337777352654721552646000065650461901806515903699665717959876900" - ), - s_field - ); - } - #[cfg(feature = "bellman")] mod bellman { use super::*; diff --git a/zokrates_field/src/bw6_761.rs b/zokrates_field/src/bw6_761.rs index ef050191..122ae912 100644 --- a/zokrates_field/src/bw6_761.rs +++ b/zokrates_field/src/bw6_761.rs @@ -1,9 +1,10 @@ +use ark_bw6_761::BW6_761; + prime_field!( b"258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177", - "bw6_761" + "bw6_761", + BW6_761 ); -#[cfg(feature = "ark")] -use ark_bw6_761::BW6_761; #[cfg(feature = "ark")] ark_extensions!(BW6_761); diff --git a/zokrates_field/src/lib.rs b/zokrates_field/src/lib.rs index 030841a9..3bdd40eb 100644 --- a/zokrates_field/src/lib.rs +++ b/zokrates_field/src/lib.rs @@ -93,7 +93,7 @@ pub trait Field: /// Returns this `Field`'s contents as decimal string fn to_dec_string(&self) -> String; /// Returns the multiplicative inverse, i.e.: self * self.inverse_mul() = Self::one() - fn inverse_mul(&self) -> Option; + //fn inverse_mul(&self) -> Option; /// Returns the smallest value that can be represented by this field type. fn min_value() -> Self; /// Returns the largest value that can be represented by this field type. @@ -153,13 +153,14 @@ pub trait Field: #[macro_use] mod prime_field { macro_rules! prime_field { - ($modulus:expr, $name:expr) => { + ($modulus:expr, $name:expr, $v:ty) => { use crate::{Field, FieldParseError, Pow}; + use ark_ff::{Field as ArkField, PrimeField}; use lazy_static::lazy_static; - use num_bigint::{BigInt, BigUint, Sign, ToBigInt}; - use num_integer::Integer; + use num_bigint::{BigInt, BigUint}; use num_traits::{CheckedDiv, One, Zero}; - use serde_derive::{Deserialize, Serialize}; + use serde::de::{self, Visitor}; + use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::convert::From; use std::convert::TryFrom; use std::fmt; @@ -170,86 +171,90 @@ mod prime_field { static ref P: BigInt = BigInt::parse_bytes($modulus, 10).unwrap(); } - #[derive(PartialEq, PartialOrd, Clone, Eq, Ord, Hash, Serialize, Deserialize)] + type Fr = <$v as ark_ec::PairingEngine>::Fr; + + #[derive(PartialEq, PartialOrd, Clone, Eq, Ord, Hash)] pub struct FieldPrime { - value: BigInt, + v: Fr, } impl Field for FieldPrime { fn bits(&self) -> u32 { - self.value.bits() as u32 + use ark_ff::BigInteger; + let bits = self.v.into_repr().to_bits_be(); + let mut size = bits.len(); + for bit in bits { + if !bit { + size -= 1; + } else { + break; + } + } + size as u32 } fn to_biguint(&self) -> BigUint { - self.value.to_biguint().unwrap() + use ark_ff::BigInteger; + BigUint::from_bytes_le(&self.v.into_repr().to_bytes_le()) } fn to_byte_vector(&self) -> Vec { - match self.value.to_biguint() { - Option::Some(val) => val.to_bytes_le(), - Option::None => panic!("Should never happen."), - } + use ark_ff::BigInteger; + self.v.into_repr().to_bytes_be() } fn from_byte_vector(bytes: Vec) -> Self { - let uval = BigUint::from_bytes_le(bytes.as_slice()); + use ark_ff::FromBytes; + FieldPrime { - value: BigInt::from_biguint(Sign::Plus, uval), + v: Fr::from(::BigInt::read(&bytes[..]).unwrap()), } } fn to_dec_string(&self) -> String { - self.value.to_str_radix(10) + self.to_string() } - fn inverse_mul(&self) -> Option { - let (b, s, _) = extended_euclid(&self.value, &*P); - if b == BigInt::one() { - Some(FieldPrime { - value: &s - s.div_floor(&*P) * &*P, - }) - } else { - None - } - } fn min_value() -> FieldPrime { - FieldPrime { - value: ToBigInt::to_bigint(&0).unwrap(), - } + FieldPrime { v: Fr::from(0u32) } } fn max_value() -> FieldPrime { FieldPrime { - value: &*P - ToBigInt::to_bigint(&1).unwrap(), + v: Fr::from(0u32) - Fr::from(1u32), } } fn max_unique_value() -> FieldPrime { - use num_traits::Pow; - FieldPrime { - value: BigInt::from(2u32).pow(Self::get_required_bits() - 1) - 1, + v: Fr::from(2u32).pow([Self::get_required_bits() as u64 - 1]) + - Fr::from(1u32), } } fn get_required_bits() -> usize { (*P).bits() } fn try_from_dec_str(s: &str) -> Result { - Self::try_from_str(s, 10) - } - fn try_from_str(s: &str, radix: u32) -> Result { - let x = BigInt::parse_bytes(s.as_bytes(), radix).ok_or(FieldParseError)?; + use std::str::FromStr; + Ok(FieldPrime { - value: &x - x.div_floor(&*P) * &*P, + v: Fr::from_str(s).map_err(|_| FieldParseError)?, }) } + fn try_from_str(_: &str, _: u32) -> Result { + unimplemented!("try from str") + // let x = BigInt::parse_bytes(s.as_bytes(), radix).ok_or(FieldParseError)?; + // Ok(FieldPrime { + // value: &x - x.div_floor(&*P) * &*P, + // v: field_new!() + // }) + } fn to_compact_dec_string(&self) -> String { - // values up to (p-1)/2 included are represented as positive, values between (p+1)/2 and p-1 as represented as negative by subtracting p - if self.value <= FieldPrime::max_value().value / 2 { - format!("{}", self.value.to_str_radix(10)) + //values up to (p-1)/2 included are represented as positive, values between (p+1)/2 and p-1 as represented as negative by subtracting p + if self.v.into_repr() <= Fr::modulus_minus_one_div_two() { + format!("{}", self.to_string()) } else { format!( - "({})", - (&self.value - (FieldPrime::max_value().value + BigInt::one())) - .to_str_radix(10) + "(-{})", + (FieldPrime::max_value() - self + FieldPrime::one()).to_string() ) } } @@ -270,57 +275,53 @@ mod prime_field { impl Default for FieldPrime { fn default() -> Self { - FieldPrime { - value: BigInt::default(), - } + FieldPrime { v: Fr::from(0u32) } } } impl Display for FieldPrime { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.value.to_str_radix(10)) + write!(f, "{}", self.to_biguint()) } } impl Debug for FieldPrime { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self.value.to_str_radix(10)) + write!(f, "{}", self.to_biguint()) } } impl From for FieldPrime { fn from(num: i32) -> Self { - let x = ToBigInt::to_bigint(&num).unwrap(); - FieldPrime { - value: &x - x.div_floor(&*P) * &*P, + if num < 0 { + FieldPrime { + v: Fr::zero() - Fr::from((-num) as u32), + } + } else { + FieldPrime { + v: Fr::from(num as u32), + } } } } impl From for FieldPrime { fn from(num: u32) -> Self { - let x = ToBigInt::to_bigint(&num).unwrap(); - FieldPrime { - value: &x - x.div_floor(&*P) * &*P, - } + FieldPrime { v: Fr::from(num) } } } impl From for FieldPrime { fn from(num: usize) -> Self { - let x = ToBigInt::to_bigint(&num).unwrap(); FieldPrime { - value: &x - x.div_floor(&*P) * &*P, + v: Fr::from(num as u128), } } } impl From for FieldPrime { fn from(num: u128) -> Self { - let x = ToBigInt::to_bigint(&num).unwrap(); - FieldPrime { - value: &x - x.div_floor(&*P) * &*P, - } + FieldPrime { v: Fr::from(num) } } } @@ -330,8 +331,10 @@ mod prime_field { fn try_from(value: BigUint) -> Result { match value <= Self::max_value().to_biguint() { true => { - let x = ToBigInt::to_bigint(&value).unwrap(); - Ok(FieldPrime { value: x }) + use std::str::FromStr; + Ok(FieldPrime { + v: Fr::from_str(&value.to_string()).unwrap(), + }) } false => Err(()), } @@ -340,20 +343,16 @@ mod prime_field { impl Zero for FieldPrime { fn zero() -> FieldPrime { - FieldPrime { - value: ToBigInt::to_bigint(&0).unwrap(), - } + FieldPrime { v: Fr::zero() } } fn is_zero(&self) -> bool { - self.value == ToBigInt::to_bigint(&0).unwrap() + self.v.is_zero() } } impl One for FieldPrime { fn one() -> FieldPrime { - FieldPrime { - value: ToBigInt::to_bigint(&1).unwrap(), - } + FieldPrime { v: Fr::one() } } } @@ -361,16 +360,8 @@ mod prime_field { type Output = FieldPrime; fn add(self, other: FieldPrime) -> FieldPrime { - if self.value == BigInt::zero() { - return other; - } - - if other.value == BigInt::zero() { - return self; - } - FieldPrime { - value: (self.value + other.value) % &*P, + v: self.v + other.v, } } } @@ -379,16 +370,8 @@ mod prime_field { type Output = FieldPrime; fn add(self, other: &FieldPrime) -> FieldPrime { - if self.value == BigInt::zero() { - return other.clone(); - } - - if other.value == BigInt::zero() { - return self; - } - FieldPrime { - value: (self.value + &other.value) % &*P, + v: self.v + other.v, } } } @@ -397,9 +380,8 @@ mod prime_field { type Output = FieldPrime; fn sub(self, other: FieldPrime) -> FieldPrime { - let x = self.value - other.value; FieldPrime { - value: &x - x.div_floor(&*P) * &*P, + v: self.v - other.v, } } } @@ -408,9 +390,8 @@ mod prime_field { type Output = FieldPrime; fn sub(self, other: &FieldPrime) -> FieldPrime { - let x = self.value - &other.value; FieldPrime { - value: &x - x.div_floor(&*P) * &*P, + v: self.v - other.v, } } } @@ -419,16 +400,8 @@ mod prime_field { type Output = FieldPrime; fn mul(self, other: FieldPrime) -> FieldPrime { - if self.value == BigInt::one() { - return other; - } - - if other.value == BigInt::one() { - return self; - } - FieldPrime { - value: (self.value * other.value) % &*P, + v: self.v * other.v, } } } @@ -437,23 +410,21 @@ mod prime_field { type Output = FieldPrime; fn mul(self, other: &FieldPrime) -> FieldPrime { - if self.value == BigInt::one() { - return other.clone(); - } - - if other.value == BigInt::one() { - return self; - } - FieldPrime { - value: (self.value * &other.value) % &*P, + v: self.v * other.v, } } } impl CheckedDiv for FieldPrime { fn checked_div(&self, other: &FieldPrime) -> Option { - other.inverse_mul().map(|inv| inv * self) + if other.v == Fr::zero() { + None + } else { + Some(FieldPrime { + v: self.v / other.v, + }) + } } } @@ -477,11 +448,9 @@ mod prime_field { type Output = FieldPrime; fn pow(self, exp: usize) -> FieldPrime { - let mut res = FieldPrime::from(1); - for _ in 0..exp { - res = res * &self; + FieldPrime { + v: self.v.pow(&[exp as u64]), } - res } } @@ -492,12 +461,21 @@ mod prime_field { assert!(self <= &bound); assert!(other <= &bound); - let big_res = &self.value + &other.value; + let mut big_res = self.v.into_repr(); - if big_res > bound.value { + use ark_ff::BigInteger; + let carry = big_res.add_nocarry(&other.v.into_repr()); + + if carry { + return None; + } + + if big_res > bound.v.into_repr() { None } else { - Some(FieldPrime { value: big_res }) + Some(FieldPrime { + v: Fr::from(big_res), + }) } } } @@ -509,40 +487,84 @@ mod prime_field { assert!(self <= &bound); assert!(other <= &bound); - let big_res = &self.value * &other.value; + let left = self.to_biguint(); + let right = other.to_biguint(); + + let big_res = left * right; // we only go up to 2**(bitwidth - 1) because after that we lose uniqueness of bit decomposition - if big_res > bound.value { + if big_res > bound.to_biguint() { None } else { - Some(FieldPrime { value: big_res }) + Some(self.clone() * other) } } } - /// Calculates the gcd using an iterative implementation of the extended euclidian algorithm. - /// Returning `(d, s, t)` so that `d = s * a + t * b` - /// - /// # Arguments - /// * `a` - First number as `BigInt` - /// * `b` - Second number as `BigInt` - fn extended_euclid(a: &BigInt, b: &BigInt) -> (BigInt, BigInt, BigInt) { - let (mut s, mut old_s) = (BigInt::zero(), BigInt::one()); - let (mut t, mut old_t) = (BigInt::one(), BigInt::zero()); - let (mut r, mut old_r) = (b.clone(), a.clone()); - while !&r.is_zero() { - let quotient = &old_r / &r; - let tmp_r = old_r.clone(); - old_r = r.clone(); - r = &tmp_r - "ient * &r; - let tmp_s = old_s.clone(); - old_s = s.clone(); - s = &tmp_s - "ient * &s; - let tmp_t = old_t.clone(); - old_t = t.clone(); - t = &tmp_t - "ient * &t; + impl Serialize for FieldPrime { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + use ark_serialize::CanonicalSerialize; + use serde::ser::Error; + let mut data: Vec = vec![]; + self.v + .serialize(&mut data) + .map_err(|e| S::Error::custom(e.to_string()))?; + serializer.serialize_bytes(&data) + } + } + + struct FieldVisitor; + + use serde::de::SeqAccess; + + impl<'de> Visitor<'de> for FieldVisitor { + type Value = FieldPrime; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("an ark field element") + } + + fn visit_bytes(self, value: &[u8]) -> Result + where + E: de::Error, + { + use ark_serialize::CanonicalDeserialize; + let value: Fr = Fr::deserialize(value).map_err(|e| E::custom(e.to_string()))?; + + Ok(FieldPrime { v: value }) + } + + fn visit_byte_buf(self, value: Vec) -> Result + where + E: de::Error, + { + self.visit_bytes(&value[..]) + } + + fn visit_seq(self, value: A) -> Result + where + A: SeqAccess<'de>, + { + let mut value = value; + let mut elements = vec![]; + while let Some(v) = value.next_element()? { + elements.push(v); + } + + self.visit_bytes(&elements[..]) + } + } + + impl<'de> Deserialize<'de> for FieldPrime { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_bytes(FieldVisitor) } - return (old_r, old_s, old_t); } }; } From 1f391e9f119f10140d35e5b7a5ea1ee4c560f66e Mon Sep 17 00:00:00 2001 From: schaeff Date: Fri, 3 Dec 2021 12:03:43 +0100 Subject: [PATCH 03/21] add tests, clean --- zokrates_core/src/ir/expression.rs | 4 ++- zokrates_field/src/bn128.rs | 28 +++++++++++++++++++++ zokrates_field/src/lib.rs | 40 ++++++++++++++---------------- 3 files changed, 50 insertions(+), 22 deletions(-) diff --git a/zokrates_core/src/ir/expression.rs b/zokrates_core/src/ir/expression.rs index 77069a4d..57ec2753 100644 --- a/zokrates_core/src/ir/expression.rs +++ b/zokrates_core/src/ir/expression.rs @@ -259,8 +259,10 @@ impl Mul<&T> for LinComb { impl Div<&T> for LinComb { type Output = LinComb; + // Clippy warns about multiplication in a method named div. It's okay, here, since we multiply with the inverse. + #[allow(clippy::suspicious_arithmetic_impl)] fn div(self, scalar: &T) -> LinComb { - self * &T::one().div(scalar) + self * &scalar.inverse_mul().unwrap() } } diff --git a/zokrates_field/src/bn128.rs b/zokrates_field/src/bn128.rs index 54c08a7a..468424f5 100644 --- a/zokrates_field/src/bn128.rs +++ b/zokrates_field/src/bn128.rs @@ -201,6 +201,31 @@ mod tests { ); } + #[test] + fn bits() { + assert_eq!(FieldPrime::from(0).bits(), 1); + assert_eq!(FieldPrime::from(1).bits(), 1); + assert_eq!(FieldPrime::from(2).bits(), 2); + assert_eq!(FieldPrime::from(3).bits(), 2); + assert_eq!(FieldPrime::from(4).bits(), 3); + } + + #[test] + fn to_biguint() { + assert_eq!( + FieldPrime::try_from(FieldPrime::from(2).to_biguint()), + Ok(FieldPrime::from(2)) + ); + assert_eq!( + FieldPrime::try_from(FieldPrime::from(0).to_biguint()), + Ok(FieldPrime::from(0)) + ); + assert_eq!( + FieldPrime::try_from(FieldPrime::max_value().to_biguint()), + Ok(FieldPrime::max_value()) + ); + } + #[test] fn division_negative() { let res = FieldPrime::from(-54) / FieldPrime::from(12); @@ -239,7 +264,9 @@ mod tests { #[test] fn bytes_ser_deser() { let fp = FieldPrime::from("101"); + println!("{}", fp); let bv = fp.to_byte_vector(); + println!("{:#?}", bv); assert_eq!(fp, FieldPrime::from_byte_vector(bv)); } @@ -276,6 +303,7 @@ mod tests { #[test] fn bigint_assertions() { + use num_integer::Integer; let x = BigInt::parse_bytes(b"65", 10).unwrap(); assert_eq!(&x + &x, BigInt::parse_bytes(b"130", 10).unwrap()); assert_eq!( diff --git a/zokrates_field/src/lib.rs b/zokrates_field/src/lib.rs index 3bdd40eb..90d3a8d6 100644 --- a/zokrates_field/src/lib.rs +++ b/zokrates_field/src/lib.rs @@ -93,7 +93,7 @@ pub trait Field: /// Returns this `Field`'s contents as decimal string fn to_dec_string(&self) -> String; /// Returns the multiplicative inverse, i.e.: self * self.inverse_mul() = Self::one() - //fn inverse_mul(&self) -> Option; + fn inverse_mul(&self) -> Option; /// Returns the smallest value that can be represented by this field type. fn min_value() -> Self; /// Returns the largest value that can be represented by this field type. @@ -190,7 +190,7 @@ mod prime_field { break; } } - size as u32 + std::cmp::max(size as u32, 1) } fn to_biguint(&self) -> BigUint { @@ -200,7 +200,7 @@ mod prime_field { fn to_byte_vector(&self) -> Vec { use ark_ff::BigInteger; - self.v.into_repr().to_bytes_be() + self.v.into_repr().to_bytes_le() } fn from_byte_vector(bytes: Vec) -> Self { @@ -215,6 +215,13 @@ mod prime_field { self.to_string() } + fn inverse_mul(&self) -> Option { + use ark_ff::Field; + Some(FieldPrime { + v: self.v.inverse()?, + }) + } + fn min_value() -> FieldPrime { FieldPrime { v: Fr::from(0u32) } } @@ -239,13 +246,9 @@ mod prime_field { v: Fr::from_str(s).map_err(|_| FieldParseError)?, }) } - fn try_from_str(_: &str, _: u32) -> Result { - unimplemented!("try from str") - // let x = BigInt::parse_bytes(s.as_bytes(), radix).ok_or(FieldParseError)?; - // Ok(FieldPrime { - // value: &x - x.div_floor(&*P) * &*P, - // v: field_new!() - // }) + fn try_from_str(s: &str, radix: u32) -> Result { + let x = BigUint::parse_bytes(s.as_bytes(), radix).ok_or(FieldParseError)?; + FieldPrime::try_from(x).map_err(|_| FieldParseError) } fn to_compact_dec_string(&self) -> String { //values up to (p-1)/2 included are represented as positive, values between (p+1)/2 and p-1 as represented as negative by subtracting p @@ -461,21 +464,16 @@ mod prime_field { assert!(self <= &bound); assert!(other <= &bound); - let mut big_res = self.v.into_repr(); + let left = self.to_biguint(); + let right = other.to_biguint(); - use ark_ff::BigInteger; - let carry = big_res.add_nocarry(&other.v.into_repr()); + let big_res = left + right; - if carry { - return None; - } - - if big_res > bound.v.into_repr() { + // we only go up to 2**(bitwidth - 1) because after that we lose uniqueness of bit decomposition + if big_res > bound.to_biguint() { None } else { - Some(FieldPrime { - v: Fr::from(big_res), - }) + Some(self.clone() * other) } } } From 7a552ea4d2f0129fceb8091c66c11c895517e612 Mon Sep 17 00:00:00 2001 From: schaeff Date: Mon, 6 Dec 2021 15:11:00 +0100 Subject: [PATCH 04/21] fix features, fix checked mul --- zokrates_field/Cargo.toml | 14 +++++++------- zokrates_field/src/lib.rs | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/zokrates_field/Cargo.toml b/zokrates_field/Cargo.toml index 7c26729b..63c21c05 100644 --- a/zokrates_field/Cargo.toml +++ b/zokrates_field/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [features] default = ["ark", "bellman"] -ark = ["ark-ff", "ark-ec", "ark-bn254", "ark-bls12-381", "ark-bls12-377", "ark-bw6-761", "ark-serialize"] +ark = ["ark-ec"] bellman = ["bellman_ce"] [dependencies] @@ -18,18 +18,18 @@ serde_json = "1.0" sha2 = "0.8.0" num-traits = { version = "0.2", default-features = false } num-integer = { version = "0.1", default-features = false } +ark-ff = { version = "^0.2.0", default-features = false } +ark-bn254 = { version = "^0.2.0", features = ["curve"], default-features = false } +ark-bls12-377 = { version = "^0.2.0", features = ["curve"], default-features = false } +ark-bls12-381 = { version = "^0.2.0", features = ["curve"], default-features = false } +ark-bw6-761 = { version = "^0.2.0", default-features = false } +ark-serialize = { version = "^0.2.0", default-features = false } # bellman bellman_ce = { version = "^0.3", default-features = false, optional = true } # ark -ark-ff = { version = "^0.2.0", default-features = false, optional = true } ark-ec = { version = "^0.2.0", default-features = false, optional = true } -ark-bn254 = { version = "^0.2.0", features = ["curve"], default-features = false, optional = true } -ark-bls12-377 = { version = "^0.2.0", features = ["curve"], default-features = false, optional = true } -ark-bls12-381 = { version = "^0.2.0", features = ["curve"], default-features = false, optional = true } -ark-bw6-761 = { version = "^0.2.0", default-features = false, optional = true } -ark-serialize = { version = "^0.2.0", default-features = false, optional = true } [dev-dependencies] rand = "0.4" diff --git a/zokrates_field/src/lib.rs b/zokrates_field/src/lib.rs index 90d3a8d6..b66d7ffb 100644 --- a/zokrates_field/src/lib.rs +++ b/zokrates_field/src/lib.rs @@ -473,7 +473,7 @@ mod prime_field { if big_res > bound.to_biguint() { None } else { - Some(self.clone() * other) + Some(self.clone() + other) } } } From 2dbb4b7a9c71dab5068d9fc61e0a0b9a2b5d6673 Mon Sep 17 00:00:00 2001 From: schaeff Date: Mon, 6 Dec 2021 15:35:48 +0100 Subject: [PATCH 05/21] update lock in zjs --- zokrates_js/Cargo.lock | 39 ++++++++++++++++++++++++++++++++++----- zokrates_js/Cargo.toml | 2 +- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/zokrates_js/Cargo.lock b/zokrates_js/Cargo.lock index adbe48e4..5a8e6312 100644 --- a/zokrates_js/Cargo.lock +++ b/zokrates_js/Cargo.lock @@ -49,6 +49,28 @@ dependencies = [ "ark-std", ] +[[package]] +name = "ark-bls12-381" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e1c2ad76c4f725520440b981df3ce2d635f2baa1122750c757c0cf0f3d4b74" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-bn254" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ead066869de5e8cb2938123204d1572f09496b629e146a6f80fa8ec508446ba" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + [[package]] name = "ark-bw6-761" version = "0.2.0" @@ -1555,7 +1577,7 @@ version = "0.1.0" [[package]] name = "zokrates_core" -version = "0.6.7" +version = "0.6.8" dependencies = [ "bellman_ce", "bincode", @@ -1584,7 +1606,7 @@ dependencies = [ [[package]] name = "zokrates_embed" -version = "0.1.4" +version = "0.1.5" dependencies = [ "ark-bls12-377", "ark-bw6-761", @@ -1604,6 +1626,13 @@ dependencies = [ name = "zokrates_field" version = "0.4.0" dependencies = [ + "ark-bls12-377", + "ark-bls12-381", + "ark-bn254", + "ark-bw6-761", + "ark-ec", + "ark-ff", + "ark-serialize", "bellman_ce", "bincode", "lazy_static", @@ -1618,7 +1647,7 @@ dependencies = [ [[package]] name = "zokrates_js" -version = "1.0.36" +version = "1.0.37" dependencies = [ "console_error_panic_hook", "js-sys", @@ -1633,7 +1662,7 @@ dependencies = [ [[package]] name = "zokrates_parser" -version = "0.2.4" +version = "0.2.5" dependencies = [ "pest", "pest_derive", @@ -1641,7 +1670,7 @@ dependencies = [ [[package]] name = "zokrates_pest_ast" -version = "0.2.3" +version = "0.2.4" dependencies = [ "from-pest", "lazy_static", diff --git a/zokrates_js/Cargo.toml b/zokrates_js/Cargo.toml index 0b29f4a2..7d0a9541 100644 --- a/zokrates_js/Cargo.toml +++ b/zokrates_js/Cargo.toml @@ -14,6 +14,6 @@ serde_json = "1.0" wasm-bindgen = { version = "0.2.46", features = ["serde-serialize"] } zokrates_core = { path = "../zokrates_core", features = ["wasm", "bellman"], default-features = false } zokrates_common = { path = "../zokrates_common" } -zokrates_field = { path = "../zokrates_field", default-features = false, features = ["bellman"] } +zokrates_field = { path = "../zokrates_field", features = ["bellman"] } zokrates_abi = { path = "../zokrates_abi" } console_error_panic_hook = "0.1.6" \ No newline at end of file From 53876eb2154b4bbef33aa6784ce08ab3bface70e Mon Sep 17 00:00:00 2001 From: schaeff Date: Mon, 6 Dec 2021 15:37:55 +0100 Subject: [PATCH 06/21] changelog --- changelogs/unreleased/1061-schaeff | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/unreleased/1061-schaeff diff --git a/changelogs/unreleased/1061-schaeff b/changelogs/unreleased/1061-schaeff new file mode 100644 index 00000000..34578f62 --- /dev/null +++ b/changelogs/unreleased/1061-schaeff @@ -0,0 +1 @@ +Use ark-ff under the hood for optimized field operations \ No newline at end of file From 9e4050f09135182ed94e01829a4fd13ba14cbf53 Mon Sep 17 00:00:00 2001 From: schaeff Date: Mon, 6 Dec 2021 17:46:05 +0100 Subject: [PATCH 07/21] remove ark feature, fix errors --- zokrates_core/Cargo.toml | 2 +- zokrates_field/Cargo.toml | 15 +++++++-------- zokrates_field/src/bls12_377.rs | 1 - zokrates_field/src/bn128.rs | 4 ++-- zokrates_field/src/bw6_761.rs | 1 - zokrates_field/src/lib.rs | 16 +++------------- 6 files changed, 13 insertions(+), 26 deletions(-) diff --git a/zokrates_core/Cargo.toml b/zokrates_core/Cargo.toml index d78d1ecd..fd0b2a8f 100644 --- a/zokrates_core/Cargo.toml +++ b/zokrates_core/Cargo.toml @@ -13,7 +13,7 @@ libsnark = ["cc", "cmake", "git2"] bellman = ["bellman_ce", "pairing_ce", "ff_ce", "zokrates_field/bellman"] wasm = ["bellman_ce/nolog", "bellman_ce/wasm"] multicore = ["bellman_ce/multicore"] -ark = ["ark-ff", "ark-ec", "ark-bn254", "ark-bls12-377", "ark-bw6-761", "ark-gm17", "ark-serialize", "ark-relations", "ark-marlin", "ark-poly", "ark-poly-commit", "zokrates_field/ark", "sha2"] +ark = ["ark-ff", "ark-ec", "ark-bn254", "ark-bls12-377", "ark-bw6-761", "ark-gm17", "ark-serialize", "ark-relations", "ark-marlin", "ark-poly", "ark-poly-commit", "sha2"] [dependencies] log = "0.4" diff --git a/zokrates_field/Cargo.toml b/zokrates_field/Cargo.toml index 63c21c05..71435ff0 100644 --- a/zokrates_field/Cargo.toml +++ b/zokrates_field/Cargo.toml @@ -5,8 +5,7 @@ authors = ["Thibaut Schaeffer ", "Guillaume Ballet ::Fqe; } -#[cfg(feature = "ark")] pub trait ArkFieldExtensions { /// An associated type to be able to operate with ark ff traits - type ArkEngine: PairingEngine; + type ArkEngine: ark_ec::PairingEngine; fn from_ark(e: ::Fr) -> Self; fn into_ark(self) -> ::Fr; @@ -602,7 +598,6 @@ mod prime_field { }; } - #[cfg(feature = "ark")] macro_rules! ark_extensions { ($ark_type:ty) => { use crate::ArkFieldExtensions; @@ -611,16 +606,11 @@ mod prime_field { type ArkEngine = $ark_type; fn from_ark(e: ::Fr) -> Self { - use ark_ff::{BigInteger, PrimeField}; - let mut res: Vec = vec![]; - e.into_repr().write_le(&mut res).unwrap(); - Self::from_byte_vector(res) + Self { v: e } } fn into_ark(self) -> ::Fr { - use core::str::FromStr; - let s = self.to_dec_string(); - ::Fr::from_str(&s).unwrap() + self.v } } }; From 6e0fb3cb0bb419a58f73b4725267c05821dbfe42 Mon Sep 17 00:00:00 2001 From: schaeff Date: Mon, 6 Dec 2021 19:54:11 +0100 Subject: [PATCH 08/21] fix test --- .../tests/tests/hashes/mimcSponge/mimcFeistel.json | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/zokrates_stdlib/tests/tests/hashes/mimcSponge/mimcFeistel.json b/zokrates_stdlib/tests/tests/hashes/mimcSponge/mimcFeistel.json index 6c6f7c65..a362cf0f 100644 --- a/zokrates_stdlib/tests/tests/hashes/mimcSponge/mimcFeistel.json +++ b/zokrates_stdlib/tests/tests/hashes/mimcSponge/mimcFeistel.json @@ -24,18 +24,6 @@ ] } } - }, - { - "input": { - "values": ["21888242871839275222246405745257275088548364400416034343698204186575808495617", "0", "0"] - }, - "output": { - "Ok": { - "values": [ - "14543742788565021628577424853847564376151732847602780516906950225481254681152", "21165881269406212375659499083070944693027168220143204011932538650149052385959" - ] - } - } } ] } From eef0cd95ae37c5b0f4ec4d41a3bdff84950905c3 Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 7 Dec 2021 12:03:01 +0100 Subject: [PATCH 09/21] simplify field trait, remove redundant modulus, add tests, implement ark for all curves --- zokrates_field/src/bls12_377.rs | 8 ++------ zokrates_field/src/bls12_381.rs | 8 +++----- zokrates_field/src/bn128.rs | 33 ++++++--------------------------- zokrates_field/src/bw6_761.rs | 6 +----- zokrates_field/src/lib.rs | 16 +++++++--------- 5 files changed, 19 insertions(+), 52 deletions(-) diff --git a/zokrates_field/src/bls12_377.rs b/zokrates_field/src/bls12_377.rs index ac5291ed..66e297dc 100644 --- a/zokrates_field/src/bls12_377.rs +++ b/zokrates_field/src/bls12_377.rs @@ -1,9 +1,5 @@ use ark_bls12_377::Bls12_377; -prime_field!( - b"8444461749428370424248824938781546531375899335154063827935233455917409239041", - "bls12_377", - Bls12_377 -); +prime_field!("bls12_377", Bls12_377); -ark_extensions!(ark_bls12_377::Bls12_377); +ark_extensions!(Bls12_377); diff --git a/zokrates_field/src/bls12_381.rs b/zokrates_field/src/bls12_381.rs index e76dbc0b..81275843 100644 --- a/zokrates_field/src/bls12_381.rs +++ b/zokrates_field/src/bls12_381.rs @@ -1,10 +1,8 @@ use ark_bls12_381::Bls12_381; -prime_field!( - b"52435875175126190479447740508185965837690552500527637822603658699938581184513", - "bls12_381", - Bls12_381 -); +prime_field!("bls12_381", Bls12_381); + +ark_extensions!(Bls12_381); #[cfg(feature = "bellman")] use bellman_ce::pairing::bls12_381::{Bls12, Fq2}; diff --git a/zokrates_field/src/bn128.rs b/zokrates_field/src/bn128.rs index ca025e6b..1af60009 100644 --- a/zokrates_field/src/bn128.rs +++ b/zokrates_field/src/bn128.rs @@ -1,10 +1,6 @@ use ark_bn254::Bn254; -prime_field!( - b"21888242871839275222246405745257275088548364400416034343698204186575808495617", - "bn128", - Bn254 -); +prime_field!("bn128", Bn254); ark_extensions!(Bn254); @@ -201,6 +197,11 @@ mod tests { ); } + #[test] + fn required_bits() { + assert_eq!(FieldPrime::get_required_bits(), 254); + } + #[test] fn bits() { assert_eq!(FieldPrime::from(0).bits(), 1); @@ -256,7 +257,6 @@ mod tests { #[test] fn serde_json_ser_deser() { let serialized = serde_json::to_string(&FieldPrime::from("11")).unwrap(); - println!("{}", serialized); let deserialized = serde_json::from_str(&serialized).unwrap(); assert_eq!(FieldPrime::from("11"), deserialized); } @@ -264,9 +264,7 @@ mod tests { #[test] fn bytes_ser_deser() { let fp = FieldPrime::from("101"); - println!("{}", fp); let bv = fp.to_byte_vector(); - println!("{:#?}", bv); assert_eq!(fp, FieldPrime::from_byte_vector(bv)); } @@ -301,25 +299,6 @@ mod tests { } } - #[test] - fn bigint_assertions() { - use num_integer::Integer; - let x = BigInt::parse_bytes(b"65", 10).unwrap(); - assert_eq!(&x + &x, BigInt::parse_bytes(b"130", 10).unwrap()); - assert_eq!( - "1".parse::().unwrap(), - "3".parse::() - .unwrap() - .div_floor(&"2".parse::().unwrap()) - ); - assert_eq!( - "-2".parse::().unwrap(), - "-3".parse::() - .unwrap() - .div_floor(&"2".parse::().unwrap()) - ); - } - #[cfg(feature = "bellman")] mod bellman { use super::*; diff --git a/zokrates_field/src/bw6_761.rs b/zokrates_field/src/bw6_761.rs index c754e8cc..82a90600 100644 --- a/zokrates_field/src/bw6_761.rs +++ b/zokrates_field/src/bw6_761.rs @@ -1,9 +1,5 @@ use ark_bw6_761::BW6_761; -prime_field!( - b"258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177", - "bw6_761", - BW6_761 -); +prime_field!("bw6_761", BW6_761); ark_extensions!(BW6_761); diff --git a/zokrates_field/src/lib.rs b/zokrates_field/src/lib.rs index fe0fd7c6..dd421a5c 100644 --- a/zokrates_field/src/lib.rs +++ b/zokrates_field/src/lib.rs @@ -149,11 +149,10 @@ pub trait Field: #[macro_use] mod prime_field { macro_rules! prime_field { - ($modulus:expr, $name:expr, $v:ty) => { + ($name:expr, $v:ty) => { use crate::{Field, FieldParseError, Pow}; use ark_ff::{Field as ArkField, PrimeField}; - use lazy_static::lazy_static; - use num_bigint::{BigInt, BigUint}; + use num_bigint::BigUint; use num_traits::{CheckedDiv, One, Zero}; use serde::de::{self, Visitor}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -163,10 +162,6 @@ mod prime_field { use std::fmt::{Debug, Display}; use std::ops::{Add, Div, Mul, Sub}; - lazy_static! { - static ref P: BigInt = BigInt::parse_bytes($modulus, 10).unwrap(); - } - type Fr = <$v as ark_ec::PairingEngine>::Fr; #[derive(PartialEq, PartialOrd, Clone, Eq, Ord, Hash)] @@ -233,7 +228,8 @@ mod prime_field { } } fn get_required_bits() -> usize { - (*P).bits() + use ark_ff::FpParameters; + ::Params::MODULUS_BITS as usize } fn try_from_dec_str(s: &str) -> Result { use std::str::FromStr; @@ -259,8 +255,10 @@ mod prime_field { } fn id() -> [u8; 4] { let mut res = [0u8; 4]; + use ark_ff::BigInteger; + use ark_ff::FpParameters; use sha2::{Digest, Sha256}; - let hash = Sha256::digest(&P.to_bytes_le().1); + let hash = Sha256::digest(&::Params::MODULUS.to_bytes_le()); for i in 0..4 { res[i] = hash[i]; } From 4c8ff7d0f618f787b0b9ae7df44b13783f902e9a Mon Sep 17 00:00:00 2001 From: schaeff Date: Tue, 7 Dec 2021 12:14:23 +0100 Subject: [PATCH 10/21] clean --- zokrates_field/src/bn128.rs | 16 ---------------- zokrates_field/src/lib.rs | 13 +++++-------- 2 files changed, 5 insertions(+), 24 deletions(-) diff --git a/zokrates_field/src/bn128.rs b/zokrates_field/src/bn128.rs index 1af60009..ddb5c4ea 100644 --- a/zokrates_field/src/bn128.rs +++ b/zokrates_field/src/bn128.rs @@ -33,22 +33,6 @@ mod tests { ); } - // #[test] - // fn positive_number() { - // assert_eq!( - // "1234245612".parse::().unwrap(), - // FieldPrime::from("1234245612").value - // ); - // } - - // #[test] - // fn negative_number() { - // assert_eq!( - // P.checked_sub(&"12".parse::().unwrap()).unwrap(), - // FieldPrime::from("-12").value - // ); - // } - #[test] fn addition() { assert_eq!( diff --git a/zokrates_field/src/lib.rs b/zokrates_field/src/lib.rs index dd421a5c..0240c7c5 100644 --- a/zokrates_field/src/lib.rs +++ b/zokrates_field/src/lib.rs @@ -214,17 +214,14 @@ mod prime_field { } fn min_value() -> FieldPrime { - FieldPrime { v: Fr::from(0u32) } + FieldPrime { v: Fr::zero() } } fn max_value() -> FieldPrime { - FieldPrime { - v: Fr::from(0u32) - Fr::from(1u32), - } + FieldPrime { v: -Fr::one() } } fn max_unique_value() -> FieldPrime { FieldPrime { - v: Fr::from(2u32).pow([Self::get_required_bits() as u64 - 1]) - - Fr::from(1u32), + v: Fr::from(2u32).pow([Self::get_required_bits() as u64 - 1]) - Fr::one(), } } fn get_required_bits() -> usize { @@ -272,7 +269,7 @@ mod prime_field { impl Default for FieldPrime { fn default() -> Self { - FieldPrime { v: Fr::from(0u32) } + FieldPrime { v: Fr::zero() } } } @@ -292,7 +289,7 @@ mod prime_field { fn from(num: i32) -> Self { if num < 0 { FieldPrime { - v: Fr::zero() - Fr::from((-num) as u32), + v: -Fr::from((-num) as u32), } } else { FieldPrime { From 13ee212f5f500d959105576b56fb74ed054a09ac Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 8 Dec 2021 13:25:16 +0100 Subject: [PATCH 11/21] remove condition cache, add condition redefiner --- zokrates_core/src/flatten/mod.rs | 12 ---- .../static_analysis/condition_redefiner.rs | 57 +++++++++++++++++++ zokrates_core/src/static_analysis/mod.rs | 7 +++ zokrates_core/src/typed_absy/identifier.rs | 2 + 4 files changed, 66 insertions(+), 12 deletions(-) create mode 100644 zokrates_core/src/static_analysis/condition_redefiner.rs diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index a8b2c68c..bc72757b 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -33,8 +33,6 @@ pub struct Flattener<'ast, T: Field> { layout: HashMap, FlatVariable>, /// Cached bit decompositions to avoid re-generating them bits_cache: HashMap, Vec>>, - /// Cached flattened conditions for branches - condition_cache: HashMap, FlatVariable>, } trait FlattenOutput: Sized { @@ -168,7 +166,6 @@ impl<'ast, T: Field> Flattener<'ast, T> { next_var_idx: 0, layout: HashMap::new(), bits_cache: HashMap::new(), - condition_cache: HashMap::new(), } } @@ -459,8 +456,6 @@ impl<'ast, T: Field> Flattener<'ast, T> { let condition_id = self.use_sym(); statements_flattened.push(FlatStatement::Definition(condition_id, condition_flat)); - self.condition_cache.insert(condition, condition_id); - let (consequence, alternative) = if self.config.isolate_branches { let mut consequence_statements = vec![]; @@ -754,11 +749,6 @@ impl<'ast, T: Field> Flattener<'ast, T> { statements_flattened: &mut FlatStatements, expression: BooleanExpression<'ast, T>, ) -> FlatExpression { - // check the cache - if let Some(c) = self.condition_cache.get(&expression) { - return (*c).into(); - } - match expression { BooleanExpression::Identifier(x) => { FlatExpression::Identifier(*self.layout.get(&x).unwrap()) @@ -2179,8 +2169,6 @@ impl<'ast, T: Field> Flattener<'ast, T> { let condition_id = self.use_sym(); statements_flattened.push(FlatStatement::Definition(condition_id, condition_flat)); - self.condition_cache.insert(condition, condition_id); - if self.config.isolate_branches { let mut consequence_statements = vec![]; let mut alternative_statements = vec![]; diff --git a/zokrates_core/src/static_analysis/condition_redefiner.rs b/zokrates_core/src/static_analysis/condition_redefiner.rs new file mode 100644 index 00000000..600a3a3d --- /dev/null +++ b/zokrates_core/src/static_analysis/condition_redefiner.rs @@ -0,0 +1,57 @@ +use crate::typed_absy::{ + folder::*, BooleanExpression, Conditional, ConditionalExpression, ConditionalOrExpression, + CoreIdentifier, Expr, Identifier, TypedProgram, TypedStatement, Variable, +}; +use zokrates_field::Field; + +#[derive(Default)] +pub struct ConditionRedefiner<'ast, T> { + index: usize, + buffer: Vec>, +} + +impl<'ast, T: Field> ConditionRedefiner<'ast, T> { + pub fn redefine(p: TypedProgram<'ast, T>) -> TypedProgram<'ast, T> { + Self::default().fold_program(p) + } +} + +impl<'ast, T: Field> Folder<'ast, T> for ConditionRedefiner<'ast, T> { + fn fold_statement(&mut self, s: TypedStatement<'ast, T>) -> Vec> { + assert!(self.buffer.is_empty()); + let s = fold_statement(self, s); + let buffer = std::mem::take(&mut self.buffer); + buffer.into_iter().chain(s).collect() + } + + fn fold_conditional_expression + Conditional<'ast, T> + Fold<'ast, T>>( + &mut self, + _: &E::Ty, + e: ConditionalExpression<'ast, T, E>, + ) -> ConditionalOrExpression<'ast, T, E> { + let condition = self.fold_boolean_expression(*e.condition); + let condition = match condition { + condition @ BooleanExpression::Value(_) + | condition @ BooleanExpression::Identifier(_) => condition, + condition => { + let condition_id = Identifier::from(CoreIdentifier::Condition(self.index)); + self.buffer.push(TypedStatement::Definition( + Variable::boolean(condition_id.clone()).into(), + condition.into(), + )); + self.index += 1; + BooleanExpression::Identifier(condition_id) + } + }; + + let consequence = e.consequence.fold(self); + let alternative = e.alternative.fold(self); + + ConditionalOrExpression::Conditional(ConditionalExpression::new( + condition, + consequence, + alternative, + e.kind, + )) + } +} diff --git a/zokrates_core/src/static_analysis/mod.rs b/zokrates_core/src/static_analysis/mod.rs index b46582c6..241d6983 100644 --- a/zokrates_core/src/static_analysis/mod.rs +++ b/zokrates_core/src/static_analysis/mod.rs @@ -5,6 +5,7 @@ //! @date 2018 mod branch_isolator; +mod condition_redefiner; mod constant_argument_checker; mod constant_resolver; mod flat_propagation; @@ -19,6 +20,7 @@ mod variable_write_remover; mod zir_propagation; use self::branch_isolator::Isolator; +use self::condition_redefiner::ConditionRedefiner; use self::constant_argument_checker::ConstantArgumentChecker; use self::flatten_complex_types::Flattener; use self::out_of_bounds::OutOfBoundsChecker; @@ -158,6 +160,11 @@ impl<'ast, T: Field> TypedProgram<'ast, T> { let r = OutOfBoundsChecker::check(r).map_err(Error::from)?; log::trace!("\n{}", r); + // redefine conditions + log::debug!("Static analyser: Redefine conditions"); + let r = ConditionRedefiner::redefine(r); + log::trace!("\n{}", r); + // convert to zir, removing complex types log::debug!("Static analyser: Convert to zir"); let zir = Flattener::flatten(r); diff --git a/zokrates_core/src/typed_absy/identifier.rs b/zokrates_core/src/typed_absy/identifier.rs index 972a69e6..56246eb5 100644 --- a/zokrates_core/src/typed_absy/identifier.rs +++ b/zokrates_core/src/typed_absy/identifier.rs @@ -7,6 +7,7 @@ pub enum CoreIdentifier<'ast> { Source(&'ast str), Call(usize), Constant(CanonicalConstantIdentifier<'ast>), + Condition(usize), } impl<'ast> fmt::Display for CoreIdentifier<'ast> { @@ -15,6 +16,7 @@ impl<'ast> fmt::Display for CoreIdentifier<'ast> { CoreIdentifier::Source(s) => write!(f, "{}", s), CoreIdentifier::Call(i) => write!(f, "#CALL_RETURN_AT_INDEX_{}", i), CoreIdentifier::Constant(c) => write!(f, "{}/{}", c.module.display(), c.id), + CoreIdentifier::Condition(i) => write!(f, "#CONDITION_{}", i), } } } From 4a2ce8c49a6b2d3207e09f907f5824f1175ff03d Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 8 Dec 2021 14:19:25 +0100 Subject: [PATCH 12/21] treat block expressions --- .../static_analysis/condition_redefiner.rs | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/zokrates_core/src/static_analysis/condition_redefiner.rs b/zokrates_core/src/static_analysis/condition_redefiner.rs index 600a3a3d..6c4fbb98 100644 --- a/zokrates_core/src/static_analysis/condition_redefiner.rs +++ b/zokrates_core/src/static_analysis/condition_redefiner.rs @@ -1,6 +1,7 @@ use crate::typed_absy::{ - folder::*, BooleanExpression, Conditional, ConditionalExpression, ConditionalOrExpression, - CoreIdentifier, Expr, Identifier, TypedProgram, TypedStatement, Variable, + folder::*, BlockExpression, BooleanExpression, Conditional, ConditionalExpression, + ConditionalOrExpression, CoreIdentifier, Expr, Identifier, TypedProgram, TypedStatement, + Variable, }; use zokrates_field::Field; @@ -24,6 +25,32 @@ impl<'ast, T: Field> Folder<'ast, T> for ConditionRedefiner<'ast, T> { buffer.into_iter().chain(s).collect() } + fn fold_block_expression>( + &mut self, + b: BlockExpression<'ast, T, E>, + ) -> BlockExpression<'ast, T, E> { + // start with a fresh state, but keep the global counter + let mut redefiner = ConditionRedefiner { + index: self.index, + buffer: vec![], + }; + + let b = fold_block_expression(&mut redefiner, b); + + let b = BlockExpression { + statements: std::mem::take(&mut redefiner.buffer) + .into_iter() + .chain(b.statements) + .collect(), + ..b + }; + + // continue from the latest index + self.index = redefiner.index; + + b + } + fn fold_conditional_expression + Conditional<'ast, T> + Fold<'ast, T>>( &mut self, _: &E::Ty, From 0626ca42977a7b7a4a3d2f4bd55e0d82dbdb51a6 Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 8 Dec 2021 14:25:09 +0100 Subject: [PATCH 13/21] reverse statement order for block expressions --- zokrates_core/src/static_analysis/condition_redefiner.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/zokrates_core/src/static_analysis/condition_redefiner.rs b/zokrates_core/src/static_analysis/condition_redefiner.rs index 6c4fbb98..1329ae58 100644 --- a/zokrates_core/src/static_analysis/condition_redefiner.rs +++ b/zokrates_core/src/static_analysis/condition_redefiner.rs @@ -37,10 +37,13 @@ impl<'ast, T: Field> Folder<'ast, T> for ConditionRedefiner<'ast, T> { let b = fold_block_expression(&mut redefiner, b); + // we add the buffer statements *after* the block statements because they refer to the return value, + // the buffered statements for the block statements are already included in the result let b = BlockExpression { - statements: std::mem::take(&mut redefiner.buffer) + statements: b + .statements .into_iter() - .chain(b.statements) + .chain(std::mem::take(&mut redefiner.buffer)) .collect(), ..b }; From 0877800cefe2c7663d2018394560fba99f69cbf7 Mon Sep 17 00:00:00 2001 From: schaeff Date: Wed, 8 Dec 2021 15:03:31 +0100 Subject: [PATCH 14/21] fix smt test --- zokrates_cli/tests/code/taxation.smt2 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zokrates_cli/tests/code/taxation.smt2 b/zokrates_cli/tests/code/taxation.smt2 index cc66ac8e..e861790c 100644 --- a/zokrates_cli/tests/code/taxation.smt2 +++ b/zokrates_cli/tests/code/taxation.smt2 @@ -261,7 +261,7 @@ (declare-const |_254| Int) (declare-const |_257| Int) (declare-const |_258| Int) -(declare-const |_263| Int) +(declare-const |_264| Int) (assert (and (= |~prime| 21888242871839275222246405745257275088548364400416034343698204186575808495617) (= |~one| 1) @@ -524,6 +524,6 @@ (= (mod (* (+ (* |~one| 14651237294507013008273219182214280847718990358813499091232105186081237893121) (* |_0| 1) (* |_1| 21888242871839275222246405745257275088548364400416034343698204186575808495616)) (* |_258| 1)) |~prime|) (mod (* |_257| 1) |~prime|)) (= (mod (* (+ (* |~one| 1) (* |_257| 21888242871839275222246405745257275088548364400416034343698204186575808495616)) (+ (* |~one| 14651237294507013008273219182214280847718990358813499091232105186081237893121) (* |_0| 1) (* |_1| 21888242871839275222246405745257275088548364400416034343698204186575808495616))) |~prime|) (mod 0 |~prime|)) (= (mod (* (* |~one| 1) 0) |~prime|) (mod (+ (* |~one| 1) (* |_257| 21888242871839275222246405745257275088548364400416034343698204186575808495616)) |~prime|)) -(= (mod (* (* |_2| 1) (+ (* |_0| 21888242871839275222246405745257275088548364400416034343698204186575808495616) (* |_1| 1))) |~prime|) (mod (* |_263| 1) |~prime|)) -(= (mod (* (* |~one| 1) (* |_263| 1)) |~prime|) (mod (* |~out_0| 1) |~prime|)) +(= (mod (* (* |_2| 1) (+ (* |_0| 21888242871839275222246405745257275088548364400416034343698204186575808495616) (* |_1| 1))) |~prime|) (mod (* |_264| 1) |~prime|)) +(= (mod (* (* |~one| 1) (* |_264| 1)) |~prime|) (mod (* |~out_0| 1) |~prime|)) )) \ No newline at end of file From 55403af8797340464fc376222c821eb666052cc4 Mon Sep 17 00:00:00 2001 From: dark64 Date: Wed, 8 Dec 2021 17:02:33 +0100 Subject: [PATCH 15/21] revert changes around condition_cache --- zokrates_core/src/flatten/mod.rs | 12 ++++-------- zokrates_core/src/zir/mod.rs | 3 --- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index 4b1338a6..a8b2c68c 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -459,9 +459,7 @@ impl<'ast, T: Field> Flattener<'ast, T> { let condition_id = self.use_sym(); statements_flattened.push(FlatStatement::Definition(condition_id, condition_flat)); - if !condition.is_constant() { - self.condition_cache.insert(condition, condition_id); - } + self.condition_cache.insert(condition, condition_id); let (consequence, alternative) = if self.config.isolate_branches { let mut consequence_statements = vec![]; @@ -756,11 +754,9 @@ impl<'ast, T: Field> Flattener<'ast, T> { statements_flattened: &mut FlatStatements, expression: BooleanExpression<'ast, T>, ) -> FlatExpression { - if !expression.is_constant() { - // check the cache - if let Some(c) = self.condition_cache.get(&expression) { - return (*c).into(); - } + // check the cache + if let Some(c) = self.condition_cache.get(&expression) { + return (*c).into(); } match expression { diff --git a/zokrates_core/src/zir/mod.rs b/zokrates_core/src/zir/mod.rs index 5d621b28..9978ed14 100644 --- a/zokrates_core/src/zir/mod.rs +++ b/zokrates_core/src/zir/mod.rs @@ -364,9 +364,6 @@ impl<'ast, T> BooleanExpression<'ast, T> { current: vec![self], } } - pub fn is_constant(&self) -> bool { - matches!(self, BooleanExpression::Value(_)) - } } // Downcasts From 71c74e596211835947b43d31095bc2ec892194fa Mon Sep 17 00:00:00 2001 From: dark64 Date: Fri, 10 Dec 2021 13:54:06 +0100 Subject: [PATCH 16/21] update rust toolchain version --- rust-toolchain.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index db4cdc1b..35f874be 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "nightly-2021-08-01" +channel = "nightly-2021-12-10" From 0cb1d352879009c9c23ae022bc011ed6823dc8c5 Mon Sep 17 00:00:00 2001 From: schaeff Date: Fri, 10 Dec 2021 14:36:34 +0100 Subject: [PATCH 17/21] add tests --- .../static_analysis/condition_redefiner.rs | 308 ++++++++++++++++++ 1 file changed, 308 insertions(+) diff --git a/zokrates_core/src/static_analysis/condition_redefiner.rs b/zokrates_core/src/static_analysis/condition_redefiner.rs index 1329ae58..2ba39ddf 100644 --- a/zokrates_core/src/static_analysis/condition_redefiner.rs +++ b/zokrates_core/src/static_analysis/condition_redefiner.rs @@ -85,3 +85,311 @@ impl<'ast, T: Field> Folder<'ast, T> for ConditionRedefiner<'ast, T> { )) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::typed_absy::{ + Block, BooleanExpression, Conditional, ConditionalKind, FieldElementExpression, Type, + }; + use zokrates_field::Bn128Field; + + #[test] + fn no_redefine_if_constant() { + // field foo = if true then 1 else 2 + // should be left unchanged + + let s = TypedStatement::Definition( + Variable::field_element("foo").into(), + FieldElementExpression::conditional( + BooleanExpression::Value(true), + FieldElementExpression::Number(Bn128Field::from(1)), + FieldElementExpression::Number(Bn128Field::from(2)), + ConditionalKind::IfElse, + ) + .into(), + ); + + let mut r = ConditionRedefiner::default(); + + assert_eq!(r.fold_statement(s.clone()), vec![s]); + } + + #[test] + fn no_redefine_if_identifier() { + // field foo = if c then 1 else 2 + // should be left unchanged + + let s = TypedStatement::Definition( + Variable::field_element("foo").into(), + FieldElementExpression::conditional( + BooleanExpression::Identifier("c".into()), + FieldElementExpression::Number(Bn128Field::from(1)), + FieldElementExpression::Number(Bn128Field::from(2)), + ConditionalKind::IfElse, + ) + .into(), + ); + + let mut r = ConditionRedefiner::default(); + + assert_eq!(r.fold_statement(s.clone()), vec![s]); + } + + #[test] + fn redefine_if_expression() { + // field foo = if c && d then 1 else 2 fi + // should become + // bool #CONDITION_0 = c && d + // field foo = if #CONDITION_0 then 1 else 2 + + let condition = BooleanExpression::And( + box BooleanExpression::Identifier("c".into()), + box BooleanExpression::Identifier("d".into()), + ); + + let s = TypedStatement::Definition( + Variable::field_element("foo").into(), + FieldElementExpression::conditional( + condition.clone(), + FieldElementExpression::Number(Bn128Field::from(1)), + FieldElementExpression::Number(Bn128Field::from(2)), + ConditionalKind::IfElse, + ) + .into(), + ); + + let mut r = ConditionRedefiner::default(); + + let expected = vec![ + // define condition + TypedStatement::Definition( + Variable::with_id_and_type(CoreIdentifier::Condition(0), Type::Boolean).into(), + condition.into(), + ), + // rewrite statement + TypedStatement::Definition( + Variable::field_element("foo").into(), + FieldElementExpression::conditional( + BooleanExpression::Identifier(CoreIdentifier::Condition(0).into()), + FieldElementExpression::Number(Bn128Field::from(1)), + FieldElementExpression::Number(Bn128Field::from(2)), + ConditionalKind::IfElse, + ) + .into(), + ), + ]; + + assert_eq!(r.fold_statement(s), expected); + } + + #[test] + fn redefine_rec() { + // field foo = if c && d then (if e && f then 1 else 2 fi) else 3 fi + // + // should become + // + // bool #CONDITION_0 = c && d + // bool #CONDITION_1 = e && f + // field foo = if #CONDITION_0 then (if #CONDITION_1 then 1 else 2 fi) else 3 fi + + let condition_0 = BooleanExpression::And( + box BooleanExpression::Identifier("c".into()), + box BooleanExpression::Identifier("d".into()), + ); + + let condition_1 = BooleanExpression::And( + box BooleanExpression::Identifier("e".into()), + box BooleanExpression::Identifier("f".into()), + ); + + let s = TypedStatement::Definition( + Variable::field_element("foo").into(), + FieldElementExpression::conditional( + condition_0.clone(), + FieldElementExpression::conditional( + condition_1.clone(), + FieldElementExpression::Number(Bn128Field::from(1)), + FieldElementExpression::Number(Bn128Field::from(2)), + ConditionalKind::IfElse, + ), + FieldElementExpression::Number(Bn128Field::from(3)), + ConditionalKind::IfElse, + ) + .into(), + ); + + let mut r = ConditionRedefiner::default(); + + let expected = vec![ + // define conditions + TypedStatement::Definition( + Variable::with_id_and_type(CoreIdentifier::Condition(0), Type::Boolean).into(), + condition_0.into(), + ), + TypedStatement::Definition( + Variable::with_id_and_type(CoreIdentifier::Condition(1), Type::Boolean).into(), + condition_1.into(), + ), + // rewrite statement + TypedStatement::Definition( + Variable::field_element("foo").into(), + FieldElementExpression::conditional( + BooleanExpression::Identifier(CoreIdentifier::Condition(0).into()), + FieldElementExpression::conditional( + BooleanExpression::Identifier(CoreIdentifier::Condition(1).into()), + FieldElementExpression::Number(Bn128Field::from(1)), + FieldElementExpression::Number(Bn128Field::from(2)), + ConditionalKind::IfElse, + ), + FieldElementExpression::Number(Bn128Field::from(3)), + ConditionalKind::IfElse, + ) + .into(), + ), + ]; + + assert_eq!(r.fold_statement(s), expected); + } + + #[test] + fn redefine_block() { + // field foo = if c && d then { + // field a = 1 + // if e && f then 2 else 3 + // } else { + // field b = 2 + // if e && f then 2 else 3 + // } + // + // should become + // + // bool #CONDITION_0 = c && d + // field foo = if c && d then { + // field a = 1 + // bool #CONDITION_1 = e && f + // if #CONDITION_1 then 2 else 3 + // } else { + // field b = 2 + // bool #CONDITION_2 = e && f + // if #CONDITION_2 then 2 else 3 + // } + + let condition_0 = BooleanExpression::And( + box BooleanExpression::Identifier("c".into()), + box BooleanExpression::Identifier("d".into()), + ); + + let condition_1 = BooleanExpression::And( + box BooleanExpression::Identifier("e".into()), + box BooleanExpression::Identifier("f".into()), + ); + + let condition_2 = BooleanExpression::And( + box BooleanExpression::Identifier("e".into()), + box BooleanExpression::Identifier("f".into()), + ); + + let condition_id_0 = BooleanExpression::Identifier(CoreIdentifier::Condition(0).into()); + let condition_id_1 = BooleanExpression::Identifier(CoreIdentifier::Condition(1).into()); + let condition_id_2 = BooleanExpression::Identifier(CoreIdentifier::Condition(2).into()); + + let s = TypedStatement::Definition( + Variable::field_element("foo").into(), + FieldElementExpression::conditional( + condition_0.clone(), + FieldElementExpression::block( + vec![TypedStatement::Definition( + Variable::field_element("a").into(), + FieldElementExpression::Number(Bn128Field::from(1)).into(), + )], + FieldElementExpression::conditional( + condition_1.clone(), + FieldElementExpression::Number(Bn128Field::from(2)), + FieldElementExpression::Number(Bn128Field::from(3)), + ConditionalKind::IfElse, + ), + ), + FieldElementExpression::block( + vec![TypedStatement::Definition( + Variable::field_element("b").into(), + FieldElementExpression::Number(Bn128Field::from(2)).into(), + )], + FieldElementExpression::conditional( + condition_2.clone(), + FieldElementExpression::Number(Bn128Field::from(2)), + FieldElementExpression::Number(Bn128Field::from(3)), + ConditionalKind::IfElse, + ), + ), + ConditionalKind::IfElse, + ) + .into(), + ); + + let mut r = ConditionRedefiner::default(); + + let expected = vec![ + // define conditions + TypedStatement::Definition( + Variable::with_id_and_type(CoreIdentifier::Condition(0), Type::Boolean).into(), + condition_0.into(), + ), + // rewrite statement + TypedStatement::Definition( + Variable::field_element("foo").into(), + FieldElementExpression::conditional( + condition_id_0.clone(), + FieldElementExpression::block( + vec![ + TypedStatement::Definition( + Variable::field_element("a").into(), + FieldElementExpression::Number(Bn128Field::from(1)).into(), + ), + TypedStatement::Definition( + Variable::with_id_and_type( + CoreIdentifier::Condition(1), + Type::Boolean, + ) + .into(), + condition_1.into(), + ), + ], + FieldElementExpression::conditional( + condition_id_1, + FieldElementExpression::Number(Bn128Field::from(2)), + FieldElementExpression::Number(Bn128Field::from(3)), + ConditionalKind::IfElse, + ), + ), + FieldElementExpression::block( + vec![ + TypedStatement::Definition( + Variable::field_element("b").into(), + FieldElementExpression::Number(Bn128Field::from(2)).into(), + ), + TypedStatement::Definition( + Variable::with_id_and_type( + CoreIdentifier::Condition(2), + Type::Boolean, + ) + .into(), + condition_2.into(), + ), + ], + FieldElementExpression::conditional( + condition_id_2, + FieldElementExpression::Number(Bn128Field::from(2)), + FieldElementExpression::Number(Bn128Field::from(3)), + ConditionalKind::IfElse, + ), + ), + ConditionalKind::IfElse, + ) + .into(), + ), + ]; + + assert_eq!(r.fold_statement(s), expected); + } +} From 95a931c57979d3c2ae0fe8de3dd0049258eb7423 Mon Sep 17 00:00:00 2001 From: dark64 Date: Fri, 10 Dec 2021 15:08:15 +0100 Subject: [PATCH 18/21] clippy --- zokrates_cli/src/ops/check.rs | 2 +- zokrates_cli/src/ops/compile.rs | 2 +- zokrates_core/src/absy/mod.rs | 1 + .../src/static_analysis/reducer/mod.rs | 9 +++------ .../src/static_analysis/zir_propagation.rs | 6 +++--- zokrates_core/src/typed_absy/mod.rs | 5 +++-- zokrates_core/src/zir/mod.rs | 19 ++++++++----------- zokrates_embed/src/ark.rs | 17 ++++++----------- zokrates_pest_ast/src/lib.rs | 2 +- zokrates_test_derive/src/lib.rs | 4 ++-- 10 files changed, 29 insertions(+), 38 deletions(-) diff --git a/zokrates_cli/src/ops/check.rs b/zokrates_cli/src/ops/check.rs index 324e8f2f..ba9a4dd0 100644 --- a/zokrates_cli/src/ops/check.rs +++ b/zokrates_cli/src/ops/check.rs @@ -74,7 +74,7 @@ fn cli_check(sub_matches: &ArgMatches) -> Result<(), String> { format!( "{}:{}", file.strip_prefix(std::env::current_dir().unwrap()) - .unwrap_or_else(|_| file.as_path()) + .unwrap_or(file.as_path()) .display(), e.value() ) diff --git a/zokrates_cli/src/ops/compile.rs b/zokrates_cli/src/ops/compile.rs index 4157effb..c09d68f3 100644 --- a/zokrates_cli/src/ops/compile.rs +++ b/zokrates_cli/src/ops/compile.rs @@ -90,7 +90,7 @@ fn cli_compile(sub_matches: &ArgMatches) -> Result<(), String> { format!( "{}:{}", file.strip_prefix(std::env::current_dir().unwrap()) - .unwrap_or_else(|_| file.as_path()) + .unwrap_or(file.as_path()) .display(), e.value() ) diff --git a/zokrates_core/src/absy/mod.rs b/zokrates_core/src/absy/mod.rs index 3983a3e8..41df4c15 100644 --- a/zokrates_core/src/absy/mod.rs +++ b/zokrates_core/src/absy/mod.rs @@ -137,6 +137,7 @@ pub enum SymbolDefinition<'ast> { Function(FunctionNode<'ast>), } +#[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Clone)] pub enum Symbol<'ast> { Here(SymbolDefinition<'ast>), diff --git a/zokrates_core/src/static_analysis/reducer/mod.rs b/zokrates_core/src/static_analysis/reducer/mod.rs index 83341a92..238333d5 100644 --- a/zokrates_core/src/static_analysis/reducer/mod.rs +++ b/zokrates_core/src/static_analysis/reducer/mod.rs @@ -257,8 +257,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> { } Err(InlineError::Generic(decl, conc)) => Err(Error::Incompatible(format!( "Call site `{}` incompatible with declaration `{}`", - conc.to_string(), - decl.to_string() + conc, decl ))), Err(InlineError::NonConstant(key, generics, arguments, _)) => { self.complete = false; @@ -388,8 +387,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> { } Err(InlineError::Generic(decl, conc)) => Err(Error::Incompatible(format!( "Call site `{}` incompatible with declaration `{}`", - conc.to_string(), - decl.to_string() + conc, decl ))), Err(InlineError::NonConstant(key, generics, arguments, output_types)) => { self.complete = false; @@ -442,8 +440,7 @@ impl<'ast, 'a, T: Field> ResultFolder<'ast, T> for Reducer<'ast, 'a, T> { UExpression::from(index as u32).into(), )) .chain(statements.clone().into_iter()) - .map(|s| transformer.fold_statement(s)) - .flatten() + .flat_map(|s| transformer.fold_statement(s)) .collect(); out_statements.extend(statements); diff --git a/zokrates_core/src/static_analysis/zir_propagation.rs b/zokrates_core/src/static_analysis/zir_propagation.rs index 7c29fd37..1dc89ad0 100644 --- a/zokrates_core/src/static_analysis/zir_propagation.rs +++ b/zokrates_core/src/static_analysis/zir_propagation.rs @@ -147,7 +147,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { UExpressionInner::Value(v) => e .get(v as usize) .cloned() - .ok_or_else(|| Error::OutOfBounds(v, e.len() as u128)), + .ok_or(Error::OutOfBounds(v, e.len() as u128)), i => Ok(FieldElementExpression::Select( e, box i.annotate(UBitwidth::B32), @@ -279,7 +279,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { UExpressionInner::Value(v) => e .get(*v as usize) .cloned() - .ok_or_else(|| Error::OutOfBounds(*v, e.len() as u128)), + .ok_or(Error::OutOfBounds(*v, e.len() as u128)), _ => Ok(BooleanExpression::Select(e, box index)), } } @@ -498,7 +498,7 @@ impl<'ast, T: Field> ResultFolder<'ast, T> for ZirPropagator<'ast, T> { UExpressionInner::Value(v) => e .get(v as usize) .cloned() - .ok_or_else(|| Error::OutOfBounds(v, e.len() as u128)) + .ok_or(Error::OutOfBounds(v, e.len() as u128)) .map(|e| e.into_inner()), i => Ok(UExpressionInner::Select(e, box i.annotate(UBitwidth::B32))), } diff --git a/zokrates_core/src/typed_absy/mod.rs b/zokrates_core/src/typed_absy/mod.rs index dbee0862..2a1258a6 100644 --- a/zokrates_core/src/typed_absy/mod.rs +++ b/zokrates_core/src/typed_absy/mod.rs @@ -190,6 +190,7 @@ impl<'ast, T> TypedConstantSymbolDeclaration<'ast, T> { } } +#[allow(clippy::large_enum_variant)] #[derive(PartialEq, Debug, Clone)] pub enum TypedSymbolDeclaration<'ast, T> { Function(TypedFunctionSymbolDeclaration<'ast, T>), @@ -424,6 +425,7 @@ impl<'ast, T: Field> Typed<'ast, T> for TypedConstant<'ast, T> { } /// Something we can assign to. +#[allow(clippy::large_enum_variant)] #[derive(Clone, PartialEq, Debug, Hash, Eq, PartialOrd, Ord)] pub enum TypedAssignee<'ast, T> { Identifier(Variable<'ast, T>), @@ -1243,8 +1245,7 @@ impl<'ast, T: Clone> ArrayValue<'ast, T> { ) -> Option { self.0 .iter() - .map(|v| Self::expression_at_aux(v.clone())) - .flatten() + .flat_map(|v| Self::expression_at_aux(v.clone())) .take_while(|e| e.is_some()) .map(|e| e.unwrap()) .nth(index) diff --git a/zokrates_core/src/zir/mod.rs b/zokrates_core/src/zir/mod.rs index 9978ed14..2f7dcd89 100644 --- a/zokrates_core/src/zir/mod.rs +++ b/zokrates_core/src/zir/mod.rs @@ -344,17 +344,14 @@ impl<'ast, T> Iterator for ConjunctionIterator> { type Item = BooleanExpression<'ast, T>; fn next(&mut self) -> Option { - self.current - .pop() - .map(|n| match n { - BooleanExpression::And(box left, box right) => { - self.current.push(left); - self.current.push(right); - self.next() - } - n => Some(n), - }) - .flatten() + self.current.pop().and_then(|n| match n { + BooleanExpression::And(box left, box right) => { + self.current.push(left); + self.current.push(right); + self.next() + } + n => Some(n), + }) } } diff --git a/zokrates_embed/src/ark.rs b/zokrates_embed/src/ark.rs index ff8826a3..beb756e4 100644 --- a/zokrates_embed/src/ark.rs +++ b/zokrates_embed/src/ark.rs @@ -144,17 +144,12 @@ pub fn generate_verify_constraints( var_to_index(&vk.h_gamma_g2.y.c1, num_instance_variables), ]; - vk_indices.extend( - vk.query - .iter() - .map(|q| { - vec![ - var_to_index(&q.x, num_instance_variables), - var_to_index(&q.y, num_instance_variables), - ] - }) - .flatten(), - ); + vk_indices.extend(vk.query.iter().flat_map(|q| { + vec![ + var_to_index(&q.x, num_instance_variables), + var_to_index(&q.y, num_instance_variables), + ] + })); let out_index = match &res { Boolean::Is(x) => x diff --git a/zokrates_pest_ast/src/lib.rs b/zokrates_pest_ast/src/lib.rs index fa5d1dcd..09a26402 100644 --- a/zokrates_pest_ast/src/lib.rs +++ b/zokrates_pest_ast/src/lib.rs @@ -705,7 +705,7 @@ mod ast { #[derive(Debug, FromPest, PartialEq, Clone)] #[pest_ast(rule(Rule::assignee_access))] pub enum AssigneeAccess<'ast> { - Select(ArrayAccess<'ast>), + Select(Box>), Member(MemberAccess<'ast>), } diff --git a/zokrates_test_derive/src/lib.rs b/zokrates_test_derive/src/lib.rs index 4cfc8d07..5f7f10f9 100644 --- a/zokrates_test_derive/src/lib.rs +++ b/zokrates_test_derive/src/lib.rs @@ -28,9 +28,9 @@ fn write_test(test_file: &mut W, test_path: &Path, base_path: &Path) { .unwrap() .display() .to_string() - .replace("/", "_") + .replace('/', "_") .replace(".json", "") - .replace(".", "") + .replace('.', "") ); write!( From f202c6837ade3fe14a126a0e55237cf4dbd79729 Mon Sep 17 00:00:00 2001 From: schaeff Date: Fri, 10 Dec 2021 15:54:05 +0100 Subject: [PATCH 19/21] remove duplicate method, use to_bits_be --- zokrates_core/src/flatten/mod.rs | 5 ++- zokrates_core/src/ir/interpreter.rs | 2 +- zokrates_field/src/bn128.rs | 9 ++++-- zokrates_field/src/lib.rs | 48 ++++++----------------------- 4 files changed, 19 insertions(+), 45 deletions(-) diff --git a/zokrates_core/src/flatten/mod.rs b/zokrates_core/src/flatten/mod.rs index 46cd264f..3292066e 100644 --- a/zokrates_core/src/flatten/mod.rs +++ b/zokrates_core/src/flatten/mod.rs @@ -674,11 +674,10 @@ impl<'ast, T: Field> Flattener<'ast, T> { self.enforce_constant_le_check( statements_flattened, &e_bits_be, - &T::max_value().bit_vector_be(), + &T::max_value().to_bits_be(), ); - let conditions = - self.constant_le_check(statements_flattened, &e_bits_be, &c.bit_vector_be()); + let conditions = self.constant_le_check(statements_flattened, &e_bits_be, &c.to_bits_be()); // return `len(conditions) == sum(conditions)` self.eq_check( diff --git a/zokrates_core/src/ir/interpreter.rs b/zokrates_core/src/ir/interpreter.rs index fb6c7ab2..67a91a02 100644 --- a/zokrates_core/src/ir/interpreter.rs +++ b/zokrates_core/src/ir/interpreter.rs @@ -144,7 +144,7 @@ impl Interpreter { // pad with zeroes so that the result is exactly `bit_width` long (0..bit_width - bits.len()) - .map(|_| 0) + .map(|_| false) .chain(bits) .map(T::from) .collect() diff --git a/zokrates_field/src/bn128.rs b/zokrates_field/src/bn128.rs index ddb5c4ea..5b8988e1 100644 --- a/zokrates_field/src/bn128.rs +++ b/zokrates_field/src/bn128.rs @@ -25,12 +25,17 @@ mod tests { use bincode::{deserialize, serialize, Infinite}; #[test] - fn max_value_bits() { - let bits = FieldPrime::max_value().bit_vector_be(); + fn to_bits_be() { + let bits = FieldPrime::max_value().to_bits_be(); + assert_eq!(bits.len(), 254); assert_eq!( bits[0..10].to_vec(), vec![true, true, false, false, false, false, false, true, true, false] ); + + let bits = FieldPrime::one().to_bits_be(); + assert_eq!(bits.len(), 254); + assert_eq!(bits[253], true); } #[test] diff --git a/zokrates_field/src/lib.rs b/zokrates_field/src/lib.rs index fa93ffe3..5262a776 100644 --- a/zokrates_field/src/lib.rs +++ b/zokrates_field/src/lib.rs @@ -53,8 +53,8 @@ pub trait Field: 'static + Sync + Send + + From + From - + From + From + From + From @@ -102,7 +102,7 @@ pub trait Field: /// m` has a single `n`-bit decomposition fn max_unique_value() -> Self; /// Return the number of bits required to represent this element - fn to_bits_be(&self) -> Vec; + fn to_bits_be(&self) -> Vec; /// Returns the number of bits required to represent any element of this field type. fn get_required_bits() -> usize; /// Tries to parse a string into this representation @@ -117,37 +117,6 @@ pub trait Field: fn name() -> &'static str; /// Gets the number of bits fn bits(&self) -> u32; - /// Returns this `Field`'s largest value as a big-endian bit vector - /// Always returns `Self::get_required_bits()` elements - fn bit_vector_be(&self) -> Vec { - fn bytes_to_bits(bytes: &[u8]) -> Vec { - bytes - .iter() - .flat_map(|&v| (0..8).rev().map(move |i| (v >> i) & 1 == 1)) - .collect() - } - - let field_bytes_le = self.to_byte_vector(); - - // reverse for big-endianess - let field_bytes_be = field_bytes_le.into_iter().rev().collect::>(); - let field_bits_be = bytes_to_bits(&field_bytes_be); - - let field_bits_be: Vec<_> = (0..Self::get_required_bits() - .saturating_sub(field_bits_be.len())) - .map(|_| &false) - .chain( - &field_bits_be[field_bits_be - .len() - .saturating_sub(Self::get_required_bits())..], - ) - .cloned() - .collect(); - - assert_eq!(field_bits_be.len(), Self::get_required_bits()); - - field_bits_be - } /// Returns the value as a BigUint fn to_biguint(&self) -> BigUint; } @@ -195,8 +164,10 @@ mod prime_field { BigUint::from_bytes_le(&self.v.into_repr().to_bytes_le()) } - fn to_bits_be(&self) -> Vec { - self.value.to_radix_be(2).1 + fn to_bits_be(&self) -> Vec { + use ark_ff::BigInteger; + let res = self.v.into_repr().to_bits_be(); + res[res.len() - Self::get_required_bits()..].to_vec() } fn to_byte_vector(&self) -> Vec { @@ -309,11 +280,10 @@ mod prime_field { } } - impl From for FieldPrime { - fn from(num: u8) -> Self { - let x = ToBigInt::to_bigint(&num).unwrap(); + impl From for FieldPrime { + fn from(num: bool) -> Self { FieldPrime { - value: &x - x.div_floor(&*P) * &*P, + v: Fr::from(num as u32), } } } From 1e44ec2b5d3c4ad9f1fbe2b43f091dac3cf1b93f Mon Sep 17 00:00:00 2001 From: Darko Macesic Date: Fri, 10 Dec 2021 18:02:42 +0100 Subject: [PATCH 20/21] Update condition_redefiner.rs typo --- zokrates_core/src/static_analysis/condition_redefiner.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zokrates_core/src/static_analysis/condition_redefiner.rs b/zokrates_core/src/static_analysis/condition_redefiner.rs index 2ba39ddf..b09f68ba 100644 --- a/zokrates_core/src/static_analysis/condition_redefiner.rs +++ b/zokrates_core/src/static_analysis/condition_redefiner.rs @@ -265,7 +265,7 @@ mod tests { // should become // // bool #CONDITION_0 = c && d - // field foo = if c && d then { + // field foo = if #CONDITION_0 then { // field a = 1 // bool #CONDITION_1 = e && f // if #CONDITION_1 then 2 else 3 From 61f902aaa26af1a48d6d23a91aea8bdbc2b0ade4 Mon Sep 17 00:00:00 2001 From: dark64 Date: Mon, 13 Dec 2021 13:32:20 +0100 Subject: [PATCH 21/21] remove box --- zokrates_pest_ast/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zokrates_pest_ast/src/lib.rs b/zokrates_pest_ast/src/lib.rs index 09a26402..bb67d2a2 100644 --- a/zokrates_pest_ast/src/lib.rs +++ b/zokrates_pest_ast/src/lib.rs @@ -702,10 +702,11 @@ mod ast { Member(MemberAccess<'ast>), } + #[allow(clippy::large_enum_variant)] #[derive(Debug, FromPest, PartialEq, Clone)] #[pest_ast(rule(Rule::assignee_access))] pub enum AssigneeAccess<'ast> { - Select(Box>), + Select(ArrayAccess<'ast>), Member(MemberAccess<'ast>), }