Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
43 changes: 40 additions & 3 deletions core/executor/src/wasm_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use wasmi::memory_units::{Pages};
use state_machine::Externalities;
use crate::error::{Error, ErrorKind, Result};
use crate::wasm_utils::UserError;
use primitives::{blake2_256, twox_128, twox_256, ed25519};
use primitives::{blake2_256, twox_128, twox_256, ed25519, sr25519};
use primitives::hexdisplay::HexDisplay;
use primitives::sandbox as sandbox_primitives;
use primitives::{H256, Blake2Hasher};
Expand Down Expand Up @@ -480,6 +480,19 @@ impl_function_executor!(this: FunctionExecutor<'e, E>,
5
})
},
ext_sr25519_verify(msg_data: *const u8, msg_len: u32, sig_data: *const u8, pubkey_data: *const u8) -> u32 => {
let mut sig = [0u8; 64];
this.memory.get_into(sig_data, &mut sig[..]).map_err(|_| UserError("Invalid attempt to get signature in ext_sr25519_verify"))?;
let mut pubkey = [0u8; 32];
this.memory.get_into(pubkey_data, &mut pubkey[..]).map_err(|_| UserError("Invalid attempt to get pubkey in ext_sr25519_verify"))?;
let msg = this.memory.get(msg_data, msg_len as usize).map_err(|_| UserError("Invalid attempt to get message in ext_sr25519_verify"))?;

Ok(if sr25519::verify(&sig, &msg, &pubkey) {
0
} else {
5
})
},
ext_secp256k1_ecdsa_recover(msg_data: *const u8, sig_data: *const u8, pubkey_data: *mut u8) -> u32 => {
let mut sig = [0u8; 65];
this.memory.get_into(sig_data, &mut sig[..]).map_err(|_| UserError("Invalid attempt to get signature in ext_secp256k1_ecdsa_recover"))?;
Expand Down Expand Up @@ -884,6 +897,32 @@ mod tests {
);
}

#[test]
fn sr25519_verify_should_work() {
let mut ext = TestExternalities::<Blake2Hasher>::default();
let test_code = include_bytes!("../wasm/target/wasm32-unknown-unknown/release/runtime_test.compact.wasm");
let key = sr25519::Pair::from_seed(&blake2_256(b"test"));
let sig = key.sign(b"all ok!");
let mut calldata = vec![];
calldata.extend_from_slice(key.public().as_ref());
calldata.extend_from_slice(sig.as_ref());

assert_eq!(
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sr25519_verify", &calldata).unwrap(),
vec![1]
);

let other_sig = key.sign(b"all is not ok!");
let mut calldata = vec![];
calldata.extend_from_slice(key.public().as_ref());
calldata.extend_from_slice(other_sig.as_ref());

assert_eq!(
WasmExecutor::new().call(&mut ext, 8, &test_code[..], "test_sr25519_verify", &calldata).unwrap(),
vec![0]
);
}

#[test]
fn enumerated_trie_root_should_work() {
let mut ext = TestExternalities::<Blake2Hasher>::default();
Expand All @@ -893,6 +932,4 @@ mod tests {
ordered_trie_root::<Blake2Hasher, _, _>(vec![b"zero".to_vec(), b"one".to_vec(), b"two".to_vec()].iter()).as_fixed_bytes().encode()
);
}


}
12 changes: 11 additions & 1 deletion core/executor/wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use alloc::slice;

use runtime_io::{
set_storage, storage, clear_prefix, print, blake2_256,
twox_128, twox_256, ed25519_verify, enumerated_trie_root
twox_128, twox_256, ed25519_verify, sr25519_verify, enumerated_trie_root
};

