From 4000adf7ba16cdd7ebf02695cd243778e1aadf7c Mon Sep 17 00:00:00 2001 From: moana <46872249+moCello@users.noreply.github.com> Date: Thu, 25 Apr 2024 14:42:21 +0100 Subject: [PATCH] Update dependencies - Update jubjub-schnorr and phoenix-core dependencies - Remove utils module since it is only used for tests --- CHANGELOG.md | 9 +++ Cargo.toml | 4 +- benches/citadel.rs | 111 ++++++++++++++++++++++++++--------- src/lib.rs | 1 - src/license.rs | 38 ++++++------ src/utils.rs | 84 --------------------------- tests/citadel.rs | 142 ++++++++++++++++++++++++++++++--------------- 7 files changed, 210 insertions(+), 179 deletions(-) delete mode 100644 src/utils.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cf2f92..efa16df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Update `jubjub-schnorr` dependency to "0.2" +- Update `phoenix-core` dependency to "0.26" + +### Removed + +- Remove `utils` module as it was only used for testing + ## [0.11.0] - 2024-04-10 ### Changed diff --git a/Cargo.toml b/Cargo.toml index 8737860..884da67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,8 +16,8 @@ dusk-plonk = { version = "0.19", default-features = false, features = ["rkyv-imp dusk-bls12_381 = { version = "0.13", default-features = false, features = ["rkyv-impl", "alloc"] } dusk-jubjub = { version = "0.14", default-features = false, features = ["rkyv-impl", "alloc"] } ff = { version = "0.13", default-features = false } -jubjub-schnorr = { version = "0.2", features = ["rkyv-impl", "alloc", "double"] } -phoenix-core = { version = "0.26", features = ["rkyv-impl", "alloc"] } +jubjub-schnorr = { version = "0.3", features = ["rkyv-impl", "alloc", "double"] } +phoenix-core = { version = "0.27", features = ["rkyv-impl", "alloc"] } rand_core = { version = "0.6", default-features=false, features = ["getrandom"] } nstack = { version = "0.16" } rkyv = { version = "0.7", default-features = false } diff --git a/benches/citadel.rs b/benches/citadel.rs index bed3dcc..a1331a1 100644 --- a/benches/citadel.rs +++ b/benches/citadel.rs @@ -4,65 +4,119 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. +use dusk_jubjub::{JubJubAffine, JubJubScalar, GENERATOR_EXTENDED}; use dusk_plonk::prelude::*; -use phoenix_core::{PublicKey as PublicSpendKey, SecretKey as SecretSpendKey}; +use dusk_poseidon::sponge; +use ff::Field; +use phoenix_core::{PublicKey, SecretKey}; +use poseidon_merkle::{Item, Opening, Tree}; use zk_citadel::gadgets; -use zk_citadel::license::{CitadelProverParameters, SessionCookie}; +use zk_citadel::license::{CitadelProverParameters, License, Request, SessionCookie}; use criterion::{criterion_group, criterion_main, Criterion}; use rand_core::OsRng; -use zk_citadel::utils::CitadelUtils; static mut CONSTRAINTS_CITADEL: usize = 0; static LABEL: &[u8; 12] = b"dusk-network"; const CAPACITY: usize = 15; // capacity required for the setup -const DEPTH_CITADEL: usize = 17; // depth of the n-ary Merkle tree +const DEPTH: usize = 17; // depth of the n-ary Merkle tree const ARITY: usize = 4; // arity of the Merkle tree +// Example values +const ATTRIBUTE_DATA: u64 = 112233445566778899u64; +const CHALLENGE: u64 = 20221126u64; + #[macro_use] extern crate lazy_static; -pub struct Keys { - ssk: SecretSpendKey, - psk: PublicSpendKey, +fn compute_random_license( + rng: &mut OsRng, + sk: &SecretKey, + sk_lp: &SecretKey, + pk_lp: &PublicKey, +) -> (License, Opening<(), DEPTH, ARITY>) { + let pk = PublicKey::from(sk); + + // First, the user computes these values and requests a License + let lsa = pk.gen_stealth_address(&JubJubScalar::random(&mut *rng)); + let lsk = sk.gen_note_sk(&lsa); + let k_lic = + JubJubAffine::from(GENERATOR_EXTENDED * sponge::truncated::hash(&[(*lsk.as_ref()).into()])); + let req = Request::new(pk_lp, &lsa, &k_lic, rng); + + // Second, the LP computes these values and grants the License + let attr_data = JubJubScalar::from(ATTRIBUTE_DATA); + let lic = License::new(&attr_data, sk_lp, &req, rng); + + let mut tree = Tree::<(), DEPTH, ARITY>::new(); + let lpk = JubJubAffine::from(lic.lsa.note_pk().as_ref()); + + let item = Item { + hash: sponge::hash(&[lpk.get_u(), lpk.get_v()]), + data: (), + }; + + let pos = 0; + tree.insert(pos, item); + + let merkle_proof = tree.opening(pos).expect("Tree was read successfully"); + + (lic, merkle_proof) +} + +fn compute_citadel_parameters( + rng: &mut OsRng, + sk: &SecretKey, + pk_lp: &PublicKey, + lic: &License, + merkle_proof: Opening<(), DEPTH, ARITY>, +) -> (CitadelProverParameters, SessionCookie) { + let c = JubJubScalar::from(CHALLENGE); + let (cpp, sc) = + CitadelProverParameters::compute_parameters(sk, lic, pk_lp, pk_lp, &c, rng, merkle_proof); + (cpp, sc) +} + +struct Keys { + sk: SecretKey, - ssk_lp: SecretSpendKey, - psk_lp: PublicSpendKey, + sk_lp: SecretKey, + pk_lp: PublicKey, citadel_prover: Prover, citadel_verifier: Verifier, } lazy_static! { - static ref KEYS: Keys = { + static ref TEST_KEYS: Keys = { // These are the keys of the user - let ssk = SecretSpendKey::random(&mut OsRng); - let psk = PublicSpendKey::from(ssk); + let sk = SecretKey::random(&mut OsRng); // These are the keys of the LP - let ssk_lp = SecretSpendKey::random(&mut OsRng); - let psk_lp = PublicSpendKey::from(ssk_lp); + let sk_lp = SecretKey::random(&mut OsRng); + let pk_lp = PublicKey::from(&sk_lp); + // Now we generate the ProverKey and VerifierKey for Citadel let pp = PublicParameters::setup(1 << CAPACITY, &mut OsRng).unwrap(); let (citadel_prover, citadel_verifier) = Compiler::compile::(&pp, LABEL).expect("failed to compile circuit"); - Keys { ssk, psk, ssk_lp, psk_lp, citadel_prover, citadel_verifier } + Keys { sk, sk_lp, pk_lp, citadel_prover, citadel_verifier } }; } #[derive(Default, Debug)] pub struct Citadel { - cpp: CitadelProverParameters, + cpp: CitadelProverParameters, sc: SessionCookie, } impl Citadel { - pub fn new(cpp: &CitadelProverParameters, sc: &SessionCookie) -> Self { + pub fn new(cpp: &CitadelProverParameters, sc: &SessionCookie) -> Self { Self { cpp: *cpp, sc: *sc } } } @@ -78,18 +132,17 @@ impl Circuit for Citadel { } fn citadel_benchmark(crit: &mut Criterion) { - let (lic, merkle_proof) = CitadelUtils::compute_random_license::( + let (lic, merkle_proof) = compute_random_license( &mut OsRng, - KEYS.ssk, - KEYS.psk, - KEYS.ssk_lp, - KEYS.psk_lp, + &TEST_KEYS.sk, + &TEST_KEYS.sk_lp, + &TEST_KEYS.pk_lp, ); - let (cpp, sc) = CitadelUtils::compute_citadel_parameters::( + let (cpp, sc) = compute_citadel_parameters( &mut OsRng, - KEYS.ssk, - KEYS.psk_lp, + &TEST_KEYS.sk, + &TEST_KEYS.pk_lp, &lic, merkle_proof, ); @@ -98,21 +151,23 @@ fn citadel_benchmark(crit: &mut Criterion) { let log = &format!("Citadel Prover ({} constraints)", CONSTRAINTS_CITADEL); crit.bench_function(log, |b| { b.iter(|| { - KEYS.citadel_prover + TEST_KEYS + .citadel_prover .prove(&mut OsRng, &Citadel::new(&cpp, &sc)) .expect("failed to prove") }) }); // Benchmark the verifier - let (proof, public_inputs) = KEYS + let (proof, public_inputs) = TEST_KEYS .citadel_prover .prove(&mut OsRng, &Citadel::new(&cpp, &sc)) .expect("failed to prove"); let log = &format!("Citadel Verifier ({} constraints)", CONSTRAINTS_CITADEL); crit.bench_function(log, |b| { b.iter(|| { - KEYS.citadel_verifier + TEST_KEYS + .citadel_verifier .verify(&proof, &public_inputs) .expect("failed to verify proof") }) diff --git a/src/lib.rs b/src/lib.rs index ab4c8ae..f74eea9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,4 +6,3 @@ pub mod gadgets; pub mod license; -pub mod utils; diff --git a/src/license.rs b/src/license.rs index 2c60c65..230cb9b 100644 --- a/src/license.rs +++ b/src/license.rs @@ -9,8 +9,10 @@ use dusk_jubjub::{dhke, GENERATOR_EXTENDED, GENERATOR_NUMS_EXTENDED}; use dusk_poseidon::cipher::PoseidonCipher; use dusk_poseidon::sponge; use ff::Field; -use jubjub_schnorr::{PublicKey, SecretKey, Signature, SignatureDouble}; -use phoenix_core::{PublicKey as PublicSpendKey, SecretKey as SecretSpendKey, StealthAddress}; +use jubjub_schnorr::{ + PublicKey as NotePublicKey, SecretKey as NoteSecretKey, Signature, SignatureDouble, +}; +use phoenix_core::{PublicKey, SecretKey, StealthAddress}; use poseidon_merkle::{Item, Opening, Tree}; use rand_core::{CryptoRng, RngCore}; @@ -37,7 +39,7 @@ pub struct Request { impl Request { pub fn new( - psk_lp: &PublicSpendKey, + pk_lp: &PublicKey, lsa: &StealthAddress, k_lic: &JubJubAffine, mut rng: &mut R, @@ -46,12 +48,12 @@ impl Request { let nonce_2 = BlsScalar::random(&mut rng); let nonce_3 = BlsScalar::random(&mut rng); - let lpk = JubJubAffine::from(*lsa.pk_r().as_ref()); + let lpk = JubJubAffine::from(*lsa.note_pk().as_ref()); let r = JubJubAffine::from(*lsa.R()); let r_dh = JubJubScalar::random(rng); - let rsa = psk_lp.gen_stealth_address(&r_dh); - let k_dh = dhke(&r_dh, psk_lp.A()); + let rsa = pk_lp.gen_stealth_address(&r_dh); + let k_dh = dhke(&r_dh, pk_lp.A()); let enc_1 = PoseidonCipher::encrypt(&[lpk.get_u(), lpk.get_v()], &k_dh, &nonce_1); @@ -185,11 +187,11 @@ pub struct License { impl License { pub fn new( attr_data: &JubJubScalar, - ssk_lp: &SecretSpendKey, + sk_lp: &SecretKey, req: &Request, mut rng: &mut R, ) -> Self { - let k_dh = dhke(ssk_lp.a(), req.rsa.R()); + let k_dh = dhke(sk_lp.a(), req.rsa.R()); let dec_1 = req .enc_1 @@ -212,7 +214,7 @@ impl License { let message = sponge::hash(&[lpk.get_u(), lpk.get_v(), BlsScalar::from(*attr_data)]); - let sig_lic = SecretKey::from(ssk_lp.a()).sign(rng, message); + let sig_lic = NoteSecretKey::from(sk_lp.a()).sign(rng, message); let sig_lic_r = JubJubAffine::from(sig_lic.R()); let nonce_1 = BlsScalar::random(&mut rng); @@ -230,7 +232,7 @@ impl License { Self { lsa: StealthAddress::from_raw_unchecked( JubJubExtended::from(r), - PublicKey::from_raw_unchecked(JubJubExtended::from(lpk)), + NotePublicKey::from_raw_unchecked(JubJubExtended::from(lpk)), ), enc_1, nonce_1, @@ -288,15 +290,15 @@ impl Default for CitadelProverParameters impl CitadelProverParameters { #[allow(clippy::too_many_arguments)] pub fn compute_parameters( - ssk: &SecretSpendKey, + sk: &SecretKey, lic: &License, - psk_lp: &PublicSpendKey, - psk_sp: &PublicSpendKey, + pk_lp: &PublicKey, + pk_sp: &PublicKey, c: &JubJubScalar, mut rng: &mut R, merkle_proof: Opening<(), DEPTH, ARITY>, ) -> (Self, SessionCookie) { - let lsk = ssk.sk_r(&lic.lsa); + let lsk = sk.gen_note_sk(lic.lsa); let k_lic = JubJubAffine::from( GENERATOR_EXTENDED * sponge::truncated::hash(&[(*lsk.as_ref()).into()]), ); @@ -323,16 +325,16 @@ impl CitadelProverParameters CitadelProverParameters( - rng: &mut R, - ssk: SecretSpendKey, - psk: PublicSpendKey, - ssk_lp: SecretSpendKey, - psk_lp: PublicSpendKey, - ) -> (License, Opening<(), DEPTH, ARITY>) { - // First, the user computes these values and requests a License - let lsa = psk.gen_stealth_address(&JubJubScalar::random(&mut *rng)); - let lsk = ssk.sk_r(&lsa); - let k_lic = JubJubAffine::from( - GENERATOR_EXTENDED * sponge::truncated::hash(&[(*lsk.as_ref()).into()]), - ); - let req = Request::new(&psk_lp, &lsa, &k_lic, rng); - - // Second, the LP computes these values and grants the License - let attr_data = JubJubScalar::from(ATTRIBUTE_DATA); - let lic = License::new(&attr_data, &ssk_lp, &req, rng); - - let mut tree = Tree::<(), DEPTH, ARITY>::new(); - let lpk = JubJubAffine::from(lic.lsa.pk_r().as_ref()); - - let item = Item { - hash: sponge::hash(&[lpk.get_u(), lpk.get_v()]), - data: (), - }; - - let pos = 0; - tree.insert(pos, item); - - let merkle_proof = tree.opening(pos).expect("Tree was read successfully"); - - (lic, merkle_proof) - } - - pub fn compute_citadel_parameters< - R: RngCore + CryptoRng, - const DEPTH: usize, - const ARITY: usize, - >( - rng: &mut R, - ssk: SecretSpendKey, - psk_lp: PublicSpendKey, - lic: &License, - merkle_proof: Opening<(), DEPTH, ARITY>, - ) -> (CitadelProverParameters, SessionCookie) { - let c = JubJubScalar::from(CHALLENGE); - let (cpp, sc) = CitadelProverParameters::compute_parameters( - &ssk, - lic, - &psk_lp, - &psk_lp, - &c, - rng, - merkle_proof, - ); - (cpp, sc) - } -} diff --git a/tests/citadel.rs b/tests/citadel.rs index 82a1ee6..efb40cf 100644 --- a/tests/citadel.rs +++ b/tests/citadel.rs @@ -4,9 +4,16 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. +use dusk_jubjub::{JubJubAffine, JubJubScalar, GENERATOR_EXTENDED}; use dusk_plonk::prelude::*; +use dusk_poseidon::sponge; use ff::Field; -use phoenix_core::{PublicKey as PublicSpendKey, SecretKey as SecretSpendKey}; +use phoenix_core::{PublicKey, SecretKey}; +use poseidon_merkle::{Item, Opening, Tree}; +use rand_core::OsRng; + +use zk_citadel::gadgets; +use zk_citadel::license::{CitadelProverParameters, License, Request, Session, SessionCookie}; static LABEL: &[u8; 12] = b"dusk-network"; @@ -14,35 +21,79 @@ const CAPACITY: usize = 15; // capacity required for the setup const DEPTH: usize = 9; // depth of the n-ary Merkle tree const ARITY: usize = 4; // arity of the Merkle tree -use zk_citadel::gadgets; -use zk_citadel::license::{CitadelProverParameters, Session, SessionCookie}; - -use rand_core::OsRng; -use zk_citadel::utils::CitadelUtils; +// Example values +const ATTRIBUTE_DATA: u64 = 112233445566778899u64; +const CHALLENGE: u64 = 20221126u64; #[macro_use] extern crate lazy_static; -pub struct Keys { - ssk: SecretSpendKey, - psk: PublicSpendKey, +fn compute_random_license( + rng: &mut OsRng, + sk: &SecretKey, + sk_lp: &SecretKey, + pk_lp: &PublicKey, +) -> (License, Opening<(), DEPTH, ARITY>) { + let pk = PublicKey::from(sk); + + // First, the user computes these values and requests a License + let lsa = pk.gen_stealth_address(&JubJubScalar::random(&mut *rng)); + let lsk = sk.gen_note_sk(&lsa); + let k_lic = + JubJubAffine::from(GENERATOR_EXTENDED * sponge::truncated::hash(&[(*lsk.as_ref()).into()])); + let req = Request::new(pk_lp, &lsa, &k_lic, rng); + + // Second, the LP computes these values and grants the License + let attr_data = JubJubScalar::from(ATTRIBUTE_DATA); + let lic = License::new(&attr_data, sk_lp, &req, rng); + + let mut tree = Tree::<(), DEPTH, ARITY>::new(); + let lpk = JubJubAffine::from(lic.lsa.note_pk().as_ref()); + + let item = Item { + hash: sponge::hash(&[lpk.get_u(), lpk.get_v()]), + data: (), + }; + + let pos = 0; + tree.insert(pos, item); + + let merkle_proof = tree.opening(pos).expect("Tree was read successfully"); + + (lic, merkle_proof) +} + +fn compute_citadel_parameters( + rng: &mut OsRng, + sk: &SecretKey, + pk_lp: &PublicKey, + lic: &License, + merkle_proof: Opening<(), DEPTH, ARITY>, +) -> (CitadelProverParameters, SessionCookie) { + let c = JubJubScalar::from(CHALLENGE); + let (cpp, sc) = + CitadelProverParameters::compute_parameters(sk, lic, pk_lp, pk_lp, &c, rng, merkle_proof); + (cpp, sc) +} + +struct Keys { + sk: SecretKey, - ssk_lp: SecretSpendKey, - psk_lp: PublicSpendKey, + sk_lp: SecretKey, + pk_lp: PublicKey, citadel_prover: Prover, citadel_verifier: Verifier, } lazy_static! { - static ref KEYS: Keys = { + static ref TEST_KEYS: Keys = { // These are the keys of the user - let ssk = SecretSpendKey::random(&mut OsRng); - let psk = PublicSpendKey::from(ssk); + let sk = SecretKey::random(&mut OsRng); // These are the keys of the LP - let ssk_lp = SecretSpendKey::random(&mut OsRng); - let psk_lp = PublicSpendKey::from(ssk_lp); + let sk_lp = SecretKey::random(&mut OsRng); + let pk_lp = PublicKey::from(&sk_lp); // Now we generate the ProverKey and VerifierKey for Citadel let pp = PublicParameters::setup(1 << CAPACITY, &mut OsRng).unwrap(); @@ -50,7 +101,7 @@ lazy_static! { let (citadel_prover, citadel_verifier) = Compiler::compile::(&pp, LABEL).expect("failed to compile circuit"); - Keys { ssk, psk, ssk_lp, psk_lp, citadel_prover, citadel_verifier } + Keys { sk, sk_lp, pk_lp, citadel_prover, citadel_verifier } }; } @@ -75,30 +126,30 @@ impl Circuit for Citadel { #[test] fn test_full_citadel() { - let (lic, merkle_proof) = CitadelUtils::compute_random_license::( + let (lic, merkle_proof) = compute_random_license( &mut OsRng, - KEYS.ssk, - KEYS.psk, - KEYS.ssk_lp, - KEYS.psk_lp, + &TEST_KEYS.sk, + &TEST_KEYS.sk_lp, + &TEST_KEYS.pk_lp, ); - let (cpp, sc) = CitadelUtils::compute_citadel_parameters::( + let (cpp, sc) = compute_citadel_parameters( &mut OsRng, - KEYS.ssk, - KEYS.psk_lp, + &TEST_KEYS.sk, + &TEST_KEYS.pk_lp, &lic, merkle_proof, ); // Then, the user generates the proof - let (proof, public_inputs) = KEYS + let (proof, public_inputs) = TEST_KEYS .citadel_prover .prove(&mut OsRng, &Citadel::new(&cpp, &sc)) .expect("failed to prove"); // After receiving the proof, the network verifies it - KEYS.citadel_verifier + TEST_KEYS + .citadel_verifier .verify(&proof, &public_inputs) .expect("failed to verify proof"); @@ -112,23 +163,22 @@ fn test_full_citadel() { #[test] #[should_panic] fn test_citadel_false_public_input() { - let (lic, merkle_proof) = CitadelUtils::compute_random_license::( + let (lic, merkle_proof) = compute_random_license( &mut OsRng, - KEYS.ssk, - KEYS.psk, - KEYS.ssk_lp, - KEYS.psk_lp, + &TEST_KEYS.sk, + &TEST_KEYS.sk_lp, + &TEST_KEYS.pk_lp, ); - let (cpp, sc) = CitadelUtils::compute_citadel_parameters::( + let (cpp, sc) = compute_citadel_parameters( &mut OsRng, - KEYS.ssk, - KEYS.psk_lp, + &TEST_KEYS.sk, + &TEST_KEYS.pk_lp, &lic, merkle_proof, ); - let (proof, public_inputs) = KEYS + let (proof, public_inputs) = TEST_KEYS .citadel_prover .prove(&mut OsRng, &Citadel::new(&cpp, &sc)) .expect("failed to prove"); @@ -137,7 +187,8 @@ fn test_citadel_false_public_input() { let mut false_public_inputs = public_inputs; false_public_inputs[0] = BlsScalar::random(&mut OsRng); - KEYS.citadel_verifier + TEST_KEYS + .citadel_verifier .verify(&proof, &false_public_inputs) .expect("failed to verify proof"); } @@ -145,23 +196,22 @@ fn test_citadel_false_public_input() { #[test] #[should_panic] fn test_citadel_false_session_cookie() { - let (lic, merkle_proof) = CitadelUtils::compute_random_license::( + let (lic, merkle_proof) = compute_random_license( &mut OsRng, - KEYS.ssk, - KEYS.psk, - KEYS.ssk_lp, - KEYS.psk_lp, + &TEST_KEYS.sk, + &TEST_KEYS.sk_lp, + &TEST_KEYS.pk_lp, ); - let (cpp, sc) = CitadelUtils::compute_citadel_parameters::( + let (cpp, sc) = compute_citadel_parameters( &mut OsRng, - KEYS.ssk, - KEYS.psk_lp, + &TEST_KEYS.sk, + &TEST_KEYS.pk_lp, &lic, merkle_proof, ); - let (_proof, public_inputs) = KEYS + let (_proof, public_inputs) = TEST_KEYS .citadel_prover .prove(&mut OsRng, &Citadel::new(&cpp, &sc)) .expect("failed to prove");