cl: output proof tests

This commit is contained in:
David Rusu 2024-06-13 13:43:09 -04:00
parent cc8c6e31cb
commit 7db1420194
3 changed files with 81 additions and 7 deletions

View File

@ -114,9 +114,8 @@ mod test {
for wrong_witness in wrong_witnesses { for wrong_witness in wrong_witnesses {
assert!(input.prove(&wrong_witness).is_err()); assert!(input.prove(&wrong_witness).is_err());
let wrong_note = Input::from_witness(wrong_witness.clone()); let wrong_input = Input::from_witness(wrong_witness.clone());
let wrong_proof = wrong_note.prove(&wrong_witness).unwrap(); let wrong_proof = wrong_input.prove(&wrong_witness).unwrap();
assert!(!input.verify(&wrong_proof)); assert!(!input.verify(&wrong_proof));
} }
} }

View File

@ -13,7 +13,7 @@ lazy_static! {
crypto::hash_to_curve(b"NOMOS_CL_PEDERSON_COMMITMENT_BLINDING"); crypto::hash_to_curve(b"NOMOS_CL_PEDERSON_COMMITMENT_BLINDING");
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct NoteCommitment([u8; 32]); pub struct NoteCommitment([u8; 32]);
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]

View File

@ -1,15 +1,18 @@
use jubjub::{ExtendedPoint, Scalar}; use jubjub::{ExtendedPoint, Scalar};
use crate::{ use crate::{
error::Error,
note::{Note, NoteCommitment}, note::{Note, NoteCommitment},
nullifier::{NullifierCommitment, NullifierNonce}, nullifier::{NullifierCommitment, NullifierNonce},
}; };
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Output { pub struct Output {
pub note_comm: NoteCommitment, pub note_comm: NoteCommitment,
pub balance: ExtendedPoint, pub balance: ExtendedPoint,
} }
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OutputWitness { pub struct OutputWitness {
note: Note, note: Note,
nf_pk: NullifierCommitment, nf_pk: NullifierCommitment,
@ -18,21 +21,93 @@ pub struct OutputWitness {
} }
// as we don't have SNARKS hooked up yet, the witness will be our proof // as we don't have SNARKS hooked up yet, the witness will be our proof
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OutputProof(OutputWitness); pub struct OutputProof(OutputWitness);
impl Output { impl Output {
pub fn prove(&self, w: OutputWitness) -> OutputProof { pub fn from_witness(w: OutputWitness) -> Self {
OutputProof(w) Self {
note_comm: w.note.commit(w.nf_pk, w.nonce),
balance: w.note.balance(w.balance_blinding),
}
}
pub fn prove(&self, w: &OutputWitness) -> Result<OutputProof, Error> {
if &Self::from_witness(w.clone()) == self {
Ok(OutputProof(w.clone()))
} else {
Err(Error::ProofFailed)
}
} }
pub fn verify(&self, proof: &OutputProof) -> bool { pub fn verify(&self, proof: &OutputProof) -> bool {
// verification checks the relation // verification checks the relation
// - note_comm == commit(note || nf_pk) // - note_comm == commit(note || nf_pk)
// - balance == v * hash_to_curve(Unit) + blinding * H // - balance == v * hash_to_curve(Unit) + blinding * H
let witness = &proof.0; let witness = &proof.0;
self.note_comm == witness.note.commit(witness.nf_pk, witness.nonce) self.note_comm == witness.note.commit(witness.nf_pk, witness.nonce)
&& self.balance == witness.note.balance(witness.balance_blinding) && self.balance == witness.note.balance(witness.balance_blinding)
} }
} }
#[cfg(test)]
mod test {
use group::ff::Field;
use super::*;
use crate::{nullifier::NullifierSecret, test_util::seed_rng};
#[test]
fn test_output_proof() {
let mut rng = seed_rng(0);
let note = Note::new(10, "NMO");
let nf_pk = NullifierSecret::random(&mut rng).commit();
let nonce = NullifierNonce::random(&mut rng);
let balance_blinding = Scalar::random(&mut rng);
let witness = OutputWitness {
note,
nf_pk,
nonce,
balance_blinding,
};
let output = Output::from_witness(witness.clone());
let proof = output.prove(&witness).unwrap();
assert!(output.verify(&proof));
let wrong_witnesses = [
OutputWitness {
note: Note::new(11, "NMO"),
..witness.clone()
},
OutputWitness {
note: Note::new(10, "ETH"),
..witness.clone()
},
OutputWitness {
nf_pk: NullifierSecret::random(&mut rng).commit(),
..witness.clone()
},
OutputWitness {
nonce: NullifierNonce::random(&mut rng),
..witness.clone()
},
OutputWitness {
balance_blinding: Scalar::random(&mut rng),
..witness.clone()
},
];
for wrong_witness in wrong_witnesses {
assert!(output.prove(&wrong_witness).is_err());
let wrong_output = Output::from_witness(wrong_witness.clone());
let wrong_proof = wrong_output.prove(&wrong_witness).unwrap();
assert!(!output.verify(&wrong_proof));
}
}
}