migrate ffi lib

This commit is contained in:
psippl 2022-02-26 18:45:25 +01:00
parent 5485799aaa
commit 978c17dfa8
8 changed files with 16 additions and 337 deletions

View File

@ -15,7 +15,6 @@ license-file = "mit-license.md"
[lib]
name = "semaphore"
crate-type = ["staticlib", "cdylib"]
[dependencies]
ark-circom = { git = "https://github.com/gakonst/ark-circom", features=["circom-2"] }
@ -55,7 +54,4 @@ opt-level = 3
# Dependencies are optimized, even in a dev build. This improves dev performance
# while having neglible impact on incremental build times.
[profile.dev.package."*"]
opt-level = 3
[target.aarch64-linux-android]
linker = "aarch64-linux-android29-clang"
opt-level = 3

View File

@ -1,8 +0,0 @@
language = "C"
autogen_warning = "// NOTE: Append the lines below to ios/Classes/GreeterPlugin.h"
#namespace = "ffi"
#include_guard = "CBINDGEN_BINDINGS_H"
[defines]
"target_os = ios" = "TARGET_OS_IOS"
"target_os = macos" = "TARGET_OS_MACOS"

View File

@ -1,73 +0,0 @@
// NOTE: Append the lines below to ios/Classes/GreeterPlugin.h
typedef struct Identity Identity;
/**
* Merkle tree with all leaf and intermediate hashes stored
*/
typedef struct MerkleTree_PoseidonHash MerkleTree_PoseidonHash;
/**
* Merkle proof path, bottom to top.
*/
typedef struct Proof_Bn_Parameters Proof_Bn_Parameters;
/**
* Merkle proof path, bottom to top.
*/
typedef struct Proof_PoseidonHash Proof_PoseidonHash;
typedef struct MerkleTree_PoseidonHash PoseidonTree;
/**
* Creates a new idenity and returns the object
*/
struct Identity *new_identity(const char *seed);
/**
* Generates the identity commitment based on seed for identity
*/
char *generate_identity_commitment(struct Identity *identity);
/**
* Generates nullifier hash based on identity and external nullifier
*/
char *generate_nullifier_hash(struct Identity *identity, const char *external_nullifier);
/**
* Generates nullifier hash based on identity and external nullifier
*/
PoseidonTree *create_poseidon_tree(int depth);
/**
* Generates nullifier hash based on identity and external nullifier
*/
void insert_leaf(PoseidonTree *tree, struct Identity *identity);
/**
* Generates nullifier hash based on identity and external nullifier
*/
char *get_root(PoseidonTree *tree);
/**
* Generates nullifier hash based on identity and external nullifier
*/
struct Proof_PoseidonHash *get_merkle_proof(PoseidonTree *tree, int leaf_idx);
/**
* Generates nullifier hash based on identity and external nullifier
*/
struct Proof_Bn_Parameters *generate_proof(struct Identity *identity,
const char *external_nullifier,
const char *signal,
struct Proof_PoseidonHash *merkle_proof,
const char *zkey_path,
const char *wasm_path);
int verify_proof(const char *root,
const char *external_nullifier,
const char *signal,
const char *nullifier,
struct Proof_Bn_Parameters *proof,
const char *zkey_path,
const char *wasm_path);

View File

@ -1,7 +1,6 @@
use ff::{PrimeField, PrimeFieldRepr};
use num_bigint::{BigInt, Sign};
use once_cell::sync::Lazy;
use poseidon_rs::{Fr, FrRepr, Poseidon};
use poseidon_rs::{Poseidon};
use sha2::{Digest, Sha256};
use crate::util::{bigint_to_fr, fr_to_bigint};

View File

