Skip to content
This repository has been archived by the owner on Feb 26, 2020. It is now read-only.

Commit

Permalink
finalize error handling #1
Browse files Browse the repository at this point in the history
  • Loading branch information
kianenigma committed Feb 15, 2019
1 parent 36f28c6 commit ddb7e86
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 20 deletions.
36 changes: 21 additions & 15 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;

extern crate schnorrkel;
extern crate sha2;

mod wrapper;
use wrapper::*;
Expand All @@ -17,8 +18,11 @@ use wrapper::*;
///
/// * returned vector is the signature consisting of 64 bytes.
#[wasm_bindgen]
pub fn sign(secret: &[u8], message: &[u8]) -> Vec<u8> {
__sign(secret, message).to_vec()
pub fn sign(secret: &[u8], message: &[u8]) -> Result<Vec<u8>, JsValue> {
match __sign(secret, message) {
Ok(some_sig) => Ok(some_sig.to_vec()),
Err(err) => Err(JsValue::from_str(&format!("{}", err)))
}
}

/// Verify a message and its corresponding against a public key;
Expand All @@ -32,8 +36,11 @@ pub fn verify(signature: &[u8], message: &[u8], pubkey: &[u8]) -> bool {
}

#[wasm_bindgen]
pub fn expand_to_public(secret: &[u8]) -> Vec<u8> {
__expand_to_public(secret).to_vec()
pub fn expand_to_public(secret: &[u8]) -> Result<Vec<u8>, JsValue> {
match __expand_to_public(secret) {
Ok(some_public) => Ok(some_public.to_vec()),
Err(err) => Err(JsValue::from_str(&format!("{}", err)))
}
}

/// Generate a secret key (aka. private key) from a seed phrase.
Expand All @@ -45,7 +52,7 @@ pub fn expand_to_public(secret: &[u8]) -> Vec<u8> {
pub fn secret_from_seed(seed: &[u8]) -> Result<Vec<u8>, JsValue> {
match __secret_from_seed(seed) {
Ok(some_seed) => Ok(some_seed.to_vec()),
Err(_) => Err(JsValue::from_str("make sure the seed is 32 bytes"))
Err(err) => Err(JsValue::from_str(&format!("{}", err)))
}
}

Expand All @@ -59,8 +66,7 @@ pub fn secret_from_seed(seed: &[u8]) -> Result<Vec<u8>, JsValue> {
pub fn keypair_from_seed(seed: &[u8]) -> Result<Vec<u8>, JsValue> {
match __keypair_from_seed(seed) {
Ok(some_kp) => Ok(some_kp.to_vec()),
Err(err) => Err(JsValue::from_str(&format!("{}", err))
)
Err(err) => Err(JsValue::from_str(&format!("{}", err)))
}
}

Expand All @@ -85,45 +91,45 @@ pub mod tests {
#[wasm_bindgen_test]
fn can_create_keypair() {
let seed = generate_random_seed();
let keypair = keypair_from_seed(seed.as_slice());
let keypair = keypair_from_seed(seed.as_slice()).unwrap();
assert!(keypair.len() == KEYPAIR_LENGTH);
}

#[wasm_bindgen_test]
fn can_create_secret() {
let seed = generate_random_seed();
let secret = secret_from_seed(seed.as_slice());
let secret = secret_from_seed(seed.as_slice()).unwrap();
assert!(secret.len() == SECRET_KEY_LENGTH);
}

#[wasm_bindgen_test]
fn can_sign_message() {
let seed = generate_random_seed();
let keypair = keypair_from_seed(seed.as_slice());
let keypair = keypair_from_seed(seed.as_slice()).unwrap();
let private = &keypair[0..SECRET_KEY_LENGTH];
let message = b"this is a message";
let signature = sign(private, message);
let signature = sign(private, message).unwrap();
assert!(signature.len() == SIGNATURE_LENGTH);
}

#[wasm_bindgen_test]
fn can_verify_message() {
let seed = generate_random_seed();
let keypair = keypair_from_seed(seed.as_slice());
let keypair = keypair_from_seed(seed.as_slice()).unwrap();
let private = &keypair[0..SECRET_KEY_LENGTH];
let public = &keypair[SECRET_KEY_LENGTH..KEYPAIR_LENGTH];
let message = b"this is a message";
let signature = sign(private, message);
let signature = sign(private, message).unwrap();
assert!(verify(&signature[..], message, public));
}

#[wasm_bindgen_test]
fn can_extract_public_from_secret() {
let seed = generate_random_seed();
let keypair = keypair_from_seed(seed.as_ref());
let keypair = keypair_from_seed(seed.as_ref()).unwrap();
let private = &keypair[0..SECRET_KEY_LENGTH];
let known_public = &keypair[SECRET_KEY_LENGTH..KEYPAIR_LENGTH];
let inferred_public = expand_to_public(private);
let inferred_public = expand_to_public(private).unwrap();
assert!(known_public.to_vec() == inferred_public);
}
}
22 changes: 17 additions & 5 deletions src/wrapper.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@

use schnorrkel::keys::*;
use schnorrkel::context::{signing_context};
use schnorrkel::sign::{Signature,SIGNATURE_LENGTH};
use schnorrkel::SignatureError;

use sha2::Sha512;

// We must make sure that this is the same as declared in the substrate source code.
const SIGNING_CTX: &'static [u8] = b"substrate transaction";

pub fn __sign(secret: &[u8], message: &[u8]) -> Result<[u8; SIGNATURE_LENGTH], SignatureError> {
let secret_key = SecretKey::from_bytes(secret)?;
let kp = secret_key.to_keypair();
// TODO: This can be used once the new version of schnorrkel is out on crates.io
// let kp = secret_key.to_keypair();
// let context = signing_context(SIGNING_CTX);
// Ok(kp.sign(context.bytes(message)).to_bytes())

// Temporary replacement method:
let public = secret_key.to_public();
let kp = Keypair {
public: public,
secret: secret_key
};

let context = signing_context(SIGNING_CTX);
Ok(kp.sign(context.bytes(message)).to_bytes())
}
Expand All @@ -29,7 +41,7 @@ pub fn __verify(signature: &[u8], message: &[u8], pubkey: &[u8]) -> bool {
/// Private helper function.
fn keypair_from_seed(seed: &[u8]) -> Result<Keypair, SignatureError> {
let mini_key: MiniSecretKey = MiniSecretKey::from_bytes(seed)?;
Ok(mini_key.expand_to_keypair())
Ok(mini_key.expand_to_keypair::<Sha512>())
}

pub fn __keypair_from_seed(seed: &[u8]) -> Result<[u8; KEYPAIR_LENGTH], SignatureError> {
Expand All @@ -46,6 +58,6 @@ pub fn __secret_from_seed(seed: &[u8]) -> Result<[u8; SECRET_KEY_LENGTH], Signat
Ok(s)
}

pub fn __expand_to_public(secret: &[u8]) -> [u8; PUBLIC_KEY_LENGTH] {
SecretKey::from_bytes(secret).unwrap().to_public().to_bytes()
pub fn __expand_to_public(secret: &[u8]) -> Result<[u8; PUBLIC_KEY_LENGTH], SignatureError> {
Ok(SecretKey::from_bytes(secret)?.to_public().to_bytes())
}

0 comments on commit ddb7e86

Please sign in to comment.