Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
61b8da3
pedersen_hash: prints hashes, adds comments
kobigurk Aug 8, 2018
0fb22c8
pedersen_hash: adds tests for Daniel's vector
kobigurk Aug 9, 2018
c2440b0
pedersen hashes: example of size limit bug
kobigurk Aug 17, 2018
7533bf5
pedersen_hash: show a tighter limit for hash sizes
kobigurk Aug 19, 2018
beec288
pedersen_hash: removes debug prints
kobigurk Sep 4, 2018
a3fc94a
pedersen_hash: adds test vectors for the circuit implementation
kobigurk Sep 4, 2018
6752725
Add blake2s test vectors for varying sizes from go-jubjub
kobigurk Oct 24, 2018
5b5e0fe
Fix blake2s test data length assertion.
defuse Mar 12, 2019
06be903
adds test vectors for NoteCommit
kobigurk Aug 29, 2018
e8e2a6c
input circuit: removes debug prints
kobigurk Sep 4, 2018
d1c4a5c
group_hash: adds test vectors generated by go-jubjub
kobigurk Aug 28, 2018
7672c41
adds group hash test vectors and debug prints
kobigurk Aug 29, 2018
5fd0fca
blake2s: adds test vectors from go-jubjub
kobigurk Sep 4, 2018
ca1b3de
Fix rebase mistake
defuse Mar 12, 2019
471b9bf
A test vector for pedersen hash
Jul 31, 2018
9faf398
Many test vectors for pedersen hash
Jul 31, 2018
86e1061
Move test vectors into own module
Aug 19, 2018
1f35614
Long and random PH test vectors
Aug 19, 2018
bff48a2
Long and random PH test vectors
Aug 19, 2018
9f1452d
PH test vectors for edge-cases
Aug 19, 2018
73eee9a
ecc: tests for assert_not_small_order
kobigurk Aug 9, 2018
e66af59
ecc: test_assert_not_small_order also tests for the generators
kobigurk Aug 9, 2018
27af9e9
ecc: makes assert_not_small_order tests deeper
kobigurk Aug 11, 2018
8555110
boolean: adds tests for alloc_conditionally
kobigurk Aug 6, 2018
adc0e74
Calculate number of constraints and more comprehensive test
Aug 21, 2018
9e05d0d
Test PH circuit for the size used in the Merkle tree
Aug 22, 2018
4c673fd
adds test for linear relation between pedersen hash generators
kobigurk Aug 1, 2018
25c1b9d
Fix broken linear relation checking
defuse Mar 12, 2019
860377b
Fix build warnings
defuse Apr 10, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions src/circuit/blake2s.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,4 +435,125 @@ mod test {
}
}
}

#[test]
fn test_blake2s_256_vars() {
let data: Vec<u8> = hex!("be9f9c485e670acce8b1516a378176161b20583637b6f1c536fbc1158a0a3296831df2920e57a442d5738f4be4dd6be89dd7913fc8b4d1c0a815646a4d674b77f7caf313bd880bf759fcac27037c48c2b2a20acd2fd5248e3be426c84a341c0a3c63eaf36e0d537d10b8db5c6e4c801832c41eb1a3ed602177acded8b4b803bd34339d99a18b71df399641cc8dfae2ad193fcd74b5913e704551777160d14c78f2e8d5c32716a8599c1080cb89a40ccd6ba596694a8b4a065d9f2d0667ef423ed2e418093caff884540858b4f4b62acd47edcea880523e1b1cda8eb225c128c2e9e83f14f6e7448c5733a195cac7d79a53dde5083172462c45b2f799e42af1c9").to_vec();
assert_eq!(data.len(), 256);

let mut cs = TestConstraintSystem::<Bls12>::new();

let mut input_bits = vec![];

for (byte_i, input_byte) in data.into_iter().enumerate() {
for bit_i in 0..8 {
let cs = cs.namespace(|| format!("input bit {} {}", byte_i, bit_i));

input_bits.push(AllocatedBit::alloc(cs, Some((input_byte >> bit_i) & 1u8 == 1u8)).unwrap().into());
}
}

let r = blake2s(&mut cs, &input_bits, b"12345678").unwrap();

assert!(cs.is_satisfied());

let expected = hex!("0af5695115ced92c8a0341e43869209636e9aa6472e4576f0f2b996cf812b30e");

let mut out = r.into_iter();
for b in expected.into_iter() {
for i in 0..8 {
let c = out.next().unwrap().get_value().unwrap();

assert_eq!(c, (b >> i) & 1u8 == 1u8);
}
}
}

