mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
make_mint_proof() / verify_mint_proof()
This commit is contained in:
@@ -5,71 +5,7 @@ use bls12_381::Bls12;
|
||||
use ff::Field;
|
||||
use group::{Curve, Group, GroupEncoding};
|
||||
|
||||
use sapvi::circuit::mint_contract::MintContract;
|
||||
|
||||
struct MintRevealedValues {
|
||||
value_commit: jubjub::SubgroupPoint,
|
||||
coin: [u8; 32],
|
||||
}
|
||||
|
||||
impl MintRevealedValues {
|
||||
fn compute(
|
||||
value: u64,
|
||||
randomness_value: &jubjub::Fr,
|
||||
serial: &jubjub::Fr,
|
||||
randomness_coin: &jubjub::Fr,
|
||||
public: &jubjub::SubgroupPoint,
|
||||
) -> Self {
|
||||
let value_commit = (zcash_primitives::constants::VALUE_COMMITMENT_VALUE_GENERATOR
|
||||
* jubjub::Fr::from(value))
|
||||
+ (zcash_primitives::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR
|
||||
* randomness_value);
|
||||
|
||||
let mut coin = [0; 32];
|
||||
coin.copy_from_slice(
|
||||
Blake2sParams::new()
|
||||
.hash_length(32)
|
||||
.personal(zcash_primitives::constants::CRH_IVK_PERSONALIZATION)
|
||||
.to_state()
|
||||
.update(&public.to_bytes())
|
||||
.update(&value.to_le_bytes())
|
||||
.update(&serial.to_bytes())
|
||||
.update(&randomness_coin.to_bytes())
|
||||
.finalize()
|
||||
.as_bytes(),
|
||||
);
|
||||
|
||||
MintRevealedValues { value_commit, coin }
|
||||
}
|
||||
|
||||
fn make_outputs(&self) -> [bls12_381::Scalar; 4] {
|
||||
let mut public_input = [bls12_381::Scalar::zero(); 4];
|
||||
|
||||
{
|
||||
let result = jubjub::ExtendedPoint::from(self.value_commit);
|
||||
let affine = result.to_affine();
|
||||
//let (u, v) = (affine.get_u(), affine.get_v());
|
||||
let u = affine.get_u();
|
||||
let v = affine.get_v();
|
||||
public_input[0] = u;
|
||||
public_input[1] = v;
|
||||
}
|
||||
|
||||
{
|
||||
// Pack the hash as inputs for proof verification.
|
||||
let hash = multipack::bytes_to_bits_le(&self.coin);
|
||||
let hash = multipack::compute_multipacking(&hash);
|
||||
|
||||
// There are 2 chunks for a blake hash
|
||||
assert_eq!(hash.len(), 2);
|
||||
|
||||
public_input[2] = hash[0];
|
||||
public_input[3] = hash[1];
|
||||
}
|
||||
|
||||
public_input
|
||||
}
|
||||
}
|
||||
use sapvi::crypto::{setup_mint_prover, create_mint_proof, verify_mint_proof};
|
||||
|
||||
fn main() {
|
||||
use rand::rngs::OsRng;
|
||||
@@ -83,80 +19,10 @@ fn main() {
|
||||
let serial: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
||||
let randomness_coin: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
|
||||
|
||||
let revealed =
|
||||
MintRevealedValues::compute(value, &randomness_value, &serial, &randomness_coin, &public);
|
||||
let (params, pvk) = setup_mint_prover();
|
||||
|
||||
println!("Making random params...");
|
||||
let start = Instant::now();
|
||||
let params = {
|
||||
let c = MintContract {
|
||||
value: None,
|
||||
randomness_value: None,
|
||||
serial: None,
|
||||
randomness_coin: None,
|
||||
public: None,
|
||||
};
|
||||
groth16::generate_random_parameters::<Bls12, _, _>(c, &mut OsRng).unwrap()
|
||||
};
|
||||
let pvk = groth16::prepare_verifying_key(¶ms.vk);
|
||||
println!("Setup: [{:?}]", start.elapsed());
|
||||
let (proof, revealed) = create_mint_proof(¶ms, value, randomness_value, serial, randomness_coin,
|
||||
public);
|
||||
|
||||
let c = MintContract {
|
||||
value: Some(value),
|
||||
randomness_value: Some(randomness_value),
|
||||
serial: Some(serial),
|
||||
randomness_coin: Some(randomness_coin),
|
||||
public: Some(public),
|
||||
};
|
||||
|
||||
let start = Instant::now();
|
||||
let proof = groth16::create_random_proof(c, ¶ms, &mut OsRng).unwrap();
|
||||
println!("Prove: [{:?}]", start.elapsed());
|
||||
|
||||
/*
|
||||
let mut public_input = [bls12_381::Scalar::zero(); 4];
|
||||
{
|
||||
let result = jubjub::ExtendedPoint::from(public);
|
||||
let affine = result.to_affine();
|
||||
//let (u, v) = (affine.get_u(), affine.get_v());
|
||||
let u = affine.get_u();
|
||||
let v = affine.get_v();
|
||||
public_input[0] = u;
|
||||
public_input[1] = v;
|
||||
}
|
||||
|
||||
{
|
||||
const CRH_IVK_PERSONALIZATION: &[u8; 8] = b"Zcashivk";
|
||||
let preimage = [42; 80];
|
||||
let hash_result = {
|
||||
let mut hash = [0; 32];
|
||||
hash.copy_from_slice(
|
||||
Blake2sParams::new()
|
||||
.hash_length(32)
|
||||
.personal(CRH_IVK_PERSONALIZATION)
|
||||
.to_state()
|
||||
.update(&ak.to_bytes())
|
||||
.finalize()
|
||||
.as_bytes()
|
||||
);
|
||||
hash
|
||||
};
|
||||
|
||||
// Pack the hash as inputs for proof verification.
|
||||
let hash = multipack::bytes_to_bits_le(&hash_result);
|
||||
let hash = multipack::compute_multipacking(&hash);
|
||||
|
||||
// There are 2 chunks for a blake hash
|
||||
assert_eq!(hash.len(), 2);
|
||||
|
||||
public_input[2] = hash[0];
|
||||
public_input[3] = hash[1];
|
||||
}
|
||||
*/
|
||||
|
||||
let public_input = revealed.make_outputs();
|
||||
|
||||
let start = Instant::now();
|
||||
assert!(groth16::verify_proof(&pvk, &proof, &public_input).is_ok());
|
||||
println!("Verify: [{:?}]", start.elapsed());
|
||||
assert!(verify_mint_proof(&pvk, &proof, &revealed));
|
||||
}
|
||||
|
||||
4
src/crypto/mod.rs
Normal file
4
src/crypto/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
pub mod payment_proof;
|
||||
|
||||
pub use payment_proof::{setup_mint_prover, create_mint_proof, verify_mint_proof};
|
||||
|
||||
132
src/crypto/payment_proof.rs
Normal file
132
src/crypto/payment_proof.rs
Normal file
@@ -0,0 +1,132 @@
|
||||
use rand::rngs::OsRng;
|
||||
use std::time::Instant;
|
||||
use bellman::gadgets::multipack;
|
||||
use bellman::groth16;
|
||||
use blake2s_simd::Params as Blake2sParams;
|
||||
use bls12_381::Bls12;
|
||||
use ff::Field;
|
||||
use group::{Curve, Group, GroupEncoding};
|
||||
|
||||
use crate::circuit::mint_contract::MintContract;
|
||||
|
||||
pub struct MintRevealedValues {
|
||||
pub value_commit: jubjub::SubgroupPoint,
|
||||
pub coin: [u8; 32],
|
||||
}
|
||||
|
||||
impl MintRevealedValues {
|
||||
fn compute(
|
||||
value: u64,
|
||||
randomness_value: &jubjub::Fr,
|
||||
serial: &jubjub::Fr,
|
||||
randomness_coin: &jubjub::Fr,
|
||||
public: &jubjub::SubgroupPoint,
|
||||
) -> Self {
|
||||
let value_commit = (zcash_primitives::constants::VALUE_COMMITMENT_VALUE_GENERATOR
|
||||
* jubjub::Fr::from(value))
|
||||
+ (zcash_primitives::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR
|
||||
* randomness_value);
|
||||
|
||||
let mut coin = [0; 32];
|
||||
coin.copy_from_slice(
|
||||
Blake2sParams::new()
|
||||
.hash_length(32)
|
||||
.personal(zcash_primitives::constants::CRH_IVK_PERSONALIZATION)
|
||||
.to_state()
|
||||
.update(&public.to_bytes())
|
||||
.update(&value.to_le_bytes())
|
||||
.update(&serial.to_bytes())
|
||||
.update(&randomness_coin.to_bytes())
|
||||
.finalize()
|
||||
.as_bytes(),
|
||||
);
|
||||
|
||||
MintRevealedValues { value_commit, coin }
|
||||
}
|
||||
|
||||
fn make_outputs(&self) -> [bls12_381::Scalar; 4] {
|
||||
let mut public_input = [bls12_381::Scalar::zero(); 4];
|
||||
|
||||
{
|
||||
let result = jubjub::ExtendedPoint::from(self.value_commit);
|
||||
let affine = result.to_affine();
|
||||
//let (u, v) = (affine.get_u(), affine.get_v());
|
||||
let u = affine.get_u();
|
||||
let v = affine.get_v();
|
||||
public_input[0] = u;
|
||||
public_input[1] = v;
|
||||
}
|
||||
|
||||
{
|
||||
// Pack the hash as inputs for proof verification.
|
||||
let hash = multipack::bytes_to_bits_le(&self.coin);
|
||||
let hash = multipack::compute_multipacking(&hash);
|
||||
|
||||
// There are 2 chunks for a blake hash
|
||||
assert_eq!(hash.len(), 2);
|
||||
|
||||
public_input[2] = hash[0];
|
||||
public_input[3] = hash[1];
|
||||
}
|
||||
|
||||
public_input
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup_mint_prover() -> (groth16::Parameters<Bls12>, groth16::PreparedVerifyingKey<Bls12>) {
|
||||
println!("Making random params...");
|
||||
let start = Instant::now();
|
||||
let params = {
|
||||
let c = MintContract {
|
||||
value: None,
|
||||
randomness_value: None,
|
||||
serial: None,
|
||||
randomness_coin: None,
|
||||
public: None,
|
||||
};
|
||||
groth16::generate_random_parameters::<Bls12, _, _>(c, &mut OsRng).unwrap()
|
||||
};
|
||||
let pvk = groth16::prepare_verifying_key(¶ms.vk);
|
||||
println!("Setup: [{:?}]", start.elapsed());
|
||||
(params, pvk)
|
||||
}
|
||||
|
||||
pub fn create_mint_proof(
|
||||
params: &groth16::Parameters<Bls12>,
|
||||
value: u64,
|
||||
randomness_value: jubjub::Fr,
|
||||
serial: jubjub::Fr,
|
||||
randomness_coin: jubjub::Fr,
|
||||
public: jubjub::SubgroupPoint
|
||||
) -> (groth16::Proof<Bls12>, MintRevealedValues) {
|
||||
let revealed =
|
||||
MintRevealedValues::compute(value, &randomness_value, &serial, &randomness_coin, &public);
|
||||
|
||||
let c = MintContract {
|
||||
value: Some(value),
|
||||
randomness_value: Some(randomness_value),
|
||||
serial: Some(serial),
|
||||
randomness_coin: Some(randomness_coin),
|
||||
public: Some(public),
|
||||
};
|
||||
|
||||
let start = Instant::now();
|
||||
let proof = groth16::create_random_proof(c, params, &mut OsRng).unwrap();
|
||||
println!("Prove: [{:?}]", start.elapsed());
|
||||
|
||||
(proof, revealed)
|
||||
}
|
||||
|
||||
pub fn verify_mint_proof(
|
||||
pvk: &groth16::PreparedVerifyingKey<Bls12>,
|
||||
proof: &groth16::Proof<Bls12>,
|
||||
revealed: &MintRevealedValues
|
||||
) -> bool {
|
||||
let public_input = revealed.make_outputs();
|
||||
|
||||
let start = Instant::now();
|
||||
let result = groth16::verify_proof(pvk, proof, &public_input).is_ok();
|
||||
println!("Verify: [{:?}]", start.elapsed());
|
||||
result
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use std::collections::{HashMap, HashSet};
|
||||
pub mod async_serial;
|
||||
pub mod bls_extensions;
|
||||
pub mod circuit;
|
||||
pub mod crypto;
|
||||
pub mod endian;
|
||||
pub mod error;
|
||||
pub mod gfx;
|
||||
|
||||
Reference in New Issue
Block a user