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

Add sign&verify and external witnesses #57

Merged
merged 8 commits into from
Oct 22, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
62 changes: 62 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,50 @@ use std::ops::{Add, Sub};
use std::str::FromStr;
use wasm_bindgen::prelude::*;

macro_rules! impl_signature {
($name:ident, $signee_type:ty, $verifier_type:ty) => {
#[wasm_bindgen]
pub struct $name(crypto::Signature<$signee_type, $verifier_type>);

#[wasm_bindgen]
impl $name {
pub fn to_bytes(&self) -> Vec<u8> {
self.0.to_bytes()
}

pub fn to_bech32(&self) -> String {
self.0.to_bech32_str()
}

pub fn to_hex(&self) -> String {
hex::encode(&self.0.as_ref())
}

pub fn from_bytes(bytes: &[u8]) -> Result<$name, JsValue> {
crypto::Signature::from_binary(bytes)
.map($name)
.map_err(|e| JsValue::from_str(&format!("{}", e)))
}

pub fn from_bech32(bech32_str: &str) -> Result<$name, JsValue> {
crypto::Signature::try_from_bech32_str(&bech32_str)
.map($name)
.map_err(|e| JsValue::from_str(&format!("{}", e)))
}

pub fn from_hex(input: &str) -> Result<$name, JsValue> {
crypto::Signature::from_str(input)
.map_err(|e| JsValue::from_str(&format!("{:?}", e)))
.map($name)
}
}
};
}

impl_signature!(Ed25519Signature, Vec<u8>, crypto::Ed25519);
impl_signature!(AccountWitness, tx::WitnessAccountData, crypto::Ed25519);
impl_signature!(UtxoWitness, tx::WitnessUtxoData, crypto::Ed25519);

/// ED25519 signing key, either normal or extended
#[wasm_bindgen]
pub struct PrivateKey(key::EitherEd25519SecretKey);
Expand Down Expand Up @@ -88,6 +132,10 @@ impl PrivateKey {
.map(PrivateKey)
.map_err(|_| JsValue::from_str("Invalid normal secret key"))
}

pub fn sign(&self, message: &[u8]) -> Ed25519Signature {
Ed25519Signature(self.0.sign(&message.to_vec()))
}
}

/// ED25519 key used as public key
Expand Down Expand Up @@ -123,6 +171,10 @@ impl PublicKey {
.map_err(|e| JsValue::from_str(&format!("{}", e)))
.map(PublicKey)
}

pub fn verify(&self, data: &[u8], signature: &Ed25519Signature) -> bool {
signature.0.verify_slice(&self.0, data) == crypto::Verification::Success
}
}

#[wasm_bindgen]
Expand Down Expand Up @@ -1425,6 +1477,11 @@ impl Witness {
))
}

// Witness for a utxo-based transaction generated externally (such as hardware wallets)
pub fn from_external_utxo(witness: &UtxoWitness) -> Witness {
Witness(tx::Witness::Utxo(witness.0.clone()))
}

/// Generate Witness for an account based transaction Input
/// the account-spending-counter should be incremented on each transaction from this account
pub fn for_account(
Expand All @@ -1441,6 +1498,11 @@ impl Witness {
))
}

// Witness for a account-based transaction generated externally (such as hardware wallets)
pub fn from_external_account(witness: &AccountWitness) -> Witness {
Witness(tx::Witness::Account(witness.0.clone()))
}

/// Get string representation
pub fn to_bech32(&self) -> Result<String, JsValue> {
let bytes = self
Expand Down