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

runtime-sdk: Add sr25519 support in EVM precompiles #2073

Merged
merged 3 commits into from
Dec 8, 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
649 changes: 435 additions & 214 deletions Cargo.lock

Large diffs are not rendered by default.

518 changes: 362 additions & 156 deletions contract-sdk/specs/access/oas173/Cargo.lock

Large diffs are not rendered by default.

518 changes: 362 additions & 156 deletions contract-sdk/specs/token/oas20/Cargo.lock

Large diffs are not rendered by default.

656 changes: 441 additions & 215 deletions examples/runtime-sdk/rofl-oracle/Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions runtime-sdk/modules/evm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ test = ["serde", "serde_json"]
[[bench]]
name = "criterion_benchmark"
harness = false
required-features = ["test"]

[[bin]]
name = "fuzz-precompile"
Expand Down
75 changes: 49 additions & 26 deletions runtime-sdk/modules/evm/src/precompile/confidential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ static KEYPAIR_GENERATE_BASE_COST: Lazy<HashMap<SignatureType, u64>> = Lazy::new
(SignatureType::Secp256k1_PrehashedSha256, 1_500),
(SignatureType::Secp256r1_PrehashedSha256, 4_000),
(SignatureType::Secp384r1_PrehashedSha384, 18_000),
(SignatureType::Sr25519_Pure, 1_000),
])
});

Expand All @@ -58,6 +59,7 @@ static SIGN_MESSAGE_COST: Lazy<HashMap<SignatureType, (u64, u64)>> = Lazy::new(|
(SignatureType::Secp256k1_PrehashedSha256, (3_000, 0)),
(SignatureType::Secp256r1_PrehashedSha256, (9_000, 0)),
(SignatureType::Secp384r1_PrehashedSha384, (43_200, 0)),
(SignatureType::Sr25519_Pure, (1_500, 8)),
])
});

Expand All @@ -72,6 +74,7 @@ static VERIFY_MESSAGE_COST: Lazy<HashMap<SignatureType, (u64, u64)>> = Lazy::new
(SignatureType::Secp256k1_PrehashedSha256, (3_000, 0)),
(SignatureType::Secp256r1_PrehashedSha256, (7_900, 0)),
(SignatureType::Secp384r1_PrehashedSha384, (37_920, 0)),
(SignatureType::Sr25519_Pure, (2_000, 8)),
])
});

