Skip to content

Commit

Permalink
stake-contract: Hide payload from transactions
Browse files Browse the repository at this point in the history
  • Loading branch information
moCello committed Aug 7, 2024
1 parent 1678575 commit f2ab923
Show file tree
Hide file tree
Showing 4 changed files with 357 additions and 33 deletions.
1 change: 1 addition & 0 deletions contracts/stake/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@

pub mod assert;
pub mod init;
pub mod prove;
pub mod utils;
283 changes: 283 additions & 0 deletions contracts/stake/tests/common/prove.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use dusk_bytes::Serializable;
use execution_core::{
plonk::{Circuit, Prover},
signatures::schnorr::{
Signature as SchnorrSignature,
SignatureDouble as SchnorrSignatureDouble,
},
transfer::phoenix::{
InputNoteInfo, Note, OutputNoteInfo, Prove, PublicKey, TxCircuit,
NOTES_TREE_DEPTH, OUTPUT_NOTES,
},
BlsScalar, JubJubAffine, JubJubScalar,
};

use poseidon_merkle::Opening as PoseidonOpening;
use rand::{CryptoRng, RngCore};

pub struct CachedProver();

impl Prove for CachedProver {
fn prove<R: RngCore + CryptoRng>(
rng: &mut R,
input_notes_information: Vec<(
PoseidonOpening<(), NOTES_TREE_DEPTH>, // opening,
Note, // note,
JubJubAffine, // note-pk prime,
u64, // value,
JubJubScalar, // value-blinder,
BlsScalar, // nullifier,
SchnorrSignatureDouble, // payload signature,
)>,
output_notes_information: [(
u64, // value,
JubJubAffine, // value-commitment,
JubJubScalar, // value-blinder,
JubJubAffine, // note-pk
[(JubJubAffine, JubJubAffine); 2], // sender-enc
[JubJubScalar; 2], // sender-blinder
); OUTPUT_NOTES],
payload_hash: BlsScalar,
root: BlsScalar,
deposit: u64,
max_fee: u64,
sender_pk: &PublicKey,
sender_signatures: (SchnorrSignature, SchnorrSignature),
) -> Vec<u8> {
// parse the circuit input data
let mut input_notes_info = Vec::new();
for (
merkle_opening,
note,
note_pk_p,
value,
value_blinder,
nullifier,
signature,
) in input_notes_information.into_iter()
{
input_notes_info.push(InputNoteInfo {
merkle_opening,
note,
note_pk_p,
value,
value_blinder,
nullifier,
signature,
});
}

let output_notes_info = [
OutputNoteInfo {
value: output_notes_information[0].0,
value_commitment: output_notes_information[0].1,
value_blinder: output_notes_information[0].2,
note_pk: output_notes_information[0].3,
sender_enc: output_notes_information[0].4,
sender_blinder: output_notes_information[0].5,
},
OutputNoteInfo {
value: output_notes_information[1].0,
value_commitment: output_notes_information[1].1,
value_blinder: output_notes_information[1].2,
note_pk: output_notes_information[1].3,
sender_enc: output_notes_information[1].4,
sender_blinder: output_notes_information[1].5,
},
];

// fetch the prover from the cache and crate the circuit
match input_notes_info.len() {
1 => {
let (circuit, circuit_name) = tx_circuit_1_2(
input_notes_info,
output_notes_info,
payload_hash,
root,
deposit,
max_fee,
*sender_pk,
sender_signatures,
);
fetch_prover_and_prove(rng, circuit, &circuit_name)
}
2 => {
let (circuit, circuit_name) = tx_circuit_2_2(
input_notes_info,
output_notes_info,
payload_hash,
root,
deposit,
max_fee,
*sender_pk,
sender_signatures,
);
fetch_prover_and_prove(rng, circuit, &circuit_name)
}
3 => {
let (circuit, circuit_name) = tx_circuit_3_2(
input_notes_info,
output_notes_info,
payload_hash,
root,
deposit,
max_fee,
*sender_pk,
sender_signatures,
);
fetch_prover_and_prove(rng, circuit, &circuit_name)
}
4 => {
let (circuit, circuit_name) = tx_circuit_4_2(
input_notes_info,
output_notes_info,
payload_hash,
root,
deposit,
max_fee,
*sender_pk,
sender_signatures,
);
fetch_prover_and_prove(rng, circuit, &circuit_name)
}
_ => panic!("The `TxCircuit` is only implemented for 1, 2, 3 or 4 input-notes.")
}
}
}