#[test]
fn test_blake2s_700_vars() {
let data: Vec<u8> = hex!("5dcfe8bab4c758d2eb1ddb7ef337583e0df3e2c358e1755b7cd303a658de9a1227eed1d1114179a5c3c38d692ff2cf2d4e5c92a9516de750106774bbf9f7d063f707f4c9b6a02c0a77e4feb99e036c3ccaee7d1a31cb144093aa074bc9da608f8ff30b39c3c60e4a243cc0bbd406d1262a7d6607b31c60275c6bcc8b0ac49a06a4b629a98693c5f7640f3bca45e4977cfabc5b17f52838af3433b1fd407dbbdc131e8e4bd58bcee85bbab4b57b656c6a2ec6cf852525bc8423675e2bf29159139cd5df99db94719f3f7167230e0d5bd76f6d7891b656732cef9c3c0d48a5fa3d7a879988157b39015a85451b25af0301ca5e759ac35fea79dca38c673ec6db9f3885d9103e2dcb3304bd3d59b0b1d01babc97ef8a74d91b6ab6bf50f29eb5adf7250a28fd85db37bff0133193635da69caeefc72979cf3bef1d2896d847eea7e8a81e0927893dbd010feb6fb845d0399007d9a148a0596d86cd8f4192631f975c560f4de8da5f712c161342063af3c11029d93d6df7ff46db48343499de9ec4786cac059c4025ef418c9fe40132428ff8b91259d71d1709ff066add84ae944b45a817f60b4c1bf719e39ae23e9b413469db2310793e9137cf38741e5dd2a3c138a566dbde1950c00071b20ac457b46ba9b0a7ebdddcc212bd228d2a4c4146a970e54158477247c27871af1564b176576e9fd43bf63740bf77434bc4ea3b1a4b430e1a11714bf43160145578a575c3f78ddeaa48de97f73460f26f8df2b5d63e31800100d16bc27160fea5ced5a977ef541cfe8dadc7b3991ed1c0d4f16a3076bbfed96ba3e155113e794987af8abb133f06feefabc2ac32eb4d4d4ba1541ca08b9e518d2e74b7f946b0cbd2663d58c689359b9a565821acc619011233d1011963fa302cde34fc9c5ba2e03eeb2512f547391e940d56218e22ae325f2dfa38d4bae35744ee707aa5dc9c17674025d15390a08f5c452343546ef6da0f7").to_vec();
assert_eq!(data.len(), 700);

let mut cs = TestConstraintSystem::<Bls12>::new();

let mut input_bits = vec![];

for (byte_i, input_byte) in data.into_iter().enumerate() {
for bit_i in 0..8 {
let cs = cs.namespace(|| format!("input bit {} {}", byte_i, bit_i));

input_bits.push(AllocatedBit::alloc(cs, Some((input_byte >> bit_i) & 1u8 == 1u8)).unwrap().into());
}
}

let r = blake2s(&mut cs, &input_bits, b"12345678").unwrap();

assert!(cs.is_satisfied());

let expected = hex!("2ab8f0683167ba220eef19dccf4f9b1a8193cc09b35e0235842323950530f18a");

let mut out = r.into_iter();
for b in expected.into_iter() {
for i in 0..8 {
let c = out.next().unwrap().get_value().unwrap();

assert_eq!(c, (b >> i) & 1u8 == 1u8);
}
}
}

#[test]
fn test_blake2s_test_vectors() {
let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);

