From 6ac48e2f920bd54358b7a4cca0a96f87753009e4 Mon Sep 17 00:00:00 2001 From: Alex Vlasov Date: Tue, 5 Mar 2019 10:28:19 +0100 Subject: [PATCH] migrate to versioned bellman --- Cargo.toml | 9 +- benches/baby_pedersen_hash.rs | 4 +- benches/pedersen_hash.rs | 4 +- examples/bench.rs | 4 +- src/alt_babyjubjub/fs.rs | 6 +- src/alt_babyjubjub/mod.rs | 283 +++++++++++++++++++++++++++++- src/alt_babyjubjub/tests.rs | 2 +- src/baby_group_hash.rs | 2 +- src/baby_pedersen_hash.rs | 2 +- src/babyjubjub/edwards.rs | 2 +- src/babyjubjub/fs.rs | 6 +- src/babyjubjub/mod.rs | 6 +- src/babyjubjub/montgomery.rs | 2 +- src/babyjubjub/tests.rs | 2 +- src/circuit/baby_ecc.rs | 8 +- src/circuit/baby_eddsa.rs | 8 +- src/circuit/baby_pedersen_hash.rs | 4 +- src/circuit/blake2s.rs | 4 +- src/circuit/boolean.rs | 8 +- src/circuit/ecc.rs | 12 +- src/circuit/float_point.rs | 6 +- src/circuit/lookup.rs | 6 +- src/circuit/mod.rs | 1 + src/circuit/multieq.rs | 4 +- src/circuit/multipack.rs | 6 +- src/circuit/num.rs | 47 +++-- src/circuit/pedersen_hash.rs | 8 +- src/circuit/polynomial_lookup.rs | 71 ++++++++ src/circuit/sapling/mod.rs | 12 +- src/circuit/sha256.rs | 4 +- src/circuit/shark_mimc.rs | 4 +- src/circuit/sprout/commitment.rs | 2 +- src/circuit/sprout/input.rs | 2 +- src/circuit/sprout/mod.rs | 6 +- src/circuit/sprout/output.rs | 2 +- src/circuit/sprout/prfs.rs | 2 +- src/circuit/test/mod.rs | 8 +- src/circuit/uint32.rs | 8 +- src/eddsa.rs | 4 +- src/group_hash.rs | 134 +++++++++++++- src/interpolation.rs | 137 +++++++++++++++ src/jubjub/edwards.rs | 2 +- src/jubjub/fs.rs | 6 +- src/jubjub/mod.rs | 13 +- src/jubjub/montgomery.rs | 2 +- src/jubjub/tests.rs | 2 +- src/lib.rs | 4 +- src/pedersen_hash.rs | 2 +- src/primitives/mod.rs | 2 +- src/redbabyjubjub.rs | 4 +- src/redjubjub.rs | 6 +- 51 files changed, 764 insertions(+), 131 deletions(-) create mode 100644 src/circuit/polynomial_lookup.rs create mode 100644 src/interpolation.rs diff --git a/Cargo.toml b/Cargo.toml index ea5d3ecc..e4b337ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ homepage = "https://github.com/matterinc/sapling-crypto" license = "MIT/Apache-2.0" name = "sapling-crypto" repository = "https://github.com/matterinc/sapling-crypto" -version = "0.0.3" +version = "0.0.4" [lib] crate-type = ["lib", "staticlib"] @@ -17,9 +17,10 @@ digest = "0.7" byteorder = "1" serde = "1.0.80" serde_derive = "1.0.80" -ff = { git = 'https://github.com/matterinc/ff', features = ["derive"] } -pairing = { git = 'https://github.com/matterinc/pairing', features = ["expose-arith"] } -bellman = { git = 'https://github.com/matterinc/bellman'} +tiny-keccak = "1.4.2" + +bellman = { git = 'https://github.com/matterinc/bellman', tag = "0.2.0"} +#bellman = { path = "../bellman"} [dependencies.blake2-rfc] git = "https://github.com/gtank/blake2-rfc" diff --git a/benches/baby_pedersen_hash.rs b/benches/baby_pedersen_hash.rs index 3bba91fb..5ee10697 100644 --- a/benches/baby_pedersen_hash.rs +++ b/benches/baby_pedersen_hash.rs @@ -2,11 +2,11 @@ extern crate rand; extern crate test; -extern crate pairing; +extern crate bellman; extern crate sapling_crypto; use rand::{Rand, thread_rng}; -use pairing::bn256::Bn256; +use bellman::pairing::bn256::Bn256; use sapling_crypto::alt_babyjubjub::AltJubjubBn256; use sapling_crypto::pedersen_hash::{pedersen_hash, Personalization}; diff --git a/benches/pedersen_hash.rs b/benches/pedersen_hash.rs index c5968dec..f39cbfa3 100644 --- a/benches/pedersen_hash.rs +++ b/benches/pedersen_hash.rs @@ -2,11 +2,11 @@ extern crate rand; extern crate test; -extern crate pairing; +extern crate bellman; extern crate sapling_crypto; use rand::{Rand, thread_rng}; -use pairing::bls12_381::Bls12; +use bellman::pairing::bls12_381::Bls12; use sapling_crypto::jubjub::JubjubBls12; use sapling_crypto::pedersen_hash::{pedersen_hash, Personalization}; diff --git a/examples/bench.rs b/examples/bench.rs index 4b7a707b..7ebfd03a 100644 --- a/examples/bench.rs +++ b/examples/bench.rs @@ -1,7 +1,6 @@ extern crate sapling_crypto; extern crate bellman; extern crate rand; -extern crate pairing; use std::time::{Duration, Instant}; use sapling_crypto::jubjub::{ @@ -17,9 +16,10 @@ use sapling_crypto::primitives::{ ProofGenerationKey, ValueCommitment }; + use bellman::groth16::*; use rand::{XorShiftRng, SeedableRng, Rng}; -use pairing::bls12_381::{Bls12, Fr}; +use bellman::pairing::bls12_381::{Bls12, Fr}; const TREE_DEPTH: usize = 32; diff --git a/src/alt_babyjubjub/fs.rs b/src/alt_babyjubjub/fs.rs index 8b519c4b..1785faf7 100644 --- a/src/alt_babyjubjub/fs.rs +++ b/src/alt_babyjubjub/fs.rs @@ -1,7 +1,7 @@ use byteorder::{ByteOrder, LittleEndian}; -use ff::{adc, sbb, mac_with_carry}; -use ff::{BitIterator, Field, PrimeField, SqrtField, PrimeFieldRepr, PrimeFieldDecodingError, LegendreSymbol}; -use ff::LegendreSymbol::*; +use bellman::pairing::ff::{adc, sbb, mac_with_carry}; +use bellman::pairing::ff::{BitIterator, Field, PrimeField, SqrtField, PrimeFieldRepr, PrimeFieldDecodingError, LegendreSymbol}; +use bellman::pairing::ff::LegendreSymbol::*; use super::ToUniform; // s = 2736030358979909402780800718157159386076813972158567259200215660948447373041 diff --git a/src/alt_babyjubjub/mod.rs b/src/alt_babyjubjub/mod.rs index 9f769e5a..c8a1f759 100644 --- a/src/alt_babyjubjub/mod.rs +++ b/src/alt_babyjubjub/mod.rs @@ -37,21 +37,21 @@ // JubjubParams, // }; -use ff::{ +use bellman::pairing::ff::{ Field, PrimeField, }; -use group_hash::baby_group_hash; +use group_hash::{baby_group_hash, generic_group_hash}; use constants; -use pairing::bn256::{ +use bellman::pairing::bn256::{ Bn256, Fr }; -pub use ::jubjub::{ +pub use super::jubjub::{ Unknown, PrimeOrder, FixedGenerators, @@ -75,6 +75,8 @@ pub mod fs; #[cfg(test)] pub mod tests; +use super::group_hash::GroupHasher; + impl JubjubEngine for Bn256 { type Fs = self::fs::Fs; type Params = AltJubjubBn256; @@ -346,6 +348,225 @@ impl AltJubjubBn256 { tmp_params } + + pub fn new_with_hasher() -> Self { + let montgomery_a = Fr::from_str("168698").unwrap(); + let mut montgomery_2a = montgomery_a; + montgomery_2a.double(); + + let mut tmp_params = AltJubjubBn256 { + // d = -(168696/168700) + edwards_d: Fr::from_str("12181644023421730124874158521699555681764249180949974110617291017600649128846").unwrap(), + // A = 168698 + montgomery_a: montgomery_a, + // 2A = 2.A + montgomery_2a: montgomery_2a, + // scaling factor = sqrt(4 / (a - d)) + scale: Fr::from_str("6360561867910373094066688120553762416144456282423235903351243436111059670888").unwrap(), + + // We'll initialize these below + pedersen_hash_generators: vec![], + pedersen_hash_exp: vec![], + pedersen_circuit_generators: vec![], + fixed_base_generators: vec![], + fixed_base_circuit_generators: vec![], + }; + + fn find_group_hash( + m: &[u8], + personalization: &[u8; 8], + params: &E::Params + ) -> edwards::Point + { + let mut tag = m.to_vec(); + let i = tag.len(); + tag.push(0u8); + + loop { + let gh = generic_group_hash::<_, HH>( + &tag, + personalization, + params + ); + + // We don't want to overflow and start reusing generators + assert!(tag[i] != u8::max_value()); + tag[i] += 1; + + if let Some(gh) = gh { + break gh; + } + } + } + + // Create the bases for the Pedersen hashes + { + let mut pedersen_hash_generators = vec![]; + + for m in 0..5 { + use byteorder::{WriteBytesExt, LittleEndian}; + + let mut segment_number = [0u8; 4]; + (&mut segment_number[0..4]).write_u32::(m).unwrap(); + + pedersen_hash_generators.push( + find_group_hash::<_, H>( + &segment_number, + constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, + &tmp_params + ) + ); + } + + // Check for duplicates, far worse than spec inconsistencies! + for (i, p1) in pedersen_hash_generators.iter().enumerate() { + if p1 == &edwards::Point::zero() { + panic!("Neutral element!"); + } + + for p2 in pedersen_hash_generators.iter().skip(i+1) { + if p1 == p2 { + panic!("Duplicate generator!"); + } + } + } + + tmp_params.pedersen_hash_generators = pedersen_hash_generators; + } + + // Create the exp table for the Pedersen hash generators + { + let mut pedersen_hash_exp = vec![]; + + for g in &tmp_params.pedersen_hash_generators { + let mut g = g.clone(); + + let window = tmp_params.pedersen_hash_exp_window_size(); + + let mut tables = vec![]; + + let mut num_bits = 0; + while num_bits <= fs::Fs::NUM_BITS { + let mut table = Vec::with_capacity(1 << window); + + let mut base = edwards::Point::zero(); + + for _ in 0..(1 << window) { + table.push(base.clone()); + base = base.add(&g, &tmp_params); + } + + tables.push(table); + num_bits += window; + + for _ in 0..window { + g = g.double(&tmp_params); + } + } + + pedersen_hash_exp.push(tables); + } + + tmp_params.pedersen_hash_exp = pedersen_hash_exp; + } + + // Create the bases for other parts of the protocol + { + let mut fixed_base_generators = vec![edwards::Point::zero(); FixedGenerators::Max as usize]; + + fixed_base_generators[FixedGenerators::ProofGenerationKey as usize] = + find_group_hash::<_, H>(&[], constants::PROOF_GENERATION_KEY_BASE_GENERATOR_PERSONALIZATION, &tmp_params); + + fixed_base_generators[FixedGenerators::NoteCommitmentRandomness as usize] = + find_group_hash::<_, H>(b"r", constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION, &tmp_params); + + fixed_base_generators[FixedGenerators::NullifierPosition as usize] = + find_group_hash::<_, H>(&[], constants::NULLIFIER_POSITION_IN_TREE_GENERATOR_PERSONALIZATION, &tmp_params); + + fixed_base_generators[FixedGenerators::ValueCommitmentValue as usize] = + find_group_hash::<_, H>(b"v", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params); + + fixed_base_generators[FixedGenerators::ValueCommitmentRandomness as usize] = + find_group_hash::<_, H>(b"r", constants::VALUE_COMMITMENT_GENERATOR_PERSONALIZATION, &tmp_params); + + fixed_base_generators[FixedGenerators::SpendingKeyGenerator as usize] = + find_group_hash::<_, H>(&[], constants::SPENDING_KEY_GENERATOR_PERSONALIZATION, &tmp_params); + + // Check for duplicates, far worse than spec inconsistencies! + for (i, p1) in fixed_base_generators.iter().enumerate() { + if p1 == &edwards::Point::zero() { + panic!("Neutral element!"); + } + + for p2 in fixed_base_generators.iter().skip(i+1) { + if p1 == p2 { + panic!("Duplicate generator!"); + } + } + } + + tmp_params.fixed_base_generators = fixed_base_generators; + } + + // Create the 2-bit window table lookups for each 4-bit + // "chunk" in each segment of the Pedersen hash + { + let mut pedersen_circuit_generators = vec![]; + + // Process each segment + for mut gen in tmp_params.pedersen_hash_generators.iter().cloned() { + let mut gen = montgomery::Point::from_edwards(&gen, &tmp_params); + let mut windows = vec![]; + for _ in 0..tmp_params.pedersen_hash_chunks_per_generator() { + // Create (x, y) coeffs for this chunk + let mut coeffs = vec![]; + let mut g = gen.clone(); + + // coeffs = g, g*2, g*3, g*4 + for _ in 0..4 { + coeffs.push(g.into_xy().expect("cannot produce O")); + g = g.add(&gen, &tmp_params); + } + windows.push(coeffs); + + // Our chunks are separated by 2 bits to prevent overlap. + for _ in 0..4 { + gen = gen.double(&tmp_params); + } + } + pedersen_circuit_generators.push(windows); + } + + tmp_params.pedersen_circuit_generators = pedersen_circuit_generators; + } + + // Create the 3-bit window table lookups for fixed-base + // exp of each base in the protocol. + { + let mut fixed_base_circuit_generators = vec![]; + + for mut gen in tmp_params.fixed_base_generators.iter().cloned() { + let mut windows = vec![]; + for _ in 0..tmp_params.fixed_base_chunks_per_generator() { + let mut coeffs = vec![(Fr::zero(), Fr::one())]; + let mut g = gen.clone(); + for _ in 0..7 { + coeffs.push(g.into_xy()); + g = g.add(&gen, &tmp_params); + } + windows.push(coeffs); + + // gen = gen * 8 + gen = g; + } + fixed_base_circuit_generators.push(windows); + } + + tmp_params.fixed_base_circuit_generators = fixed_base_circuit_generators; + } + + tmp_params + } } #[test] @@ -375,3 +596,57 @@ fn test_jubjub_altbn256() { // assert!(p == q); } + +#[test] +fn test_generic_params() { + use super::group_hash::BlakeHasher; + + let params = AltJubjubBn256::new(); + let generic_params = AltJubjubBn256::new_with_hasher::(); + + assert!(params.pedersen_hash_generators == generic_params.pedersen_hash_generators); + assert!(params.fixed_base_generators == generic_params.fixed_base_generators); + + assert_eq!(params.pedersen_circuit_generators, generic_params.pedersen_circuit_generators); + assert_eq!(params.fixed_base_circuit_generators, generic_params.fixed_base_circuit_generators); +} + +#[test] +fn pretty_print_params_for_blake() { + use super::group_hash::BlakeHasher; + + let generic_params = AltJubjubBn256::new_with_hasher::(); + + println!("Creating generators using Blake2s"); + + println!("Using personalization `{}`", std::str::from_utf8(constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION).unwrap()); + + println!("Pedersen hash generators:"); + + for (i, e) in generic_params.pedersen_hash_generators.iter().enumerate() { + let (x, y) = e.into_xy(); + println!("Generator {}", i); + println!("X = {}", x); + println!("Y = {}", y); + } +} + +#[test] +fn pretty_print_params_for_keccak() { + use super::group_hash::Keccak256Hasher; + + let generic_params = AltJubjubBn256::new_with_hasher::(); + + println!("Creating generators using Keccak256 (Ethereum style)"); + + println!("Using personalization `{}`", std::str::from_utf8(constants::PEDERSEN_HASH_GENERATORS_PERSONALIZATION).unwrap()); + + println!("Pedersen hash generators:"); + + for (i, e) in generic_params.pedersen_hash_generators.iter().enumerate() { + let (x, y) = e.into_xy(); + println!("Generator {}", i); + println!("X = {}", x); + println!("Y = {}", y); + } +} \ No newline at end of file diff --git a/src/alt_babyjubjub/tests.rs b/src/alt_babyjubjub/tests.rs index eb7e36b7..77813b4d 100644 --- a/src/alt_babyjubjub/tests.rs +++ b/src/alt_babyjubjub/tests.rs @@ -6,7 +6,7 @@ use super::{ edwards }; -use ff::{ +use bellman::pairing::ff::{ Field, PrimeField, PrimeFieldRepr, diff --git a/src/baby_group_hash.rs b/src/baby_group_hash.rs index b132c90e..c9b3d2d6 100644 --- a/src/baby_group_hash.rs +++ b/src/baby_group_hash.rs @@ -4,7 +4,7 @@ use babyjubjub::{ edwards }; -use ff::{ +use bellman::pairing::ff::{ PrimeField }; diff --git a/src/baby_pedersen_hash.rs b/src/baby_pedersen_hash.rs index c888e1ac..0c87fd9d 100644 --- a/src/baby_pedersen_hash.rs +++ b/src/baby_pedersen_hash.rs @@ -1,5 +1,5 @@ use babyjubjub::*; -use ff::{Field, PrimeField, PrimeFieldRepr}; +use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; #[derive(Copy, Clone)] pub enum Personalization { diff --git a/src/babyjubjub/edwards.rs b/src/babyjubjub/edwards.rs index 8677a7f6..4f40d561 100644 --- a/src/babyjubjub/edwards.rs +++ b/src/babyjubjub/edwards.rs @@ -1,4 +1,4 @@ -use ff::{ +use bellman::pairing::ff::{ Field, SqrtField, PrimeField, diff --git a/src/babyjubjub/fs.rs b/src/babyjubjub/fs.rs index 243c1180..bfaa3f5b 100644 --- a/src/babyjubjub/fs.rs +++ b/src/babyjubjub/fs.rs @@ -1,7 +1,7 @@ use byteorder::{ByteOrder, LittleEndian}; -use ff::{adc, sbb, mac_with_carry}; -use ff::{BitIterator, Field, PrimeField, SqrtField, PrimeFieldRepr, PrimeFieldDecodingError, LegendreSymbol}; -use ff::LegendreSymbol::*; +use bellman::pairing::ff::{adc, sbb, mac_with_carry}; +use bellman::pairing::ff::{BitIterator, Field, PrimeField, SqrtField, PrimeFieldRepr, PrimeFieldDecodingError, LegendreSymbol}; +use bellman::pairing::ff::LegendreSymbol::*; use super::ToUniform; // s = 2736030358979909402780800718157159386076813972158567259200215660948447373041 diff --git a/src/babyjubjub/mod.rs b/src/babyjubjub/mod.rs index 6f073a55..59fcf9d2 100644 --- a/src/babyjubjub/mod.rs +++ b/src/babyjubjub/mod.rs @@ -19,11 +19,11 @@ //! the Montgomery curve forms a group isomorphism, allowing points //! to be freely converted between the two forms. -use pairing::{ +use bellman::pairing::{ Engine, }; -use ff::{ +use bellman::pairing::ff::{ Field, PrimeField, SqrtField @@ -33,7 +33,7 @@ use baby_group_hash::group_hash; use constants; -use pairing::bn256::{ +use bellman::pairing::bn256::{ Bn256, Fr }; diff --git a/src/babyjubjub/montgomery.rs b/src/babyjubjub/montgomery.rs index 5d1e5c6a..53ed1d83 100644 --- a/src/babyjubjub/montgomery.rs +++ b/src/babyjubjub/montgomery.rs @@ -1,4 +1,4 @@ -use ff::{ +use bellman::pairing::ff::{ Field, SqrtField, PrimeField, diff --git a/src/babyjubjub/tests.rs b/src/babyjubjub/tests.rs index 8233fd24..7b097dbe 100644 --- a/src/babyjubjub/tests.rs +++ b/src/babyjubjub/tests.rs @@ -6,7 +6,7 @@ use super::{ edwards }; -use ff::{ +use bellman::pairing::ff::{ Field, PrimeField, PrimeFieldRepr, diff --git a/src/circuit/baby_ecc.rs b/src/circuit/baby_ecc.rs index 17018235..9036a12c 100644 --- a/src/circuit/baby_ecc.rs +++ b/src/circuit/baby_ecc.rs @@ -1,8 +1,8 @@ -use pairing::{ +use bellman::pairing::{ Engine, }; -use ff::{Field}; +use bellman::pairing::ff::{Field}; use bellman::{ SynthesisError, @@ -724,8 +724,8 @@ impl MontgomeryPoint { mod test { use bellman::{ConstraintSystem}; use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use pairing::bn256::{Bn256, Fr}; - use ff::{BitIterator, Field, PrimeField}; + use bellman::pairing::bn256::{Bn256, Fr}; + use bellman::pairing::ff::{BitIterator, Field, PrimeField}; use ::circuit::test::*; use ::babyjubjub::{ montgomery, diff --git a/src/circuit/baby_eddsa.rs b/src/circuit/baby_eddsa.rs index 4cc09ad2..67832fea 100644 --- a/src/circuit/baby_eddsa.rs +++ b/src/circuit/baby_eddsa.rs @@ -1,8 +1,8 @@ -use pairing::{ +use bellman::pairing::{ Engine, }; -use ff::{Field}; +use bellman::pairing::ff::{Field}; use bellman::{ SynthesisError, @@ -233,8 +233,8 @@ mod test { use super::*; use ::circuit::test::*; use ::circuit::boolean::{Boolean, AllocatedBit}; - use pairing::bn256::{Bn256, Fr}; - use ff::{PrimeField, PrimeFieldRepr}; + use bellman::pairing::bn256::{Bn256, Fr}; + use bellman::pairing::ff::{PrimeField, PrimeFieldRepr}; use ::alt_babyjubjub::AltJubjubBn256; #[test] diff --git a/src/circuit/baby_pedersen_hash.rs b/src/circuit/baby_pedersen_hash.rs index 1939835d..184cd203 100644 --- a/src/circuit/baby_pedersen_hash.rs +++ b/src/circuit/baby_pedersen_hash.rs @@ -116,8 +116,8 @@ mod test { use super::*; use ::circuit::test::*; use ::circuit::boolean::{Boolean, AllocatedBit}; - use pairing::bn256::{Bn256, Fr}; - use ff::PrimeField; + use bellman::pairing::bn256::{Bn256, Fr}; + use bellman::pairing::ff::PrimeField; #[test] fn test_pedersen_hash_constraints() { diff --git a/src/circuit/blake2s.rs b/src/circuit/blake2s.rs index 93af8069..ccc5d159 100644 --- a/src/circuit/blake2s.rs +++ b/src/circuit/blake2s.rs @@ -1,4 +1,4 @@ -use pairing::{ +use bellman::pairing::{ Engine, }; @@ -321,7 +321,7 @@ pub fn blake2s>( #[cfg(test)] mod test { use rand::{XorShiftRng, SeedableRng, Rng}; - use pairing::bls12_381::{Bls12}; + use bellman::pairing::bls12_381::{Bls12}; use ::circuit::boolean::{Boolean, AllocatedBit}; use ::circuit::test::TestConstraintSystem; use super::blake2s; diff --git a/src/circuit/boolean.rs b/src/circuit/boolean.rs index e1e41796..da79ced1 100644 --- a/src/circuit/boolean.rs +++ b/src/circuit/boolean.rs @@ -1,8 +1,8 @@ -use pairing::{ +use bellman::pairing::{ Engine, }; -use ff::{ +use bellman::pairing::ff::{ Field, PrimeField, BitIterator @@ -817,8 +817,8 @@ impl From for Boolean { #[cfg(test)] mod test { use bellman::{ConstraintSystem}; - use pairing::bls12_381::{Bls12, Fr}; - use ff::{Field, PrimeField}; + use bellman::pairing::bls12_381::{Bls12, Fr}; + use bellman::pairing::ff::{Field, PrimeField}; use ::circuit::test::*; use super::{ AllocatedBit, diff --git a/src/circuit/ecc.rs b/src/circuit/ecc.rs index 61125ca8..d98756dc 100644 --- a/src/circuit/ecc.rs +++ b/src/circuit/ecc.rs @@ -1,8 +1,8 @@ -use pairing::{ +use bellman::pairing::{ Engine, }; -use ff::{Field}; +use bellman::pairing::ff::{Field}; use bellman::{ SynthesisError, @@ -752,8 +752,8 @@ impl MontgomeryPoint { mod test { use bellman::{ConstraintSystem}; use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use pairing::bls12_381::{Bls12, Fr}; - use ff::{BitIterator, Field, PrimeField}; + use bellman::pairing::bls12_381::{Bls12, Fr}; + use bellman::pairing::ff::{BitIterator, Field, PrimeField}; use ::circuit::test::*; use ::jubjub::{ montgomery, @@ -1217,8 +1217,8 @@ mod test { mod baby_test { use bellman::{ConstraintSystem}; use rand::{XorShiftRng, SeedableRng, Rand, Rng}; - use pairing::bn256::{Bn256, Fr}; - use ff::{BitIterator, Field, PrimeField}; + use bellman::pairing::bn256::{Bn256, Fr}; + use bellman::pairing::ff::{BitIterator, Field, PrimeField}; use ::circuit::test::*; use ::alt_babyjubjub::{ montgomery, diff --git a/src/circuit/float_point.rs b/src/circuit/float_point.rs index 7ac0bbbe..4bd5c6d0 100644 --- a/src/circuit/float_point.rs +++ b/src/circuit/float_point.rs @@ -1,5 +1,5 @@ -use pairing::{Engine}; -use ff::{Field, PrimeField}; +use bellman::pairing::{Engine}; +use bellman::pairing::ff::{Field, PrimeField}; use bellman::{ConstraintSystem, SynthesisError}; use super::boolean::{Boolean}; use super::num::{AllocatedNum, Num}; @@ -237,7 +237,7 @@ pub fn parse_float_to_u128( fn test_parsing() { use rand::{SeedableRng, Rng, XorShiftRng}; use bellman::{ConstraintSystem}; - use pairing::bn256::{Bn256}; + use bellman::pairing::bn256::{Bn256}; use ::circuit::test::*; use super::boolean::{AllocatedBit, Boolean}; diff --git a/src/circuit/lookup.rs b/src/circuit/lookup.rs index 629eeb0e..a3e95f8e 100644 --- a/src/circuit/lookup.rs +++ b/src/circuit/lookup.rs @@ -1,5 +1,5 @@ -use pairing::{Engine,}; -use ff::{Field}; +use bellman::pairing::{Engine,}; +use bellman::pairing::ff::{Field}; use super::*; use super::num::{ AllocatedNum, @@ -199,7 +199,7 @@ mod test { use super::*; use ::circuit::test::*; use ::circuit::boolean::{Boolean, AllocatedBit}; - use pairing::bls12_381::{Bls12, Fr}; + use bellman::pairing::bls12_381::{Bls12, Fr}; #[test] fn test_lookup3_xy() { diff --git a/src/circuit/mod.rs b/src/circuit/mod.rs index 4ddbd0a8..0faa79c2 100644 --- a/src/circuit/mod.rs +++ b/src/circuit/mod.rs @@ -15,6 +15,7 @@ pub mod multipack; pub mod sha256; pub mod baby_eddsa; pub mod float_point; +pub mod polynomial_lookup; // pub mod shark_mimc; pub mod sapling; diff --git a/src/circuit/multieq.rs b/src/circuit/multieq.rs index 763d52ad..b4ded939 100644 --- a/src/circuit/multieq.rs +++ b/src/circuit/multieq.rs @@ -1,8 +1,8 @@ -use pairing::{ +use bellman::pairing::{ Engine, }; -use ff::{ +use bellman::pairing::ff::{ Field, PrimeField }; diff --git a/src/circuit/multipack.rs b/src/circuit/multipack.rs index a333dec3..8c80cc80 100644 --- a/src/circuit/multipack.rs +++ b/src/circuit/multipack.rs @@ -1,5 +1,5 @@ -use pairing::{Engine,}; -use ff::{Field, PrimeField}; +use bellman::pairing::{Engine,}; +use bellman::pairing::ff::{Field, PrimeField}; use bellman::{ConstraintSystem, SynthesisError}; use super::boolean::{Boolean}; use super::num::Num; @@ -82,7 +82,7 @@ pub fn compute_multipacking( fn test_multipacking() { use rand::{SeedableRng, Rng, XorShiftRng}; use bellman::{ConstraintSystem}; - use pairing::bls12_381::{Bls12}; + use bellman::pairing::bls12_381::{Bls12}; use ::circuit::test::*; use super::boolean::{AllocatedBit, Boolean}; diff --git a/src/circuit/num.rs b/src/circuit/num.rs index d7021795..782c2b60 100644 --- a/src/circuit/num.rs +++ b/src/circuit/num.rs @@ -1,8 +1,8 @@ -use pairing::{ +use bellman::pairing::{ Engine, }; -use ff::{ +use bellman::pairing::ff::{ Field, PrimeField, PrimeFieldRepr, @@ -460,13 +460,7 @@ impl AllocatedNum { coeff.double(); } - // let top_bits_value = AllocatedNum::alloc( - // cs.namespace(|| "allocate top bits"), - // || Ok(top_bits_lc.get_value().get()?) - // ).unwrap(); - // enforce packing and zeroness - cs.enforce( || "repack top bits", |lc| lc, @@ -474,15 +468,6 @@ impl AllocatedNum { |_| top_bits_lc.lc(E::Fr::one()) ); - // enforce top bits to be zero - // cs.enforce( - // || "repack top bits", - // |lc| lc + top_bits_value.get_variable(), - // |lc| lc + CS::one(), - // |_| top_bits_lc.lc(E::Fr::one()) - // ); - - Ok(()) } @@ -525,6 +510,30 @@ impl Num { LinearCombination::zero() + (coeff, &self.lc) } + pub fn add_number_with_coeff( + self, + variable: &AllocatedNum, + coeff: E::Fr + ) -> Self + { + let newval = match (self.value, variable.get_value()) { + (Some(mut curval), Some(val)) => { + let mut tmp = val; + tmp.mul_assign(&coeff); + + curval.add_assign(&tmp); + + Some(curval) + }, + _ => None + }; + + Num { + value: newval, + lc: self.lc + (coeff, variable.get_variable()) + } + } + pub fn add_bool_with_coeff( self, one: Variable, @@ -554,8 +563,8 @@ impl Num { mod test { use rand::{SeedableRng, Rand, Rng, XorShiftRng}; use bellman::{ConstraintSystem}; - use pairing::bls12_381::{Bls12, Fr}; - use ff::{Field, PrimeField, BitIterator}; + use bellman::pairing::bls12_381::{Bls12, Fr}; + use bellman::pairing::ff::{Field, PrimeField, BitIterator}; use ::circuit::test::*; use super::{AllocatedNum, Boolean}; diff --git a/src/circuit/pedersen_hash.rs b/src/circuit/pedersen_hash.rs index 432a19d8..2ed23c2b 100644 --- a/src/circuit/pedersen_hash.rs +++ b/src/circuit/pedersen_hash.rs @@ -116,8 +116,8 @@ mod test { use super::*; use ::circuit::test::*; use ::circuit::boolean::{Boolean, AllocatedBit}; - use pairing::bls12_381::{Bls12, Fr}; - use ff::PrimeField; + use bellman::pairing::bls12_381::{Bls12, Fr}; + use bellman::pairing::ff::PrimeField; #[test] fn test_pedersen_hash_constraints() { @@ -199,8 +199,8 @@ mod baby_test { use super::*; use ::circuit::test::*; use ::circuit::boolean::{Boolean, AllocatedBit}; - use pairing::bn256::{Bn256, Fr}; - use ff::PrimeField; + use bellman::pairing::bn256::{Bn256, Fr}; + use bellman::pairing::ff::PrimeField; use ::alt_babyjubjub::{AltJubjubBn256}; #[test] diff --git a/src/circuit/polynomial_lookup.rs b/src/circuit/polynomial_lookup.rs new file mode 100644 index 00000000..4a604759 --- /dev/null +++ b/src/circuit/polynomial_lookup.rs @@ -0,0 +1,71 @@ +use bellman::pairing::{Engine}; +use bellman::{ConstraintSystem, SynthesisError}; +use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr, BitIterator}; +use super::*; + +pub fn generate_powers( + mut cs: CS, + base: &num::AllocatedNum, + max_power: usize +) -> Result>, SynthesisError> + where CS: ConstraintSystem + { + let mut result = vec![]; + + let mut power = num::AllocatedNum::alloc( + cs.namespace(|| format!("0-th power")), + || { + return Ok(E::Fr::one()); + } + )?; + + result.push(power.clone()); + + for i in 1..max_power { + power = num::AllocatedNum::alloc( + cs.namespace(|| format!("{}-th power", i)), + || { + let mut power = power.get_value().get()?.clone(); + let value = base.get_value().get()?.clone(); + power.mul_assign(&value); + + Ok(power) + } + )?; + + result.push(power.clone()); + } + + Ok(result) +} + +pub fn do_the_lookup( + mut cs: CS, + coeffs: &[E::Fr], + bases: &[num::AllocatedNum], +) -> Result, SynthesisError> + where CS: ConstraintSystem + { + assert_eq!(coeffs.len(), bases.len()); + + let mut num = num::Num::::zero(); + for (c, b) in coeffs.iter().zip(bases.iter()) { + num = num.add_number_with_coeff(b, c.clone()); + } + + let result = num::AllocatedNum::alloc( + cs.namespace(|| "do the lookup"), + || { + Ok(*num.get_value().get()?) + } + )?; + + cs.enforce( + || "enforce a lookup", + |lc| lc + result.get_variable(), + |lc| lc + CS::one(), + |_| num.lc(E::Fr::one()) + ); + + Ok(result) + } \ No newline at end of file diff --git a/src/circuit/sapling/mod.rs b/src/circuit/sapling/mod.rs index dbb82d91..240f02cf 100644 --- a/src/circuit/sapling/mod.rs +++ b/src/circuit/sapling/mod.rs @@ -1,8 +1,8 @@ -// use pairing::{ +// use bellman::pairing::{ // // }; -use ff::{ +use bellman::pairing::ff::{ PrimeField, PrimeFieldRepr, Field, @@ -604,8 +604,8 @@ impl<'a, E: JubjubEngine> Circuit for Output<'a, E> { #[test] fn test_input_circuit_with_bls12_381() { - use ff::{Field, BitIterator}; - use pairing::bls12_381::*; + use bellman::pairing::ff::{Field, BitIterator}; + use bellman::pairing::bls12_381::*; use rand::{SeedableRng, Rng, XorShiftRng}; use ::circuit::test::*; use jubjub::{JubjubBls12, fs, edwards}; @@ -736,8 +736,8 @@ fn test_input_circuit_with_bls12_381() { #[test] fn test_output_circuit_with_bls12_381() { - use ff::{Field}; - use pairing::bls12_381::*; + use bellman::pairing::ff::{Field}; + use bellman::pairing::bls12_381::*; use rand::{SeedableRng, Rng, XorShiftRng}; use ::circuit::test::*; use jubjub::{JubjubBls12, fs, edwards}; diff --git a/src/circuit/sha256.rs b/src/circuit/sha256.rs index eec27a70..bae74aaa 100644 --- a/src/circuit/sha256.rs +++ b/src/circuit/sha256.rs @@ -2,7 +2,7 @@ use super::uint32::UInt32; use super::multieq::MultiEq; use super::boolean::Boolean; use bellman::{ConstraintSystem, SynthesisError}; -use pairing::Engine; +use bellman::pairing::Engine; const ROUND_CONSTANTS: [u32; 64] = [ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, @@ -306,7 +306,7 @@ pub fn sha256_compression_function( mod test { use super::*; use circuit::boolean::AllocatedBit; - use pairing::bls12_381::Bls12; + use bellman::pairing::bls12_381::Bls12; use circuit::test::TestConstraintSystem; use rand::{XorShiftRng, SeedableRng, Rng}; diff --git a/src/circuit/shark_mimc.rs b/src/circuit/shark_mimc.rs index 47bfad7b..f67d44c5 100644 --- a/src/circuit/shark_mimc.rs +++ b/src/circuit/shark_mimc.rs @@ -1,9 +1,9 @@ // This is an attempt to write an implementation of Dmitry Khovratovich -use pairing::{Engine}; +use bellman::pairing::{Engine}; use bellman::{ConstraintSystem, SynthesisError}; use rand::Rng; -use ff::{Field, PrimeField, PrimeFieldRepr, BitIterator}; +use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr, BitIterator}; use super::*; diff --git a/src/circuit/sprout/commitment.rs b/src/circuit/sprout/commitment.rs index a32f05c3..6e078ffb 100644 --- a/src/circuit/sprout/commitment.rs +++ b/src/circuit/sprout/commitment.rs @@ -1,4 +1,4 @@ -use pairing::{Engine}; +use bellman::pairing::{Engine}; use bellman::{ConstraintSystem, SynthesisError}; use circuit::sha256::{ sha256 diff --git a/src/circuit/sprout/input.rs b/src/circuit/sprout/input.rs index ce69bc00..fd8288af 100644 --- a/src/circuit/sprout/input.rs +++ b/src/circuit/sprout/input.rs @@ -1,4 +1,4 @@ -use pairing::{Engine}; +use bellman::pairing::{Engine}; use bellman::{ConstraintSystem, SynthesisError}; use circuit::sha256::{ sha256_block_no_padding diff --git a/src/circuit/sprout/mod.rs b/src/circuit/sprout/mod.rs index 19a3be7c..a70bb44e 100644 --- a/src/circuit/sprout/mod.rs +++ b/src/circuit/sprout/mod.rs @@ -1,5 +1,5 @@ -use pairing::{Engine}; -use ff::{Field}; +use bellman::pairing::{Engine}; +use bellman::pairing::ff::{Field}; use bellman::{ConstraintSystem, SynthesisError, Circuit, LinearCombination}; use circuit::boolean::{ AllocatedBit, @@ -354,7 +354,7 @@ fn witness_u252( #[test] fn test_sprout_constraints() { - use pairing::bls12_381::{Bls12}; + use bellman::pairing::bls12_381::{Bls12}; use ::circuit::test::*; use byteorder::{WriteBytesExt, ReadBytesExt, LittleEndian}; diff --git a/src/circuit/sprout/output.rs b/src/circuit/sprout/output.rs index 9cdbf527..a452d6b2 100644 --- a/src/circuit/sprout/output.rs +++ b/src/circuit/sprout/output.rs @@ -1,4 +1,4 @@ -use pairing::{Engine}; +use bellman::pairing::{Engine}; use bellman::{ConstraintSystem, SynthesisError}; use circuit::boolean::{Boolean}; diff --git a/src/circuit/sprout/prfs.rs b/src/circuit/sprout/prfs.rs index fff86481..3811b420 100644 --- a/src/circuit/sprout/prfs.rs +++ b/src/circuit/sprout/prfs.rs @@ -1,4 +1,4 @@ -use pairing::{Engine}; +use bellman::pairing::{Engine}; use bellman::{ConstraintSystem, SynthesisError}; use circuit::sha256::{ sha256_block_no_padding diff --git a/src/circuit/test/mod.rs b/src/circuit/test/mod.rs index 5fa36812..69bc4d57 100644 --- a/src/circuit/test/mod.rs +++ b/src/circuit/test/mod.rs @@ -1,8 +1,8 @@ -use pairing::{ +use bellman::pairing::{ Engine, }; -use ff::{ +use bellman::pairing::ff::{ Field, PrimeField, PrimeFieldRepr @@ -495,8 +495,8 @@ impl ConstraintSystem for TestConstraintSystem { #[test] fn test_cs() { - use pairing::bls12_381::{Bls12, Fr}; - use ff::PrimeField; + use bellman::pairing::bls12_381::{Bls12, Fr}; + use bellman::pairing::ff::PrimeField; let mut cs = TestConstraintSystem::::new(); assert!(cs.is_satisfied()); diff --git a/src/circuit/uint32.rs b/src/circuit/uint32.rs index d1e84b61..122d74d0 100644 --- a/src/circuit/uint32.rs +++ b/src/circuit/uint32.rs @@ -1,8 +1,8 @@ -use pairing::{ +use bellman::pairing::{ Engine, }; -use ff::{ +use bellman::pairing::ff::{ Field, PrimeField }; @@ -418,8 +418,8 @@ mod test { use rand::{XorShiftRng, SeedableRng, Rng}; use ::circuit::boolean::{Boolean}; use super::{UInt32}; - use pairing::bls12_381::{Bls12}; - use ff::{Field}; + use bellman::pairing::bls12_381::{Bls12}; + use bellman::pairing::ff::{Field}; use ::circuit::test::*; use bellman::{ConstraintSystem}; use circuit::multieq::MultiEq; diff --git a/src/eddsa.rs b/src/eddsa.rs index 7093fc50..7f380995 100644 --- a/src/eddsa.rs +++ b/src/eddsa.rs @@ -1,7 +1,7 @@ //! This is an implementation of EdDSA as refered in literature //! Generation of randomness is not specified -use ff::{Field, PrimeField, PrimeFieldRepr}; +use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; use rand::{Rng}; use std::io::{self, Read, Write}; @@ -442,7 +442,7 @@ impl PublicKey { #[cfg(test)] mod baby_tests { - use pairing::bn256::Bn256; + use bellman::pairing::bn256::Bn256; use rand::thread_rng; use alt_babyjubjub::{AltJubjubBn256, fs::Fs, edwards, FixedGenerators}; diff --git a/src/group_hash.rs b/src/group_hash.rs index 47dfc59e..571c3664 100644 --- a/src/group_hash.rs +++ b/src/group_hash.rs @@ -4,13 +4,80 @@ use jubjub::{ edwards }; -use ff::{ +use bellman::pairing::ff::{ PrimeField }; +use tiny_keccak::Keccak; use blake2_rfc::blake2s::Blake2s; use constants; +pub trait GroupHasher { + fn new(personalization: &[u8]) -> Self; + fn update(&mut self, data: &[u8]); + fn finalize(&mut self) -> Vec; +} + +pub struct BlakeHasher { + h: Blake2s +} + +impl GroupHasher for BlakeHasher { + fn new(personalization: &[u8]) -> Self { + let h = Blake2s::with_params(32, &[], &[], personalization); + + Self { + h: h + } + } + + fn update(&mut self, data: &[u8]) { + self.h.update(data); + } + + fn finalize(&mut self) -> Vec { + use std::mem; + + let new_h = Blake2s::with_params(32, &[], &[], &[]); + let h = std::mem::replace(&mut self.h, new_h); + + let result = h.finalize(); + + result.as_ref().to_vec().clone() + } +} + +pub struct Keccak256Hasher { + h: Keccak +} + +impl GroupHasher for Keccak256Hasher { + fn new(personalization: &[u8]) -> Self { + let mut h = Keccak::new_keccak256(); + h.update(personalization); + + Self { + h: h + } + } + + fn update(&mut self, data: &[u8]) { + self.h.update(data); + } + + fn finalize(&mut self) -> Vec { + use std::mem; + + let new_h = Keccak::new_keccak256(); + let h = std::mem::replace(&mut self.h, new_h); + + let mut res: [u8; 32] = [0; 32]; + h.finalize(&mut res); + + res[..].to_vec() + } +} + /// Produces a random point in the Jubjub curve. /// The point is guaranteed to be prime order /// and not the identity. @@ -79,3 +146,68 @@ pub fn baby_group_hash( } } +/// Produces a random point in the Jubjub curve. +/// The point is guaranteed to be prime order +/// and not the identity. +pub fn generic_group_hash( + tag: &[u8], + personalization: &[u8], + params: &E::Params +) -> Option> +{ + assert_eq!(personalization.len(), 8); + + // Due to small number of iterations Fr should be close to 255 bits + assert!(E::Fr::NUM_BITS == 255 || E::Fr::NUM_BITS == 254); + + let mut h = H::new(personalization); + h.update(constants::GH_FIRST_BLOCK); + h.update(tag); + let h = h.finalize(); + assert!(h.len() == 32); + + match edwards::Point::::read(&h[..], params) { + Ok(p) => { + let p = p.mul_by_cofactor(params); + + if p != edwards::Point::zero() { + Some(p) + } else { + None + } + }, + Err(_) => None + } +} + +#[test] +fn test_generic_hash() { + use bellman::pairing::bn256::Bn256; + use alt_babyjubjub::JubjubEngine; + use alt_babyjubjub::AltJubjubBn256; + + let personalization = b"Hello123"; + let params = AltJubjubBn256::new(); + for t in 0u8..=255u8 { + let tag = [t]; + let blake_point = baby_group_hash::(&tag, &personalization[..], ¶ms); + let generic_point = generic_group_hash::(&tag, &personalization[..], ¶ms); + assert!(blake_point == generic_point); + } +} + +#[test] +fn test_export_blake_generators() { + use bellman::pairing::bn256::Bn256; + use alt_babyjubjub::JubjubEngine; + use alt_babyjubjub::AltJubjubBn256; + + let personalization = b"Hello123"; + let params = AltJubjubBn256::new(); + for t in 0u8..=255u8 { + let tag = [t]; + let blake_point = baby_group_hash::(&tag, &personalization[..], ¶ms); + let generic_point = generic_group_hash::(&tag, &personalization[..], ¶ms); + assert!(blake_point == generic_point); + } +} \ No newline at end of file diff --git a/src/interpolation.rs b/src/interpolation.rs new file mode 100644 index 00000000..77aaeb8e --- /dev/null +++ b/src/interpolation.rs @@ -0,0 +1,137 @@ +use bellman::pairing::Engine; + +use bellman::pairing::ff::{ + Field, + PrimeField +}; + +/// Perform a Lagrange interpolation for a set of points +/// It's O(n^2) operations, so use with caution +pub fn interpolate( + points: &[(E::Fr, E::Fr)] +) -> Option> { + let max_degree_plus_one = points.len(); + assert!(max_degree_plus_one >= 2, "should interpolate for degree >= 1"); + let external_iter = points.clone().into_iter(); + let internal = points.clone(); + let mut coeffs = vec![E::Fr::zero(); max_degree_plus_one]; + for (k, p_k) in external_iter.enumerate() { + let (x_k, y_k) = p_k; + // coeffs from 0 to max_degree - 1 + let mut contribution = vec![E::Fr::zero(); max_degree_plus_one]; + let mut demoninator = E::Fr::one(); + let mut max_contribution_degree = 0; + for (j, p_j) in internal.iter().enumerate() { + let (x_j, _) = p_j; + if j == k { + continue; + } + + let mut diff = x_k.clone(); + diff.sub_assign(&x_j); + demoninator.mul_assign(&diff); + + if max_contribution_degree == 0 { + max_contribution_degree = 1; + contribution.get_mut(0).expect("must have enough coefficients").sub_assign(&x_j); + contribution.get_mut(1).expect("must have enough coefficients").add_assign(&E::Fr::one()); + } else { + let mul_by_minus_x_j: Vec = contribution.iter().map(|el| { + let mut tmp = el.clone(); + tmp.mul_assign(&x_j); + tmp.negate(); + + tmp + }).collect(); + + contribution.insert(0, E::Fr::zero()); + contribution.truncate(max_degree_plus_one); + + assert_eq!(mul_by_minus_x_j.len(), max_degree_plus_one); + for (i, c) in contribution.iter_mut().enumerate() { + let other = mul_by_minus_x_j.get(i).expect("should have enough elements"); + c.add_assign(&other); + } + } + } + + demoninator = demoninator.inverse().expect("denominator must be non-zero"); + for (i, this_contribution) in contribution.into_iter().enumerate() { + let c = coeffs.get_mut(i).expect("should have enough coefficients"); + let mut tmp = this_contribution; + tmp.mul_assign(&demoninator); + tmp.mul_assign(&y_k); + c.add_assign(&tmp); + } + + } + + Some(coeffs) +} + +pub fn evaluate_at_x( + coeffs: &[E::Fr], + x: &E::Fr +) -> E::Fr { + let mut res = E::Fr::zero(); + let mut pow = E::Fr::one(); + for c in coeffs.iter() { + let mut tmp = c.clone(); + tmp.mul_assign(&pow); + res.add_assign(&tmp); + + pow.mul_assign(&x); + } + + res +} + +#[test] +fn test_interpolation_1(){ + use bellman::pairing::bn256::{Bn256, Fr}; + let points = vec![(Fr::zero(), Fr::one()), (Fr::one(), Fr::from_str("2").unwrap())]; + let interpolation_res = interpolate::(&points[..]).expect("must interpolate a linear func"); + assert_eq!(interpolation_res.len(), 2); + for (i, c) in interpolation_res.iter().enumerate() { + println!("Coeff {} = {}", i, c); + } + + for (i, p) in points.iter().enumerate() { + let (x, y) = p; + let val = evaluate_at_x::(&interpolation_res[..], &x); + assert_eq!(*y, val); + println!("Eval at {} = {}, original value = {}", x, val, y); + } +} + +#[test] +fn test_interpolation_powers_of_2(){ + use bellman::pairing::bn256::{Bn256, Fr}; + const MAX_POWER: u32 = Fr::CAPACITY; + + let mut points: Vec<(Fr, Fr)> = vec![]; + let mut power = Fr::one(); + let two = Fr::from_str("2").unwrap(); + for i in 0..MAX_POWER { + let x = Fr::from_str(&i.to_string()).unwrap(); + let y = power.clone(); + points.push((x,y)); + + power.mul_assign(&two); + } + let interpolation_res = interpolate::(&points[..]).expect("must interpolate"); + assert_eq!(*interpolation_res.get(0).unwrap(), Fr::one()); + assert_eq!(interpolation_res.len(), points.len(), "array sized must match"); + assert_eq!(interpolation_res.len(), MAX_POWER as usize, "array size must be equal to the max power"); + + for (i, p) in points.iter().enumerate() { + let (x, y) = p; + let val = evaluate_at_x::(&interpolation_res[..], &x); + // println!("Eval at {} = {}, original value = {}", x, val, y); + // assert!(*y == val, format!("must assert equality for x = {}", x) ); + assert_eq!(*y, val); + + } +} + + diff --git a/src/jubjub/edwards.rs b/src/jubjub/edwards.rs index d80424fa..7453fb92 100644 --- a/src/jubjub/edwards.rs +++ b/src/jubjub/edwards.rs @@ -1,4 +1,4 @@ -use ff::{ +use bellman::pairing::ff::{ Field, SqrtField, PrimeField, diff --git a/src/jubjub/fs.rs b/src/jubjub/fs.rs index 44643207..ae013d88 100644 --- a/src/jubjub/fs.rs +++ b/src/jubjub/fs.rs @@ -1,7 +1,7 @@ use byteorder::{ByteOrder, LittleEndian}; -use ff::{adc, sbb, mac_with_carry}; -use ff::{BitIterator, Field, PrimeField, SqrtField, PrimeFieldRepr, PrimeFieldDecodingError, LegendreSymbol}; -use ff::LegendreSymbol::*; +use bellman::pairing::ff::{adc, sbb, mac_with_carry}; +use bellman::pairing::ff::{BitIterator, Field, PrimeField, SqrtField, PrimeFieldRepr, PrimeFieldDecodingError, LegendreSymbol}; +use bellman::pairing::ff::LegendreSymbol::*; use super::ToUniform; // s = 6554484396890773809930967563523245729705921265872317281365359162392183254199 diff --git a/src/jubjub/mod.rs b/src/jubjub/mod.rs index cb2bb29a..0d4f9947 100644 --- a/src/jubjub/mod.rs +++ b/src/jubjub/mod.rs @@ -17,11 +17,11 @@ //! the Montgomery curve forms a group isomorphism, allowing points //! to be freely converted between the two forms. -use pairing::{ +use bellman::pairing::{ Engine, }; -use ff::{ +use bellman::pairing::ff::{ Field, PrimeField, SqrtField @@ -31,7 +31,7 @@ use group_hash::group_hash; use constants; -use pairing::bls12_381::{ +use bellman::pairing::bls12_381::{ Bls12, Fr }; @@ -437,3 +437,10 @@ fn test_jubjub_bls12() { assert!(p == q); } + +#[test] +fn test_jubjub_bls12_num_generators() { + let params = JubjubBls12::new(); + + assert_eq!(params.pedersen_circuit_generators.len(), 5); +} diff --git a/src/jubjub/montgomery.rs b/src/jubjub/montgomery.rs index 5d1e5c6a..53ed1d83 100644 --- a/src/jubjub/montgomery.rs +++ b/src/jubjub/montgomery.rs @@ -1,4 +1,4 @@ -use ff::{ +use bellman::pairing::ff::{ Field, SqrtField, PrimeField, diff --git a/src/jubjub/tests.rs b/src/jubjub/tests.rs index eb7e36b7..77813b4d 100644 --- a/src/jubjub/tests.rs +++ b/src/jubjub/tests.rs @@ -6,7 +6,7 @@ use super::{ edwards }; -use ff::{ +use bellman::pairing::ff::{ Field, PrimeField, PrimeFieldRepr, diff --git a/src/lib.rs b/src/lib.rs index 9c01faf5..55cacb30 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,13 +2,12 @@ #![allow(dead_code)] #![allow(unused_variables)] -extern crate pairing; extern crate bellman; extern crate blake2_rfc; extern crate digest; extern crate rand; extern crate byteorder; -extern crate ff; +extern crate tiny_keccak; #[cfg(test)] #[macro_use] @@ -32,6 +31,7 @@ pub mod redjubjub; pub mod baby_util; pub mod util; pub mod eddsa; +pub mod interpolation; extern crate serde; #[macro_use] diff --git a/src/pedersen_hash.rs b/src/pedersen_hash.rs index 5883af79..f5d02fa4 100644 --- a/src/pedersen_hash.rs +++ b/src/pedersen_hash.rs @@ -1,5 +1,5 @@ use jubjub::*; -use ff::{Field, PrimeField, PrimeFieldRepr}; +use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; #[derive(Copy, Clone)] pub enum Personalization { diff --git a/src/primitives/mod.rs b/src/primitives/mod.rs index 4470b8b5..ba5c45df 100644 --- a/src/primitives/mod.rs +++ b/src/primitives/mod.rs @@ -1,4 +1,4 @@ -use ff::{ +use bellman::pairing::ff::{ Field, PrimeField, PrimeFieldRepr diff --git a/src/redbabyjubjub.rs b/src/redbabyjubjub.rs index 1f87597b..803b9845 100644 --- a/src/redbabyjubjub.rs +++ b/src/redbabyjubjub.rs @@ -1,7 +1,7 @@ //! Implementation of RedJubjub, a specialization of RedDSA to the Jubjub curve. //! See section 5.4.6 of the Sapling protocol specification. -use ff::{Field, PrimeField, PrimeFieldRepr}; +use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; use rand::{Rng, Rand}; use std::io::{self, Read, Write}; @@ -204,7 +204,7 @@ pub fn batch_verify<'a, E: JubjubEngine, R: Rng>( #[cfg(test)] mod tests { - use pairing::bn256::Bn256; + use bellman::pairing::bn256::Bn256; use rand::thread_rng; use babyjubjub::{JubjubBn256, fs::Fs, edwards}; diff --git a/src/redjubjub.rs b/src/redjubjub.rs index 784dbf62..b70e5046 100644 --- a/src/redjubjub.rs +++ b/src/redjubjub.rs @@ -1,7 +1,7 @@ //! Implementation of RedJubjub, a specialization of RedDSA to the Jubjub curve. //! See section 5.4.6 of the Sapling protocol specification. -use ff::{Field, PrimeField, PrimeFieldRepr}; +use bellman::pairing::ff::{Field, PrimeField, PrimeFieldRepr}; use rand::{Rng, Rand}; use std::io::{self, Read, Write}; @@ -205,7 +205,7 @@ pub fn batch_verify<'a, E: JubjubEngine, R: Rng>( #[cfg(test)] mod tests { - use pairing::bls12_381::Bls12; + use bellman::pairing::bls12_381::Bls12; use rand::thread_rng; use jubjub::{JubjubBls12, fs::Fs, edwards}; @@ -345,7 +345,7 @@ mod tests { #[cfg(test)] mod baby_tests { - use pairing::bn256::Bn256; + use bellman::pairing::bn256::Bn256; use rand::thread_rng; use alt_babyjubjub::{AltJubjubBn256, fs::Fs, edwards, FixedGenerators};