From aeabe51bce8dea1c3ebee30aa9fb3686511fd160 Mon Sep 17 00:00:00 2001 From: David Rusu Date: Tue, 16 Jul 2024 18:26:55 +0400 Subject: [PATCH] cl: add death_cm to cl::Input commitment --- cl/cl/src/balance.rs | 8 +++--- cl/cl/src/input.rs | 21 +++++++------- cl/cl/src/note.rs | 11 ++++---- cl/ledger/src/input.rs | 46 ++++++++++++++++++------------- cl/proof_statements/src/input.rs | 8 ++---- cl/risc0_proofs/input/src/main.rs | 13 ++------- 6 files changed, 53 insertions(+), 54 deletions(-) diff --git a/cl/cl/src/balance.rs b/cl/cl/src/balance.rs index 01fb26a..b09202d 100644 --- a/cl/cl/src/balance.rs +++ b/cl/cl/src/balance.rs @@ -7,10 +7,10 @@ lazy_static! { static ref PEDERSON_COMMITMENT_BLINDING_POINT: RistrettoPoint = crate::crypto::hash_to_curve(b"NOMOS_CL_PEDERSON_COMMITMENT_BLINDING"); } -#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)] pub struct Balance(pub RistrettoPoint); -#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)] pub struct BalanceWitness { pub value: u64, pub unit: RistrettoPoint, @@ -27,7 +27,7 @@ impl BalanceWitness { pub fn new(value: u64, unit: impl Into, blinding: Scalar) -> Self { Self { value, - unit: unit_point(&unit.into()).into(), + unit: unit_point(&unit.into()), blinding, } } @@ -37,7 +37,7 @@ impl BalanceWitness { } pub fn commit(&self) -> Balance { - Balance(balance(self.value, self.unit.into(), self.blinding).into()) + Balance(balance(self.value, self.unit, self.blinding)) } } diff --git a/cl/cl/src/input.rs b/cl/cl/src/input.rs index 7feba93..445d8c8 100644 --- a/cl/cl/src/input.rs +++ b/cl/cl/src/input.rs @@ -4,21 +4,20 @@ /// which on their own may not balance (i.e. \sum inputs != \sum outputs) use crate::{ balance::Balance, - note::{NoteCommitment, NoteWitness}, + note::{DeathCommitment, NoteWitness}, nullifier::{Nullifier, NullifierNonce, NullifierSecret}, }; use rand_core::RngCore; -// use risc0_groth16::{PublicInputsJson, Verifier}; use serde::{Deserialize, Serialize}; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub struct Input { - pub note_comm: NoteCommitment, pub nullifier: Nullifier, pub balance: Balance, + pub death_cm: DeathCommitment, } -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub struct InputWitness { pub note: NoteWitness, pub nf_sk: NullifierSecret, @@ -36,9 +35,9 @@ impl InputWitness { pub fn commit(&self) -> Input { Input { - note_comm: self.note.commit(self.nf_sk.commit(), self.nonce), nullifier: Nullifier::new(self.nf_sk, self.nonce), balance: self.note.balance(), + death_cm: self.note.death_commitment(), } } @@ -52,11 +51,11 @@ impl InputWitness { } impl Input { - pub fn to_bytes(&self) -> [u8; 96] { - let mut bytes = [0u8; 96]; - bytes[..32].copy_from_slice(self.note_comm.as_bytes()); - bytes[32..64].copy_from_slice(self.nullifier.as_bytes()); - bytes[64..96].copy_from_slice(&self.balance.to_bytes()); + pub fn to_bytes(&self) -> [u8; 64] { + let mut bytes = [0u8; 64]; + bytes[..32].copy_from_slice(self.nullifier.as_bytes()); + bytes[32..64].copy_from_slice(&self.balance.to_bytes()); + bytes[64..96].copy_from_slice(&self.death_cm.0); bytes } } diff --git a/cl/cl/src/note.rs b/cl/cl/src/note.rs index ab328b5..0beed54 100644 --- a/cl/cl/src/note.rs +++ b/cl/cl/src/note.rs @@ -8,7 +8,8 @@ use crate::{ }; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] -pub struct DeathCommitment([u8; 32]); +pub struct DeathCommitment(pub [u8; 32]); + pub fn death_commitment(death_constraint: &[u8]) -> DeathCommitment { let mut hasher = Sha256::new(); hasher.update(b"NOMOS_CL_DEATH_COMMIT"); @@ -29,10 +30,10 @@ impl NoteCommitment { // TODO: Rename Note to NoteWitness and NoteCommitment to Note -#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)] pub struct NoteWitness { pub balance: BalanceWitness, - pub death_constraint: Vec, // serialized verification key of death constraint + pub death_constraint: [u8; 32], // death constraint verification key pub state: [u8; 32], } @@ -45,7 +46,7 @@ impl NoteWitness { ) -> Self { Self { balance: BalanceWitness::random(value, unit, rng), - death_constraint: vec![], + death_constraint: [0u8; 32], state, } } @@ -63,7 +64,7 @@ impl NoteWitness { hasher.update(self.state); // COMMIT TO DEATH CONSTRAINT - hasher.update(&self.death_constraint); + hasher.update(self.death_constraint); // COMMIT TO NULLIFIER hasher.update(nf_pk.as_bytes()); diff --git a/cl/ledger/src/input.rs b/cl/ledger/src/input.rs index 198a078..f09603e 100644 --- a/cl/ledger/src/input.rs +++ b/cl/ledger/src/input.rs @@ -25,23 +25,19 @@ impl InputProof { } pub fn prove_input_nullifier( - input: &cl::InputWitness, + input: cl::InputWitness, note_commitments: &[cl::NoteCommitment], ) -> InputProof { - let output = input.to_output_witness(); + let output_cm = input.to_output_witness().commit_note(); + let cm_leaves = note_commitment_leaves(note_commitments); - let output_cm = output.commit_note(); let cm_idx = note_commitments .iter() .position(|c| c == &output_cm) .unwrap(); let cm_path = cl::merkle::path(cm_leaves, cm_idx); - let secrets = InputPrivate { - nf_sk: input.nf_sk, - output, - cm_path, - }; + let secrets = InputPrivate { input, cm_path }; let env = risc0_zkvm::ExecutorEnv::builder() .write(&secrets) @@ -90,7 +86,7 @@ mod test { let input = cl::InputWitness { note: cl::NoteWitness { balance: cl::BalanceWitness::random(32, "NMO", &mut rng), - death_constraint: vec![], + death_constraint: [0u8; 32], state: [0u8; 32], }, nf_sk: cl::NullifierSecret::random(&mut rng), @@ -99,12 +95,11 @@ mod test { let notes = vec![input.to_output_witness().commit_note()]; - let proof = prove_input_nullifier(&input, ¬es); + let proof = prove_input_nullifier(input, ¬es); let expected_public_inputs = InputPublic { cm_root: cl::merkle::root(note_commitment_leaves(¬es)), - nf: input.commit().nullifier, - death_cm: cl::note::death_commitment(&[]), + input: input.commit(), }; assert!(proof.verify(&expected_public_inputs)); @@ -112,17 +107,30 @@ mod test { let wrong_public_inputs = [ InputPublic { cm_root: cl::merkle::root([cl::merkle::leaf(b"bad_root")]), - ..expected_public_inputs.clone() + ..expected_public_inputs }, InputPublic { - nf: cl::Nullifier::new( - cl::NullifierSecret::random(&mut rng), - cl::NullifierNonce::random(&mut rng), - ), - ..expected_public_inputs.clone() + input: cl::Input { + nullifier: cl::Nullifier::new( + cl::NullifierSecret::random(&mut rng), + cl::NullifierNonce::random(&mut rng), + ), + ..expected_public_inputs.input + }, + ..expected_public_inputs }, InputPublic { - death_cm: cl::note::death_commitment(b"wrong death vk"), + input: cl::Input { + death_cm: cl::note::death_commitment(b"wrong death vk"), + ..expected_public_inputs.input + }, + ..expected_public_inputs + }, + InputPublic { + input: cl::Input { + balance: cl::BalanceWitness::random(32, "NMO", &mut rng).commit(), + ..expected_public_inputs.input + }, ..expected_public_inputs }, ]; diff --git a/cl/proof_statements/src/input.rs b/cl/proof_statements/src/input.rs index c2e2d34..20dab89 100644 --- a/cl/proof_statements/src/input.rs +++ b/cl/proof_statements/src/input.rs @@ -8,16 +8,14 @@ use serde::{Deserialize, Serialize}; /// 3. verify_merkle_path(note_cm, root, path) /// 4. death_cm = death_commitment(note.death_constraint) -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub struct InputPublic { pub cm_root: [u8; 32], - pub nf: cl::Nullifier, - pub death_cm: cl::DeathCommitment, + pub input: cl::Input, } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct InputPrivate { - pub nf_sk: cl::NullifierSecret, - pub output: cl::OutputWitness, + pub input: cl::InputWitness, pub cm_path: Vec, } diff --git a/cl/risc0_proofs/input/src/main.rs b/cl/risc0_proofs/input/src/main.rs index fa0b2ca..b84517f 100644 --- a/cl/risc0_proofs/input/src/main.rs +++ b/cl/risc0_proofs/input/src/main.rs @@ -1,24 +1,17 @@ /// Input Proof use cl::merkle; -use cl::nullifier::Nullifier; use proof_statements::input::{InputPrivate, InputPublic}; use risc0_zkvm::guest::env; fn main() { let secret: InputPrivate = env::read(); - assert_eq!(secret.output.nf_pk, secret.nf_sk.commit()); - let cm_out = secret.output.commit_note(); - let cm_leaf = merkle::leaf(cm_out.as_bytes()); + let out_cm = secret.input.to_output_witness().commit_note(); + let cm_leaf = merkle::leaf(out_cm.as_bytes()); let cm_root = merkle::path_root(cm_leaf, &secret.cm_path); - let nf = Nullifier::new(secret.nf_sk, secret.output.nonce); - - let death_cm = secret.output.note.death_commitment(); - env::commit(&InputPublic { + input: secret.input.commit(), cm_root, - nf, - death_cm, }); }