@ -1,252 +1,12 @@
mod hash;
mod identity;
mod merkle_tree;
mod poseidon_tree;
mod protocol;
mod util;
pub mod hash;
pub mod identity;
pub mod merkle_tree;
pub mod poseidon_tree;
pub mod protocol;
pub mod util;
use ark_bn254::Parameters;
use ark_ec::bn::Bn;
use ark_groth16::Proof;
use hex_literal::hex;
use num_bigint::BigInt;
use poseidon_tree::PoseidonHash;
use protocol::SnarkFileConfig;
use std::{
ffi::{CStr, CString},
os::raw::{c_char, c_int},
};
use crate::{hash::Hash, poseidon_tree::PoseidonTree};
/// Creates a new idenity and returns the object
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn new_identity(seed: *const c_char) -> *mut identity::Identity {
let c_str = unsafe { CStr::from_ptr(seed) };
let seed = match c_str.to_str() {
Err(_) => "there",
Ok(string) => string,
};
let id = identity::Identity::new(seed.as_bytes());
let boxed: Box<identity::Identity> = Box::new(id);
Box::into_raw(boxed)
}
/// Generates the identity commitment based on seed for identity
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn generate_identity_commitment(
identity: *mut identity::Identity,
) -> *mut c_char {
let identity = &*identity;
CString::new(identity.commitment().to_str_radix(10))
.unwrap()
.into_raw()
}
/// Generates nullifier hash based on identity and external nullifier
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn generate_nullifier_hash(
identity: *mut identity::Identity,
external_nullifier: *const c_char,
) -> *mut c_char {
let identity = &*identity;
let c_str = unsafe { CStr::from_ptr(external_nullifier) };
let external_nullifier = match c_str.to_str() {
Err(_) => "there",
Ok(string) => string,
};
CString::new(
protocol::generate_nullifier_hash(identity, external_nullifier.as_bytes()).to_str_radix(10),
)
.unwrap()
.into_raw()
}
/// Initializes new poseidon tree of given depth
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn create_poseidon_tree(depth: c_int) -> *mut PoseidonTree {
const LEAF: Hash = Hash::from_bytes_be(hex!(
"0000000000000000000000000000000000000000000000000000000000000000"
));
let tree = PoseidonTree::new(depth as usize, LEAF);
let boxed: Box<PoseidonTree> = Box::new(tree);
Box::into_raw(boxed)
}
/// Insert leaf into given poseidon tree
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn insert_leaf(tree: *mut PoseidonTree, identity: *mut identity::Identity) {
let identity = &*identity;
let tree = unsafe {
assert!(!tree.is_null());
&mut *tree
};
let (_, leaf) = identity.commitment().to_bytes_be();
tree.set(0, leaf.into());
}
/// Returns root for given tree
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn get_root(tree: *mut PoseidonTree) -> *mut c_char {
let tree = unsafe {
assert!(!tree.is_null());
&mut *tree
};
let root: BigInt = tree.root().into();
CString::new(root.to_str_radix(10)).unwrap().into_raw()
}
/// Generates merkle proof for given leaf index
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn get_merkle_proof(
tree: *mut PoseidonTree,
leaf_idx: c_int,
) -> *mut merkle_tree::Proof<PoseidonHash> {
let tree = unsafe {
assert!(!tree.is_null());
&mut *tree
};
let proof = tree.proof(leaf_idx as usize).expect("proof should exist");
let boxed: Box<merkle_tree::Proof<PoseidonHash>> = Box::new(proof);
Box::into_raw(boxed)
}
/// Generates semaphore proof
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn generate_proof(
identity: *mut identity::Identity,
external_nullifier: *const c_char,
signal: *const c_char,
merkle_proof: *mut merkle_tree::Proof<PoseidonHash>,
zkey_path: *const c_char,
wasm_path: *const c_char,
) -> *mut Proof<Bn<Parameters>> {
let c_str = unsafe { CStr::from_ptr(external_nullifier) };
let external_nullifier = match c_str.to_str() {
Err(_) => "there",
Ok(string) => string,
};
let c_str = unsafe { CStr::from_ptr(signal) };
let signal = match c_str.to_str() {
Err(_) => "there",
Ok(string) => string,
};
let c_str = unsafe { CStr::from_ptr(zkey_path) };
let zkey_path = match c_str.to_str() {
Err(_) => "there",
Ok(string) => string,
};
let c_str = unsafe { CStr::from_ptr(wasm_path) };
let wasm_path = match c_str.to_str() {
Err(_) => "there",
Ok(string) => string,
};
let config = SnarkFileConfig {
zkey: zkey_path.to_string(),
wasm: wasm_path.to_string(),
};
let identity = &*identity;
let merkle_proof = &*merkle_proof;
let res = protocol::generate_proof(
&config,
identity,
merkle_proof,
external_nullifier.as_bytes(),
signal.as_bytes(),
);
let boxed: Box<Proof<Bn<Parameters>>> = Box::new(res.unwrap());
Box::into_raw(boxed)
}
/// Verifies semaphore proof
#[no_mangle]
#[allow(clippy::missing_safety_doc)]
pub unsafe extern "C" fn verify_proof(
root: *const c_char,
external_nullifier: *const c_char,
signal: *const c_char,
nullifier: *const c_char,
proof: *mut Proof<Bn<Parameters>>,
zkey_path: *const c_char,
wasm_path: *const c_char,
) -> c_int {
let c_str = unsafe { CStr::from_ptr(root) };
let root = match c_str.to_str() {
Err(_) => "there",
Ok(string) => string,
};
let c_str = unsafe { CStr::from_ptr(external_nullifier) };
let external_nullifier = match c_str.to_str() {
Err(_) => "there",
Ok(string) => string,
};
let c_str = unsafe { CStr::from_ptr(signal) };
let signal = match c_str.to_str() {
Err(_) => "there",
Ok(string) => string,
};
let c_str = unsafe { CStr::from_ptr(nullifier) };
let nullifier = match c_str.to_str() {
Err(_) => "there",
Ok(string) => string,
};
let c_str = unsafe { CStr::from_ptr(zkey_path) };
let zkey_path = match c_str.to_str() {
Err(_) => "there",
Ok(string) => string,
};
let c_str = unsafe { CStr::from_ptr(wasm_path) };
let wasm_path = match c_str.to_str() {
Err(_) => "there",
Ok(string) => string,
};
let config = SnarkFileConfig {
zkey: zkey_path.to_string(),
wasm: wasm_path.to_string(),
};
let proof = &*proof;
let root = BigInt::parse_bytes(root.as_bytes(), 10).unwrap();
let nullifier = BigInt::parse_bytes(nullifier.as_bytes(), 10).unwrap();
protocol::verify_proof(
&config,
&root,
&nullifier,
signal.as_bytes(),
external_nullifier.as_bytes(),
proof,
)
.unwrap() as i32
}
pub type Groth16Proof = Proof<Bn<Parameters>>;

5
src/libsemaphore.h Normal file
View File

@ -0,0 +1,5 @@
// NOTE: Append the lines below to ios/Classes/GreeterPlugin.h
typedef struct Identity Identity;
struct Identity *new_identity(const char *seed);

View File

@ -9,7 +9,7 @@ use color_eyre::Result;
use ethers_core::utils::keccak256;
use num_bigint::{BigInt, Sign};
use once_cell::sync::Lazy;
use poseidon_rs::{Fr, FrRepr, Poseidon};
use poseidon_rs::{Poseidon};
use std::{collections::HashMap, fs::File, ops::Shr};
use crate::{

View File

@ -1,6 +1,6 @@
use ff::{PrimeField, PrimeFieldRepr};
use num_bigint::{BigInt, Sign};
use poseidon_rs::{Fr, FrRepr, Poseidon};
use poseidon_rs::{Fr, FrRepr};
pub fn fr_to_bigint(fr: Fr) -> BigInt {
let mut bytes = [0_u8; 32];