Skip to content

Commit

Permalink
add c sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
allen-cmyk committed May 27, 2024
1 parent eb6a844 commit eadf411
Show file tree
Hide file tree
Showing 8 changed files with 812 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
members = [
"uzkge",
"shuffle",
"shuffle/wasm",
"matchmaking",
"c-uzkge",
]
resolver = "2"

Expand Down
40 changes: 40 additions & 0 deletions c-uzkge/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[package]
name = "c-uzkge"
version = "0.1.0"
edition = "2021"

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

[dependencies]
ethabi = "18.0"
primitive-types = "0.12"
lazy_static = "1.4"
bincode = "1.3"
sha3 = "0.10"
rayon = "1.7"
num-bigint = "0.4"
ark-ff = "0.4"
ark-ec = "0.4"
ark-std = "0.4"
ark-serialize = "0.4"
ark-bn254 = "0.4"
ark-ed-on-bn254 = "0.4"
uzkge = { git = "https://github.com/zypher-game/uzkge.git" }
zmatchmaking = { git = "https://github.com/zypher-game/uzkge.git" }
zshuffle = { git = "https://github.com/zypher-game/uzkge.git" }

[dev-dependencies]
hex = "0.4.3"
rand_chacha = "0.3"

[patch.crates-io]
ark-ff = { git = "https://github.com/arkworks-rs/algebra" }
ark-ec = { git = "https://github.com/arkworks-rs/algebra" }
ark-poly = { git = "https://github.com/arkworks-rs/algebra" }
ark-serialize = { git = "https://github.com/arkworks-rs/algebra" }
ark-bn254 = { git = "https://github.com/arkworks-rs/algebra" }
ark-ed-on-bn254 = { git = "https://github.com/arkworks-rs/algebra" }
ark-groth16 = { git = "https://github.com/arkworks-rs/groth16" }
ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std" }
ark-relations = { git = "https://github.com/arkworks-rs/snark" }
43 changes: 43 additions & 0 deletions c-uzkge/c-uzkge.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#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 VerifyMatchmakingParam {
struct Bytes verifier_params;
const struct Bytes *inputs;
uint32_t inputs_len;
const struct Bytes *outputs;
uint32_t outputs_len;
struct Bytes commitment;
struct Bytes random_number;
struct Bytes proof;
} VerifyMatchmakingParam;

typedef struct VerifyShuffleParam {
struct Bytes verifier_params;
const struct Bytes *const *inputs;
uint32_t inputs_len;
const struct Bytes *const *outputs;
uint32_t outputs_len;
struct Bytes proof;
} VerifyShuffleParam;

int32_t __point_add(const uint8_t *x1,
const uint8_t *x2,
const uint8_t *y1,
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 __verify_matchmaking(struct VerifyMatchmakingParam param);

int32_t __verify_shuffle(struct VerifyShuffleParam param);
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"
54 changes: 54 additions & 0 deletions c-uzkge/src/anemoi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
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);

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 ark_std::rand::SeedableRng;
use rand_chacha::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);
}
}
134 changes: 134 additions & 0 deletions c-uzkge/src/ed_on_bn254.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
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,
x2: *const u8,
y1: *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 x2 = unsafe { slice::from_raw_parts(x2, 32) };
let x_2 = Fq::from_be_bytes_mod_order(x2);

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

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, x_2, y_1, y_2, ret)
}

fn point_add(x_1: Fq, x_2: Fq, y_1: 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 ark_std::rand::SeedableRng;
use rand_chacha::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, p2_0, p1_1, 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);
}
}
23 changes: 23 additions & 0 deletions c-uzkge/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#![no_std]
#![deny(warnings)]

extern crate alloc;

pub mod ed_on_bn254;

pub mod anemoi;

pub mod plonk;

#[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

0 comments on commit eadf411

Please sign in to comment.