mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
115 lines
3.7 KiB
Rust
115 lines
3.7 KiB
Rust
use halo2::dev::MockProver;
|
|
use halo2_gadgets::{
|
|
primitives,
|
|
primitives::poseidon::{ConstantLength, P128Pow5T3},
|
|
};
|
|
use pasta_curves::{
|
|
arithmetic::{CurveAffine, Field},
|
|
group::{Curve, Group},
|
|
pallas,
|
|
};
|
|
use rand::rngs::OsRng;
|
|
use std::{collections::HashMap, fs::File, time::Instant};
|
|
|
|
use darkfi::{
|
|
crypto::{
|
|
constants::OrchardFixedBases,
|
|
proof::{Proof, ProvingKey, VerifyingKey},
|
|
util::pedersen_commitment_u64,
|
|
},
|
|
util::serial::Decodable,
|
|
zk::vm,
|
|
Error,
|
|
};
|
|
|
|
fn main() -> std::result::Result<(), Error> {
|
|
// The number of rows in our circuit cannot exceed 2^k
|
|
let k: u32 = 11;
|
|
|
|
let start = Instant::now();
|
|
let file = File::open("../proof/mint.zk.bin")?;
|
|
let zkbin = vm::ZkBinary::decode(file)?;
|
|
for contract_name in zkbin.contracts.keys() {
|
|
println!("Loaded '{}' contract.", contract_name);
|
|
}
|
|
println!("Load time: [{:?}]", start.elapsed());
|
|
|
|
let contract = &zkbin.contracts["Mint"];
|
|
|
|
//contract.witness_base(...);
|
|
//contract.witness_base(...);
|
|
//contract.witness_base(...);
|
|
|
|
let pubkey = pallas::Point::random(&mut OsRng);
|
|
let coords = pubkey.to_affine().coordinates().unwrap();
|
|
|
|
let value = 110;
|
|
let asset = 1;
|
|
|
|
let value_blind = pallas::Scalar::random(&mut OsRng);
|
|
let asset_blind = pallas::Scalar::random(&mut OsRng);
|
|
|
|
let serial = pallas::Base::random(&mut OsRng);
|
|
let coin_blind = pallas::Base::random(&mut OsRng);
|
|
|
|
let mut coin = pallas::Base::zero();
|
|
|
|
let messages = [
|
|
[*coords.x(), *coords.y()],
|
|
[pallas::Base::from(value), pallas::Base::from(asset)],
|
|
[serial, coin_blind],
|
|
];
|
|
|
|
for msg in messages.iter() {
|
|
coin += primitives::poseidon::Hash::init(P128Pow5T3, ConstantLength::<2>).hash(*msg);
|
|
}
|
|
|
|
let _coin2 = primitives::poseidon::Hash::init(P128Pow5T3, ConstantLength::<2>)
|
|
.hash([*coords.x(), *coords.y()]);
|
|
|
|
let value_commit = pedersen_commitment_u64(value, value_blind);
|
|
let value_coords = value_commit.to_affine().coordinates().unwrap();
|
|
|
|
let asset_commit = pedersen_commitment_u64(asset, asset_blind);
|
|
let asset_coords = asset_commit.to_affine().coordinates().unwrap();
|
|
|
|
let public_inputs =
|
|
vec![coin, *value_coords.x(), *value_coords.y(), *asset_coords.x(), *asset_coords.y()];
|
|
|
|
let mut const_fixed_points = HashMap::new();
|
|
const_fixed_points.insert("VALUE_COMMIT_VALUE".to_string(), OrchardFixedBases::ValueCommitV);
|
|
const_fixed_points.insert("VALUE_COMMIT_RANDOM".to_string(), OrchardFixedBases::ValueCommitR);
|
|
|
|
let mut circuit = vm::ZkCircuit::new(const_fixed_points, &zkbin.constants, contract);
|
|
let empty_circuit = circuit.clone();
|
|
|
|
circuit.witness_base("pub_x", *coords.x())?;
|
|
circuit.witness_base("pub_y", *coords.y())?;
|
|
circuit.witness_base("value", pallas::Base::from(value))?;
|
|
circuit.witness_base("asset", pallas::Base::from(asset))?;
|
|
circuit.witness_base("serial", serial)?;
|
|
circuit.witness_base("coin_blind", coin_blind)?;
|
|
circuit.witness_scalar("value_blind", value_blind)?;
|
|
circuit.witness_scalar("asset_blind", asset_blind)?;
|
|
|
|
// Valid MockProver
|
|
let prover = MockProver::run(k, &circuit, vec![public_inputs.clone()]).unwrap();
|
|
assert_eq!(prover.verify(), Ok(()));
|
|
|
|
// Actual ZK proof
|
|
let start = Instant::now();
|
|
let vk = VerifyingKey::build(k, empty_circuit.clone());
|
|
let pk = ProvingKey::build(k, empty_circuit.clone());
|
|
println!("\nSetup: [{:?}]", start.elapsed());
|
|
|
|
let start = Instant::now();
|
|
let proof = Proof::create(&pk, &[circuit], &public_inputs).unwrap();
|
|
println!("Prove: [{:?}]", start.elapsed());
|
|
|
|
let start = Instant::now();
|
|
assert!(proof.verify(&vk, &public_inputs).is_ok());
|
|
println!("Verify: [{:?}]", start.elapsed());
|
|
|
|
Ok(())
|
|
}
|