Expand Down Expand Up @@ -680,21 +683,6 @@ mod test {
.expect("call should return something")
.expect_err("call should fail");

// Unsupported method.
let params = ethabi::encode(&[
Token::Uint(6.into()), // sr25519 is not yet supported.
Token::Bytes(b"01234567890123456789012345678901".to_vec()),
]);
call_contract(
H160([
0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x05,
]),
&params,
10_000_000,
)
.expect("call should return something")
.expect_err("call should fail");

// Working test.
let params = ethabi::encode(&[
Token::Uint(SignatureType::Ed25519_Oasis.as_int().into()),
Expand Down Expand Up @@ -773,13 +761,18 @@ mod test {
bench_keypair_generate(b, SignatureType::Secp384r1_PrehashedSha384);
}

#[bench]
fn bench_keypair_generate_sr25519(b: &mut Bencher) {
bench_keypair_generate(b, SignatureType::Sr25519_Pure);
}

#[test]
fn test_basic_roundtrip() {
let seed = b"01234567890123456789012345678901";
let context = b"test context";
let message = b"test message";

for method in 0u8..6u8 {
for method in 0u8..=6u8 {
let sig_type: SignatureType = method.try_into().unwrap();
if sig_type.is_prehashed() {
// Tested in test_basic_roundtrip_prehashed below.
Expand Down Expand Up @@ -999,11 +992,6 @@ mod test {
.expect("call should return something")
.expect_err("call should fail");

// Unsupported method.
push_all_and_test(Some(6), None, None, None) // sr25519 is not yet supported.
.expect("call should return something")
.expect_err("call should fail");

// All ok, with context.
push_all_and_test(None, None, None, None)
.expect("call should return something")
Expand Down Expand Up @@ -1110,6 +1098,26 @@ mod test {
bench_signer(b, SignatureType::Secp384r1_PrehashedSha384, false, false);
}

#[bench]
fn bench_sign_sr25519_shortctx_shortmsg(b: &mut Bencher) {
bench_signer(b, SignatureType::Sr25519_Pure, false, false);
}

#[bench]
fn bench_sign_sr25519_shortctx_longmsg(b: &mut Bencher) {
bench_signer(b, SignatureType::Sr25519_Pure, false, true);
}

#[bench]
fn bench_sign_sr25519_longctx_shortmsg(b: &mut Bencher) {
bench_signer(b, SignatureType::Sr25519_Pure, true, false);
}

#[bench]
fn bench_sign_sr25519_longctx_longmsg(b: &mut Bencher) {
bench_signer(b, SignatureType::Sr25519_Pure, true, true);
}

#[test]
fn test_verification_params() {
fn push_all_and_test(
Expand Down Expand Up @@ -1156,11 +1164,6 @@ mod test {
.expect("call should return something")
.expect_err("call should fail");

// Unsupported method.
push_all_and_test(Some(6), None, None, None, None) // sr25519 is not yet supported.
.expect("call should return something")
.expect_err("call should fail");

// Invalid public key.
let zeroes: Vec<u8> = vec![0; 32];
let mut output = push_all_and_test(None, Some(&zeroes), None, None, None)
Expand Down Expand Up @@ -1307,4 +1310,24 @@ mod test {
fn bench_verify_secp384r1_prehashed_sha384(b: &mut Bencher) {
bench_verification(b, SignatureType::Secp384r1_PrehashedSha384, false, false);
}

#[bench]
fn bench_verify_sr25519_shortctx_shortmsg(b: &mut Bencher) {
bench_verification(b, SignatureType::Sr25519_Pure, false, false);
}

#[bench]
fn bench_verify_sr25519_shortctx_longmsg(b: &mut Bencher) {
bench_verification(b, SignatureType::Sr25519_Pure, false, true);
}

#[bench]
fn bench_verify_sr25519_longctx_shortmsg(b: &mut Bencher) {
bench_verification(b, SignatureType::Sr25519_Pure, true, false);
}

#[bench]
fn bench_verify_sr25519_longctx_longmsg(b: &mut Bencher) {
bench_verification(b, SignatureType::Sr25519_Pure, true, true);
}
}
4 changes: 2 additions & 2 deletions runtime-sdk/src/crypto/signature/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::convert::TryInto;
use base64::prelude::*;
use curve25519_dalek::{digest::consts::U64, edwards::CompressedEdwardsY};
use ed25519_dalek::Signer as _;
use rand_core::RngCore;
use rand_core::{CryptoRng, RngCore};
use sha2::{Digest as _, Sha512, Sha512_256};

use oasis_core_runtime::common::crypto::signature::{
Expand Down Expand Up @@ -217,7 +217,7 @@ impl MemorySigner {
}

impl Signer for MemorySigner {
fn random(rng: &mut impl RngCore) -> Result<Self, Error> {
fn random(rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error> {
let mut seed = [0u8; 32];
rng.fill_bytes(&mut seed);
Self::new_from_seed(&seed)
Expand Down
45 changes: 34 additions & 11 deletions runtime-sdk/src/crypto/signature/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use std::convert::TryFrom;

use digest::{typenum::Unsigned as _, Digest as _};
use rand_core::RngCore;
use rand_core::{CryptoRng, RngCore};
use thiserror::Error;

use crate::core::common::crypto::signature::{PublicKey as CorePublicKey, Signer as CoreSigner};
Expand Down Expand Up @@ -31,8 +31,8 @@ pub enum SignatureType {
Secp256k1_PrehashedKeccak256,
#[cbor(rename = "secp256k1_prehashed_sha256")]
Secp256k1_PrehashedSha256,
#[cbor(rename = "sr25519")]
Sr25519,
#[cbor(rename = "sr25519_pure")]
Sr25519_Pure,
#[cbor(rename = "secp256r1_prehashed_sha256")]
Secp256r1_PrehashedSha256,
#[cbor(rename = "secp384r1_prehashed_sha384")]
Expand All @@ -48,7 +48,7 @@ impl SignatureType {
Self::Secp256k1_Oasis => 3,
Self::Secp256k1_PrehashedKeccak256 => 4,
Self::Secp256k1_PrehashedSha256 => 5,
Self::Sr25519 => 6,
Self::Sr25519_Pure => 6,
Self::Secp256r1_PrehashedSha256 => 7,
Self::Secp384r1_PrehashedSha384 => 8,
}
Expand Down Expand Up @@ -88,6 +88,10 @@ impl SignatureType {
pub fn is_secp384r1_variant(&self) -> bool {
matches!(self, Self::Secp384r1_PrehashedSha384)
}

pub fn is_sr25519_variant(&self) -> bool {
matches!(self, Self::Sr25519_Pure)
}
}

impl TryFrom<u8> for SignatureType {
Expand All @@ -101,7 +105,7 @@ impl TryFrom<u8> for SignatureType {
3 => Ok(Self::Secp256k1_Oasis),
4 => Ok(Self::Secp256k1_PrehashedKeccak256),
5 => Ok(Self::Secp256k1_PrehashedSha256),
6 => Ok(Self::Sr25519),
6 => Ok(Self::Sr25519_Pure),
7 => Ok(Self::Secp256r1_PrehashedSha256),
8 => Ok(Self::Secp384r1_PrehashedSha384),
_ => Err(Error::InvalidArgument),
Expand Down Expand Up @@ -189,7 +193,9 @@ impl PublicKey {
SignatureType::Secp384r1_PrehashedSha384 => {
Ok(Self::Secp384r1(secp384r1::PublicKey::from_bytes(bytes)?))
}
SignatureType::Sr25519 => Ok(Self::Sr25519(sr25519::PublicKey::from_bytes(bytes)?)),
SignatureType::Sr25519_Pure => {
Ok(Self::Sr25519(sr25519::PublicKey::from_bytes(bytes)?))
}
}
}

Expand Down Expand Up @@ -298,7 +304,10 @@ impl PublicKey {
}
_ => Err(Error::InvalidArgument),
},
Self::Sr25519(_) => Err(Error::InvalidArgument),
Self::Sr25519(pk) => match signature_type {
SignatureType::Sr25519_Pure => pk.verify_raw(context_or_hash, message, signature),
_ => Err(Error::InvalidArgument),
},
}
}

Expand Down Expand Up @@ -379,7 +388,7 @@ impl From<Signature> for Vec<u8> {
/// Common trait for memory signers.
pub trait Signer: Send + Sync {
/// Create a new random signer.
fn random(rng: &mut impl RngCore) -> Result<Self, Error>
fn random(rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error>
where
Self: Sized;

Expand Down Expand Up @@ -407,7 +416,7 @@ pub trait Signer: Send + Sync {
}

impl<T: Signer + ?Sized> Signer for std::sync::Arc<T> {
fn random(_rng: &mut impl RngCore) -> Result<Self, Error>
fn random(_rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error>
where
Self: Sized,
{
Expand Down Expand Up @@ -446,7 +455,7 @@ impl<T: Signer + ?Sized> Signer for std::sync::Arc<T> {
}

impl<T: CoreSigner> Signer for &T {
fn random(_rng: &mut impl RngCore) -> Result<Self, Error>
fn random(_rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error>
where
Self: Sized,
{
Expand Down Expand Up @@ -486,7 +495,7 @@ impl<T: CoreSigner> Signer for &T {
}

impl Signer for crate::core::identity::Identity {
fn random(_rng: &mut impl RngCore) -> Result<Self, Error>
fn random(_rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error>
where
Self: Sized,
{
Expand Down Expand Up @@ -531,6 +540,7 @@ pub enum MemorySigner {
Secp256k1(secp256k1::MemorySigner),
Secp256r1(secp256r1::MemorySigner),
Secp384r1(secp384r1::MemorySigner),
Sr25519(sr25519::MemorySigner),
}

impl MemorySigner {
Expand All @@ -550,6 +560,8 @@ impl MemorySigner {
Ok(Self::Secp384r1(secp384r1::MemorySigner::new_from_seed(
seed,
)?))
} else if sig_type.is_sr25519_variant() {
Ok(Self::Sr25519(sr25519::MemorySigner::new_from_seed(seed)?))
} else {
Err(Error::InvalidArgument)
}
Expand All @@ -574,6 +586,8 @@ impl MemorySigner {
Ok(Self::Secp256r1(secp256r1::MemorySigner::from_bytes(bytes)?))
} else if sig_type.is_secp384r1_variant() {
Ok(Self::Secp384r1(secp384r1::MemorySigner::from_bytes(bytes)?))
} else if sig_type.is_sr25519_variant() {
Ok(Self::Sr25519(sr25519::MemorySigner::from_bytes(bytes)?))
} else {
Err(Error::InvalidArgument)
}
Expand All @@ -586,6 +600,7 @@ impl MemorySigner {
Self::Secp256k1(signer) => signer.to_bytes(),
Self::Secp256r1(signer) => signer.to_bytes(),
Self::Secp384r1(signer) => signer.to_bytes(),
Self::Sr25519(signer) => signer.to_bytes(),
}
}

Expand All @@ -596,6 +611,7 @@ impl MemorySigner {
Self::Secp256k1(signer) => signer.public_key(),
Self::Secp256r1(signer) => signer.public_key(),
Self::Secp384r1(signer) => signer.public_key(),
Self::Sr25519(signer) => signer.public_key(),
}
}

Expand All @@ -606,6 +622,7 @@ impl MemorySigner {
Self::Secp256k1(signer) => signer.sign(context, message),
Self::Secp256r1(signer) => signer.sign(context, message),
Self::Secp384r1(signer) => signer.sign(context, message),
Self::Sr25519(signer) => signer.sign(context, message),
}
}

Expand All @@ -616,6 +633,7 @@ impl MemorySigner {
Self::Secp256k1(signer) => signer.sign_raw(message),
Self::Secp256r1(signer) => signer.sign_raw(message),
Self::Secp384r1(signer) => signer.sign_raw(message),
Self::Sr25519(signer) => signer.sign_raw(message),
}
}

Expand Down Expand Up @@ -695,6 +713,10 @@ impl MemorySigner {
}
_ => Err(Error::InvalidArgument),
},
Self::Sr25519(signer) => match signature_type {
SignatureType::Sr25519_Pure => signer.sign(context_or_hash, message),
_ => Err(Error::InvalidArgument),
},
}
}
}
Expand Down Expand Up @@ -725,6 +747,7 @@ mod test {
SignatureType::Ed25519_Oasis,
SignatureType::Ed25519_Pure,
SignatureType::Secp256k1_Oasis,
SignatureType::Sr25519_Pure,
] {
let signer = MemorySigner::new_test(sig_type, "memory signer test");
let pk = signer.public_key();
Expand Down
4 changes: 2 additions & 2 deletions runtime-sdk/src/crypto/signature/secp256k1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use k256::{
elliptic_curve::sec1::{FromEncodedPoint, ToEncodedPoint},
sha2::Sha512_256,
};
use rand_core::RngCore;
use rand_core::{CryptoRng, RngCore};

use crate::crypto::signature::{Error, Signature};

Expand Down Expand Up @@ -122,7 +122,7 @@ impl MemorySigner {
}

impl super::Signer for MemorySigner {
fn random(rng: &mut impl RngCore) -> Result<Self, Error> {
fn random(rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error> {
let mut seed = [0u8; 32];
rng.fill_bytes(&mut seed);
Self::new_from_seed(&seed)
Expand Down
4 changes: 2 additions & 2 deletions runtime-sdk/src/crypto/signature/secp256r1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use p256::{
signature::{DigestSigner as _, DigestVerifier, Signer as _, Verifier as _},
},
};
use rand_core::RngCore;
use rand_core::{CryptoRng, RngCore};

use crate::crypto::signature::{Error, Signature};

Expand Down Expand Up @@ -108,7 +108,7 @@ impl MemorySigner {
}

impl super::Signer for MemorySigner {
fn random(rng: &mut impl RngCore) -> Result<Self, Error> {
fn random(rng: &mut (impl RngCore + CryptoRng)) -> Result<Self, Error> {
let mut seed = [0u8; 32];
rng.fill_bytes(&mut seed);
Self::new_from_seed(&seed)
Expand Down
Loading
Loading