fix(poseidon-tornado): use poseidon tornado

Not multiplier
This commit is contained in:
Oskar Thoren 2022-03-16 14:40:00 +08:00
parent 83ef5ae3c3
commit d692757dca
No known key found for this signature in database
GPG Key ID: B2ECCFD3BC2EF77E
2 changed files with 129 additions and 25 deletions

View File

@ -1,4 +1,4 @@
use crate::public::Multiplier; use crate::public::PoseidonTornado;
use std::slice; use std::slice;
/// Buffer struct is taken from /// Buffer struct is taken from
@ -30,9 +30,9 @@ impl<'a> From<&Buffer> for &'a [u8] {
#[allow(clippy::not_unsafe_ptr_arg_deref)] #[allow(clippy::not_unsafe_ptr_arg_deref)]
#[no_mangle] #[no_mangle]
pub extern "C" fn new_circuit(ctx: *mut *mut Multiplier) -> bool { pub extern "C" fn new_circuit(ctx: *mut *mut PoseidonTornado) -> bool {
println!("multiplier ffi: new"); println!("multiplier ffi: new");
let mul = Multiplier::new(); let mul = PoseidonTornado::new();
unsafe { *ctx = Box::into_raw(Box::new(mul)) }; unsafe { *ctx = Box::into_raw(Box::new(mul)) };
@ -41,7 +41,7 @@ pub extern "C" fn new_circuit(ctx: *mut *mut Multiplier) -> bool {
#[allow(clippy::not_unsafe_ptr_arg_deref)] #[allow(clippy::not_unsafe_ptr_arg_deref)]
#[no_mangle] #[no_mangle]
pub extern "C" fn prove(ctx: *const Multiplier, output_buffer: *mut Buffer) -> bool { pub extern "C" fn prove(ctx: *const PoseidonTornado, output_buffer: *mut Buffer) -> bool {
println!("multiplier ffi: prove"); println!("multiplier ffi: prove");
let mul = unsafe { &*ctx }; let mul = unsafe { &*ctx };
let mut output_data: Vec<u8> = Vec::new(); let mut output_data: Vec<u8> = Vec::new();
@ -58,7 +58,7 @@ pub extern "C" fn prove(ctx: *const Multiplier, output_buffer: *mut Buffer) -> b
#[allow(clippy::not_unsafe_ptr_arg_deref)] #[allow(clippy::not_unsafe_ptr_arg_deref)]
#[no_mangle] #[no_mangle]
pub extern "C" fn verify( pub extern "C" fn verify(
ctx: *const Multiplier, ctx: *const PoseidonTornado,
proof_buffer: *const Buffer, proof_buffer: *const Buffer,
result_ptr: *mut u32, result_ptr: *mut u32,
) -> bool { ) -> bool {

View File

@ -9,40 +9,144 @@ use ark_groth16::{
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
// , SerializationError}; // , SerializationError};
use num_bigint::BigInt;
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
pub struct Multiplier { use serde::Deserialize;
pub struct PoseidonTornado {
circom: CircomCircuit<Bn254>, circom: CircomCircuit<Bn254>,
params: ProvingKey<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 // TODO This should use poseidon-tornado stuff in main.rs for proper example
impl Multiplier { impl PoseidonTornado {
// TODO Break this apart here // TODO Break this apart here
pub fn new() -> Multiplier { pub fn new() -> PoseidonTornado {
let cfg = CircomConfig::<Bn254>::new( let cfg =
"./resources/circom2_multiplier2.wasm", CircomConfig::<Bn254>::new("./resources/withdraw.wasm", "./resources/withdraw.r1cs")
"./resources/circom2_multiplier2.r1cs", .unwrap();
)
.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); let mut builder = CircomBuilder::new(cfg);
builder.push_input("a", 3);
builder.push_input("b", 11); 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 // create an empty instance for setting it up
let circom = builder.setup(); let circom = builder.setup();
let mut rng = thread_rng(); let mut rng = thread_rng();
let params = generate_random_parameters::<Bn254, _, _>(circom, &mut rng).unwrap(); let params = generate_random_parameters::<Bn254, _, _>(circom, &mut rng).unwrap();
let circom = builder.build().unwrap(); let circom = builder.build().unwrap();
//let inputs = circom.get_public_inputs().unwrap(); let inputs = circom.get_public_inputs().unwrap();
Multiplier { circom, params } println!("Public inputs {:#?} ", inputs);
PoseidonTornado { circom, params }
} }
// TODO Input Read // TODO Input Read
@ -75,26 +179,26 @@ impl Multiplier {
} }
} }
impl Default for Multiplier { impl Default for PoseidonTornado {
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()
} }
} }
#[test] #[test]
fn multiplier_proof() { fn poseidon_tornado_proof() {
let mul = Multiplier::new(); let pt = PoseidonTornado::new();
//let inputs = mul.circom.get_public_inputs().unwrap(); //let inputs = pt.circom.get_public_inputs().unwrap();
let mut output_data: Vec<u8> = Vec::new(); let mut output_data: Vec<u8> = Vec::new();
let _ = mul.prove(&mut output_data); let _ = pt.prove(&mut output_data);
let proof_data = &output_data[..]; let proof_data = &output_data[..];
// XXX Pass as arg? // XXX Pass as arg?
//let pvk = prepare_verifying_key(&mul.params.vk); //let pvk = prepare_verifying_key(&pt.params.vk);
let verified = mul.verify(proof_data).unwrap(); let verified = pt.verify(proof_data).unwrap();
assert!(verified); assert!(verified);
} }