mirror of https://github.com/vacp2p/zerokit.git
poseidon-tornado init from multiplier
This commit is contained in:
parent
721f3b8fa9
commit
3139738a88
|
@ -0,0 +1,35 @@
|
||||||
|
[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 }
|
||||||
|
ark-serialize = { version = "0.3.0", default-features = false }
|
||||||
|
|
||||||
|
ark-circom = { git = "https://github.com/gakonst/ark-circom", features = ["circom-2"] }
|
||||||
|
|
||||||
|
# error handling
|
||||||
|
# thiserror = "1.0.26"
|
||||||
|
color-eyre = "0.5"
|
||||||
|
|
||||||
|
# decoding of data
|
||||||
|
# hex = "0.4.3"
|
||||||
|
# byteorder = "1.4.3"
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,77 @@
|
||||||
|
use crate::public::Multiplier;
|
||||||
|
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) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn new_circuit(ctx: *mut *mut Multiplier) -> bool {
|
||||||
|
println!("multiplier ffi: new");
|
||||||
|
let mul = Multiplier::new();
|
||||||
|
|
||||||
|
unsafe { *ctx = Box::into_raw(Box::new(mul)) };
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn prove(
|
||||||
|
ctx: *const Multiplier,
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn verify(
|
||||||
|
ctx: *const Multiplier,
|
||||||
|
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
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod ffi;
|
||||||
|
pub mod public;
|
|
@ -0,0 +1,48 @@
|
||||||
|
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 as prove, generate_random_parameters, prepare_verifying_key, verify_proof,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn groth16_proof_example() -> Result<()> {
|
||||||
|
let cfg = CircomConfig::<Bn254>::new(
|
||||||
|
"./resources/circom2_multiplier2.wasm",
|
||||||
|
"./resources/circom2_multiplier2.r1cs",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let mut builder = CircomBuilder::new(cfg);
|
||||||
|
builder.push_input("a", 3);
|
||||||
|
builder.push_input("b", 11);
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
let proof = prove(circom, ¶ms, &mut rng)?;
|
||||||
|
|
||||||
|
let pvk = prepare_verifying_key(¶ms.vk);
|
||||||
|
|
||||||
|
let verified = verify_proof(&pvk, &proof, &inputs)?;
|
||||||
|
|
||||||
|
assert!(verified);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
|
||||||
|
match groth16_proof_example() {
|
||||||
|
Ok(_) => println!("Success"),
|
||||||
|
Err(_) => println!("Error"),
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
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 std::io::{self, Read, Write};
|
||||||
|
|
||||||
|
pub struct Multiplier {
|
||||||
|
circom: CircomCircuit<Bn254>,
|
||||||
|
params: ProvingKey<Bn254>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Multiplier {
|
||||||
|
// TODO Break this apart here
|
||||||
|
pub fn new() -> Multiplier {
|
||||||
|
let cfg = CircomConfig::<Bn254>::new(
|
||||||
|
"./resources/circom2_multiplier2.wasm",
|
||||||
|
"./resources/circom2_multiplier2.r1cs",
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut builder = CircomBuilder::new(cfg);
|
||||||
|
builder.push_input("a", 3);
|
||||||
|
builder.push_input("b", 11);
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
Multiplier { 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multiplier_proof() {
|
||||||
|
let mul = Multiplier::new();
|
||||||
|
//let inputs = mul.circom.get_public_inputs().unwrap();
|
||||||
|
|
||||||
|
let mut output_data: Vec<u8> = Vec::new();
|
||||||
|
let _ = mul.prove(&mut output_data);
|
||||||
|
|
||||||
|
let proof_data = &output_data[..];
|
||||||
|
|
||||||
|
// XXX Pass as arg?
|
||||||
|
//let pvk = prepare_verifying_key(&mul.params.vk);
|
||||||
|
|
||||||
|
let verified = mul.verify(proof_data).unwrap();
|
||||||
|
|
||||||
|
assert!(verified);
|
||||||
|
}
|
Loading…
Reference in New Issue