macro_rules! impl_stubs {
Expand Down Expand Up @@ -79,6 +79,16 @@ impl_stubs!(
let msg = b"all ok!";
[ed25519_verify(&sig, &msg[..], &pubkey) as u8].to_vec()
},
test_sr25519_verify => |input: &[u8]| {
let mut pubkey = [0; 32];
let mut sig = [0; 64];

pubkey.copy_from_slice(&input[0..32]);
sig.copy_from_slice(&input[32..96]);

let msg = b"all ok!";
[sr25519_verify(&sig, &msg[..], &pubkey) as u8].to_vec()
},
test_enumerated_trie_root => |_| {
enumerated_trie_root::<substrate_primitives::Blake2Hasher>(&[&b"zero"[..], &b"one"[..], &b"two"[..]]).to_vec()
},
Expand Down
7 changes: 6 additions & 1 deletion core/sr-io/with_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ extern crate secp256k1;
#[doc(hidden)]
pub extern crate parity_codec as codec;
// re-export hashing functions.
pub use primitives::{blake2_256, twox_128, twox_256, ed25519};
pub use primitives::{blake2_256, twox_128, twox_256, ed25519, sr25519};
pub use tiny_keccak::keccak256 as keccak_256;

pub use primitives::{Blake2Hasher};
Expand Down Expand Up @@ -203,6 +203,11 @@ pub fn ed25519_verify<P: AsRef<[u8]>>(sig: &[u8; 64], msg: &[u8], pubkey: P) ->
ed25519::verify(sig, msg, pubkey)
}

/// Verify an sr25519 signature.
pub fn sr25519_verify<P: AsRef<[u8]>>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> bool {
sr25519::verify(sig, msg, pubkey)
}

/// Verify and recover a SECP256k1 ECDSA signature.
/// - `sig` is passed in RSV format. V should be either 0/1 or 27/28.
/// - returns `Err` if the signatue is bad, otherwise the 64-byte pubkey (doesn't include the 0x04 prefix).
Expand Down
9 changes: 9 additions & 0 deletions core/sr-io/without_std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ extern "C" {
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_sr25519_verify returns 0 if the signature is correct, nonzero otherwise.
fn ext_sr25519_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;
}
Expand Down Expand Up @@ -376,6 +378,13 @@ pub fn ed25519_verify<P: AsRef<[u8]>>(sig: &[u8; 64], msg: &[u8], pubkey: P) ->
}
}

/// Verify a sr25519 signature.
pub fn sr25519_verify<P: AsRef<[u8]>>(sig: &[u8; 64], msg: &[u8], pubkey: P) -> bool {
unsafe {
ext_sr25519_verify(msg.as_ptr(), msg.len() as u32, sig.as_ptr(), pubkey.as_ref().as_ptr()) == 0
}
}

/// 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).
Expand Down
18 changes: 18 additions & 0 deletions core/sr-primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,24 @@ impl From<H512> for Ed25519Signature {
}
}

/// Sr25519 signature verify.
#[derive(Eq, PartialEq, Clone, Default, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
pub struct Sr25519Signature(pub H512);

impl Verify for Sr25519Signature {
type Signer = H256;
fn verify<L: Lazy<[u8]>>(&self, mut msg: L, signer: &Self::Signer) -> bool {
runtime_io::sr25519_verify((self.0).as_fixed_bytes(), msg.get(), &signer.as_bytes())
}
}

impl From<H512> for Sr25519Signature {
fn from(h: H512) -> Sr25519Signature {
Sr25519Signature(h)
}
}

#[derive(Eq, PartialEq, Clone, Copy, Decode)]
#[cfg_attr(feature = "std", derive(Debug, Serialize))]
#[repr(u8)]
Expand Down
13 changes: 7 additions & 6 deletions node/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,19 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(not(feature = "std"), feature(alloc))]

use runtime_primitives::generic;
use runtime_primitives::{OpaqueExtrinsic, traits::BlakeTwo256};
use runtime_primitives::{
generic, traits::{Verify, BlakeTwo256, Sr25519Signature}, OpaqueExtrinsic
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is Sr25519Signature being imported from traits submodule of the runtime? Moving it outside (directly imported from runtime_primitives) seems to take the build error at least a step further toward success.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed that - was just a typo.

};

/// An index to a block.
pub type BlockNumber = u64;

/// Alias to 512-bit hash when used in the context of a signature on the chain.
pub type Signature = Sr25519Signature;

/// Alias to Ed25519 pubkey that identifies an account on the chain. This will almost
/// certainly continue to be the same as the substrate's `AuthorityId`.
pub type AccountId = ::primitives::H256;
pub type AccountId = <Signature as Verify>::Signer;

/// The type for looking up accounts. We don't expect more than 4 billion of them, but you
/// never know...
Expand All @@ -48,9 +52,6 @@ pub type Index = u64;
/// A hash of some data used by the chain.
pub type Hash = primitives::H256;

/// Alias to 512-bit hash when used in the context of a signature on the chain.
pub type Signature = runtime_primitives::Ed25519Signature;

/// A timestamp: seconds since the unix epoch.
pub type Timestamp = u64;

Expand Down