mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-20 19:11:08 +03:00
added basic tests around range_proof (#121)
Pass nonce in to range_proof (we need it for rewind_range_proof, at least for testing)
This commit is contained in:
parent
6056c16cfa
commit
87cd0e5c58
5 changed files with 87 additions and 15 deletions
|
@ -458,7 +458,8 @@ impl Block {
|
|||
let sig = try!(secp.sign(&msg, &skey));
|
||||
let commit = secp.commit(REWARD, skey).unwrap();
|
||||
//let switch_commit = secp.switch_commit(skey).unwrap();
|
||||
let rproof = secp.range_proof(0, REWARD, skey, commit);
|
||||
let nonce = secp.nonce();
|
||||
let rproof = secp.range_proof(0, REWARD, skey, commit, nonce);
|
||||
|
||||
let output = Output {
|
||||
features: COINBASE_OUTPUT,
|
||||
|
|
|
@ -110,7 +110,8 @@ pub fn input_rand(value: u64) -> Box<Append> {
|
|||
pub fn output(value: u64, blinding: SecretKey) -> Box<Append> {
|
||||
Box::new(move |build, (tx, sum)| -> (Transaction, BlindSum) {
|
||||
let commit = build.secp.commit(value, blinding).unwrap();
|
||||
let rproof = build.secp.range_proof(0, value, blinding, commit);
|
||||
let nonce = build.secp.nonce();
|
||||
let rproof = build.secp.range_proof(0, value, blinding, commit, nonce);
|
||||
(tx.with_output(Output {
|
||||
features: DEFAULT_OUTPUT,
|
||||
commit: commit,
|
||||
|
@ -127,7 +128,8 @@ pub fn output_rand(value: u64) -> Box<Append> {
|
|||
Box::new(move |build, (tx, sum)| -> (Transaction, BlindSum) {
|
||||
let blinding = SecretKey::new(&build.secp, &mut build.rng);
|
||||
let commit = build.secp.commit(value, blinding).unwrap();
|
||||
let rproof = build.secp.range_proof(0, value, blinding, commit);
|
||||
let nonce = build.secp.nonce();
|
||||
let rproof = build.secp.range_proof(0, value, blinding, commit, nonce);
|
||||
(tx.with_output(Output {
|
||||
features: DEFAULT_OUTPUT,
|
||||
commit: commit,
|
||||
|
|
|
@ -233,7 +233,7 @@ mod tests {
|
|||
let outputs = vec![core::transaction::Output{
|
||||
features: core::transaction::DEFAULT_OUTPUT,
|
||||
commit: output_commit,
|
||||
proof: ec.range_proof(0, 100, key::ZERO_KEY, output_commit)}];
|
||||
proof: ec.range_proof(0, 100, key::ZERO_KEY, output_commit, ec.nonce())}];
|
||||
let test_transaction = core::transaction::Transaction::new(inputs,
|
||||
outputs, 5);
|
||||
|
||||
|
|
|
@ -892,7 +892,7 @@ mod tests {
|
|||
transaction::Output{
|
||||
features: transaction::DEFAULT_OUTPUT,
|
||||
commit: output_commitment,
|
||||
proof: ec.range_proof(0, value, output_key, output_commitment)}
|
||||
proof: ec.range_proof(0, value, output_key, output_commitment, ec.nonce())}
|
||||
}
|
||||
|
||||
/// Makes a SecretKey from a single u64
|
||||
|
|
|
@ -163,6 +163,7 @@ impl RangeProof {
|
|||
}
|
||||
|
||||
/// The range that was proven
|
||||
#[derive(Debug)]
|
||||
pub struct ProofRange {
|
||||
/// Min value that was proven
|
||||
pub min: u64,
|
||||
|
@ -306,20 +307,25 @@ impl Secp256k1 {
|
|||
SecretKey::from_slice(self, &ret)
|
||||
}
|
||||
|
||||
/// Convenience function for generating a random nonce for a range proof.
|
||||
/// We will need the nonce later if we want to rewind the range proof.
|
||||
pub fn nonce(&self) -> [u8; 32] {
|
||||
let mut rng = OsRng::new().unwrap();
|
||||
let mut nonce = [0u8; 32];
|
||||
rng.fill_bytes(&mut nonce);
|
||||
nonce
|
||||
}
|
||||
|
||||
/// Produces a range proof for the provided value, using min and max
|
||||
/// bounds, relying
|
||||
/// on the blinding factor and commitment.
|
||||
pub fn range_proof(&self,
|
||||
min: u64,
|
||||
value: u64,
|
||||
blind: SecretKey,
|
||||
commit: Commitment)
|
||||
-> RangeProof {
|
||||
|
||||
let mut rng = OsRng::new().unwrap();
|
||||
let mut nonce = [0u8; 32];
|
||||
rng.fill_bytes(&mut nonce);
|
||||
|
||||
min: u64,
|
||||
value: u64,
|
||||
blind: SecretKey,
|
||||
commit: Commitment,
|
||||
nonce: [u8; 32])
|
||||
-> RangeProof {
|
||||
let mut retried = false;
|
||||
let mut proof = [0; constants::MAX_PROOF_SIZE];
|
||||
let mut plen = constants::MAX_PROOF_SIZE as i32;
|
||||
|
@ -585,4 +591,67 @@ mod tests {
|
|||
1001
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_commit_sum() {
|
||||
let secp = Secp256k1::with_caps(ContextFlag::Commit);
|
||||
|
||||
fn commit(value: u64, blinding: SecretKey) -> Commitment {
|
||||
let secp = Secp256k1::with_caps(ContextFlag::Commit);
|
||||
secp.commit(value, blinding).unwrap()
|
||||
}
|
||||
|
||||
let blind_a = SecretKey::new(&secp, &mut OsRng::new().unwrap());
|
||||
let blind_b = SecretKey::new(&secp, &mut OsRng::new().unwrap());
|
||||
|
||||
let commit_a = commit(3, blind_a);
|
||||
let commit_b = commit(2, blind_b);
|
||||
|
||||
let blind_c = secp.blind_sum(vec![blind_a, blind_b], vec![]).unwrap();
|
||||
|
||||
let commit_c = commit(3 + 2, blind_c);
|
||||
|
||||
let commit_d = secp.commit_sum(vec![commit_a, commit_b], vec![]).unwrap();
|
||||
assert_eq!(commit_c, commit_d);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_proof() {
|
||||
let secp = Secp256k1::with_caps(ContextFlag::Commit);
|
||||
let blinding = SecretKey::new(&secp, &mut OsRng::new().unwrap());
|
||||
|
||||
let commit = secp.commit(7, blinding).unwrap();
|
||||
let nonce = secp.nonce();
|
||||
let range_proof = secp.range_proof(0, 7, blinding, commit, nonce);
|
||||
let proof_range = secp.verify_range_proof(commit, range_proof).unwrap();
|
||||
|
||||
assert_eq!(proof_range.min, 0);
|
||||
|
||||
let proof_info = secp.range_proof_info(range_proof);
|
||||
assert!(proof_info.success);
|
||||
assert_eq!(proof_info.min, 0);
|
||||
// check we get no information back for the value here
|
||||
assert_eq!(proof_info.value, 0);
|
||||
|
||||
let proof_info = secp.rewind_range_proof(commit, range_proof, nonce);
|
||||
assert!(proof_info.success);
|
||||
assert_eq!(proof_info.min, 0);
|
||||
assert_eq!(proof_info.value, 7);
|
||||
|
||||
// check we cannot rewind a range proof without the original nonce
|
||||
let bad_nonce = secp.nonce();
|
||||
let bad_info = secp.rewind_range_proof(commit, range_proof, bad_nonce);
|
||||
assert_eq!(bad_info.success, false);
|
||||
assert_eq!(bad_info.value, 0);
|
||||
|
||||
// check we can construct and verify a range proof on value 0
|
||||
let commit = secp.commit(0, blinding).unwrap();
|
||||
let nonce = secp.nonce();
|
||||
let range_proof = secp.range_proof(0, 0, blinding, commit, nonce);
|
||||
let proof_range = secp.verify_range_proof(commit, range_proof).unwrap();
|
||||
let proof_info = secp.rewind_range_proof(commit, range_proof, nonce);
|
||||
assert!(proof_info.success);
|
||||
assert_eq!(proof_info.min, 0);
|
||||
assert_eq!(proof_info.value, 0);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue