Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

feat: convert signing to k256 #72

Merged
merged 7 commits into from
Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from 6 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
836 changes: 555 additions & 281 deletions Cargo.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ mod tests {
// no inputs
let params = vec![];
let token_stream = expand_inputs_call_arg(&params);
assert_eq!(token_stream.to_string(), "( )");
assert_eq!(token_stream.to_string(), "()");

// single input
let params = vec![Param {
Expand All @@ -137,7 +137,7 @@ mod tests {
},
];
let token_stream = expand_inputs_call_arg(&params);
assert_eq!(token_stream.to_string(), "( arg_a , arg_b , )");
assert_eq!(token_stream.to_string(), "(arg_a , arg_b ,)");

// three inputs
let params = vec![
Expand All @@ -155,7 +155,7 @@ mod tests {
},
];
let token_stream = expand_inputs_call_arg(&params);
assert_eq!(token_stream.to_string(), "( arg_a , arg_b , arg_c , )");
assert_eq!(token_stream.to_string(), "(arg_a , arg_b , arg_c ,)");
}

#[test]
Expand Down
7 changes: 5 additions & 2 deletions ethers-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@ ethabi = { package = "ethabi-next", version = "12.0.0", default-features = false
arrayvec = { version = "0.5.1", default-features = false }

# crypto
secp256k1 = { package = "libsecp256k1", version = "0.3.5" }
ecdsa = { version = "0.8.0", features = ["std"] }
elliptic-curve = { version = "0.6.1", features = ["arithmetic"] }
generic-array = "0.14.4"
k256 = { git = "https://github.com/RustCrypto/elliptic-curves", version = "0.5.2", features = ["keccak256", "ecdsa"] }
rand = "0.7.2"
tiny-keccak = { version = "2.0.2", default-features = false }

sha2 = { version = "0.9.1" }

# misc
serde = { version = "1.0.110", default-features = false, features = ["derive"] }
Expand Down
4 changes: 2 additions & 2 deletions ethers-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,5 @@ pub mod utils;
// re-export rand to avoid potential confusion when there's rand version mismatches
pub use rand;

// re-export libsecp
pub use secp256k1;
// re-export k256
pub use k256;
85 changes: 85 additions & 0 deletions ethers-core/src/types/crypto/hash.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//! This is a helper module used to pass the pre-hashed message for signing to the
//! `sign_digest` methods of K256.
Comment on lines +1 to +2

Choose a reason for hiding this comment

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

It might be a bit more straightforward to use RecoverableSignPrimitive:: try_sign_recoverable_prehashed (which is impl'd on k256::Scalar) for this:

https://docs.rs/ecdsa/0.8.3/ecdsa/hazmat/trait.RecoverableSignPrimitive.html

The API to compute an ephemeral scalar with RFC6979 is public:

https://docs.rs/ecdsa/0.8.3/ecdsa/rfc6979/fn.generate_k.html

You can convert the raw message digest to a scalar using Scalar::from_bytes_reduced

use crate::types::H256;
use k256::ecdsa::signature::digest::{
generic_array::GenericArray, BlockInput, Digest, FixedOutput, Output, Reset, Update,
};

pub type Sha256Proxy = ProxyDigest<sha2::Sha256>;

#[derive(Clone)]
pub enum ProxyDigest<D: Digest> {
Proxy(Output<D>),
Digest(D),
}

impl<D: Digest + Clone> From<H256> for ProxyDigest<D>
where
GenericArray<u8, <D as Digest>::OutputSize>: Copy,
{
fn from(src: H256) -> Self {
ProxyDigest::Proxy(*GenericArray::from_slice(src.as_bytes()))
}
}

impl<D: Digest> Default for ProxyDigest<D> {
fn default() -> Self {
ProxyDigest::Digest(D::new())
}
}

impl<D: Digest> Update for ProxyDigest<D> {
// we update only if we are digest
fn update(&mut self, data: impl AsRef<[u8]>) {
match self {
ProxyDigest::Digest(ref mut d) => {
d.update(data);
}
ProxyDigest::Proxy(..) => {
unreachable!("can not update if we are proxy");
}
}
}

// we chain only if we are digest
fn chain(self, data: impl AsRef<[u8]>) -> Self {
match self {
ProxyDigest::Digest(d) => ProxyDigest::Digest(d.chain(data)),
ProxyDigest::Proxy(..) => {
unreachable!("can not update if we are proxy");
}
}
}
}

impl<D: Digest> Reset for ProxyDigest<D> {
// make new one
fn reset(&mut self) {
*self = Self::default();
}
}

impl<D: Digest> BlockInput for ProxyDigest<D> {
type BlockSize = D::OutputSize;
}

impl<D: Digest> FixedOutput for ProxyDigest<D> {
// we default to the output of the orignal digest
type OutputSize = D::OutputSize;

fn finalize_into(self, out: &mut GenericArray<u8, Self::OutputSize>) {
match self {
ProxyDigest::Digest(d) => {
*out = d.finalize();
}
ProxyDigest::Proxy(p) => {
*out = p;
}
}
}

fn finalize_into_reset(&mut self, out: &mut GenericArray<u8, Self::OutputSize>) {
let s = core::mem::replace(self, Self::default());
s.finalize_into(out);
}
}
Loading