Skip to content

Commit 301aa74

Browse files
committed
WASM: add bindings for the primitive types
Added bindings for: - `Scalar` - `Fr` - `ExtendedPoint` - `SubgroupPoint` - `Nullifier` - `redjubjub::PrivateKey` - `redjubjub::PublicKey` - `redjubjub::Signature` These are all structs that are required by transactions.
1 parent a243067 commit 301aa74

File tree

4 files changed

+270
-0
lines changed

4 files changed

+270
-0
lines changed

Cargo.lock

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

ironfish-rust-wasm/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ publish = false
1414
crate-type = ["cdylib"]
1515

1616
[dependencies]
17+
blstrs = "0.6.0"
1718
getrandom = { version = "0.2.8", features = ["js"] } # need to explicitly enable the `js` feature in order to run in a browser
19+
group = "0.12.0"
1820
ironfish = { version = "0.3.0", path = "../ironfish-rust" }
21+
ironfish-jubjub = "0.1.0"
22+
ironfish_zkp = { version = "0.2.0", path = "../ironfish-zkp" }
23+
rand = "0.8.5"
1924
wasm-bindgen = "0.2.95"

ironfish-rust-wasm/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
use getrandom as _;
1111

1212
pub mod errors;
13+
pub mod primitives;

ironfish-rust-wasm/src/primitives.rs

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
use crate::errors::IronfishError;
2+
use group::GroupEncoding;
3+
use ironfish::errors::IronfishErrorKind;
4+
use ironfish_zkp::redjubjub;
5+
use rand::thread_rng;
6+
use wasm_bindgen::prelude::*;
7+
8+
#[wasm_bindgen]
9+
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
10+
pub struct Scalar(blstrs::Scalar);
11+
12+
#[wasm_bindgen]
13+
impl Scalar {
14+
#[wasm_bindgen(js_name = toBytesBe)]
15+
pub fn to_bytes_be(&self) -> Vec<u8> {
16+
self.0.to_bytes_be().to_vec()
17+
}
18+
19+
#[wasm_bindgen(js_name = toBytesLe)]
20+
pub fn to_bytes_le(&self) -> Vec<u8> {
21+
self.0.to_bytes_le().to_vec()
22+
}
23+
}
24+
25+
impl From<blstrs::Scalar> for Scalar {
26+
fn from(s: blstrs::Scalar) -> Self {
27+
Self(s)
28+
}
29+
}
30+
31+
impl AsRef<blstrs::Scalar> for Scalar {
32+
fn as_ref(&self) -> &blstrs::Scalar {
33+
&self.0
34+
}
35+
}
36+
37+
#[wasm_bindgen]
38+
#[derive(Default, Copy, Clone, PartialEq, Eq, Debug)]
39+
pub struct Fr(ironfish_jubjub::Fr);
40+
41+
#[wasm_bindgen]
42+
impl Fr {
43+
#[wasm_bindgen(js_name = toBytes)]
44+
pub fn to_bytes(&self) -> Vec<u8> {
45+
self.0.to_bytes().to_vec()
46+
}
47+
}
48+
49+
impl From<ironfish_jubjub::Fr> for Fr {
50+
fn from(s: ironfish_jubjub::Fr) -> Self {
51+
Self(s)
52+
}
53+
}
54+
55+
impl AsRef<ironfish_jubjub::Fr> for Fr {
56+
fn as_ref(&self) -> &ironfish_jubjub::Fr {
57+
&self.0
58+
}
59+
}
60+
61+
#[wasm_bindgen]
62+
#[derive(Default, Copy, Clone, PartialEq, Eq, Debug)]
63+
pub struct ExtendedPoint(ironfish_jubjub::ExtendedPoint);
64+
65+
#[wasm_bindgen]
66+
impl ExtendedPoint {
67+
#[wasm_bindgen(js_name = toBytes)]
68+
pub fn to_bytes(&self) -> Vec<u8> {
69+
self.0.to_bytes().to_vec()
70+
}
71+
}
72+
73+
impl From<ironfish_jubjub::ExtendedPoint> for ExtendedPoint {
74+
fn from(s: ironfish_jubjub::ExtendedPoint) -> Self {
75+
Self(s)
76+
}
77+
}
78+
79+
impl AsRef<ironfish_jubjub::ExtendedPoint> for ExtendedPoint {
80+
fn as_ref(&self) -> &ironfish_jubjub::ExtendedPoint {
81+
&self.0
82+
}
83+
}
84+
85+
#[wasm_bindgen]
86+
#[derive(Default, Copy, Clone, PartialEq, Eq, Debug)]
87+
pub struct SubgroupPoint(ironfish_jubjub::SubgroupPoint);
88+
89+
#[wasm_bindgen]
90+
impl SubgroupPoint {
91+
#[wasm_bindgen(js_name = toBytes)]
92+
pub fn to_bytes(&self) -> Vec<u8> {
93+
self.0.to_bytes().to_vec()
94+
}
95+
}
96+
97+
impl From<ironfish_jubjub::SubgroupPoint> for SubgroupPoint {
98+
fn from(s: ironfish_jubjub::SubgroupPoint) -> Self {
99+
Self(s)
100+
}
101+
}
102+
103+
impl AsRef<ironfish_jubjub::SubgroupPoint> for SubgroupPoint {
104+
fn as_ref(&self) -> &ironfish_jubjub::SubgroupPoint {
105+
&self.0
106+
}
107+
}
108+
109+
#[wasm_bindgen]
110+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
111+
pub struct Nullifier(ironfish_zkp::Nullifier);
112+
113+
#[wasm_bindgen]
114+
impl Nullifier {
115+
#[wasm_bindgen(js_name = toBytes)]
116+
pub fn to_bytes(&self) -> Vec<u8> {
117+
self.0.to_vec()
118+
}
119+
}
120+
121+
impl From<ironfish_zkp::Nullifier> for Nullifier {
122+
fn from(s: ironfish_zkp::Nullifier) -> Self {
123+
Self(s)
124+
}
125+
}
126+
127+
impl AsRef<ironfish_zkp::Nullifier> for Nullifier {
128+
fn as_ref(&self) -> &ironfish_zkp::Nullifier {
129+
&self.0
130+
}
131+
}
132+
133+
#[wasm_bindgen]
134+
pub struct PrivateKey(redjubjub::PrivateKey);
135+
136+
#[wasm_bindgen]
137+
impl PrivateKey {
138+
#[wasm_bindgen(constructor)]
139+
pub fn deserialize(bytes: &[u8]) -> Result<Self, IronfishError> {
140+
let s = redjubjub::PrivateKey::read(bytes)?;
141+
Ok(Self::from(s))
142+
}
143+
144+
#[wasm_bindgen]
145+
pub fn serialize(&self) -> Vec<u8> {
146+
let mut buf = Vec::new();
147+
self.0.write(&mut buf).expect("serialization failed");
148+
buf
149+
}
150+
151+
#[wasm_bindgen]
152+
pub fn randomize(&self, alpha: &Fr) -> Self {
153+
self.0.randomize(*alpha.as_ref()).into()
154+
}
155+
156+
#[wasm_bindgen]
157+
pub fn sign(&self, msg: &[u8], p_g: &SubgroupPoint) -> Signature {
158+
self.0.sign(msg, &mut thread_rng(), *p_g.as_ref()).into()
159+
}
160+
161+
#[wasm_bindgen(js_name = toPublicKey)]
162+
pub fn to_public_key(&self, p_g: &SubgroupPoint) -> PublicKey {
163+
redjubjub::PublicKey::from_private(self.as_ref(), *p_g.as_ref()).into()
164+
}
165+
}
166+
167+
impl From<redjubjub::PrivateKey> for PrivateKey {
168+
fn from(p: redjubjub::PrivateKey) -> Self {
169+
Self(p)
170+
}
171+
}
172+
173+
impl AsRef<redjubjub::PrivateKey> for PrivateKey {
174+
fn as_ref(&self) -> &redjubjub::PrivateKey {
175+
&self.0
176+
}
177+
}
178+
179+
#[wasm_bindgen]
180+
#[derive(Clone, Debug)]
181+
pub struct PublicKey(redjubjub::PublicKey);
182+
183+
#[wasm_bindgen]
184+
impl PublicKey {
185+
#[wasm_bindgen(constructor)]
186+
pub fn deserialize(bytes: &[u8]) -> Result<Self, IronfishError> {
187+
let s = redjubjub::PublicKey::read(bytes)?;
188+
Ok(Self::from(s))
189+
}
190+
191+
#[wasm_bindgen]
192+
pub fn serialize(&self) -> Vec<u8> {
193+
let mut buf = Vec::new();
194+
self.0.write(&mut buf).expect("serialization failed");
195+
buf
196+
}
197+
198+
#[wasm_bindgen]
199+
pub fn randomize(&self, alpha: &Fr, p_g: &SubgroupPoint) -> Self {
200+
self.0.randomize(*alpha.as_ref(), *p_g.as_ref()).into()
201+
}
202+
203+
#[wasm_bindgen]
204+
pub fn verify(
205+
&self,
206+
msg: &[u8],
207+
sig: &Signature,
208+
p_g: &SubgroupPoint,
209+
) -> Result<(), IronfishError> {
210+
self.0
211+
.verify(msg, sig.as_ref(), *p_g.as_ref())
212+
.then_some(())
213+
.ok_or_else(|| IronfishErrorKind::InvalidSignature.into())
214+
}
215+
}
216+
217+
impl From<redjubjub::PublicKey> for PublicKey {
218+
fn from(p: redjubjub::PublicKey) -> Self {
219+
Self(p)
220+
}
221+
}
222+
223+
impl AsRef<redjubjub::PublicKey> for PublicKey {
224+
fn as_ref(&self) -> &redjubjub::PublicKey {
225+
&self.0
226+
}
227+
}
228+
229+
#[wasm_bindgen]
230+
#[derive(Clone, Debug)]
231+
pub struct Signature(redjubjub::Signature);
232+
233+
#[wasm_bindgen]
234+
impl Signature {
235+
#[wasm_bindgen(constructor)]
236+
pub fn deserialize(bytes: &[u8]) -> Result<Self, IronfishError> {
237+
let s = redjubjub::Signature::read(bytes)?;
238+
Ok(Self::from(s))
239+
}
240+
241+
#[wasm_bindgen]
242+
pub fn serialize(&self) -> Vec<u8> {
243+
let mut buf = Vec::new();
244+
self.0.write(&mut buf).expect("serialization failed");
245+
buf
246+
}
247+
}
248+
249+
impl From<redjubjub::Signature> for Signature {
250+
fn from(s: redjubjub::Signature) -> Self {
251+
Self(s)
252+
}
253+
}
254+
255+
impl AsRef<redjubjub::Signature> for Signature {
256+
fn as_ref(&self) -> &redjubjub::Signature {
257+
&self.0
258+
}
259+
}

0 commit comments

Comments
 (0)