let expecteds = [
hex!("a1309e334376c8f36a736a4ab0e691ef931ee3ebdb9ea96187127136fea622a1"),
hex!("82fefff60f265cea255252f7c194a7f93965dffee0609ef74eb67f0d76cd41c6"),
];
for i in 0..2 {
let mut h = Blake2s::with_params(32, &[], &[], b"12345678");
let input_len = 1024;
let data: Vec<u8> = (0..input_len).map(|_| rng.gen()).collect();

h.update(&data);

let hash_result = h.finalize();

let mut cs = TestConstraintSystem::<Bls12>::new();

let mut input_bits = vec![];

for (byte_i, input_byte) in data.into_iter().enumerate() {
for bit_i in 0..8 {
let cs = cs.namespace(|| format!("input bit {} {}", byte_i, bit_i));

input_bits.push(AllocatedBit::alloc(cs, Some((input_byte >> bit_i) & 1u8 == 1u8)).unwrap().into());
}
}

let r = blake2s(&mut cs, &input_bits, b"12345678").unwrap();

assert!(cs.is_satisfied());

let mut s = hash_result.as_ref().iter()
.flat_map(|&byte| (0..8).map(move |i| (byte >> i) & 1u8 == 1u8));

for b in r {
match b {
Boolean::Is(b) => {
assert!(s.next().unwrap() == b.get_value().unwrap());
},
Boolean::Not(b) => {
assert!(s.next().unwrap() != b.get_value().unwrap());
},
Boolean::Constant(b) => {
assert!(input_len == 0);
assert!(s.next().unwrap() == b);
}
}
}

assert_eq!(expecteds[i], hash_result.as_bytes());
}
}
}
77 changes: 77 additions & 0 deletions src/circuit/boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1579,4 +1579,81 @@ mod test {
}
}
}


#[test]
fn test_alloc_conditionally() {

{
let mut cs = TestConstraintSystem::<Bls12>::new();
let b = AllocatedBit::alloc(&mut cs, Some(false)).unwrap();

let value = None;
// if value is none, fail with SynthesisError
let is_err = AllocatedBit::alloc_conditionally(
cs.namespace(|| "alloc_conditionally"),
value,
&b,
).is_err();
assert!(is_err);
}


{
// since value is true, b must be false, so it should succeed
let mut cs = TestConstraintSystem::<Bls12>::new();

let value = Some(true);
let b = AllocatedBit::alloc(&mut cs, Some(false)).unwrap();
let allocated_value = AllocatedBit::alloc_conditionally(
cs.namespace(|| "alloc_conditionally"),
value,
&b,
).unwrap();

assert_eq!(allocated_value.get_value().unwrap(), true);
assert!(cs.is_satisfied());
}

{
// since value is true, b must be false, so it should fail
let mut cs = TestConstraintSystem::<Bls12>::new();

let value = Some(true);
let b = AllocatedBit::alloc(&mut cs, Some(true)).unwrap();
AllocatedBit::alloc_conditionally(
cs.namespace(|| "alloc_conditionally"),
value,
&b,
).unwrap();

assert!(!cs.is_satisfied());
}

{
// since value is false, we don't care about the value of the bit

let value = Some(false);
//check with false bit
let mut cs = TestConstraintSystem::<Bls12>::new();
let b1 = AllocatedBit::alloc(&mut cs, Some(false)).unwrap();
AllocatedBit::alloc_conditionally(
cs.namespace(|| "alloc_conditionally"),
value,
&b1,
).unwrap();

//check with true bit
let mut cs = TestConstraintSystem::<Bls12>::new();
let b2 = AllocatedBit::alloc(&mut cs, Some(true)).unwrap();
AllocatedBit::alloc_conditionally(
cs.namespace(|| "alloc_conditionally"),
value,
&b2,
).unwrap();

assert!(cs.is_satisfied());
}

}
}
77 changes: 76 additions & 1 deletion src/circuit/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ mod test {
edwards,
JubjubBls12,
JubjubParams,
FixedGenerators
FixedGenerators,
};
use ::jubjub::fs::Fs;
use super::{
Expand Down Expand Up @@ -1210,4 +1210,79 @@ mod test {
assert_eq!(cs.which_is_unsatisfied(), Some("addition/evaluate lambda"));
}
}

