Skip to content

Commit

Permalink
Make the hasher a type param of sig schemes
Browse files Browse the repository at this point in the history
  • Loading branch information
sug0 committed Jul 5, 2023
1 parent b33212b commit 044cfb0
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 44 deletions.
38 changes: 23 additions & 15 deletions core/src/types/key/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ use super::{
ParseSignatureError, RefTo, SchemeType, SigScheme as SigSchemeTrait,
VerifySigError,
};
use crate::ledger::storage::DummyHasher;
use crate::types::ethereum_events::EthAddress;
use crate::types::key::SignableBytes;
use crate::types::key::{SignableBytes, StorageHasher};

/// Public key
#[derive(
Expand Down Expand Up @@ -305,7 +304,6 @@ impl super::Signature for Signature {
pub struct SigScheme;

impl super::SigScheme for SigScheme {
type Hasher = DummyHasher;
type PublicKey = PublicKey;
type SecretKey = SecretKey;
type Signature = Signature;
Expand All @@ -330,31 +328,41 @@ impl super::SigScheme for SigScheme {
);
}

fn sign(
fn sign_with_hasher<H>(
keypair: &SecretKey,
data: impl super::SignableBytes,
) -> Self::Signature {
) -> Self::Signature
where
H: 'static + StorageHasher,
{
match keypair {
SecretKey::Ed25519(kp) => {
Signature::Ed25519(ed25519::SigScheme::sign(kp, data))
}
SecretKey::Secp256k1(kp) => {
Signature::Secp256k1(secp256k1::SigScheme::sign(kp, data))
}
SecretKey::Ed25519(kp) => Signature::Ed25519(
ed25519::SigScheme::sign_with_hasher::<H>(kp, data),
),
SecretKey::Secp256k1(kp) => Signature::Secp256k1(
secp256k1::SigScheme::sign_with_hasher::<H>(kp, data),
),
}
}

fn verify_signature(
fn verify_signature_with_hasher<H>(
pk: &Self::PublicKey,
data: &impl SignableBytes,
sig: &Self::Signature,
) -> Result<(), VerifySigError> {
) -> Result<(), VerifySigError>
where
H: 'static + StorageHasher,
{
match (pk, sig) {
(PublicKey::Ed25519(pk), Signature::Ed25519(sig)) => {
ed25519::SigScheme::verify_signature(pk, data, sig)
ed25519::SigScheme::verify_signature_with_hasher::<H>(
pk, data, sig,
)
}
(PublicKey::Secp256k1(pk), Signature::Secp256k1(sig)) => {
secp256k1::SigScheme::verify_signature(pk, data, sig)
secp256k1::SigScheme::verify_signature_with_hasher::<H>(
pk, data, sig,
)
}
_ => Err(VerifySigError::MismatchedScheme),
}
Expand Down
22 changes: 15 additions & 7 deletions core/src/types/key/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use super::{
ParsePublicKeyError, ParseSecretKeyError, ParseSignatureError, RefTo,
SchemeType, SigScheme as SigSchemeTrait, SignableBytes, VerifySigError,
};
use crate::ledger::storage::Sha256Hasher;
use crate::types::key::StorageHasher;

const PUBLIC_KEY_LENGTH: usize = 32;
const SECRET_KEY_LENGTH: usize = 32;
Expand Down Expand Up @@ -323,7 +323,6 @@ impl PartialOrd for Signature {
pub struct SigScheme;

impl super::SigScheme for SigScheme {
type Hasher = Sha256Hasher;
type PublicKey = PublicKey;
type SecretKey = SecretKey;
type Signature = Signature;
Expand All @@ -342,16 +341,25 @@ impl super::SigScheme for SigScheme {
SecretKey(Box::new(ed25519_consensus::SigningKey::from(bytes)))
}

fn sign(keypair: &SecretKey, data: impl SignableBytes) -> Self::Signature {
Signature(keypair.0.sign(&data.signable_hash::<Self::Hasher>()))
fn sign_with_hasher<H>(
keypair: &SecretKey,
data: impl SignableBytes,
) -> Self::Signature
where
H: 'static + StorageHasher,
{
Signature(keypair.0.sign(&data.signable_hash::<H>()))
}

fn verify_signature(
fn verify_signature_with_hasher<H>(
pk: &Self::PublicKey,
data: &impl SignableBytes,
sig: &Self::Signature,
) -> Result<(), VerifySigError> {
pk.0.verify(&sig.0, &data.signable_hash::<Self::Hasher>())
) -> Result<(), VerifySigError>
where
H: 'static + StorageHasher,
{
pk.0.verify(&sig.0, &data.signable_hash::<H>())
.map_err(|err| VerifySigError::SigVerifyError(err.to_string()))
}
}
34 changes: 28 additions & 6 deletions core/src/types/key/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use thiserror::Error;

use super::address::Address;
use super::storage::{self, DbKeySeg, Key, KeySeg};
use crate::ledger::storage::StorageHasher;
use crate::ledger::storage::{Sha256Hasher, StorageHasher};
use crate::types::address;

const PK_STORAGE_KEY: &str = "public_key";
Expand Down Expand Up @@ -261,8 +261,6 @@ pub trait SigScheme: Eq + Ord + Debug + Serialize + Default {
type PublicKey: 'static + PublicKey;
/// Represents the secret key for this scheme
type SecretKey: 'static + SecretKey;
/// Represents the data hasher for this scheme
type Hasher: 'static + StorageHasher;
/// The scheme type of this implementation
const TYPE: SchemeType;

Expand All @@ -276,17 +274,41 @@ pub trait SigScheme: Eq + Ord + Debug + Serialize + Default {
fn from_bytes(bytes: [u8; 32]) -> Self::SecretKey;

/// Sign the data with a key.
fn sign(
fn sign_with_hasher<H>(
keypair: &Self::SecretKey,
data: impl SignableBytes,
) -> Self::Signature;
) -> Self::Signature
where
H: 'static + StorageHasher;

/// Check that the public key matches the signature on the given data.
fn verify_signature_with_hasher<H>(
pk: &Self::PublicKey,
data: &impl SignableBytes,
sig: &Self::Signature,
) -> Result<(), VerifySigError>
where
H: 'static + StorageHasher;

/// Sign the data with a key, using a SHA256 hasher.
#[inline]
fn sign(
keypair: &Self::SecretKey,
data: impl SignableBytes,
) -> Self::Signature {
Self::sign_with_hasher::<Sha256Hasher>(keypair, data)
}

/// Check that the public key matches the signature on the given data,
/// using a SHA256 hasher.
#[inline]
fn verify_signature(
pk: &Self::PublicKey,
data: &impl SignableBytes,
sig: &Self::Signature,
) -> Result<(), VerifySigError>;
) -> Result<(), VerifySigError> {
Self::verify_signature_with_hasher::<Sha256Hasher>(pk, data, sig)
}
}

/// Public key hash derived from `common::Key` borsh encoded bytes (hex string
Expand Down
35 changes: 19 additions & 16 deletions core/src/types/key/secp256k1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use super::{
use crate::hints;
use crate::types::eth_abi::Encode;
use crate::types::ethereum_events::EthAddress;
use crate::types::key::StorageHasher;

/// The provided constant is for a traditional
/// signature on this curve. For Ethereum, an extra byte is included
Expand Down Expand Up @@ -551,10 +552,6 @@ impl TryFrom<&[u8; 65]> for Signature {
pub struct SigScheme;

impl super::SigScheme for SigScheme {
#[cfg(any(test, feature = "secp256k1-sign-verify"))]
type Hasher = crate::ledger::storage::KeccakHasher;
#[cfg(not(any(test, feature = "secp256k1-sign-verify")))]
type Hasher = crate::ledger::storage::DummyHasher;
type PublicKey = PublicKey;
type SecretKey = SecretKey;
type Signature = Signature;
Expand All @@ -576,8 +573,13 @@ impl super::SigScheme for SigScheme {
))
}

/// Sign the data with a key
fn sign(keypair: &SecretKey, data: impl SignableBytes) -> Self::Signature {
fn sign_with_hasher<H>(
keypair: &SecretKey,
data: impl SignableBytes,
) -> Self::Signature
where
H: 'static + StorageHasher,
{
#[cfg(not(any(test, feature = "secp256k1-sign-verify")))]
{
// to avoid `unused-variables` warn
Expand All @@ -587,20 +589,22 @@ impl super::SigScheme for SigScheme {

#[cfg(any(test, feature = "secp256k1-sign-verify"))]
{
let message = libsecp256k1::Message::parse_slice(
&data.signable_hash::<Self::Hasher>(),
)
.expect("Message encoding should not fail");
let message =
libsecp256k1::Message::parse_slice(&data.signable_hash::<H>())
.expect("Message encoding should not fail");
let (sig, recovery_id) = libsecp256k1::sign(&message, &keypair.0);
Signature(sig, recovery_id)
}
}

fn verify_signature(
fn verify_signature_with_hasher<H>(
pk: &Self::PublicKey,
data: &impl SignableBytes,
sig: &Self::Signature,
) -> Result<(), VerifySigError> {
) -> Result<(), VerifySigError>
where
H: 'static + StorageHasher,
{
#[cfg(not(any(test, feature = "secp256k1-sign-verify")))]
{
// to avoid `unused-variables` warn
Expand All @@ -610,10 +614,9 @@ impl super::SigScheme for SigScheme {

#[cfg(any(test, feature = "secp256k1-sign-verify"))]
{
let message = libsecp256k1::Message::parse_slice(
&data.signable_hash::<Self::Hasher>(),
)
.expect("Message encoding should not fail");
let message =
libsecp256k1::Message::parse_slice(&data.signable_hash::<H>())
.expect("Message encoding should not fail");
let is_valid = libsecp256k1::verify(&message, &sig.0, &pk.0);
if is_valid {
Ok(())
Expand Down

0 comments on commit 044cfb0

Please sign in to comment.