Additional externs for ecdsa recovery and keccak (#1583)

* Additional externs for ecdsa recovery and keccak

* Update core/executor/src/wasm_executor.rs

Co-Authored-By: gavofyork <github@gavwood.com>

* Update core/executor/src/wasm_executor.rs

Co-Authored-By: gavofyork <github@gavwood.com>

* Fix grumble

* Grumble.
This commit is contained in:
Gav Wood
2019-01-25 19:07:02 +00:00
committed by GitHub
parent 5ddcbe0ca6
commit c132e84572
14 changed files with 441 additions and 7 deletions
+28
View File
@@ -91,8 +91,11 @@ extern "C" {
fn ext_blake2_256(data: *const u8, len: u32, out: *mut u8);
fn ext_twox_128(data: *const u8, len: u32, out: *mut u8);
fn ext_twox_256(data: *const u8, len: u32, out: *mut u8);
fn ext_keccak_256(data: *const u8, len: u32, out: *mut u8);
/// Note: ext_ed25519_verify returns 0 if the signature is correct, nonzero otherwise.
fn ext_ed25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32;
/// Note: ext_secp256k1_ecdsa_recover returns 0 if the signature is correct, nonzero otherwise.
fn ext_secp256k1_ecdsa_recover(msg_data: *const u8, sig_data: *const u8, pubkey_data: *mut u8) -> u32;
}
/// Ensures we use the right crypto when calling into native
@@ -343,6 +346,15 @@ pub fn blake2_256(data: &[u8]) -> [u8; 32] {
result
}
/// Conduct a 256-bit Keccak hash.
pub fn keccak_256(data: &[u8]) -> [u8; 32] {
let mut result: [u8; 32] = Default::default();
unsafe {
ext_keccak_256(data.as_ptr(), data.len() as u32, result.as_mut_ptr());
}
result
}
/// Conduct four XX hashes to give a 256-bit result.
pub fn twox_256(data: &[u8]) -> [u8; 32] {
let mut result: [u8; 32] = Default::default();
@@ -368,6 +380,22 @@ pub fn ed25519_verify<P: AsRef<[u8]>>(sig: &[u8; 64], msg: &[u8], pubkey: P) ->
}
}
/// Verify and recover a SECP256k1 ECDSA signature.
/// - `sig` is passed in RSV format. V should be either 0/1 or 27/28.
/// - returns `None` if the signatue is bad, the 64-byte pubkey (doesn't include the 0x04 prefix).
pub fn secp256k1_ecdsa_recover(sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 64], EcdsaVerifyError> {
let mut pubkey = [0u8; 64];
match unsafe {
ext_secp256k1_ecdsa_recover(msg.as_ptr(), sig.as_ptr(), pubkey.as_mut_ptr())
} {
0 => Ok(pubkey),
1 => Err(EcdsaVerifyError::BadRS),
2 => Err(EcdsaVerifyError::BadV),
3 => Err(EcdsaVerifyError::BadSignature),
_ => unreachable!("`ext_secp256k1_ecdsa_recover` only returns 0, 1, 2 or 3; qed"),
}
}
/// Trait for things which can be printed.
pub trait Printable {
fn print(self);