|
|
@@ -1,17 +1,24 @@
|
|
|
-use rand::rngs::OsRng;
|
|
|
-use ff::Field;
|
|
|
use bellman::groth16;
|
|
|
use bls12_381::Bls12;
|
|
|
+use ff::Field;
|
|
|
+use group::Group;
|
|
|
+use rand::rngs::OsRng;
|
|
|
|
|
|
-use sapvi::crypto::{save_params, load_params, setup_mint_prover, create_mint_proof, verify_mint_proof, MintRevealedValues};
|
|
|
+use sapvi::crypto::{
|
|
|
+ create_mint_proof, load_params, save_params, setup_mint_prover, verify_mint_proof,
|
|
|
+ MintRevealedValues,
|
|
|
+};
|
|
|
|
|
|
struct TransactionBuilder {
|
|
|
clear_inputs: Vec<TransactionBuilderClearInputInfo>,
|
|
|
- outputs: Vec<TransactionBuilderOutputInfo>
|
|
|
+ outputs: Vec<TransactionBuilderOutputInfo>,
|
|
|
}
|
|
|
|
|
|
impl TransactionBuilder {
|
|
|
- fn compute_remainder_blind(clear_inputs: &Vec<TransactionClearInput>, output_blinds: &Vec<jubjub::Fr>) -> jubjub::Fr {
|
|
|
+ fn compute_remainder_blind(
|
|
|
+ clear_inputs: &Vec<TransactionClearInput>,
|
|
|
+ output_blinds: &Vec<jubjub::Fr>,
|
|
|
+ ) -> jubjub::Fr {
|
|
|
let mut lhs_total = jubjub::Fr::zero();
|
|
|
for input in clear_inputs {
|
|
|
lhs_total += input.valcom_blind;
|
|
|
@@ -22,7 +29,7 @@ impl TransactionBuilder {
|
|
|
rhs_total += output_blind;
|
|
|
}
|
|
|
|
|
|
- rhs_total - lhs_total
|
|
|
+ lhs_total - rhs_total
|
|
|
}
|
|
|
|
|
|
fn build(self, mint_params: &groth16::Parameters<Bls12>) -> Transaction {
|
|
|
@@ -31,7 +38,7 @@ impl TransactionBuilder {
|
|
|
let valcom_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
|
|
let clear_input = TransactionClearInput {
|
|
|
value: input.value,
|
|
|
- valcom_blind
|
|
|
+ valcom_blind,
|
|
|
};
|
|
|
clear_inputs.push(clear_input);
|
|
|
}
|
|
|
@@ -49,17 +56,24 @@ impl TransactionBuilder {
|
|
|
let serial: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
|
|
let coin_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
|
|
|
|
|
- let (mint_proof, revealed) = create_mint_proof(mint_params, output.value, valcom_blind, serial, coin_blind, output.public);
|
|
|
+ let (mint_proof, revealed) = create_mint_proof(
|
|
|
+ mint_params,
|
|
|
+ output.value,
|
|
|
+ valcom_blind,
|
|
|
+ serial,
|
|
|
+ coin_blind,
|
|
|
+ output.public,
|
|
|
+ );
|
|
|
let output = TransactionOutput {
|
|
|
mint_proof,
|
|
|
- revealed
|
|
|
+ revealed,
|
|
|
};
|
|
|
outputs.push(output);
|
|
|
}
|
|
|
|
|
|
Transaction {
|
|
|
clear_inputs,
|
|
|
- outputs
|
|
|
+ outputs,
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -73,32 +87,38 @@ struct TransactionBuilderOutputInfo {
|
|
|
public: jubjub::SubgroupPoint,
|
|
|
}
|
|
|
|
|
|
-impl TransactionBuilderOutputInfo {
|
|
|
- fn build() {
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
struct Transaction {
|
|
|
clear_inputs: Vec<TransactionClearInput>,
|
|
|
- outputs: Vec<TransactionOutput>
|
|
|
+ outputs: Vec<TransactionOutput>,
|
|
|
}
|
|
|
|
|
|
impl Transaction {
|
|
|
+ fn compute_value_commit(value: u64, blind: &jubjub::Fr) -> jubjub::SubgroupPoint {
|
|
|
+ let value_commit = (zcash_primitives::constants::VALUE_COMMITMENT_VALUE_GENERATOR
|
|
|
+ * jubjub::Fr::from(value))
|
|
|
+ + (zcash_primitives::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR * blind);
|
|
|
+ value_commit
|
|
|
+ }
|
|
|
+
|
|
|
fn verify(&self, pvk: &groth16::PreparedVerifyingKey<Bls12>) -> bool {
|
|
|
+ let mut valcom_total = jubjub::SubgroupPoint::identity();
|
|
|
for input in &self.clear_inputs {
|
|
|
+ valcom_total += Self::compute_value_commit(input.value, &input.valcom_blind);
|
|
|
}
|
|
|
for output in &self.outputs {
|
|
|
if !verify_mint_proof(pvk, &output.mint_proof, &output.revealed) {
|
|
|
return false;
|
|
|
}
|
|
|
+ valcom_total -= &output.revealed.value_commit;
|
|
|
}
|
|
|
- true
|
|
|
+
|
|
|
+ valcom_total == jubjub::SubgroupPoint::identity()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
struct TransactionClearInput {
|
|
|
value: u64,
|
|
|
- valcom_blind: jubjub::Fr
|
|
|
+ valcom_blind: jubjub::Fr,
|
|
|
}
|
|
|
|
|
|
struct TransactionOutput {
|
|
|
@@ -113,12 +133,13 @@ fn main() {
|
|
|
}
|
|
|
let (mint_params, mint_pvk) = load_params("mint.params").expect("params should load");
|
|
|
|
|
|
+ let public = jubjub::SubgroupPoint::random(&mut OsRng);
|
|
|
+
|
|
|
let builder = TransactionBuilder {
|
|
|
- clear_inputs: vec![],
|
|
|
- outputs: vec![]
|
|
|
+ clear_inputs: vec![TransactionBuilderClearInputInfo { value: 110 }],
|
|
|
+ outputs: vec![TransactionBuilderOutputInfo { value: 110, public }],
|
|
|
};
|
|
|
|
|
|
let tx = builder.build(&mint_params);
|
|
|
assert!(tx.verify(&mint_pvk));
|
|
|
}
|
|
|
-
|