goas: make nullifier is collision resistant

This commit is contained in:
David Rusu 2024-08-17 10:52:29 +04:00
parent 733b316815
commit c0aa2b0e08
4 changed files with 32 additions and 7 deletions

View File

@ -66,7 +66,7 @@ impl InputWitness {
} }
pub fn nullifier(&self) -> Nullifier { pub fn nullifier(&self) -> Nullifier {
Nullifier::new(self.nf_sk, self.nonce) Nullifier::new(self.nf_sk, self.nonce, self.note_commitment())
} }
pub fn commit(&self) -> Input { pub fn commit(&self) -> Input {

View File

@ -1,3 +1,4 @@
use rand_core::CryptoRngCore;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
@ -23,16 +24,20 @@ pub fn unit_point(unit: &str) -> Unit {
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct NoteCommitment([u8; 32]); pub struct NoteCommitment(pub [u8; 32]);
impl NoteCommitment { impl NoteCommitment {
pub fn random(mut rng: impl CryptoRngCore) -> Self {
let mut cm = [0u8; 32];
rng.fill_bytes(&mut cm);
Self(cm)
}
pub fn as_bytes(&self) -> &[u8; 32] { pub fn as_bytes(&self) -> &[u8; 32] {
&self.0 &self.0
} }
} }
// TODO: Rename Note to NoteWitness and NoteCommitment to Note
#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize)]
pub struct NoteWitness { pub struct NoteWitness {
pub value: u64, pub value: u64,

View File

@ -9,6 +9,8 @@ use rand_core::RngCore;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256}; use sha2::{Digest, Sha256};
use crate::NoteCommitment;
// TODO: create a nullifier witness and use it throughout. // TODO: create a nullifier witness and use it throughout.
// struct NullifierWitness { // struct NullifierWitness {
// nf_sk: NullifierSecret, // nf_sk: NullifierSecret,
@ -102,11 +104,12 @@ impl NullifierNonce {
} }
impl Nullifier { impl Nullifier {
pub fn new(sk: NullifierSecret, nonce: NullifierNonce) -> Self { pub fn new(sk: NullifierSecret, nonce: NullifierNonce, note_cm: NoteCommitment) -> Self {
let mut hasher = Sha256::new(); let mut hasher = Sha256::new();
hasher.update(b"NOMOS_CL_NULLIFIER"); hasher.update(b"NOMOS_CL_NULLIFIER");
hasher.update(sk.0); hasher.update(sk.0);
hasher.update(nonce.0); hasher.update(nonce.0);
hasher.update(note_cm.0);
let nf_bytes: [u8; 32] = hasher.finalize().into(); let nf_bytes: [u8; 32] = hasher.finalize().into();
Self(nf_bytes) Self(nf_bytes)
@ -144,8 +147,24 @@ mod test {
let sk = NullifierSecret::random(&mut rng); let sk = NullifierSecret::random(&mut rng);
let nonce_1 = NullifierNonce::random(&mut rng); let nonce_1 = NullifierNonce::random(&mut rng);
let nonce_2 = NullifierNonce::random(&mut rng); let nonce_2 = NullifierNonce::random(&mut rng);
let nf_1 = Nullifier::new(sk, nonce_1); let note_cm = NoteCommitment::random(&mut rng);
let nf_2 = Nullifier::new(sk, nonce_2);
let nf_1 = Nullifier::new(sk, nonce_1, note_cm);
let nf_2 = Nullifier::new(sk, nonce_2, note_cm);
assert_ne!(nf_1, nf_2);
}
#[test]
fn test_same_sk_same_nonce_different_note() {
let mut rng = rand::thread_rng();
let sk = NullifierSecret::random(&mut rng);
let nonce = NullifierNonce::random(&mut rng);
let note_cm_1 = NoteCommitment::random(&mut rng);
let note_cm_2 = NoteCommitment::random(&mut rng);
let nf_1 = Nullifier::new(sk, nonce, note_cm_1);
let nf_2 = Nullifier::new(sk, nonce, note_cm_2);
assert_ne!(nf_1, nf_2); assert_ne!(nf_1, nf_2);
} }

View File

@ -128,6 +128,7 @@ mod test {
nullifier: cl::Nullifier::new( nullifier: cl::Nullifier::new(
cl::NullifierSecret::random(&mut rng), cl::NullifierSecret::random(&mut rng),
cl::NullifierNonce::random(&mut rng), cl::NullifierNonce::random(&mut rng),
input.note_commitment(),
), ),
..expected_public_inputs.input ..expected_public_inputs.input
}, },