From 55bb29fc63b9fae262655e889a8e44a6055aa4b7 Mon Sep 17 00:00:00 2001 From: jaspervdm Date: Sun, 26 May 2019 11:31:40 +0200 Subject: [PATCH 1/6] Bulletproofs: change message to 20 bytes, allow 2 nonces in generation --- src/constants.rs | 2 +- src/pedersen.rs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/constants.rs b/src/constants.rs index cdbd67f..1318a0b 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -66,7 +66,7 @@ pub const PROOF_MSG_SIZE: usize = 2048; pub const PROOF_MSG_SIZE: usize = 2048; /// The maximum size of an optional message embedded in a bullet proof -pub const BULLET_PROOF_MSG_SIZE: usize = 16; +pub const BULLET_PROOF_MSG_SIZE: usize = 20; /// The order of the secp256k1 curve pub const CURVE_ORDER: [u8; 32] = [ diff --git a/src/pedersen.rs b/src/pedersen.rs index 94105bd..b2ada3c 100644 --- a/src/pedersen.rs +++ b/src/pedersen.rs @@ -745,7 +745,8 @@ impl Secp256k1 { &self, value: u64, blind: SecretKey, - nonce: SecretKey, + rewind_nonce: SecretKey, + private_nonce: SecretKey, extra_data_in: Option>, message: Option, ) -> RangeProof { @@ -773,12 +774,11 @@ impl Secp256k1 { None => ptr::null(), }; - // This api is not for multi-party range proof, so all null for these 5 parameters. + // This api is not for multi-party range proof, so all null for these 4 parameters. let tau_x = ptr::null_mut(); let t_one = ptr::null_mut(); let t_two = ptr::null_mut(); let commits = ptr::null_mut(); - let private_nonce = ptr::null(); let _success = unsafe { let scratch = ffi::secp256k1_scratch_space_create(self.ctx, SCRATCH_SPACE_SIZE); @@ -798,8 +798,8 @@ impl Secp256k1 { 1, constants::GENERATOR_H.as_ptr(), n_bits as size_t, - nonce.as_ptr(), - private_nonce, + rewind_nonce.as_ptr(), + private_nonce.as_ptr(), extra_data, extra_data_len as size_t, message_ptr, @@ -1085,7 +1085,7 @@ impl Secp256k1 { let mut blind_out = [0u8; constants::SECRET_KEY_SIZE]; let mut value_out = 0; - let mut message_out = [0u8; 16]; + let mut message_out = [0u8; 20]; let commit = self.commit_parse(commit.0)?; let success = unsafe { From b90d6f81372005c6962d0c65e558fbf0bfb1af6d Mon Sep 17 00:00:00 2001 From: jaspervdm Date: Mon, 27 May 2019 13:28:38 +0200 Subject: [PATCH 2/6] Updated syntax of rewind function --- src/ffi.rs | 1 - src/pedersen.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/ffi.rs b/src/ffi.rs index aab6883..c616f7e 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -576,7 +576,6 @@ extern "C" { pub fn secp256k1_bulletproof_rangeproof_rewind( ctx: *const Context, - gens: *const BulletproofGenerators, value: *mut uint64_t, blind: *mut c_uchar, proof: *const c_uchar, diff --git a/src/pedersen.rs b/src/pedersen.rs index b2ada3c..8dc59e4 100644 --- a/src/pedersen.rs +++ b/src/pedersen.rs @@ -1092,7 +1092,6 @@ impl Secp256k1 { let scratch = ffi::secp256k1_scratch_space_create(self.ctx, SCRATCH_SPACE_SIZE); let result = ffi::secp256k1_bulletproof_rangeproof_rewind( self.ctx, - shared_generators(self.ctx), &mut value_out, blind_out.as_mut_ptr(), proof.proof.as_ptr(), From 88b917ba30d4755386817ef5683d788753943c71 Mon Sep 17 00:00:00 2001 From: jaspervdm Date: Mon, 3 Jun 2019 13:26:51 +0200 Subject: [PATCH 3/6] Update to latest libsecp --- depend/secp256k1-zkp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depend/secp256k1-zkp b/depend/secp256k1-zkp index 1985d18..84563ed 160000 --- a/depend/secp256k1-zkp +++ b/depend/secp256k1-zkp @@ -1 +1 @@ -Subproject commit 1985d187eff4c1558b885701dd54760387a91010 +Subproject commit 84563edb127a8f7a9c56c2cccbaa35882bbbf036 From 3c4a6c4f2b2a365772662b849f44620a5513b5fa Mon Sep 17 00:00:00 2001 From: jaspervdm Date: Mon, 3 Jun 2019 14:11:38 +0200 Subject: [PATCH 4/6] Update tests --- src/pedersen.rs | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/pedersen.rs b/src/pedersen.rs index 8dc59e4..617c69c 100644 --- a/src/pedersen.rs +++ b/src/pedersen.rs @@ -1392,7 +1392,7 @@ mod tests { let blinding = SecretKey::new(&secp, &mut thread_rng()); let value = 12345678; let commit = secp.commit(value, blinding).unwrap(); - let bullet_proof = secp.bullet_proof(value, blinding, blinding, None, None); + let bullet_proof = secp.bullet_proof(value, blinding.clone(), blinding.clone(), blinding.clone(), None, None); // correct verification println!("Bullet proof len: {}", bullet_proof.plen); @@ -1404,7 +1404,7 @@ mod tests { // wrong value committed to let value = 12345678; let wrong_commit = secp.commit(87654321, blinding).unwrap(); - let bullet_proof = secp.bullet_proof(value, blinding, blinding, None, None); + let bullet_proof = secp.bullet_proof(value, blinding.clone(), blinding.clone(), blinding.clone(), None, None); if !secp .verify_bullet_proof(wrong_commit, bullet_proof, None) .is_err() @@ -1416,7 +1416,7 @@ mod tests { let value = 12345678; let commit = secp.commit(value, blinding).unwrap(); let blinding = SecretKey::new(&secp, &mut thread_rng()); - let bullet_proof = secp.bullet_proof(value, blinding, blinding, None, None); + let bullet_proof = secp.bullet_proof(value, blinding.clone(), blinding.clone(), blinding.clone(), None, None); if !secp .verify_bullet_proof(commit, bullet_proof, None) .is_err() @@ -1430,7 +1430,7 @@ mod tests { let value = 12345678; let commit = secp.commit(value, blinding).unwrap(); let bullet_proof = - secp.bullet_proof(value, blinding, blinding, Some(extra_data.clone()), None); + secp.bullet_proof(value, blinding.clone(), blinding.clone(), blinding.clone(), Some(extra_data.clone()), None); if secp .verify_bullet_proof(commit, bullet_proof, Some(extra_data.clone())) .is_err() @@ -1452,15 +1452,16 @@ mod tests { // Ensure rewinding works let blinding = SecretKey::new(&secp, &mut thread_rng()); - let nonce = SecretKey::new(&secp, &mut thread_rng()); + let rewind_nonce = SecretKey::new(&secp, &mut thread_rng()); + let private_nonce = SecretKey::new(&secp, &mut thread_rng()); let value = 12345678; let commit = secp.commit(value, blinding).unwrap(); let bullet_proof = - secp.bullet_proof(value, blinding, nonce, Some(extra_data.clone()), None); + secp.bullet_proof(value, blinding.clone(), private_nonce.clone(), private_nonce.clone(), Some(extra_data.clone()), None); // Unwind message with same blinding factor let proof_info = secp - .rewind_bullet_proof(commit, nonce, Some(extra_data.clone()), bullet_proof) + .rewind_bullet_proof(commit, private_nonce, Some(extra_data.clone()), bullet_proof) .unwrap(); assert_eq!(proof_info.value, value); assert_eq!(blinding, proof_info.blinding); @@ -1477,26 +1478,28 @@ mod tests { } // unwinding with wrong extra data should puke - let proof_info = secp.rewind_bullet_proof(commit, nonce, None, bullet_proof); + let proof_info = secp.rewind_bullet_proof(commit, private_nonce, None, bullet_proof); if !proof_info.is_err() { panic!("Bullet proof verify with message should have errored."); } // Ensure including a message also works - let message_bytes: [u8; 16] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + let message_bytes: [u8; 20] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; let message = ProofMessage::from_bytes(&message_bytes); let bullet_proof = secp.bullet_proof( value, - blinding, - nonce, + blinding.clone(), + rewind_nonce.clone(), + private_nonce.clone(), Some(extra_data.clone()), Some(message.clone()), ); // Unwind message with same blinding factor let proof_info = secp - .rewind_bullet_proof(commit, nonce, Some(extra_data.clone()), bullet_proof) + .rewind_bullet_proof(commit, rewind_nonce, Some(extra_data.clone()), bullet_proof) .unwrap(); + assert_eq!(proof_info.value, value); assert_eq!(proof_info.message, message); } @@ -1790,7 +1793,7 @@ mod tests { let commit = secp.commit(value, blinding).unwrap(); let mut pm = ProofMessage::from_bytes(&[0u8;32]); - let bullet_proof = secp.bullet_proof(value, blinding, nonce, None, Some(pm.clone())); + let bullet_proof = secp.bullet_proof(value, blinding, nonce.clone(), nonce.clone(), None, Some(pm.clone())); // Unwind message with same blinding factor let proof_info = secp .rewind_bullet_proof(commit, nonce, None, bullet_proof) @@ -1809,7 +1812,7 @@ mod tests { let value = ::max_value() - 1; let commit = secp.commit(value, blinding).unwrap(); - let bullet_proof = secp.bullet_proof(value, blinding, nonce, None, None); + let bullet_proof = secp.bullet_proof(value, blinding, nonce.clone(), nonce.clone(), None, None); // Unwind message with same blinding factor let proof_info = secp .rewind_bullet_proof(commit, nonce, None, bullet_proof) @@ -1834,7 +1837,7 @@ mod tests { let mut proofs: Vec = vec![]; for i in 0..v { commits.push(secp.commit(value + i as u64, blinding).unwrap()); - proofs.push(secp.bullet_proof(value + i as u64, blinding, blinding, None, None)); + proofs.push(secp.bullet_proof(value + i as u64, blinding, blinding, blinding, None, None)); } println!("--------"); println!("Comparing {} Proofs", v); @@ -1871,7 +1874,7 @@ mod tests { let wrong_commit = secp.commit(value, wrong_blinding).unwrap(); commits.push(secp.commit(value, blinding).unwrap()); - proofs.push(secp.bullet_proof(value, blinding, blinding, None, None)); + proofs.push(secp.bullet_proof(value, blinding, blinding, blinding, None, None)); let proof_range = secp .verify_bullet_proof(commits[0].clone(), proofs[0].clone(), None) .unwrap(); @@ -1897,8 +1900,8 @@ mod tests { proofs = vec![]; commits.push(secp.commit(value + 1, blinding).unwrap()); commits.push(secp.commit(value - 1, blinding).unwrap()); - proofs.push(secp.bullet_proof(value + 1, blinding, blinding, None, None)); - proofs.push(secp.bullet_proof(value - 1, blinding, blinding, None, None)); + proofs.push(secp.bullet_proof(value + 1, blinding, blinding, blinding, None, None)); + proofs.push(secp.bullet_proof(value - 1, blinding, blinding, blinding, None, None)); let proof_range = secp .verify_bullet_proof_multi(commits.clone(), proofs.clone(), None) .unwrap(); @@ -1915,6 +1918,7 @@ mod tests { value + 1, blinding, blinding, + blinding, Some(extra_data1.clone()), None, )); @@ -1922,6 +1926,7 @@ mod tests { value - 1, blinding, blinding, + blinding, Some(extra_data2.clone()), None, )); @@ -1953,7 +1958,7 @@ mod tests { for i in 1..100 { print!("\r\r\r{}", i); commits.push(secp.commit(value + i as u64, blinding).unwrap()); - proofs.push(secp.bullet_proof(value + i as u64, blinding, blinding, None, None)); + proofs.push(secp.bullet_proof(value + i as u64, blinding, blinding, blinding, None, None)); let proof_range = secp.verify_bullet_proof_multi(commits.clone(), proofs.clone(), None); //.unwrap(); if proof_range.is_err() { println!(" proofs batch verify failed"); From db602326752d15659b0f0bdfc953f82a3f1156cd Mon Sep 17 00:00:00 2001 From: jaspervdm Date: Mon, 3 Jun 2019 14:26:25 +0200 Subject: [PATCH 5/6] Fix borrow after move --- src/pedersen.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pedersen.rs b/src/pedersen.rs index 5c577ca..9cd8a2c 100644 --- a/src/pedersen.rs +++ b/src/pedersen.rs @@ -1461,7 +1461,7 @@ mod tests { secp.bullet_proof(value, blinding.clone(), private_nonce.clone(), private_nonce.clone(), Some(extra_data.clone()), None); // Unwind message with same blinding factor let proof_info = secp - .rewind_bullet_proof(commit, private_nonce, Some(extra_data.clone()), bullet_proof) + .rewind_bullet_proof(commit, private_nonce.clone(), Some(extra_data.clone()), bullet_proof) .unwrap(); assert_eq!(proof_info.value, value); assert_eq!(blinding, proof_info.blinding); @@ -1478,7 +1478,7 @@ mod tests { } // unwinding with wrong extra data should puke - let proof_info = secp.rewind_bullet_proof(commit, private_nonce, None, bullet_proof); + let proof_info = secp.rewind_bullet_proof(commit, private_nonce.clone(), None, bullet_proof); if !proof_info.is_err() { panic!("Bullet proof verify with message should have errored."); } From 12ee00a0648c0fd943256257b7dff4d9c8772470 Mon Sep 17 00:00:00 2001 From: jaspervdm Date: Thu, 6 Jun 2019 19:38:28 +0200 Subject: [PATCH 6/6] Update tests --- src/pedersen.rs | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/pedersen.rs b/src/pedersen.rs index 9cd8a2c..05137e2 100644 --- a/src/pedersen.rs +++ b/src/pedersen.rs @@ -1815,10 +1815,19 @@ mod tests { let bullet_proof = secp.bullet_proof(value, blinding.clone(), nonce.clone(), nonce.clone(), None, None); // Unwind message with same blinding factor let proof_info = secp - .rewind_bullet_proof(commit, nonce, None, bullet_proof) + .rewind_bullet_proof(commit, nonce.clone(), None, bullet_proof) .unwrap(); assert_eq!(proof_info.value, value); assert_eq!(blinding, proof_info.blinding); + + // Using a different private nonce should prevent rewind of blinding factor + let private_nonce = SecretKey::new(&secp, &mut thread_rng()); + let bullet_proof = secp.bullet_proof(value, blinding.clone(), nonce.clone(), private_nonce.clone(), None, None); + let proof_info = secp + .rewind_bullet_proof(commit, nonce, None, bullet_proof) + .unwrap(); + assert_eq!(proof_info.value, value); + assert_ne!(blinding, proof_info.blinding); } #[ignore] @@ -1868,13 +1877,15 @@ mod tests { let secp = Secp256k1::with_caps(ContextFlag::Commit); let blinding = SecretKey::new(&secp, &mut thread_rng()); + let rewind_nonce = SecretKey::new(&secp, &mut thread_rng()); + let private_nonce = SecretKey::new(&secp, &mut thread_rng()); let wrong_blinding = SecretKey::new(&secp, &mut thread_rng()); let value = 12345678; let wrong_commit = secp.commit(value, wrong_blinding).unwrap(); commits.push(secp.commit(value, blinding.clone()).unwrap()); - proofs.push(secp.bullet_proof(value, blinding.clone(), blinding.clone(), blinding.clone(), None, None)); + proofs.push(secp.bullet_proof(value, blinding.clone(), rewind_nonce.clone(), private_nonce.clone(), None, None)); let proof_range = secp .verify_bullet_proof(commits[0].clone(), proofs[0].clone(), None) .unwrap(); @@ -1900,8 +1911,8 @@ mod tests { proofs = vec![]; commits.push(secp.commit(value + 1, blinding.clone()).unwrap()); commits.push(secp.commit(value - 1, blinding.clone()).unwrap()); - proofs.push(secp.bullet_proof(value + 1, blinding.clone(), blinding.clone(), blinding.clone(), None, None)); - proofs.push(secp.bullet_proof(value - 1, blinding.clone(), blinding.clone(), blinding.clone(), None, None)); + proofs.push(secp.bullet_proof(value + 1, blinding.clone(), rewind_nonce.clone(), private_nonce.clone(), None, None)); + proofs.push(secp.bullet_proof(value - 1, blinding.clone(), rewind_nonce.clone(), private_nonce.clone(), None, None)); let proof_range = secp .verify_bullet_proof_multi(commits.clone(), proofs.clone(), None) .unwrap(); @@ -1917,16 +1928,16 @@ mod tests { proofs.push(secp.bullet_proof( value + 1, blinding.clone(), - blinding.clone(), - blinding.clone(), + rewind_nonce.clone(), + private_nonce.clone(), Some(extra_data1.clone()), None, )); proofs.push(secp.bullet_proof( value - 1, blinding.clone(), - blinding.clone(), - blinding.clone(), + rewind_nonce.clone(), + private_nonce.clone(), Some(extra_data2.clone()), None, )); @@ -1958,7 +1969,7 @@ mod tests { for i in 1..100 { print!("\r\r\r{}", i); commits.push(secp.commit(value + i as u64, blinding.clone()).unwrap()); - proofs.push(secp.bullet_proof(value + i as u64, blinding.clone(), blinding.clone(), blinding.clone(), None, None)); + proofs.push(secp.bullet_proof(value + i as u64, blinding.clone(), rewind_nonce.clone(), private_nonce.clone(), None, None)); let proof_range = secp.verify_bullet_proof_multi(commits.clone(), proofs.clone(), None); //.unwrap(); if proof_range.is_err() { println!(" proofs batch verify failed");