Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ members = [
"shuffle",
"shuffle/wasm",
"matchmaking",
"c-uzkge",
"wasm",
]
resolver = "2"

Expand Down Expand Up @@ -53,6 +55,7 @@ sha3 = "0.10"
structopt = "0.3"
tera = "1.19"
thiserror = "1.0"
ethabi = "18.0.0"

# wasm
getrandom = { version = "0.2", features = ["js"] }
Expand Down
19 changes: 19 additions & 0 deletions c-uzkge/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "c-uzkge"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["rlib", "cdylib", "staticlib"]

[dependencies]
bincode.workspace = true
ark-ec.workspace = true
ark-ff.workspace = true
ark-bn254.workspace = true
ark-serialize.workspace = true
ark-ed-on-bn254 = { workspace = true, features = ["r1cs"] }
uzkge = { workspace = true, features = ["shuffle"] }
zmatchmaking = { workspace = true }
zshuffle = { workspace = true }
rand_chacha = { workspace = true }
66 changes: 66 additions & 0 deletions c-uzkge/c-uzkge.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

typedef struct Bytes {
uint32_t len;
const uint8_t *data;
} Bytes;

typedef struct CardParam {
struct Bytes x1;
struct Bytes y1;
struct Bytes x2;
struct Bytes y2;
} CardParam;

int32_t __point_add(const uint8_t *x1,
const uint8_t *y1,
const uint8_t *x2,
const uint8_t *y2,
uint8_t *ret_val);

int32_t __scalar_mul(const uint8_t *s, const uint8_t *x, const uint8_t *y, uint8_t *ret_val);

int32_t __anemoi_hash(const struct Bytes *data, uint32_t data_len, uint8_t *ret_val);

int32_t __generate_shuffle_proof(struct Bytes rng_seed,
struct Bytes pk,
const struct CardParam *inputs_param,
uint32_t inputs_len,
uint32_t n_cards,
uint8_t *out_verifier_params,
uint32_t *out_verifier_params_len,
uint8_t *out_outputs,
uint32_t *out_outputs_len,
uint8_t *out_proof,
uint32_t *out_proof_len);

int32_t __verify_shuffle(struct Bytes verifier_params,
const struct CardParam *inputs_param,
uint32_t inputs_len,
const struct CardParam *outputs_param,
uint32_t outputs_len,
struct Bytes proof);

int32_t __verifier_matchmaking_params(uint8_t *ret_val, uint32_t ret_len);

int32_t __generate_matchmaking_proof(struct Bytes rng_seed,
const struct Bytes *inputs_param,
uint32_t inputs_len,
struct Bytes committed_seed,
struct Bytes random_number,
uint8_t *out_outputs,
uint32_t *out_outputs_len,
uint8_t *out_proof,
uint32_t *out_proof_len);

int32_t __verify_matchmaking(struct Bytes verifier_params,
const struct Bytes *inputs_param,
uint32_t inputs_len,
const struct Bytes *outputs_param,
uint32_t outputs_len,
struct Bytes commitment,
struct Bytes random_number,
struct Bytes proof);
1 change: 1 addition & 0 deletions c-uzkge/cbindgen.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
language = "C"
241 changes: 241 additions & 0 deletions c-uzkge/examples.c

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions c-uzkge/src/anemoi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use alloc::{slice, vec::Vec};
use ark_bn254::Fr;
use ark_ff::{BigInteger, PrimeField};
use uzkge::anemoi::{AnemoiJive, AnemoiJive254};

use crate::Bytes;

#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn __anemoi_hash(data: *const Bytes, data_len: u32, ret_val: *mut u8) -> i32 {
let mut inputs: Vec<Fr> = Vec::new();
for i in 0..data_len as usize {
let bytes = unsafe { *data.wrapping_add(i) };
let slice = bytes.to_slice();
let input = Fr::from_be_bytes_mod_order(slice);
inputs.push(input);
}
let ret = unsafe { slice::from_raw_parts_mut(ret_val, 32) };

anemoi_hash(inputs, ret)
}

fn anemoi_hash(inputs: Vec<Fr>, ret: &mut [u8]) -> i32 {
let res = AnemoiJive254::eval_variable_length_hash(inputs.as_slice());

let hash = res.into_bigint().to_bytes_be();
ret.copy_from_slice(&hash);

hash.len() as i32
}

#[cfg(test)]
mod tests {
use super::*;
use ark_ff::{vec, UniformRand};
use rand_chacha::{rand_core::SeedableRng, ChaChaRng};

#[test]
fn test_anemoi_hash() {
let mut prng = ChaChaRng::from_seed([0u8; 32]);
let f1 = Fr::rand(&mut prng);
let f2 = Fr::rand(&mut prng);
let f3 = Fr::rand(&mut prng);

let inputs = vec![f1, f2, f3];
let mut hash1 = [0; 32];

let res = anemoi_hash(inputs, &mut hash1);

assert_eq!(res, 32);
}
}
133 changes: 133 additions & 0 deletions c-uzkge/src/ed_on_bn254.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
use ark_ec::{AffineRepr, CurveGroup};
use ark_ed_on_bn254::{EdwardsAffine, Fq, Fr};
use ark_ff::{BigInteger, PrimeField};
use core::slice;

