Skip to content

Commit 9d53572

Browse files
plonk-neon: Add new crate for nodejs
1 parent 0ecaa9b commit 9d53572

12 files changed

+1109
-0
lines changed

Cargo.lock

Lines changed: 80 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ members = [
1414
"msm",
1515
"mvpoly",
1616
"o1vm",
17+
"plonk-neon",
1718
"plonk-wasm",
1819
"poly-commitment",
1920
"poseidon",

plonk-neon/Cargo.toml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
[package]
2+
name = "plonk_neon"
3+
version = "0.1.0"
4+
authors = ["[email protected]"]
5+
description = "Neon module for plonk proof systems"
6+
repository = "https://github.com/MinaProtocol/mina"
7+
license = "MIT/Apache-2.0"
8+
edition = "2021"
9+
10+
[lib]
11+
name = "plonk_neon"
12+
crate-type = ["cdylib"]
13+
14+
################################# Dependencies ################################
15+
16+
[dependencies]
17+
# Strictly enforcing 0.2.87
18+
19+
libc = "0.2.62"
20+
once_cell = "1.10.0"
21+
22+
# arkworks
23+
ark-ec.workspace = true
24+
ark-ff.workspace = true
25+
ark-poly.workspace = true
26+
ark-serialize.workspace = true
27+
arkworks.workspace = true
28+
29+
# proof-systems
30+
mina-curves = { path = "../curves" }
31+
mina-poseidon = { path = "../poseidon" }
32+
o1-utils = { path = "../utils" }
33+
34+
getrandom.workspace = true
35+
neon = { version = "1.0.0" }
36+
num-bigint.workspace = true
37+
paste.workspace = true
38+
rand.workspace = true
39+
rayon.workspace = true
40+
rmp-serde.workspace = true
41+
serde.workspace = true
42+
serde_with.workspace = true
43+
wasm-bindgen.workspace = true
44+
wasm-types.workspace = true

plonk-neon/src/arkworks.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//! This module contains wrapper types to Arkworks types.
2+
//! To use Arkwork types in OCaml, you have to convert to these types,
3+
//! and convert back from them to use them in Rust.
4+
//!
5+
//! For example:
6+
//!
7+
//! ```
8+
//! use marlin_plonk_bindings::arkworks::CamlBiginteger256;
9+
//! use ark_ff::BigInteger256;
10+
//!
11+
//! #[ocaml::func]
12+
//! pub fn caml_add(x: CamlBigInteger256, y: CamlBigInteger256) -> CamlBigInteger256 {
13+
//! let x: BigInteger256 = x.into();
14+
//! let y: BigInteger256 = y.into();
15+
//! (x + y).into()
16+
//! }
17+
//! ```
18+
//!
19+
20+
mod bigint_256;
21+
mod group_affine;
22+
mod group_projective;
23+
mod pasta_fp;
24+
mod pasta_fq;
25+
26+
// re-export what's important
27+
28+
pub use pasta_fp::WasmPastaFp;
29+
pub use pasta_fq::WasmPastaFq;

plonk-neon/src/arkworks/bigint_256.rs

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
use ark_ff::{BigInt, BigInteger as ark_BigInteger, BigInteger256};
2+
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Write};
3+
use num_bigint::BigUint;
4+
use std::{
5+
cmp::Ordering::{Equal, Greater, Less},
6+
convert::TryInto,
7+
};
8+
use wasm_bindgen::{
9+
convert::{FromWasmAbi, IntoWasmAbi},
10+
prelude::*,
11+
};
12+
13+
//
14+
// Handy constants
15+
//
16+
17+
const BIGINT256_NUM_BITS: i32 = 256;
18+
const BIGINT256_LIMB_BITS: i32 = 64;
19+
const BIGINT256_LIMB_BYTES: i32 = BIGINT256_LIMB_BITS / 8;
20+
const BIGINT256_NUM_LIMBS: i32 =
21+
(BIGINT256_NUM_BITS + BIGINT256_LIMB_BITS - 1) / BIGINT256_LIMB_BITS;
22+
const BIGINT256_NUM_BYTES: usize = (BIGINT256_NUM_LIMBS as usize) * 8;
23+
24+
pub struct WasmBigInteger256(pub BigInteger256);
25+
26+
impl wasm_bindgen::describe::WasmDescribe for WasmBigInteger256 {
27+
fn describe() {
28+
<Vec<u8> as wasm_bindgen::describe::WasmDescribe>::describe()
29+
}
30+
}
31+
32+
impl FromWasmAbi for WasmBigInteger256 {
33+
type Abi = <Vec<u8> as FromWasmAbi>::Abi;
34+
unsafe fn from_abi(js: Self::Abi) -> Self {
35+
let bytes: Vec<u8> = FromWasmAbi::from_abi(js);
36+
// TODO this used FromBytes before arkworks 0.4.2, check serialization is consistent after update
37+
WasmBigInteger256(BigInteger256::deserialize_compressed(bytes.as_slice()).unwrap())
38+
}
39+
}
40+
41+
impl IntoWasmAbi for WasmBigInteger256 {
42+
type Abi = <Vec<u8> as FromWasmAbi>::Abi;
43+
fn into_abi(self) -> Self::Abi {
44+
let mut bytes: Vec<u8> = vec![];
45+
bytes.write_all(self.0.to_bytes_le().as_slice()).unwrap();
46+
bytes.into_abi()
47+
}
48+
}
49+
50+
pub fn to_biguint(x: &BigInteger256) -> BigUint {
51+
let x_ = x.0.as_ptr() as *const u8;
52+
let x_ = unsafe { std::slice::from_raw_parts(x_, BIGINT256_NUM_BYTES) };
53+
num_bigint::BigUint::from_bytes_le(x_)
54+
}
55+
56+
pub fn of_biguint(x: &BigUint) -> BigInteger256 {
57+
let mut bytes = x.to_bytes_le();
58+
bytes.resize(BIGINT256_NUM_BYTES, 0);
59+
let limbs = bytes.as_ptr();
60+
let limbs = limbs as *const [u64; BIGINT256_NUM_LIMBS as usize];
61+
let limbs = unsafe { &(*limbs) };
62+
BigInt(*limbs)
63+
}
64+
65+
#[wasm_bindgen]
66+
pub fn caml_bigint_256_of_numeral(s: String, _len: u32, base: u32) -> WasmBigInteger256 {
67+
match BigUint::parse_bytes(&s.into_bytes(), base) {
68+
Some(data) => WasmBigInteger256(of_biguint(&data)),
69+
None => panic!("caml_bigint_256_of_numeral"),
70+
}
71+
}
72+
73+
#[wasm_bindgen]
74+
pub fn caml_bigint_256_of_decimal_string(s: String) -> WasmBigInteger256 {
75+
match BigUint::parse_bytes(&s.into_bytes(), 10) {
76+
Some(data) => WasmBigInteger256(of_biguint(&data)),
77+
None => panic!("caml_bigint_256_of_decimal_string"),
78+
}
79+
}
80+
81+
#[wasm_bindgen]
82+
pub fn caml_bigint_256_num_limbs() -> i32 {
83+
BIGINT256_NUM_LIMBS
84+
}
85+
86+
#[wasm_bindgen]
87+
pub fn caml_bigint_256_bytes_per_limb() -> i32 {
88+
BIGINT256_LIMB_BYTES
89+
}
90+
91+
#[wasm_bindgen]
92+
pub fn caml_bigint_256_div(x: WasmBigInteger256, y: WasmBigInteger256) -> WasmBigInteger256 {
93+
let res: BigUint = to_biguint(&x.0) / to_biguint(&y.0);
94+
WasmBigInteger256(of_biguint(&res))
95+
}
96+
97+
#[wasm_bindgen]
98+
pub fn caml_bigint_256_compare(x: WasmBigInteger256, y: WasmBigInteger256) -> i8 {
99+
match x.0.cmp(&y.0) {
100+
Less => -1,
101+
Equal => 0,
102+
Greater => 1,
103+
}
104+
}
105+
106+
#[wasm_bindgen]
107+
pub fn caml_bigint_256_print(x: WasmBigInteger256) {
108+
println!("{}", to_biguint(&x.0));
109+
}
110+
111+
#[wasm_bindgen]
112+
pub fn caml_bigint_256_to_string(x: WasmBigInteger256) -> String {
113+
to_biguint(&x.0).to_string()
114+
}
115+
116+
#[wasm_bindgen]
117+
pub fn caml_bigint_256_test_bit(x: WasmBigInteger256, i: i32) -> bool {
118+
match i.try_into() {
119+
Ok(i) => x.0.get_bit(i),
120+
Err(_) => panic!("caml_bigint_256_test_bit"),
121+
}
122+
}
123+
124+
#[wasm_bindgen]
125+
pub fn caml_bigint_256_to_bytes(x: WasmBigInteger256) -> Vec<u8> {
126+
let mut serialized_bytes = vec![];
127+
x.0.serialize_compressed(&mut serialized_bytes)
128+
.expect("serialize failed");
129+
serialized_bytes
130+
}
131+
132+
#[wasm_bindgen]
133+
pub fn caml_bigint_256_of_bytes(x: &[u8]) -> WasmBigInteger256 {
134+
let len = std::mem::size_of::<WasmBigInteger256>();
135+
if x.len() != len {
136+
panic!("caml_bigint_256_of_bytes");
137+
};
138+
// TODO this used FromBytes before arkworks 0.4.2, check serialization is consistent after update
139+
WasmBigInteger256(
140+
BigInteger256::deserialize_compressed(&mut &x[..]).expect("deserialization error"),
141+
)
142+
}
143+
144+
#[wasm_bindgen]
145+
pub fn caml_bigint_256_deep_copy(x: WasmBigInteger256) -> WasmBigInteger256 {
146+
x
147+
}

0 commit comments

Comments
 (0)