Skip to content

Commit

Permalink
circuits: Small fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
xevisalle committed Jun 6, 2024
1 parent eaf2b71 commit 866bc1c
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 40 deletions.
9 changes: 9 additions & 0 deletions circuits/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Add Recipient gadget [#197]

### Changed

- Remove `ViewKey` from `TxOutputNote::new()` parameters [#191]
- Make `rng` the first param in `TxInputNote::new` [#189]
- Rename `crossover` to `deposit` [#190]
- Remove recomputation of `value_commitment` in `TxOutputNote::New()`
- Rename `skeleton_hash` to `payload_hash` [#188]
- Make `TxCircuit` to use the Recipient gadget

## [0.1.0] - 2024-05-22

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

<!-- ISSUES -->
[#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
[#190]: https://github.com/dusk-network/phoenix/issues/190
[#189]: https://github.com/dusk-network/phoenix/issues/189
Expand Down
28 changes: 14 additions & 14 deletions circuits/src/recipient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::elgamal;
use phoenix_core::PublicKey;

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

use phoenix_core::SecretKey;

Expand All @@ -21,15 +21,15 @@ const TX_OUTPUT_NOTES: usize = 2;
/// Parameters needed to prove a recipient in-circuit
#[derive(Debug, Clone, Copy)]
pub struct RecipientParameters {
/// Public key of the transaction recipient
pub recipient_pk: PublicKey,
/// Note public keys of each note receiver
pub receiver_npk_vec: [JubJubAffine; TX_OUTPUT_NOTES],
/// 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],
/// Signatures of 'payload_hash' verifiable using 'pk_A' and 'pk_B'
pub sig_vec: [Signature; TX_OUTPUT_NOTES],
/// Asymmetric encryption of 'pk_A' using both receivers 'npk'
/// Asymmetric encryption of 'pk_A' using both recipients 'npk'
pub enc_A_vec: [(JubJubExtended, JubJubExtended); TX_OUTPUT_NOTES],
/// Asymmetric encryption of 'pk_B' using both receivers 'npk'
/// Asymmetric encryption of 'pk_B' using both recipients 'npk'
pub enc_B_vec: [(JubJubExtended, JubJubExtended); TX_OUTPUT_NOTES],
/// Randomness needed to encrypt/decrypt 'pk_A'
pub r_A_vec: [JubJubScalar; TX_OUTPUT_NOTES],
Expand All @@ -42,11 +42,11 @@ impl Default for RecipientParameters {
let mut rng = StdRng::seed_from_u64(0xbeef);

let sk = SecretKey::random(&mut rng);
let recipient_pk = PublicKey::from(&sk);
let sender_pk = PublicKey::from(&sk);

Self {
recipient_pk,
receiver_npk_vec: [
sender_pk,
recipient_npk_vec: [
JubJubAffine::default(),
JubJubAffine::default(),
],
Expand All @@ -68,8 +68,8 @@ pub(crate) fn gadget(
payload_hash: &Witness,
) -> Result<(), Error> {
// VERIFY A SIGNATURE FOR EACH KEY 'A' AND 'B'
let pk_A = composer.append_point(rp.recipient_pk.A());
let pk_B = composer.append_point(rp.recipient_pk.B());
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());
Expand All @@ -81,8 +81,8 @@ pub(crate) fn gadget(
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.receiver_npk_vec[0]);
let note_pk_2 = composer.append_public_point(rp.receiver_npk_vec[1]);
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 r_A_1 = composer.append_witness(rp.r_A_vec[0]);
let r_A_2 = composer.append_witness(rp.r_A_vec[1]);
Expand Down
25 changes: 17 additions & 8 deletions circuits/src/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Copyright (c) DUSK NETWORK. All rights reserved.

use dusk_jubjub::{
JubJubAffine, JubJubScalar, GENERATOR, GENERATOR_EXTENDED, GENERATOR_NUMS,
JubJubAffine, JubJubScalar, GENERATOR, GENERATOR_NUMS,
GENERATOR_NUMS_EXTENDED,
};
use dusk_plonk::prelude::*;
Expand Down Expand Up @@ -141,12 +141,11 @@ struct WitnessTxOutputNote {

impl TxOutputNote {
/// Crate a new `TxOutputNote`.
pub fn new(value: u64, blinding_factor: JubJubScalar) -> Self {
let value_commitment = JubJubAffine::from(
(GENERATOR_EXTENDED * JubJubScalar::from(value))
+ (GENERATOR_NUMS_EXTENDED * blinding_factor),
);

pub fn new(
value: u64,
value_commitment: JubJubAffine,
blinding_factor: JubJubScalar,
) -> Self {
Self {
value,
value_commitment,
Expand Down Expand Up @@ -418,6 +417,16 @@ impl<const H: usize, const I: usize> TxCircuit<H, I> {
}

impl<const H: usize, const I: usize> Circuit for TxCircuit<H, I> {
/// The circuit has the following public inputs:
/// - `payload_hash`
/// - `root`
/// - `[nullifier; I]`
/// - `[output_value_commitment; 2]`
/// - `max_fee`
/// - `deposit`
/// - `(npk_1, npk_2)`
/// - `(enc_A_npk_1, enc_A_npk_2)`
/// - `(enc_B_npk_1, enc_B_npk_2)`
fn circuit(&self, composer: &mut Composer) -> Result<(), Error> {
// Make the payload hash a public input of the circuit
let payload_hash = composer.append_public(self.payload_hash);
Expand All @@ -433,7 +442,7 @@ impl<const H: usize, const I: usize> Circuit for TxCircuit<H, I> {
self.deposit,
)?;

// Prove correctess of the recipient encryption
// Prove correctness of the sender keys encryption
recipient::gadget(composer, &self.rp, &payload_hash)?;

Ok(())
Expand Down
43 changes: 25 additions & 18 deletions circuits/tests/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,26 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use rand::rngs::StdRng;
use rand::SeedableRng;
use rand::{CryptoRng, RngCore};

use dusk_jubjub::JubJubScalar;
use phoenix_circuits::transaction::{TxCircuit, TxInputNote, TxOutputNote};
use phoenix_core::{Note, PublicKey, SecretKey};
use dusk_jubjub::{JubJubScalar, GENERATOR_EXTENDED, GENERATOR_NUMS_EXTENDED};

use dusk_plonk::prelude::*;
use ff::Field;
use jubjub_schnorr::SecretKey as SchnorrSecretKey;

use phoenix_circuits::{
elgamal,
transaction::{TxCircuit, TxInputNote, TxOutputNote},
RecipientParameters,
};
use phoenix_core::{Note, PublicKey, SecretKey, ViewKey};
use phoenix_core::{Note, PublicKey, SecretKey};

use poseidon_merkle::{Item, Tree};

#[macro_use]
extern crate lazy_static;

Expand Down Expand Up @@ -60,49 +62,49 @@ lazy_static! {
let max_fee = 5;

// Compute the tx output note public keys using
// the receiver public key
let pk_receiver = PublicKey::from(&sk);
// the recipient public key
let recipient_pk = PublicKey::from(&sk);

let r = JubJubScalar::random(&mut rng);
let sa = pk_receiver.gen_stealth_address(&r);
let sa = recipient_pk.gen_stealth_address(&r);
let note_pk_1 = sa.note_pk();

let r = JubJubScalar::random(&mut rng);
let sa = pk_receiver.gen_stealth_address(&r);
let sa = recipient_pk.gen_stealth_address(&r);
let note_pk_2 = sa.note_pk();

let receiver_npk_vec = [
let recipient_npk_vec = [
JubJubAffine::from(note_pk_1.as_ref()),
JubJubAffine::from(note_pk_2.as_ref()),
];

// Encrypt the public key of the recipient. We need to encrypt
// Encrypt the public key of the sender. We need to encrypt
// both 'A' and 'B', using both tx output note public keys.
// We use the same 'sk' just for testing.
let recipient_pk = PublicKey::from(&sk);
let sender_pk = PublicKey::from(&sk);

#[allow(non_snake_case)]
let r_A_1 = JubJubScalar::random(&mut rng);
#[allow(non_snake_case)]
let (A_enc_1_c1, A_enc_1_c2) =
elgamal::encrypt(note_pk_1.as_ref(), &recipient_pk.A(), &r_A_1);
elgamal::encrypt(note_pk_1.as_ref(), &sender_pk.A(), &r_A_1);

#[allow(non_snake_case)]
let r_B_1 = JubJubScalar::random(&mut rng);
#[allow(non_snake_case)]
let (B_enc_1_c1, B_enc_1_c2) =
elgamal::encrypt(note_pk_1.as_ref(), &recipient_pk.B(), &r_B_1);
elgamal::encrypt(note_pk_1.as_ref(), &sender_pk.B(), &r_B_1);
#[allow(non_snake_case)]
let r_A_2 = JubJubScalar::random(&mut rng);
#[allow(non_snake_case)]
let (A_enc_2_c1, A_enc_2_c2) =
elgamal::encrypt(note_pk_2.as_ref(), &recipient_pk.A(), &r_A_2);
elgamal::encrypt(note_pk_2.as_ref(), &sender_pk.A(), &r_A_2);

#[allow(non_snake_case)]
let r_B_2 = JubJubScalar::random(&mut rng);
#[allow(non_snake_case)]
let (B_enc_2_c1, B_enc_2_c2) =
elgamal::encrypt(note_pk_2.as_ref(), &recipient_pk.B(), &r_B_2);
elgamal::encrypt(note_pk_2.as_ref(), &sender_pk.B(), &r_B_2);

#[allow(non_snake_case)]
let enc_A_vec = [(A_enc_1_c1, A_enc_1_c2), (A_enc_2_c1, A_enc_2_c2)];
Expand All @@ -125,9 +127,9 @@ lazy_static! {

let sig_vec = [sig_A, sig_B];

let rp = RecipientParameters { recipient_pk, receiver_npk_vec, sig_vec, enc_A_vec, enc_B_vec, r_A_vec, r_B_vec };
let rp = RecipientParameters { sender_pk, recipient_npk_vec, sig_vec, enc_A_vec, enc_B_vec, r_A_vec, r_B_vec };

TestingParameters { sk, pp, tx_input_notes, payload_hash, root, crossover, max_fee, rp }
TestingParameters { pp, tx_input_notes, payload_hash, root, deposit, max_fee, rp }
};
}

Expand Down Expand Up @@ -191,7 +193,12 @@ fn create_test_tx_input_notes<const I: usize>(
fn create_test_tx_output_note(value: u64) -> TxOutputNote {
let blinding_factor = JubJubScalar::from(42u64);

TxOutputNote::new(value, blinding_factor)
let value_commitment = JubJubAffine::from(
(GENERATOR_EXTENDED * JubJubScalar::from(value))
+ (GENERATOR_NUMS_EXTENDED * blinding_factor),
);

TxOutputNote::new(value, value_commitment, blinding_factor)
}

#[test]
Expand Down

0 comments on commit 866bc1c

Please sign in to comment.