Skip to content

Commit

Permalink
Wasm readability (#115)
Browse files Browse the repository at this point in the history
reorg code for better reading through
  • Loading branch information
skaunov authored Jul 17, 2024
1 parent 83e3ed9 commit 92315e2
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 49 deletions.
5 changes: 2 additions & 3 deletions javascript/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,23 @@ license = "MIT"
crate-type = ["cdylib", "rlib"]

[features]
# I'd alias this to `sec1` if that won't be tricky
verify = ["dep:sec1"]

[dependencies]
wasm-bindgen = "~0.2.84"
js-sys = "0.3"

plume_rustcrypto = {version = "~0.2.1", default-features = false}
sec1 = {version = "~0.7.3", optional = true} # match with `k256`
elliptic-curve = {version = "~0.13.8"}
zeroize = "1.8"
signature = "^2.2.0"
getrandom = { version = "0.2", features = ["js"] }
anyhow = "1"
sec1 = {version = "~0.7.3", optional = true} # match with `k256`

[dev-dependencies]
wasm-bindgen-test = "~0.3.34"

[profile.release] # This comes from template; didn't touch this yet - docs doesn't tell much about it.
[profile.release] # This comes from template; docs doesn't tell much about it.
# Tell `rustc` to optimize for small code size.
# opt-level = "s"
91 changes: 45 additions & 46 deletions javascript/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
//! sadly `wasm-bindgen` doesn't support top-level @module docs yet

#[cfg(feature = "verify")]
use std::convert::TryInto;

use wasm_bindgen::prelude::*;

#[cfg(feature = "verify")]
use elliptic_curve::sec1::FromEncodedPoint;
use elliptic_curve::sec1::ToEncodedPoint;
use signature::RandomizedSigner;
#[cfg(feature = "verify")]
use std::convert::TryInto;
use zeroize::Zeroize;

#[wasm_bindgen(getter_with_clone)]
Expand Down Expand Up @@ -45,13 +44,6 @@ impl PlumeSignatureV1Fields {

#[wasm_bindgen]
impl PlumeSignature {
#[cfg(feature = "verify")]
/// @deprecated Use this only for testing purposes.
/// @throws an error if the data in the object doesn't let it to properly run verification; message contains nature of the problem and indicates relevant property of the object. In case of other (crypto) problems returns `false`.
pub fn verify(self) -> Result<bool, JsError> {
Ok(plume_rustcrypto::PlumeSignature::verify(&self.try_into()?))
}

/// there's no case for constructing it from values, so this only used internally and for testing
/// `v1specific` discriminates if it's V1 or V2 scheme used. Pls, see wrapped docs for details.
#[wasm_bindgen(constructor)]
Expand Down Expand Up @@ -97,6 +89,13 @@ impl PlumeSignature {
v1.r_point.zeroize();
}
}

#[cfg(feature = "verify")]
/// @deprecated Use this only for testing purposes.
/// @throws an error if the data in the object doesn't let it to properly run verification; message contains nature of the problem and indicates relevant property of the object. In case of other (crypto) problems returns `false`.
pub fn verify(self) -> Result<bool, JsError> {
Ok(plume_rustcrypto::PlumeSignature::verify(&self.try_into()?))
}
}

#[wasm_bindgen(skip_jsdoc)]
Expand All @@ -115,6 +114,42 @@ pub fn sign(v1: bool, sk: &mut [u8], msg: &[u8]) -> Result<PlumeSignature, JsErr
.into())
}

impl From<plume_rustcrypto::PlumeSignature> for PlumeSignature {
fn from(value: plume_rustcrypto::PlumeSignature) -> Self {
PlumeSignature {
message: value.message,
pk: value.pk.to_encoded_point(true).as_bytes().to_vec(),
nullifier: value.nullifier.to_encoded_point(true).as_bytes().to_vec(),
c: plume_rustcrypto::SecretKey::from(value.c).to_sec1_der().expect("`k256` restricts this type to proper keys, so it's serialized representation shouldn't have a chance to fail")
.to_vec(),
s: plume_rustcrypto::SecretKey::from(value.s).to_sec1_der().expect("`k256` restricts this type to proper keys, so it's serialized representation shouldn't have a chance to fail")
.to_vec(),
v1specific: value.v1specific.map(|v1| {PlumeSignatureV1Fields {
r_point: v1.r_point.to_encoded_point(true).as_bytes().to_vec(),
hashed_to_curve_r: v1.hashed_to_curve_r.to_encoded_point(true).as_bytes().to_vec(),
}})
}
}
}

#[wasm_bindgen(js_name = sec1DerScalarToBigint)]
/// This might leave values in memory! Don't use for private values.
/// JS most native format for scalar is `BigInt`, but it's not really transportable or secure, so for uniformity of approach `s` in `PlumeSignature` is defined similar to `c`;
/// but if you want to have it as a `BigInt` this util is left here.
pub fn sec1derscalar_to_bigint(scalar: &[u8]) -> Result<js_sys::BigInt, JsError> {
Ok(js_sys::BigInt::new(&JsValue::from_str(
("0x".to_owned()
+ plume_rustcrypto::SecretKey::from_sec1_der(scalar)?
.to_nonzero_scalar()
.to_string()
.as_str())
.as_str(),
))
.expect(
"`BigInt` always can be created from hex string, and `v.to_string()` always produce that",
))
}

// TODO deprecate when `verify` gone
#[cfg(feature = "verify")]
impl TryInto<plume_rustcrypto::PlumeSignature> for PlumeSignature {
Expand Down Expand Up @@ -159,39 +194,3 @@ impl TryInto<plume_rustcrypto::PlumeSignature> for PlumeSignature {
})
}
}

impl From<plume_rustcrypto::PlumeSignature> for PlumeSignature {
fn from(value: plume_rustcrypto::PlumeSignature) -> Self {
PlumeSignature {
message: value.message,
pk: value.pk.to_encoded_point(true).as_bytes().to_vec(),
nullifier: value.nullifier.to_encoded_point(true).as_bytes().to_vec(),
c: plume_rustcrypto::SecretKey::from(value.c).to_sec1_der().expect("`k256` restricts this type to proper keys, so it's serialized representation shouldn't have a chance to fail")
.to_vec(),
s: plume_rustcrypto::SecretKey::from(value.s).to_sec1_der().expect("`k256` restricts this type to proper keys, so it's serialized representation shouldn't have a chance to fail")
.to_vec(),
v1specific: value.v1specific.map(|v1| {PlumeSignatureV1Fields {
r_point: v1.r_point.to_encoded_point(true).as_bytes().to_vec(),
hashed_to_curve_r: v1.hashed_to_curve_r.to_encoded_point(true).as_bytes().to_vec(),
}})
}
}
}

#[wasm_bindgen(js_name = sec1DerScalarToBigint)]
/// This might leave values in memory! Don't use for private values.
/// JS most native format for scalar is `BigInt`, but it's not really transportable or secure, so for uniformity of approach `s` in `PlumeSignature` is defined similar to `c`;
/// but if you want to have it as a `BigInt` this util is left here.
pub fn sec1derscalar_to_bigint(scalar: &[u8]) -> Result<js_sys::BigInt, JsError> {
Ok(js_sys::BigInt::new(&JsValue::from_str(
("0x".to_owned()
+ plume_rustcrypto::SecretKey::from_sec1_der(scalar)?
.to_nonzero_scalar()
.to_string()
.as_str())
.as_str(),
))
.expect(
"`BigInt` always can be created from hex string, and `v.to_string()` always produce that",
))
}

0 comments on commit 92315e2

Please sign in to comment.