mirror of https://github.com/vacp2p/zerokit.git
This reverts commit 4ec93c5e1f
.
This commit is contained in:
parent
4ec93c5e1f
commit
c6b7a8c0a4
|
@ -5,6 +5,7 @@ on:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**.md'
|
- '**.md'
|
||||||
- '!.github/workflows/*.yml'
|
- '!.github/workflows/*.yml'
|
||||||
|
- '!multiplier/src/**'
|
||||||
- '!private-settlement/src/**'
|
- '!private-settlement/src/**'
|
||||||
- '!rln-wasm/**'
|
- '!rln-wasm/**'
|
||||||
- '!rln/src/**'
|
- '!rln/src/**'
|
||||||
|
@ -15,6 +16,7 @@ on:
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- '**.md'
|
- '**.md'
|
||||||
- '!.github/workflows/*.yml'
|
- '!.github/workflows/*.yml'
|
||||||
|
- '!multiplier/src/**'
|
||||||
- '!private-settlement/src/**'
|
- '!private-settlement/src/**'
|
||||||
- '!rln-wasm/**'
|
- '!rln-wasm/**'
|
||||||
- '!rln/src/**'
|
- '!rln/src/**'
|
||||||
|
@ -30,7 +32,7 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
platform: [ubuntu-latest, macos-latest]
|
platform: [ubuntu-latest, macos-latest]
|
||||||
crate: [semaphore, rln, utils]
|
crate: [multiplier, semaphore, rln, utils]
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
|
|
||||||
|
@ -83,7 +85,7 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
# we run lint tests only on ubuntu
|
# we run lint tests only on ubuntu
|
||||||
platform: [ubuntu-latest]
|
platform: [ubuntu-latest]
|
||||||
crate: [semaphore, rln, utils]
|
crate: [multiplier, semaphore, rln, utils]
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
|
|
||||||
|
|
|
@ -1532,8 +1532,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ethers-core"
|
name = "ethers-core"
|
||||||
version = "2.0.8"
|
version = "2.0.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/gakonst/ethers-rs?rev=030bf43#030bf439a100dcacd2e968e3114de0612229056b"
|
||||||
checksum = "60ca2514feb98918a0a31de7e1983c29f2267ebf61b2dc5d4294f91e5b866623"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -2078,6 +2077,18 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389"
|
checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "multiplier"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"ark-bn254 0.3.0",
|
||||||
|
"ark-circom 0.1.0 (git+https://github.com/gakonst/ark-circom?rev=35ce5a9)",
|
||||||
|
"ark-groth16 0.3.0",
|
||||||
|
"ark-serialize 0.3.0",
|
||||||
|
"ark-std 0.3.0",
|
||||||
|
"color-eyre 0.6.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num"
|
name = "num"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
|
"multiplier",
|
||||||
"private-settlement",
|
"private-settlement",
|
||||||
"semaphore",
|
"semaphore",
|
||||||
"rln",
|
"rln",
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
[package]
|
||||||
|
name = "multiplier"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
|
# 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 }
|
||||||
|
|
||||||
|
# ZKP Generation
|
||||||
|
# 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-serialize = { version = "0.3.0", default-features = false }
|
||||||
|
|
||||||
|
ark-circom = { git = "https://github.com/gakonst/ark-circom", features = ["circom-2"], rev = "35ce5a9" }
|
||||||
|
|
||||||
|
# error handling
|
||||||
|
color-eyre = "0.6.1"
|
||||||
|
|
||||||
|
# decoding of data
|
||||||
|
# hex = "0.4.3"
|
||||||
|
# byteorder = "1.4.3"
|
|
@ -0,0 +1,7 @@
|
||||||
|
[tasks.build]
|
||||||
|
command = "cargo"
|
||||||
|
args = ["build", "--release"]
|
||||||
|
|
||||||
|
[tasks.test]
|
||||||
|
command = "cargo"
|
||||||
|
args = ["test", "--release"]
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Multiplier example
|
||||||
|
|
||||||
|
Example wrapper around a basic Circom circuit to test Circom 2 integration
|
||||||
|
through ark-circom and FFI.
|
||||||
|
|
||||||
|
## Build and Test
|
||||||
|
|
||||||
|
To build and test, run the following commands within the module folder
|
||||||
|
```bash
|
||||||
|
cargo make build
|
||||||
|
cargo make test
|
||||||
|
```
|
||||||
|
|
||||||
|
## FFI
|
||||||
|
|
||||||
|
To generate C or Nim bindings from Rust FFI, use `cbindgen` or `nbindgen`:
|
||||||
|
|
||||||
|
```
|
||||||
|
cbindgen . -o target/multiplier.h
|
||||||
|
nbindgen . -o target/multiplier.nim
|
||||||
|
```
|
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) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn new_circuit(ctx: *mut *mut Multiplier) -> bool {
|
||||||
|
if let Ok(mul) = Multiplier::new() {
|
||||||
|
unsafe { *ctx = Box::into_raw(Box::new(mul)) };
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
|
#[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
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
|
#[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,49 @@
|
||||||
|
use ark_circom::{CircomBuilder, CircomConfig};
|
||||||
|
use ark_std::rand::thread_rng;
|
||||||
|
use color_eyre::{Report, 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()
|
||||||
|
.ok_or(Report::msg("no public inputs"))?;
|
||||||
|
|
||||||
|
let proof = prove(circom, ¶ms, &mut rng)?;
|
||||||
|
|
||||||
|
let pvk = prepare_verifying_key(¶ms.vk);
|
||||||
|
|
||||||
|
match verify_proof(&pvk, &proof, &inputs) {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(_) => Err(Report::msg("not verified")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
|
||||||
|
match groth16_proof_example() {
|
||||||
|
Ok(_) => println!("Success"),
|
||||||
|
Err(_) => println!("Error"),
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
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};
|
||||||
|
use color_eyre::{Report, Result};
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
|
pub struct Multiplier {
|
||||||
|
circom: CircomCircuit<Bn254>,
|
||||||
|
params: ProvingKey<Bn254>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Multiplier {
|
||||||
|
// TODO Break this apart here
|
||||||
|
pub fn new() -> Result<Multiplier> {
|
||||||
|
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()?;
|
||||||
|
|
||||||
|
Ok(Multiplier { circom, params })
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Input Read
|
||||||
|
pub fn prove<W: Write>(&self, result_data: W) -> 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)?;
|
||||||
|
|
||||||
|
// XXX: Unclear if this is different from other serialization(s)
|
||||||
|
proof.serialize(result_data)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn verify<R: Read>(&self, input_data: R) -> Result<bool> {
|
||||||
|
let proof = Proof::deserialize(input_data)?;
|
||||||
|
|
||||||
|
let pvk = prepare_verifying_key(&self.params.vk);
|
||||||
|
|
||||||
|
// XXX Part of input data?
|
||||||
|
let inputs = self
|
||||||
|
.circom
|
||||||
|
.get_public_inputs()
|
||||||
|
.ok_or(Report::msg("no public inputs"))?;
|
||||||
|
|
||||||
|
let verified = verify_proof(&pvk, &proof, &inputs)?;
|
||||||
|
|
||||||
|
Ok(verified)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Multiplier {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new().unwrap()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use multiplier::public::Multiplier;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multiplier_proof() {
|
||||||
|
let mul = Multiplier::new().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