#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn __point_add(
x1: *const u8,
y1: *const u8,
x2: *const u8,
y2: *const u8,
ret_val: *mut u8,
) -> i32 {
let x1 = unsafe { slice::from_raw_parts(x1, 32) };
let x_1 = Fq::from_be_bytes_mod_order(x1);

let y1 = unsafe { slice::from_raw_parts(y1, 32) };
let y_1 = Fq::from_be_bytes_mod_order(y1);

let x2 = unsafe { slice::from_raw_parts(x2, 32) };
let x_2 = Fq::from_be_bytes_mod_order(x2);

let y2 = unsafe { slice::from_raw_parts(y2, 32) };
let y_2 = Fq::from_be_bytes_mod_order(y2);

let ret = unsafe { slice::from_raw_parts_mut(ret_val, 64) };

point_add(x_1, y_1, x_2, y_2, ret)
}

fn point_add(x_1: Fq, y_1: Fq, x_2: Fq, y_2: Fq, ret: &mut [u8]) -> i32 {
let p1 = EdwardsAffine::new(x_1, y_1);
let p2 = EdwardsAffine::new(x_2, y_2);
let p3 = p1 + p2;

match p3.into_affine().xy() {
Some((r_x, r_y)) => {
ret[0..32].copy_from_slice(&r_x.into_bigint().to_bytes_be());
ret[32..64].copy_from_slice(&r_y.into_bigint().to_bytes_be());
ret.len() as i32
}
None => -1,
}
}

#[no_mangle]
#[allow(clippy::not_unsafe_ptr_arg_deref)]
pub extern "C" fn __scalar_mul(s: *const u8, x: *const u8, y: *const u8, ret_val: *mut u8) -> i32 {
let s = unsafe { slice::from_raw_parts(s, 32) };
let s = Fr::from_be_bytes_mod_order(s);

let x = unsafe { slice::from_raw_parts(x, 32) };
let x = Fq::from_be_bytes_mod_order(x);

let y = unsafe { slice::from_raw_parts(y, 32) };
let y = Fq::from_be_bytes_mod_order(y);

let ret = unsafe { slice::from_raw_parts_mut(ret_val, 64) };

scalar_mul(s, x, y, ret)
}

fn scalar_mul(s: Fr, x: Fq, y: Fq, ret: &mut [u8]) -> i32 {
let p = EdwardsAffine::new(x, y);
let p2 = p * s;

match p2.into_affine().xy() {
Some((r_x, r_y)) => {
ret[0..32].copy_from_slice(&r_x.into_bigint().to_bytes_be());
ret[32..64].copy_from_slice(&r_y.into_bigint().to_bytes_be());
ret.len() as i32
}
None => -1,
}
}

#[cfg(test)]
mod tests {
use super::*;
use ark_ff::{vec, UniformRand};
use rand_chacha::{rand_core::SeedableRng, ChaChaRng};

#[test]
fn test_point_add() {
// generate p1, p2
let mut prng = ChaChaRng::from_seed([0u8; 32]);
let p1 = EdwardsAffine::rand(&mut prng);
let p2 = EdwardsAffine::rand(&mut prng);
let (p1_0, p1_1) = p1.xy().unwrap();
let (p2_0, p2_1) = p2.xy().unwrap();

// add with rust
let (p3_0, p3_1) = (p1 + p2)
.into_affine()
.xy()
.map(|(x, y)| (x.into_bigint().to_bytes_be(), y.into_bigint().to_bytes_be()))
.unwrap();

let mut ret = vec![0u8; 64];

let res = point_add(p1_0, p1_1, p2_0, p2_1, &mut ret);

assert_eq!(res, 64);

assert_eq!(ret[..32].to_vec(), p3_0);
assert_eq!(ret[32..].to_vec(), p3_1);
}

#[test]
fn test_scalar_mul() {
// generate scalar, p1
let mut prng = ChaChaRng::from_seed([0u8; 32]);
let s = Fr::rand(&mut prng);
let p1 = EdwardsAffine::rand(&mut prng);
let (p1_0, p1_1) = p1.xy().unwrap();

// add with rust
let (p3_0, p3_1) = (p1 * s)
.into_affine()
.xy()
.map(|(x, y)| (x.into_bigint().to_bytes_be(), y.into_bigint().to_bytes_be()))
.unwrap();

let mut ret = vec![0u8; 64];

let res = scalar_mul(s, p1_0, p1_1, &mut ret);
assert_eq!(res, 64);

assert_eq!(ret[..32].to_vec(), p3_0);
assert_eq!(ret[32..].to_vec(), p3_1);
}
}
24 changes: 24 additions & 0 deletions c-uzkge/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#![deny(warnings, unused_crate_dependencies)]

extern crate alloc;

pub mod ed_on_bn254;

pub mod anemoi;

pub mod shuffle;

pub mod matchmaking;

#[repr(C)]
#[derive(Clone, Copy)]
pub struct Bytes {
pub len: u32,
pub data: *const u8,
}

impl Bytes {
pub fn to_slice(&self) -> &[u8] {
unsafe { core::slice::from_raw_parts(self.data, self.len as usize) }
}
}
Loading