fn fetch_prover_and_prove<R: RngCore + CryptoRng>(
rng: &mut R,
circuit: impl Circuit,
circuit_name: &str,
) -> Vec<u8> {
let circuit_profile = rusk_profile::Circuit::from_name(circuit_name)
.expect(&format!(
"There should be circuit data stored for {}",
circuit_name
));
let (pk, _vd) = circuit_profile
.get_keys()
.expect(&format!("there should be keys stored for {}", circuit_name));

let prover = Prover::try_from_bytes(pk).unwrap();

let (proof, _pi) = prover
.prove(rng, &circuit)
.expect("The circuit should be correct");

proof.to_bytes().into()
}

fn tx_circuit_1_2(
input_notes_info: Vec<InputNoteInfo<NOTES_TREE_DEPTH>>,
output_notes_info: [OutputNoteInfo; OUTPUT_NOTES],
payload_hash: BlsScalar,
root: BlsScalar,
deposit: u64,
max_fee: u64,
sender_pk: PublicKey,
signatures: (SchnorrSignature, SchnorrSignature),
) -> (TxCircuit<NOTES_TREE_DEPTH, 1>, String) {
let input_notes_info: [InputNoteInfo<NOTES_TREE_DEPTH>; 1] =
input_notes_info
.try_into()
.expect("There should be exactly one input");
let circuit = TxCircuit {
input_notes_info,
output_notes_info,
payload_hash,
root,
deposit,
max_fee,
sender_pk,
signatures,
};
(circuit, "ExecuteCircuitOneTwo".into())
}

fn tx_circuit_2_2(
input_notes_info: Vec<InputNoteInfo<NOTES_TREE_DEPTH>>,
output_notes_info: [OutputNoteInfo; OUTPUT_NOTES],
payload_hash: BlsScalar,
root: BlsScalar,
deposit: u64,
max_fee: u64,
sender_pk: PublicKey,
signatures: (SchnorrSignature, SchnorrSignature),
) -> (TxCircuit<NOTES_TREE_DEPTH, 2>, String) {
let input_notes_info: [InputNoteInfo<NOTES_TREE_DEPTH>; 2] =
input_notes_info
.try_into()
.expect("There should be exactly two inputs");
let circuit = TxCircuit {
input_notes_info,
output_notes_info,
payload_hash,
root,
deposit,
max_fee,
sender_pk,
signatures,
};
(circuit, "ExecuteCircuitTwoTwo".into())
}

fn tx_circuit_3_2(
input_notes_info: Vec<InputNoteInfo<NOTES_TREE_DEPTH>>,
output_notes_info: [OutputNoteInfo; OUTPUT_NOTES],
payload_hash: BlsScalar,
root: BlsScalar,
deposit: u64,
max_fee: u64,
sender_pk: PublicKey,
signatures: (SchnorrSignature, SchnorrSignature),
) -> (TxCircuit<NOTES_TREE_DEPTH, 3>, String) {
let input_notes_info: [InputNoteInfo<NOTES_TREE_DEPTH>; 3] =
input_notes_info
.try_into()
.expect("There should be exactly three inputs");
let circuit = TxCircuit {
input_notes_info,
output_notes_info,
payload_hash,
root,
deposit,
max_fee,
sender_pk,
signatures,
};
(circuit, "ExecuteCircuitThreeTwo".into())
}

fn tx_circuit_4_2(
input_notes_info: Vec<InputNoteInfo<NOTES_TREE_DEPTH>>,
output_notes_info: [OutputNoteInfo; OUTPUT_NOTES],
payload_hash: BlsScalar,
root: BlsScalar,
deposit: u64,
max_fee: u64,
sender_pk: PublicKey,
signatures: (SchnorrSignature, SchnorrSignature),
) -> (TxCircuit<NOTES_TREE_DEPTH, 4>, String) {
let input_notes_info: [InputNoteInfo<NOTES_TREE_DEPTH>; 4] =
input_notes_info
.try_into()
.expect("There should be exactly four inputs");
let circuit = TxCircuit {
input_notes_info,
output_notes_info,
payload_hash,
root,
deposit,
max_fee,
sender_pk,
signatures,
};
(circuit, "ExecuteCircuitFourTwo".into())
}
Loading

0 comments on commit f2ab923

Please sign in to comment.