#[test]
fn test_assert_not_small_order() {

let params = &JubjubBls12::new();

let check_small_order_from_p = |p:edwards::Point<Bls12,_>, is_small_order| {
let mut cs = TestConstraintSystem::<Bls12>::new();

let p = EdwardsPoint::witness(&mut cs, Some(p), params).unwrap();
assert!(cs.is_satisfied());
assert!(p.assert_not_small_order(&mut cs, params).is_err() == is_small_order);
};

let check_small_order_from_strs = |x,y| {
//let (x,y) = (Fr::from_str("14080418777298869350588389379361252092475090129841789940098060767181937064268").unwrap(), Fr::from_str("4408371274642418797323679050836535851651768103477128764103246588657558662748").unwrap());
let (x, y) = (Fr::from_str(x).unwrap(), Fr::from_str(y).unwrap());
let p = edwards::Point::<Bls12, _>::get_for_y(y, false, params).unwrap();
assert_eq!(x, p.into_xy().0);

check_small_order_from_p(p, true);

};

// zero has low order
check_small_order_from_strs("0", "1");

// prime subgroup order
let prime_subgroup_order = Fs::from_str("6554484396890773809930967563523245729705921265872317281365359162392183254199").unwrap();
let largest_small_subgroup_order = Fs::from_str("8").unwrap();

let (zero_x, zero_y) = (Fr::from_str("0").unwrap(), Fr::from_str("1").unwrap());

// generator for jubjub
let (x, y) = (Fr::from_str("11076627216317271660298050606127911965867021807910416450833192264015104452986").unwrap(), Fr::from_str("44412834903739585386157632289020980010620626017712148233229312325549216099227").unwrap());
let g = edwards::Point::<Bls12, _>::get_for_y(y, false, params).unwrap();
assert_eq!(x, g.into_xy().0);
check_small_order_from_p(g.clone(), false);


// generator for the prime subgroup
let g_prime = g.mul(largest_small_subgroup_order, params);
check_small_order_from_p(g_prime.clone(), false);
let mut prime_subgroup_order_minus_1 = prime_subgroup_order.clone();
prime_subgroup_order_minus_1.sub_assign(&Fs::from_str("1").unwrap());

let should_not_be_zero = g_prime.mul(prime_subgroup_order_minus_1, params);
assert_ne!(zero_x, should_not_be_zero.into_xy().0);
assert_ne!(zero_y, should_not_be_zero.into_xy().1);
let should_be_zero = should_not_be_zero.add(&g_prime, params);
assert_eq!(zero_x, should_be_zero.into_xy().0);
assert_eq!(zero_y, should_be_zero.into_xy().1);

// generator for the small order subgroup
let g_small = g.mul(prime_subgroup_order_minus_1, params);
let g_small = g_small.add(&g, params);
check_small_order_from_p(g_small.clone(), true);

// g_small does have order 8
let mut largest_small_subgroup_order_minus_1 = largest_small_subgroup_order.clone();
largest_small_subgroup_order_minus_1.sub_assign(&Fs::from_str("1").unwrap());

let should_not_be_zero = g_small.mul(largest_small_subgroup_order_minus_1, params);
assert_ne!(zero_x, should_not_be_zero.into_xy().0);
assert_ne!(zero_y, should_not_be_zero.into_xy().1);

let should_be_zero = should_not_be_zero.add(&g_small, params);
assert_eq!(zero_x, should_be_zero.into_xy().0);
assert_eq!(zero_y, should_be_zero.into_xy().1);

// take all the points from the script
// assert should be different than multiplying by cofactor, which is the solution
// is user input verified? https://github.com/zcash/librustzcash/blob/f5d2afb4eabac29b1b1cc860d66e45a5b48b4f88/src/rustzcash.rs#L299

}
}
Loading