mirror of https://github.com/vacp2p/zerokit.git
feat: Remove unsupported poseidon-tornado example
Currently a basic PoC, and a better starting point here is probably RLN package. Can still be looked at as an example where relevant.
This commit is contained in:
parent
2455bea922
commit
f5897eb752
|
@ -1,7 +1,6 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"multiplier",
|
"multiplier",
|
||||||
"poseidon-tornado",
|
|
||||||
"semaphore",
|
"semaphore",
|
||||||
"rln",
|
"rln",
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "poseidon-tornado"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
|
|
||||||
# WASM operations
|
|
||||||
# wasmer = { version = "2.0" }
|
|
||||||
# fnv = { version = "1.0.3", default-features = false }
|
|
||||||
# num = { version = "0.4.0" }
|
|
||||||
# num-traits = { version = "0.2.0", default-features = false }
|
|
||||||
num-bigint = { version = "0.4", default-features = false, features = ["rand"] }
|
|
||||||
|
|
||||||
# ZKP Generation
|
|
||||||
ark-ec = { version = "0.3.0", default-features = false, features = ["parallel"] }
|
|
||||||
# ark-ff = { version = "0.3.0", default-features = false, features = ["parallel", "asm"] }
|
|
||||||
ark-std = { version = "0.3.0", default-features = false, features = ["parallel"] }
|
|
||||||
ark-bn254 = { version = "0.3.0" }
|
|
||||||
ark-groth16 = { git = "https://github.com/arkworks-rs/groth16", rev = "765817f", features = ["parallel"] }
|
|
||||||
# ark-poly = { version = "^0.3.0", default-features = false, features = ["parallel"] }
|
|
||||||
#ark-relations = { version = "0.3.0", default-features = false, path = "../../../arkworks-rs/snark/relations", features = [ "std" ] }
|
|
||||||
ark-relations = { version = "0.3.0", default-features = false, features = [ "std" ] }
|
|
||||||
ark-serialize = { version = "0.3.0", default-features = false }
|
|
||||||
|
|
||||||
ark-circom = { git = "https://github.com/gakonst/ark-circom", features = ["circom-2"] }
|
|
||||||
#ark-circom = { features = ["circom-2"], path = "../../../gakonst/ark-circom" }
|
|
||||||
|
|
||||||
# error handling
|
|
||||||
# thiserror = "1.0.26"
|
|
||||||
color-eyre = "0.5"
|
|
||||||
|
|
||||||
# decoding of data
|
|
||||||
# hex = "0.4.3"
|
|
||||||
# byteorder = "1.4.3"
|
|
||||||
|
|
||||||
# tracing
|
|
||||||
tracing = "0.1"
|
|
||||||
tracing-subscriber = "0.2"
|
|
||||||
|
|
||||||
# json
|
|
||||||
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
|
|
||||||
serde_json = "1.0.48"
|
|
|
@ -1,15 +0,0 @@
|
||||||
# Poseidon-Tornado wrapper
|
|
||||||
|
|
||||||
`cargo run` should produce a verified proof:
|
|
||||||
|
|
||||||
```
|
|
||||||
Proof: Proof { a: GroupAffine { x: Fp256(BigInteger256([16555594431582187512, 832858929541131044, 7422422334369615701, 1990800952833984962])), y: Fp256(BigInteger256([1644467721434014430, 4218632298063479714, 6653830397826554436, 2216376957148540579])), infinity: false }, b: GroupAffine { x: QuadExtField { c0: Fp256(BigInteger256([9273689851960082102, 5457182187245793764, 4494028383047773695, 687780230949438867])), c1: Fp256(BigInteger256([12997553955801245812, 6091827827641861199, 16980634323548746344, 1216645975304436003])) }, y: QuadExtField { c0: Fp256(BigInteger256([7010712503187563018, 15102268349222123061, 14879829328512306542, 2444470763551517194])), c1: Fp256(BigInteger256([4642236806924837044, 921676552384439839, 10863230380949696869, 2028214605332280376])) }, infinity: false }, c: GroupAffine { x: Fp256(BigInteger256([12984346165775776486, 2185711386225701726, 2181293997313656330, 2510009027820905919])), y: Fp256(BigInteger256([7404331360498713396, 3383561268178375173, 1263588809399542185, 3239606895069814303])), infinity: false } }
|
|
||||||
```
|
|
||||||
|
|
||||||
## poseidon-tornado
|
|
||||||
|
|
||||||
See:
|
|
||||||
https://github.com/ChihChengLiang/poseidon-tornado
|
|
||||||
|
|
||||||
Some issues with mixing BigNumber radix 10 and 16 etc. The input currently used was generated with:
|
|
||||||
https://github.com/oskarth/poseidon-tornado/commit/db64ad09fdb16ad310ba395fc73520f87ad7d344
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,27 +0,0 @@
|
||||||
{"root":"0x11cd2b4d61ad61dee506cac59c657e269cbbf5fbd548cd2f1d41dedaf4293748",
|
|
||||||
"nullifierHash":"0x285edfd6d2499ea9eea742d4ece6a4668efbbf93b4c2194d9e086997ad59aa4f",
|
|
||||||
"recipient":"0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
|
|
||||||
"relayer":"0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
|
|
||||||
"fee":0,
|
|
||||||
"nullifier":"34284017061184348684424679404576688",
|
|
||||||
"pathElements":["21663839004416932945382355908790599225266501822907911457504978515578255421292",
|
|
||||||
"0x13e37f2d6cb86c78ccc1788607c2b199788c6bb0a615a21f2e7a8e88384222f8",
|
|
||||||
"0x217126fa352c326896e8c2803eec8fd63ad50cf65edfef27a41a9e32dc622765",
|
|
||||||
"0x0e28a61a9b3e91007d5a9e3ada18e1b24d6d230c618388ee5df34cacd7397eee",
|
|
||||||
"0x27953447a6979839536badc5425ed15fadb0e292e9bc36f92f0aa5cfa5013587",
|
|
||||||
"0x194191edbfb91d10f6a7afd315f33095410c7801c47175c2df6dc2cce0e3affc",
|
|
||||||
"0x1733dece17d71190516dbaf1927936fa643dc7079fc0cc731de9d6845a47741f",
|
|
||||||
"0x267855a7dc75db39d81d17f95d0a7aa572bf5ae19f4db0e84221d2b2ef999219",
|
|
||||||
"0x1184e11836b4c36ad8238a340ecc0985eeba665327e33e9b0e3641027c27620d",
|
|
||||||
"0x0702ab83a135d7f55350ab1bfaa90babd8fc1d2b3e6a7215381a7b2213d6c5ce",
|
|
||||||
"0x2eecc0de814cfd8c57ce882babb2e30d1da56621aef7a47f3291cffeaec26ad7",
|
|
||||||
"0x280bc02145c155d5833585b6c7b08501055157dd30ce005319621dc462d33b47",
|
|
||||||
"0x045132221d1fa0a7f4aed8acd2cbec1e2189b7732ccb2ec272b9c60f0d5afc5b",
|
|
||||||
"0x27f427ccbf58a44b1270abbe4eda6ba53bd6ac4d88cf1e00a13c4371ce71d366",
|
|
||||||
"0x1617eaae5064f26e8f8a6493ae92bfded7fde71b65df1ca6d5dcec0df70b2cef",
|
|
||||||
"0x20c6b400d0ea1b15435703c31c31ee63ad7ba5c8da66cec2796feacea575abca",
|
|
||||||
"0x09589ddb438723f53a8e57bdada7c5f8ed67e8fece3889a73618732965645eec",
|
|
||||||
"0x0064b6a738a5ff537db7b220f3394f0ecbd35bfd355c5425dc1166bf3236079b",
|
|
||||||
"0x095de56281b1d5055e897c3574ff790d5ee81dbc5df784ad2d67795e557c9e9f",
|
|
||||||
"0x11cf2e2887aa21963a6ec14289183efe4d4c60f14ecd3d6fe0beebdf855a9b63"],
|
|
||||||
"pathIndices":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}
|
|
|
@ -1,77 +0,0 @@
|
||||||
use crate::public::PoseidonTornado;
|
|
||||||
use std::slice;
|
|
||||||
|
|
||||||
/// Buffer struct is taken from
|
|
||||||
/// https://github.com/celo-org/celo-threshold-bls-rs/blob/master/crates/threshold-bls-ffi/src/ffi.rs
|
|
||||||
///
|
|
||||||
/// Also heavily inspired by https://github.com/kilic/rln/blob/master/src/ffi.rs
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
|
||||||
pub struct Buffer {
|
|
||||||
pub ptr: *const u8,
|
|
||||||
pub len: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&[u8]> for Buffer {
|
|
||||||
fn from(src: &[u8]) -> Self {
|
|
||||||
Self {
|
|
||||||
ptr: &src[0] as *const u8,
|
|
||||||
len: src.len(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&Buffer> for &'a [u8] {
|
|
||||||
fn from(src: &Buffer) -> &'a [u8] {
|
|
||||||
unsafe { slice::from_raw_parts(src.ptr, src.len) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn new_circuit(ctx: *mut *mut PoseidonTornado) -> bool {
|
|
||||||
println!("multiplier ffi: new");
|
|
||||||
let mul = PoseidonTornado::new();
|
|
||||||
|
|
||||||
unsafe { *ctx = Box::into_raw(Box::new(mul)) };
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn prove(ctx: *const PoseidonTornado, output_buffer: *mut Buffer) -> bool {
|
|
||||||
println!("multiplier ffi: prove");
|
|
||||||
let mul = unsafe { &*ctx };
|
|
||||||
let mut output_data: Vec<u8> = Vec::new();
|
|
||||||
|
|
||||||
match mul.prove(&mut output_data) {
|
|
||||||
Ok(proof_data) => proof_data,
|
|
||||||
Err(_) => return false,
|
|
||||||
};
|
|
||||||
unsafe { *output_buffer = Buffer::from(&output_data[..]) };
|
|
||||||
std::mem::forget(output_data);
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn verify(
|
|
||||||
ctx: *const PoseidonTornado,
|
|
||||||
proof_buffer: *const Buffer,
|
|
||||||
result_ptr: *mut u32,
|
|
||||||
) -> bool {
|
|
||||||
println!("multiplier ffi: verify");
|
|
||||||
let mul = unsafe { &*ctx };
|
|
||||||
let proof_data = <&[u8]>::from(unsafe { &*proof_buffer });
|
|
||||||
if match mul.verify(proof_data) {
|
|
||||||
Ok(verified) => verified,
|
|
||||||
Err(_) => return false,
|
|
||||||
} {
|
|
||||||
unsafe { *result_ptr = 0 };
|
|
||||||
} else {
|
|
||||||
unsafe { *result_ptr = 1 };
|
|
||||||
};
|
|
||||||
true
|
|
||||||
}
|
|
|
@ -1,2 +0,0 @@
|
||||||
pub mod ffi;
|
|
||||||
pub mod public;
|
|
|
@ -1,176 +0,0 @@
|
||||||
use ark_circom::{CircomBuilder, CircomConfig};
|
|
||||||
use ark_std::rand::thread_rng;
|
|
||||||
use color_eyre::Result;
|
|
||||||
|
|
||||||
use ark_bn254::Bn254;
|
|
||||||
use ark_groth16::{
|
|
||||||
create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof,
|
|
||||||
};
|
|
||||||
|
|
||||||
use num_bigint::BigInt;
|
|
||||||
|
|
||||||
// Tracing
|
|
||||||
use ark_relations::r1cs::{ConstraintLayer, ConstraintTrace, TracingMode};
|
|
||||||
//use tracing::{event, span, Level};
|
|
||||||
use tracing_subscriber::layer::SubscriberExt;
|
|
||||||
|
|
||||||
// JSON
|
|
||||||
use serde::Deserialize;
|
|
||||||
//use serde_json;
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
struct WitnessInput {
|
|
||||||
root: String,
|
|
||||||
nullifier_hash: String,
|
|
||||||
recipient: String,
|
|
||||||
relayer: String,
|
|
||||||
//fee: String,
|
|
||||||
fee: i32,
|
|
||||||
nullifier: String,
|
|
||||||
path_elements: Vec<String>,
|
|
||||||
path_indices: Vec<i32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Poseidon-tornado
|
|
||||||
fn groth16_proof_example() -> Result<()> {
|
|
||||||
// Tracing to help with debugging
|
|
||||||
let mut layer = ConstraintLayer::default();
|
|
||||||
layer.mode = TracingMode::OnlyConstraints;
|
|
||||||
let subscriber = tracing_subscriber::Registry::default().with(layer);
|
|
||||||
let _guard = tracing::subscriber::set_default(subscriber);
|
|
||||||
|
|
||||||
let trace = ConstraintTrace::capture();
|
|
||||||
println!("Trace is: {:?}", trace);
|
|
||||||
|
|
||||||
let cfg = CircomConfig::<Bn254>::new("./resources/withdraw.wasm", "./resources/withdraw.r1cs")?;
|
|
||||||
|
|
||||||
// Test
|
|
||||||
let trace = ConstraintTrace::capture();
|
|
||||||
println!("Trace is: {:?}", trace);
|
|
||||||
|
|
||||||
// From poseidon-tornado JSON witness
|
|
||||||
// Input generated with https://github.com/oskarth/poseidon-tornado/commit/db64ad09fdb16ad310ba395fc73520f87ad7d344
|
|
||||||
// With nullifier set to 0
|
|
||||||
let input_json_str = r#"
|
|
||||||
{
|
|
||||||
"root": "17777834528943231885798890273562835075271930126129561600279382876922601684948",
|
|
||||||
"nullifierHash": "8506691148847834795277894036216352001616813487121834991716343668271924769133",
|
|
||||||
"recipient": "344073830386746567427978432078835137280280269756",
|
|
||||||
"relayer": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
|
|
||||||
"fee": 0,
|
|
||||||
"nullifier": "0",
|
|
||||||
"pathElements": [
|
|
||||||
"21663839004416932945382355908790599225266501822907911457504978515578255421292",
|
|
||||||
"8995896153219992062710898675021891003404871425075198597897889079729967997688",
|
|
||||||
"15126246733515326086631621937388047923581111613947275249184377560170833782629",
|
|
||||||
"6404200169958188928270149728908101781856690902670925316782889389790091378414",
|
|
||||||
"17903822129909817717122288064678017104411031693253675943446999432073303897479",
|
|
||||||
"11423673436710698439362231088473903829893023095386581732682931796661338615804",
|
|
||||||
"10494842461667482273766668782207799332467432901404302674544629280016211342367",
|
|
||||||
"17400501067905286947724900644309270241576392716005448085614420258732805558809",
|
|
||||||
"7924095784194248701091699324325620647610183513781643345297447650838438175245",
|
|
||||||
"3170907381568164996048434627595073437765146540390351066869729445199396390350",
|
|
||||||
"21224698076141654110749227566074000819685780865045032659353546489395159395031",
|
|
||||||
"18113275293366123216771546175954550524914431153457717566389477633419482708807",
|
|
||||||
"1952712013602708178570747052202251655221844679392349715649271315658568301659",
|
|
||||||
"18071586466641072671725723167170872238457150900980957071031663421538421560166",
|
|
||||||
"9993139859464142980356243228522899168680191731482953959604385644693217291503",
|
|
||||||
"14825089209834329031146290681677780462512538924857394026404638992248153156554",
|
|
||||||
"4227387664466178643628175945231814400524887119677268757709033164980107894508",
|
|
||||||
"177945332589823419436506514313470826662740485666603469953512016396504401819",
|
|
||||||
"4236715569920417171293504597566056255435509785944924295068274306682611080863",
|
|
||||||
"8055374341341620501424923482910636721817757020788836089492629714380498049891"
|
|
||||||
],
|
|
||||||
"pathIndices": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}
|
|
||||||
"#;
|
|
||||||
|
|
||||||
let witness_input: WitnessInput =
|
|
||||||
serde_json::from_str(input_json_str).expect("JSON was not well-formatted");
|
|
||||||
|
|
||||||
println!("Witness input JSON: {:?}", witness_input);
|
|
||||||
|
|
||||||
let mut builder = CircomBuilder::new(cfg);
|
|
||||||
|
|
||||||
builder.push_input(
|
|
||||||
"root",
|
|
||||||
BigInt::parse_bytes(witness_input.root.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.push_input(
|
|
||||||
"nullifierHash",
|
|
||||||
BigInt::parse_bytes(witness_input.nullifier_hash.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.push_input(
|
|
||||||
"recipient",
|
|
||||||
BigInt::parse_bytes(witness_input.recipient.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.push_input(
|
|
||||||
"relayer",
|
|
||||||
BigInt::parse_bytes(
|
|
||||||
witness_input.relayer.strip_prefix("0x").unwrap().as_bytes(),
|
|
||||||
16,
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// XXX
|
|
||||||
builder.push_input(
|
|
||||||
"fee",
|
|
||||||
witness_input.fee, //BigInt::parse_bytes(witness_input.fee.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.push_input(
|
|
||||||
"nullifier",
|
|
||||||
BigInt::parse_bytes(witness_input.nullifier.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
for v in witness_input.path_elements.iter() {
|
|
||||||
builder.push_input(
|
|
||||||
"pathElements",
|
|
||||||
BigInt::parse_bytes(v.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for v in witness_input.path_indices.iter() {
|
|
||||||
builder.push_input("pathIndices", BigInt::from(*v));
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("Builder input:\n {:#?}", builder.inputs);
|
|
||||||
|
|
||||||
// create an empty instance for setting it up
|
|
||||||
let circom = builder.setup();
|
|
||||||
|
|
||||||
let mut rng = thread_rng();
|
|
||||||
let params = generate_random_parameters::<Bn254, _, _>(circom, &mut rng)?;
|
|
||||||
|
|
||||||
let circom = builder.build()?;
|
|
||||||
|
|
||||||
let inputs = circom.get_public_inputs().unwrap();
|
|
||||||
|
|
||||||
println!("Public inputs {:#?} ", inputs);
|
|
||||||
|
|
||||||
let proof = create_random_proof(circom, ¶ms, &mut rng)?;
|
|
||||||
|
|
||||||
println!("Proof: {:?}", proof);
|
|
||||||
|
|
||||||
let pvk = prepare_verifying_key(¶ms.vk);
|
|
||||||
|
|
||||||
let verified = verify_proof(&pvk, &proof, &inputs)?;
|
|
||||||
|
|
||||||
assert!(verified);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
println!("tornado-poseidon example proof");
|
|
||||||
|
|
||||||
// Tornado-core
|
|
||||||
match groth16_proof_example() {
|
|
||||||
Ok(_) => println!("Success"),
|
|
||||||
Err(_) => println!("Error"),
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,204 +0,0 @@
|
||||||
use ark_circom::{CircomBuilder, CircomCircuit, CircomConfig};
|
|
||||||
use ark_std::rand::thread_rng;
|
|
||||||
|
|
||||||
use ark_bn254::Bn254;
|
|
||||||
use ark_groth16::{
|
|
||||||
create_random_proof as prove, generate_random_parameters, prepare_verifying_key, verify_proof,
|
|
||||||
Proof, ProvingKey,
|
|
||||||
};
|
|
||||||
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
|
|
||||||
// , SerializationError};
|
|
||||||
|
|
||||||
use num_bigint::BigInt;
|
|
||||||
|
|
||||||
use std::io::{self, Read, Write};
|
|
||||||
|
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
pub struct PoseidonTornado {
|
|
||||||
circom: CircomCircuit<Bn254>,
|
|
||||||
params: ProvingKey<Bn254>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
struct WitnessInput {
|
|
||||||
root: String,
|
|
||||||
nullifier_hash: String,
|
|
||||||
recipient: String,
|
|
||||||
relayer: String,
|
|
||||||
//fee: String,
|
|
||||||
fee: i32,
|
|
||||||
nullifier: String,
|
|
||||||
path_elements: Vec<String>,
|
|
||||||
path_indices: Vec<i32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO This should use poseidon-tornado stuff in main.rs for proper example
|
|
||||||
|
|
||||||
impl PoseidonTornado {
|
|
||||||
// TODO Break this apart here
|
|
||||||
pub fn new() -> PoseidonTornado {
|
|
||||||
let cfg =
|
|
||||||
CircomConfig::<Bn254>::new("./resources/withdraw.wasm", "./resources/withdraw.r1cs")
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// From poseidon-tornado JSON witness
|
|
||||||
// Input generated with https://github.com/oskarth/poseidon-tornado/commit/db64ad09fdb16ad310ba395fc73520f87ad7d344
|
|
||||||
// With nullifier set to 0
|
|
||||||
let input_json_str = r#"
|
|
||||||
{
|
|
||||||
"root": "17777834528943231885798890273562835075271930126129561600279382876922601684948",
|
|
||||||
"nullifierHash": "8506691148847834795277894036216352001616813487121834991716343668271924769133",
|
|
||||||
"recipient": "344073830386746567427978432078835137280280269756",
|
|
||||||
"relayer": "0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
|
|
||||||
"fee": 0,
|
|
||||||
"nullifier": "0",
|
|
||||||
"pathElements": [
|
|
||||||
"21663839004416932945382355908790599225266501822907911457504978515578255421292",
|
|
||||||
"8995896153219992062710898675021891003404871425075198597897889079729967997688",
|
|
||||||
"15126246733515326086631621937388047923581111613947275249184377560170833782629",
|
|
||||||
"6404200169958188928270149728908101781856690902670925316782889389790091378414",
|
|
||||||
"17903822129909817717122288064678017104411031693253675943446999432073303897479",
|
|
||||||
"11423673436710698439362231088473903829893023095386581732682931796661338615804",
|
|
||||||
"10494842461667482273766668782207799332467432901404302674544629280016211342367",
|
|
||||||
"17400501067905286947724900644309270241576392716005448085614420258732805558809",
|
|
||||||
"7924095784194248701091699324325620647610183513781643345297447650838438175245",
|
|
||||||
"3170907381568164996048434627595073437765146540390351066869729445199396390350",
|
|
||||||
"21224698076141654110749227566074000819685780865045032659353546489395159395031",
|
|
||||||
"18113275293366123216771546175954550524914431153457717566389477633419482708807",
|
|
||||||
"1952712013602708178570747052202251655221844679392349715649271315658568301659",
|
|
||||||
"18071586466641072671725723167170872238457150900980957071031663421538421560166",
|
|
||||||
"9993139859464142980356243228522899168680191731482953959604385644693217291503",
|
|
||||||
"14825089209834329031146290681677780462512538924857394026404638992248153156554",
|
|
||||||
"4227387664466178643628175945231814400524887119677268757709033164980107894508",
|
|
||||||
"177945332589823419436506514313470826662740485666603469953512016396504401819",
|
|
||||||
"4236715569920417171293504597566056255435509785944924295068274306682611080863",
|
|
||||||
"8055374341341620501424923482910636721817757020788836089492629714380498049891"
|
|
||||||
],
|
|
||||||
"pathIndices": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}
|
|
||||||
"#;
|
|
||||||
|
|
||||||
let witness_input: WitnessInput =
|
|
||||||
serde_json::from_str(input_json_str).expect("JSON was not well-formatted");
|
|
||||||
|
|
||||||
println!("Witness input JSON: {:?}", witness_input);
|
|
||||||
|
|
||||||
let mut builder = CircomBuilder::new(cfg);
|
|
||||||
|
|
||||||
builder.push_input(
|
|
||||||
"root",
|
|
||||||
BigInt::parse_bytes(witness_input.root.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.push_input(
|
|
||||||
"nullifierHash",
|
|
||||||
BigInt::parse_bytes(witness_input.nullifier_hash.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.push_input(
|
|
||||||
"recipient",
|
|
||||||
BigInt::parse_bytes(witness_input.recipient.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.push_input(
|
|
||||||
"relayer",
|
|
||||||
BigInt::parse_bytes(
|
|
||||||
witness_input.relayer.strip_prefix("0x").unwrap().as_bytes(),
|
|
||||||
16,
|
|
||||||
)
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// XXX
|
|
||||||
builder.push_input(
|
|
||||||
"fee",
|
|
||||||
witness_input.fee, //BigInt::parse_bytes(witness_input.fee.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.push_input(
|
|
||||||
"nullifier",
|
|
||||||
BigInt::parse_bytes(witness_input.nullifier.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
for v in witness_input.path_elements.iter() {
|
|
||||||
builder.push_input(
|
|
||||||
"pathElements",
|
|
||||||
BigInt::parse_bytes(v.as_bytes(), 10).unwrap(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for v in witness_input.path_indices.iter() {
|
|
||||||
builder.push_input("pathIndices", BigInt::from(*v));
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("Builder input:\n {:#?}", builder.inputs);
|
|
||||||
|
|
||||||
// create an empty instance for setting it up
|
|
||||||
let circom = builder.setup();
|
|
||||||
|
|
||||||
let mut rng = thread_rng();
|
|
||||||
let params = generate_random_parameters::<Bn254, _, _>(circom, &mut rng).unwrap();
|
|
||||||
|
|
||||||
let circom = builder.build().unwrap();
|
|
||||||
|
|
||||||
let inputs = circom.get_public_inputs().unwrap();
|
|
||||||
|
|
||||||
println!("Public inputs {:#?} ", inputs);
|
|
||||||
|
|
||||||
PoseidonTornado { circom, params }
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Input Read
|
|
||||||
pub fn prove<W: Write>(&self, result_data: W) -> io::Result<()> {
|
|
||||||
let mut rng = thread_rng();
|
|
||||||
|
|
||||||
// XXX: There's probably a better way to do this
|
|
||||||
let circom = self.circom.clone();
|
|
||||||
let params = self.params.clone();
|
|
||||||
|
|
||||||
let proof = prove(circom, ¶ms, &mut rng).unwrap();
|
|
||||||
|
|
||||||
// XXX: Unclear if this is different from other serialization(s)
|
|
||||||
let _ = proof.serialize(result_data).unwrap();
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn verify<R: Read>(&self, input_data: R) -> io::Result<bool> {
|
|
||||||
let proof = Proof::deserialize(input_data).unwrap();
|
|
||||||
|
|
||||||
let pvk = prepare_verifying_key(&self.params.vk);
|
|
||||||
|
|
||||||
// XXX Part of input data?
|
|
||||||
let inputs = self.circom.get_public_inputs().unwrap();
|
|
||||||
|
|
||||||
let verified = verify_proof(&pvk, &proof, &inputs).unwrap();
|
|
||||||
|
|
||||||
Ok(verified)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for PoseidonTornado {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn poseidon_tornado_proof() {
|
|
||||||
let pt = PoseidonTornado::new();
|
|
||||||
//let inputs = pt.circom.get_public_inputs().unwrap();
|
|
||||||
|
|
||||||
let mut output_data: Vec<u8> = Vec::new();
|
|
||||||
let _ = pt.prove(&mut output_data);
|
|
||||||
|
|
||||||
let proof_data = &output_data[..];
|
|
||||||
|
|
||||||
// XXX Pass as arg?
|
|
||||||
//let pvk = prepare_verifying_key(&pt.params.vk);
|
|
||||||
|
|
||||||
let verified = pt.verify(proof_data).unwrap();
|
|
||||||
|
|
||||||
assert!(verified);
|
|
||||||
}
|
|
Loading…
Reference in New Issue