diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cecef6..0f3b25b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,9 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Update `jubjub-schnorr` dependency to "0.2" -- Update `phoenix-core` dependency to "0.26" +- Update `jubjub-schnorr` dependency to "0.4" +- Update `phoenix-core` dependency to "0.28" - Use AES instead of PoseidonCipher [#109] +- Update `dusk-poseidon` dependency to "0.39" [#111] +- Update `poseidon-merkle` dependency to "0.6" ### Removed @@ -152,6 +154,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add workflows for the Github Actions +[#111]: https://github.com/dusk-network/citadel/issues/111 [#109]: https://github.com/dusk-network/citadel/issues/109 [#87]: https://github.com/dusk-network/citadel/issues/87 [#86]: https://github.com/dusk-network/citadel/issues/86 diff --git a/Cargo.toml b/Cargo.toml index 884da67..f852024 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,14 +10,14 @@ license = "MPL-2.0" [dependencies] dusk-bytes = "0.1" -dusk-poseidon = { version = "0.33", default-features = false, features = ["rkyv-impl", "alloc", "size_32", "merkle"] } -poseidon-merkle = { version = "0.5", features = ["rkyv-impl", "zk", "size_32"] } +dusk-poseidon = { version = "0.39", features = ["zk"] } +poseidon-merkle = { version = "0.6", features = ["rkyv-impl", "zk", "size_32"] } dusk-plonk = { version = "0.19", default-features = false, features = ["rkyv-impl", "alloc"] } 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.3", features = ["rkyv-impl", "alloc", "double"] } -phoenix-core = { version = "0.27", features = ["rkyv-impl", "alloc"] } +jubjub-schnorr = { version = "0.4", features = ["zk", "rkyv-impl", "alloc"] } +phoenix-core = { version = "0.28", 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 aeb07a9..69fd646 100644 --- a/benches/citadel.rs +++ b/benches/citadel.rs @@ -6,7 +6,7 @@ use dusk_jubjub::{JubJubAffine, JubJubScalar, GENERATOR_EXTENDED}; use dusk_plonk::prelude::*; -use dusk_poseidon::sponge; +use dusk_poseidon::{Domain, Hash}; use ff::Field; use phoenix_core::{PublicKey, SecretKey}; use poseidon_merkle::{Item, Opening, Tree}; @@ -23,7 +23,6 @@ static LABEL: &[u8; 12] = b"dusk-network"; const CAPACITY: usize = 15; // capacity required for the setup 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; @@ -37,25 +36,26 @@ fn compute_random_license( sk: &SecretKey, sk_lp: &SecretKey, pk_lp: &PublicKey, -) -> (License, Opening<(), DEPTH, ARITY>) { +) -> (License, Opening<(), DEPTH>) { 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 k_lic = JubJubAffine::from( + GENERATOR_EXTENDED * Hash::digest_truncated(Domain::Other, &[(*lsk.as_ref()).into()])[0], + ); let req = Request::new(pk_lp, &lsa, &k_lic, rng).expect("Request correctly computed."); // 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).expect("License correctly computed."); - let mut tree = Tree::<(), DEPTH, ARITY>::new(); + let mut tree = Tree::<(), DEPTH>::new(); let lpk = JubJubAffine::from(lic.lsa.note_pk().as_ref()); let item = Item { - hash: sponge::hash(&[lpk.get_u(), lpk.get_v()]), + hash: Hash::digest(Domain::Other, &[lpk.get_u(), lpk.get_v()])[0], data: (), }; @@ -72,8 +72,8 @@ fn compute_citadel_parameters( sk: &SecretKey, pk_lp: &PublicKey, lic: &License, - merkle_proof: Opening<(), DEPTH, ARITY>, -) -> (CitadelProverParameters, SessionCookie) { + merkle_proof: Opening<(), DEPTH>, +) -> (CitadelProverParameters, SessionCookie) { let c = JubJubScalar::from(CHALLENGE); let (cpp, sc) = CitadelProverParameters::compute_parameters(sk, lic, pk_lp, pk_lp, &c, rng, merkle_proof) @@ -112,12 +112,12 @@ lazy_static! { #[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 } } } diff --git a/src/gadgets.rs b/src/gadgets.rs index f3c260e..f1c67fc 100644 --- a/src/gadgets.rs +++ b/src/gadgets.rs @@ -6,7 +6,7 @@ use dusk_jubjub::{GENERATOR, GENERATOR_NUMS}; use dusk_plonk::prelude::*; -use dusk_poseidon::sponge; +use dusk_poseidon::{Domain, HashGadget}; use jubjub_schnorr::gadgets; use poseidon_merkle::zk::opening_gadget; @@ -25,9 +25,9 @@ use crate::license::{CitadelProverParameters, SessionCookie}; // public_inputs[6]: com_2.y // public_inputs[7]: root -pub fn use_license_citadel( +pub fn use_license_citadel( composer: &mut Composer, - cpp: &CitadelProverParameters, + cpp: &CitadelProverParameters, sc: &SessionCookie, ) -> Result<(), Error> { // APPEND THE LICENSE PUBLIC KEYS OF THE USER @@ -37,21 +37,23 @@ pub fn use_license_citadel( // COMPUTE THE SESSION ID let c = composer.append_witness(sc.c); let session_id_pi = composer.append_public(sc.session_id); - let session_id = sponge::gadget(composer, &[*lpk_p.x(), *lpk_p.y(), c]); + let session_id = HashGadget::digest(composer, Domain::Other, &[*lpk_p.x(), *lpk_p.y(), c]); - composer.assert_equal(session_id, session_id_pi); + composer.assert_equal(session_id[0], session_id_pi); // VERIFY THE LICENSE SIGNATURE - let (sig_lic_u, sig_lic_r) = cpp.sig_lic.append(composer); + let sig_lic_u = composer.append_witness(*cpp.sig_lic.u()); + let sig_lic_r = composer.append_point(cpp.sig_lic.R()); let pk_lp = composer.append_point(sc.pk_lp); let attr_data = composer.append_witness(sc.attr_data); - let message = sponge::gadget(composer, &[*lpk.x(), *lpk.y(), attr_data]); - gadgets::verify_signature(composer, sig_lic_u, sig_lic_r, pk_lp, message)?; + let message = HashGadget::digest(composer, Domain::Other, &[*lpk.x(), *lpk.y(), attr_data]); + gadgets::verify_signature(composer, sig_lic_u, sig_lic_r, pk_lp, message[0])?; // VERIFY THE SESSION HASH SIGNATURE - let (sig_session_hash_u, sig_session_hash_r, sig_session_hash_r_p) = - cpp.sig_session_hash.append(composer); + let sig_session_hash_u = composer.append_witness(*cpp.sig_session_hash.u()); + let sig_session_hash_r = composer.append_point(cpp.sig_session_hash.R()); + let sig_session_hash_r_p = composer.append_point(cpp.sig_session_hash.R_prime()); let session_hash = composer.append_public(cpp.session_hash); gadgets::verify_signature_double( @@ -67,9 +69,9 @@ pub fn use_license_citadel( // COMMIT TO THE PK_LP USING A HASH FUNCTION let s_0 = composer.append_witness(sc.s_0); let com_0_pi = composer.append_public(cpp.com_0); - let com_0 = sponge::gadget(composer, &[*pk_lp.x(), *pk_lp.y(), s_0]); + let com_0 = HashGadget::digest(composer, Domain::Other, &[*pk_lp.x(), *pk_lp.y(), s_0]); - composer.assert_equal(com_0, com_0_pi); + composer.assert_equal(com_0[0], com_0_pi); // COMMIT TO THE ATTRIBUTE DATA let s_1 = composer.append_witness(sc.s_1); @@ -88,11 +90,11 @@ pub fn use_license_citadel( composer.assert_equal_public_point(com_2, cpp.com_2); // COMPUTE THE HASH OF THE LICENSE - let license_hash = sponge::gadget(composer, &[*lpk.x(), *lpk.y()]); + let license_hash = HashGadget::digest(composer, Domain::Other, &[*lpk.x(), *lpk.y()]); // VERIFY THE MERKLE PROOF let root_pi = composer.append_public(cpp.merkle_proof.root().hash); - let root = opening_gadget(composer, &cpp.merkle_proof, license_hash); + let root = opening_gadget(composer, &cpp.merkle_proof, license_hash[0]); composer.assert_equal(root, root_pi); Ok(()) diff --git a/src/license.rs b/src/license.rs index 8c0c794..1944145 100644 --- a/src/license.rs +++ b/src/license.rs @@ -6,11 +6,12 @@ use dusk_bytes::Serializable; use dusk_jubjub::{dhke, GENERATOR_EXTENDED, GENERATOR_NUMS_EXTENDED}; -use dusk_poseidon::sponge; +use dusk_poseidon::{Domain, Hash}; use ff::Field; use jubjub_schnorr::{SecretKey as NoteSecretKey, Signature, SignatureDouble}; use phoenix_core::{ - decrypt, encrypt, Error, PublicKey, SecretKey, StealthAddress, ENCRYPTION_EXTRA_SIZE, + aes::{decrypt, encrypt, ENCRYPTION_EXTRA_SIZE}, + Error, PublicKey, SecretKey, StealthAddress, }; use poseidon_merkle::{Item, Opening, Tree}; use rand_core::{CryptoRng, RngCore}; @@ -111,12 +112,13 @@ impl Session { return false; } - let session_hash = sponge::hash(&[sc.pk_sp.get_u(), sc.pk_sp.get_v(), sc.r]); + let session_hash = + Hash::digest(Domain::Other, &[sc.pk_sp.get_u(), sc.pk_sp.get_v(), sc.r])[0]; if session_hash != self.session_hash { return false; } - let com_0 = sponge::hash(&[pk_lp.get_u(), pk_lp.get_v(), sc.s_0]); + let com_0 = Hash::digest(Domain::Other, &[pk_lp.get_u(), pk_lp.get_v(), sc.s_0])[0]; if com_0 != self.com_0 { return false; } @@ -183,12 +185,14 @@ impl License { k_lic_bytes.copy_from_slice(&dec[StealthAddress::SIZE..]); let k_lic = JubJubAffine::from_bytes(k_lic_bytes).expect("Deserialization was correct."); - let message = sponge::hash(&[ - lsa.note_pk().as_ref().get_u(), - lsa.note_pk().as_ref().get_v(), - BlsScalar::from(*attr_data), - ]); - + let message = Hash::digest( + Domain::Other, + &[ + lsa.note_pk().as_ref().get_u(), + lsa.note_pk().as_ref().get_v(), + BlsScalar::from(*attr_data), + ], + )[0]; let sig_lic = NoteSecretKey::from(sk_lp.a()).sign(rng, message); let mut plaintext = sig_lic.to_bytes().to_vec(); @@ -206,7 +210,7 @@ impl License { archive_attr(derive(bytecheck::CheckBytes)) )] #[derive(Debug, Clone, Copy)] -pub struct CitadelProverParameters { +pub struct CitadelProverParameters { pub lpk: JubJubAffine, // license public key pub lpk_p: JubJubAffine, // license public key prime pub sig_lic: Signature, // signature of the license @@ -215,12 +219,12 @@ pub struct CitadelProverParameters { pub com_1: JubJubExtended, // Pedersen Commitment 1 pub com_2: JubJubExtended, // Pedersen Commitment 2 - pub session_hash: BlsScalar, // hash of the session - pub sig_session_hash: SignatureDouble, // signature of the session_hash - pub merkle_proof: Opening<(), DEPTH, ARITY>, // Merkle proof for the Proof of Validity + pub session_hash: BlsScalar, // hash of the session + pub sig_session_hash: SignatureDouble, // signature of the session_hash + pub merkle_proof: Opening<(), DEPTH>, // Merkle proof for the Proof of Validity } -impl Default for CitadelProverParameters { +impl Default for CitadelProverParameters { fn default() -> Self { let mut tree = Tree::new(); let item = Item { @@ -245,7 +249,7 @@ impl Default for CitadelProverParameters } } -impl CitadelProverParameters { +impl CitadelProverParameters { #[allow(clippy::too_many_arguments)] pub fn compute_parameters( sk: &SecretKey, @@ -254,11 +258,12 @@ impl CitadelProverParameters, + merkle_proof: Opening<(), DEPTH>, ) -> Result<(Self, SessionCookie), Error> { let lsk = sk.gen_note_sk(lic.lsa); let k_lic = JubJubAffine::from( - GENERATOR_EXTENDED * sponge::truncated::hash(&[(*lsk.as_ref()).into()]), + GENERATOR_EXTENDED + * Hash::digest_truncated(Domain::Other, &[(*lsk.as_ref()).into()])[0], ); let dec: [u8; LIC_PLAINTEXT_SIZE] = decrypt(&k_lic, &lic.enc)?; @@ -284,15 +289,17 @@ impl CitadelProverParameters (License, Opening<(), DEPTH, ARITY>) { +) -> (License, Opening<(), DEPTH>) { 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 k_lic = JubJubAffine::from( + GENERATOR_EXTENDED * Hash::digest_truncated(Domain::Other, &[(*lsk.as_ref()).into()])[0], + ); let req = Request::new(pk_lp, &lsa, &k_lic, rng).expect("Request correctly computed."); // 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).expect("License correctly computed."); - let mut tree = Tree::<(), DEPTH, ARITY>::new(); + let mut tree = Tree::<(), DEPTH>::new(); let lpk = JubJubAffine::from(lic.lsa.note_pk().as_ref()); let item = Item { - hash: sponge::hash(&[lpk.get_u(), lpk.get_v()]), + hash: Hash::digest(Domain::Other, &[lpk.get_u(), lpk.get_v()])[0], data: (), }; @@ -68,8 +68,8 @@ fn compute_citadel_parameters( sk: &SecretKey, pk_lp: &PublicKey, lic: &License, - merkle_proof: Opening<(), DEPTH, ARITY>, -) -> (CitadelProverParameters, SessionCookie) { + merkle_proof: Opening<(), DEPTH>, +) -> (CitadelProverParameters, SessionCookie) { let c = JubJubScalar::from(CHALLENGE); let (cpp, sc) = CitadelProverParameters::compute_parameters(sk, lic, pk_lp, pk_lp, &c, rng, merkle_proof) @@ -108,12 +108,12 @@ lazy_static! { #[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 } } }