Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wasm readability #115

Merged
merged 2 commits into from
Jul 17, 2024
Merged
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
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",
))
}
Loading