diff --git a/depend/secp256k1-zkp b/depend/secp256k1-zkp index 07a94be..84563ed 160000 --- a/depend/secp256k1-zkp +++ b/depend/secp256k1-zkp @@ -1 +1 @@ -Subproject commit 07a94beb737b816cdc65e54ee4c6c310544206df +Subproject commit 84563edb127a8f7a9c56c2cccbaa35882bbbf036 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/ffi.rs b/src/ffi.rs index 3313d87..a677bbf 100644 --- a/src/ffi.rs +++ b/src/ffi.rs @@ -589,7 +589,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 95a7aa2..05137e2 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,14 +1085,13 @@ 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 { 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(), @@ -1393,7 +1392,7 @@ mod tests { let blinding = SecretKey::new(&secp, &mut thread_rng()); let value = 12345678; let commit = secp.commit(value, blinding.clone()).unwrap(); - let bullet_proof = secp.bullet_proof(value, blinding.clone(), blinding.clone(), 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); @@ -1405,7 +1404,7 @@ mod tests { // wrong value committed to let value = 12345678; let wrong_commit = secp.commit(87654321, blinding.clone()).unwrap(); - let bullet_proof = secp.bullet_proof(value, blinding.clone(), blinding.clone(), 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() @@ -1417,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.clone(), blinding.clone(), 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() @@ -1431,7 +1430,7 @@ mod tests { let value = 12345678; let commit = secp.commit(value, blinding.clone()).unwrap(); let bullet_proof = - secp.bullet_proof(value, blinding.clone(), blinding.clone(), 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() @@ -1453,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.clone()).unwrap(); let bullet_proof = - secp.bullet_proof(value, blinding.clone(), nonce.clone(), 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.clone(), 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,26 +1478,28 @@ mod tests { } // unwinding with wrong extra data should puke - let proof_info = secp.rewind_bullet_proof(commit, nonce.clone(), 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."); } // 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.clone(), - nonce.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); } @@ -1791,7 +1793,7 @@ mod tests { let commit = secp.commit(value, blinding.clone()).unwrap(); let mut pm = ProofMessage::from_bytes(&[0u8;32]); - let bullet_proof = secp.bullet_proof(value, blinding.clone(), nonce.clone(), None, Some(pm.clone())); + let bullet_proof = secp.bullet_proof(value, blinding.clone(), 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) @@ -1810,13 +1812,22 @@ mod tests { let value = ::max_value() - 1; let commit = secp.commit(value, blinding.clone()).unwrap(); - let bullet_proof = secp.bullet_proof(value, blinding.clone(), nonce.clone(), None, None); + 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] @@ -1835,7 +1846,7 @@ mod tests { let mut proofs: Vec = vec![]; for i in 0..v { commits.push(secp.commit(value + i as u64, blinding.clone()).unwrap()); - proofs.push(secp.bullet_proof(value + i as u64, blinding.clone(), blinding.clone(), None, None)); + proofs.push(secp.bullet_proof(value + i as u64, blinding.clone(), blinding.clone(), blinding.clone(), None, None)); } println!("--------"); println!("Comparing {} Proofs", v); @@ -1866,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(), 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(); @@ -1898,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(), None, None)); - proofs.push(secp.bullet_proof(value - 1, 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(); @@ -1915,14 +1928,16 @@ mod tests { proofs.push(secp.bullet_proof( value + 1, 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(), + rewind_nonce.clone(), + private_nonce.clone(), Some(extra_data2.clone()), None, )); @@ -1954,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(), 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");