Skip to content

Commit

Permalink
Merge pull request #202 from dusk-network/mocello/201_api_changes
Browse files Browse the repository at this point in the history
API changes
  • Loading branch information
moCello authored Jun 12, 2024
2 parents 66ac595 + 9445b6b commit ac886f4
Show file tree
Hide file tree
Showing 14 changed files with 255 additions and 202 deletions.
2 changes: 2 additions & 0 deletions circuits/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Add Recipient gadget [#197]
- Add `RecipientParameter::new` constructor [#201]

### Changed

Expand All @@ -36,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Update `poseidon-merkle` to v0.6 [#179]

<!-- ISSUES -->
[#201]: https://github.com/dusk-network/phoenix/issues/201
[#197]: https://github.com/dusk-network/phoenix/issues/197
[#188]: https://github.com/dusk-network/phoenix/issues/188
[#191]: https://github.com/dusk-network/phoenix/issues/191
Expand Down
4 changes: 2 additions & 2 deletions circuits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ exclude = [".github/workflows/dusk-ci.yml", ".gitignore"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
phoenix-core = { version = "0.28.0", path = "../core" }
phoenix-core = { version = "0.28.0", default-features = false, path = "../core" }
dusk-plonk = { version = "0.19", default-features = false }
dusk-jubjub = { version = "0.14", default-features = false }
poseidon-merkle = { version = "0.6", features = ["rkyv-impl", "zk", "size_32"] }
dusk-poseidon = { version = "0.39", features = ["zk"] }
jubjub-schnorr = { version = "0.4", features = ["zk"] }
rand = { version = "0.8", default-features = false, features = ["std_rng"] }
ff = { version = "0.13", default-features = false }

[dev-dependencies]
ff = { version = "0.13", default-features = false }
lazy_static = "1.4"
149 changes: 106 additions & 43 deletions circuits/src/recipient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,16 @@
//
// Copyright (c) DUSK NETWORK. All rights reserved.

#![allow(non_snake_case)]

use dusk_jubjub::JubJubScalar;
use dusk_plonk::prelude::*;
use jubjub_schnorr::{gadgets, Signature};
use ff::Field;
use jubjub_schnorr::{gadgets, SecretKey as SchnorrSecretKey, Signature};
use rand::{CryptoRng, RngCore};

use crate::elgamal;
use phoenix_core::PublicKey;

use rand::rngs::StdRng;
use rand::SeedableRng;

use phoenix_core::SecretKey;
use phoenix_core::{PublicKey, SecretKey};

const TX_OUTPUT_NOTES: usize = 2;

Expand All @@ -24,39 +23,103 @@ pub struct RecipientParameters {
/// Public key of the transaction sender
pub sender_pk: PublicKey,
/// Note public keys of each note recipient
pub recipient_npk_vec: [JubJubAffine; TX_OUTPUT_NOTES],
pub output_npk: [JubJubAffine; TX_OUTPUT_NOTES],
/// Signatures of 'payload_hash' verifiable using 'pk_A' and 'pk_B'
pub sig_vec: [Signature; TX_OUTPUT_NOTES],
pub sig: [Signature; TX_OUTPUT_NOTES],
/// Asymmetric encryption of 'pk_A' using both recipients 'npk'
pub enc_A_vec: [(JubJubExtended, JubJubExtended); TX_OUTPUT_NOTES],
pub enc_A: [(JubJubExtended, JubJubExtended); TX_OUTPUT_NOTES],
/// Asymmetric encryption of 'pk_B' using both recipients 'npk'
pub enc_B_vec: [(JubJubExtended, JubJubExtended); TX_OUTPUT_NOTES],
pub enc_B: [(JubJubExtended, JubJubExtended); TX_OUTPUT_NOTES],
/// Randomness needed to encrypt/decrypt 'pk_A'
pub r_A_vec: [JubJubScalar; TX_OUTPUT_NOTES],
pub r_A: [JubJubScalar; TX_OUTPUT_NOTES],
/// Randomness needed to encrypt/decrypt 'pk_B'
pub r_B_vec: [JubJubScalar; TX_OUTPUT_NOTES],
pub r_B: [JubJubScalar; TX_OUTPUT_NOTES],
}

impl Default for RecipientParameters {
fn default() -> Self {
let mut rng = StdRng::seed_from_u64(0xbeef);

let sk = SecretKey::random(&mut rng);
let sk =
SecretKey::new(JubJubScalar::default(), JubJubScalar::default());
let sender_pk = PublicKey::from(&sk);

Self {
sender_pk,
recipient_npk_vec: [
JubJubAffine::default(),
JubJubAffine::default(),
],
sig_vec: [Signature::default(), Signature::default()],
enc_A_vec: [(JubJubExtended::default(), JubJubExtended::default());
output_npk: [JubJubAffine::default(), JubJubAffine::default()],
sig: [Signature::default(), Signature::default()],
enc_A: [(JubJubExtended::default(), JubJubExtended::default());
TX_OUTPUT_NOTES],
enc_B_vec: [(JubJubExtended::default(), JubJubExtended::default());
enc_B: [(JubJubExtended::default(), JubJubExtended::default());
TX_OUTPUT_NOTES],
r_A_vec: [JubJubScalar::default(); TX_OUTPUT_NOTES],
r_B_vec: [JubJubScalar::default(); TX_OUTPUT_NOTES],
r_A: [JubJubScalar::default(); TX_OUTPUT_NOTES],
r_B: [JubJubScalar::default(); TX_OUTPUT_NOTES],
}
}
}

impl RecipientParameters {
/// Create the recipient parameter
pub fn new(
rng: &mut (impl RngCore + CryptoRng),
sender_sk: &SecretKey,
output_npk: [JubJubAffine; TX_OUTPUT_NOTES],
payload_hash: BlsScalar,
) -> Self {
// Encrypt the public key of the sender. We need to encrypt
// both 'A' and 'B', using both tx output note public keys.
let sender_pk = PublicKey::from(sender_sk);

let r_A = [
JubJubScalar::random(&mut *rng),
JubJubScalar::random(&mut *rng),
];
let r_B = [
JubJubScalar::random(&mut *rng),
JubJubScalar::random(&mut *rng),
];

let (A_enc_1_c1, A_enc_1_c2) = elgamal::encrypt(
&output_npk[0].into(), // note_pk_1.as_ref(),
sender_pk.A(),
&r_A[0],
);

let (B_enc_1_c1, B_enc_1_c2) = elgamal::encrypt(
&output_npk[0].into(), // note_pk_1.as_ref(),
sender_pk.B(),
&r_B[0],
);
let (A_enc_2_c1, A_enc_2_c2) = elgamal::encrypt(
&output_npk[1].into(), // note_pk_2.as_ref(),
sender_pk.A(),
&r_A[1],
);

let (B_enc_2_c1, B_enc_2_c2) = elgamal::encrypt(
&output_npk[1].into(), // note_pk_2.as_ref(),
sender_pk.B(),
&r_B[1],
);

let enc_A = [(A_enc_1_c1, A_enc_1_c2), (A_enc_2_c1, A_enc_2_c2)];
let enc_B = [(B_enc_1_c1, B_enc_1_c2), (B_enc_2_c1, B_enc_2_c2)];

// Sign the payload hash using both 'a' and 'b'
let schnorr_sk_a = SchnorrSecretKey::from(sender_sk.a());
let sig_A = schnorr_sk_a.sign(rng, payload_hash);

let schnorr_sk_b = SchnorrSecretKey::from(sender_sk.b());
let sig_B = schnorr_sk_b.sign(rng, payload_hash);

let sig = [sig_A, sig_B];

RecipientParameters {
sender_pk,
output_npk,
sig,
enc_A,
enc_B,
r_A,
r_B,
}
}
}
Expand All @@ -71,24 +134,24 @@ pub(crate) fn gadget(
let pk_A = composer.append_point(rp.sender_pk.A());
let pk_B = composer.append_point(rp.sender_pk.B());

let sig_A_u = composer.append_witness(*rp.sig_vec[0].u());
let sig_A_R = composer.append_point(rp.sig_vec[0].R());
let sig_A_u = composer.append_witness(*rp.sig[0].u());
let sig_A_R = composer.append_point(rp.sig[0].R());

let sig_B_u = composer.append_witness(*rp.sig_vec[1].u());
let sig_B_R = composer.append_point(rp.sig_vec[1].R());
let sig_B_u = composer.append_witness(*rp.sig[1].u());
let sig_B_R = composer.append_point(rp.sig[1].R());

gadgets::verify_signature(composer, sig_A_u, sig_A_R, pk_A, payload_hash)?;
gadgets::verify_signature(composer, sig_B_u, sig_B_R, pk_B, payload_hash)?;

// ENCRYPT EACH KEY 'A' and 'B' USING EACH OUTPUT 'NPK'
let note_pk_1 = composer.append_public_point(rp.recipient_npk_vec[0]);
let note_pk_2 = composer.append_public_point(rp.recipient_npk_vec[1]);
let note_pk_1 = composer.append_public_point(rp.output_npk[0]);
let note_pk_2 = composer.append_public_point(rp.output_npk[1]);

let r_A_1 = composer.append_witness(rp.r_A_vec[0]);
let r_A_2 = composer.append_witness(rp.r_A_vec[1]);
let r_A_1 = composer.append_witness(rp.r_A[0]);
let r_A_2 = composer.append_witness(rp.r_A[1]);

let r_B_1 = composer.append_witness(rp.r_B_vec[0]);
let r_B_2 = composer.append_witness(rp.r_B_vec[1]);
let r_B_1 = composer.append_witness(rp.r_B[0]);
let r_B_2 = composer.append_witness(rp.r_B[1]);

let (enc_A_1_c1, enc_A_1_c2) =
elgamal::encrypt_gadget(composer, note_pk_1, pk_A, r_A_1)?;
Expand All @@ -100,15 +163,15 @@ pub(crate) fn gadget(
let (enc_B_2_c1, enc_B_2_c2) =
elgamal::encrypt_gadget(composer, note_pk_2, pk_B, r_B_2)?;

composer.assert_equal_public_point(enc_A_1_c1, rp.enc_A_vec[0].0);
composer.assert_equal_public_point(enc_A_1_c2, rp.enc_A_vec[0].1);
composer.assert_equal_public_point(enc_A_2_c1, rp.enc_A_vec[1].0);
composer.assert_equal_public_point(enc_A_2_c2, rp.enc_A_vec[1].1);
composer.assert_equal_public_point(enc_A_1_c1, rp.enc_A[0].0);
composer.assert_equal_public_point(enc_A_1_c2, rp.enc_A[0].1);
composer.assert_equal_public_point(enc_A_2_c1, rp.enc_A[1].0);
composer.assert_equal_public_point(enc_A_2_c2, rp.enc_A[1].1);

composer.assert_equal_public_point(enc_B_1_c1, rp.enc_B_vec[0].0);
composer.assert_equal_public_point(enc_B_1_c2, rp.enc_B_vec[0].1);
composer.assert_equal_public_point(enc_B_2_c1, rp.enc_B_vec[1].0);
composer.assert_equal_public_point(enc_B_2_c2, rp.enc_B_vec[1].1);
composer.assert_equal_public_point(enc_B_1_c1, rp.enc_B[0].0);
composer.assert_equal_public_point(enc_B_1_c2, rp.enc_B[0].1);
composer.assert_equal_public_point(enc_B_2_c1, rp.enc_B[1].0);
composer.assert_equal_public_point(enc_B_2_c2, rp.enc_B[1].1);

Ok(())
}
9 changes: 4 additions & 5 deletions circuits/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ struct WitnessTxOutputNote {
}

impl TxOutputNote {
/// Crate a new `TxOutputNote`.
/// Create a new `TxOutputNote`.
pub fn new(
value: u64,
value_commitment: JubJubAffine,
Expand Down Expand Up @@ -337,9 +337,8 @@ pub struct TxCircuit<const H: usize, const I: usize> {

impl<const H: usize, const I: usize> Default for TxCircuit<H, I> {
fn default() -> Self {
let mut rng = StdRng::seed_from_u64(0xbeef);

let sk = SecretKey::random(&mut rng);
let sk =
SecretKey::new(JubJubScalar::default(), JubJubScalar::default());

let mut tree = Tree::<(), H>::new();
let payload_hash = BlsScalar::default();
Expand All @@ -355,7 +354,7 @@ impl<const H: usize, const I: usize> Default for TxCircuit<H, I> {
for _ in 0..I {
let merkle_opening = tree.opening(*note.pos()).expect("Tree read.");
let tx_input_note = TxInputNote::new(
&mut rng,
&mut StdRng::seed_from_u64(0xb001),
&note,
merkle_opening,
&sk,
Expand Down
Loading

0 comments on commit ac886f4

Please sign in to comment.