diff --git a/Cargo.lock b/Cargo.lock index 59d8551..e1f333d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,7 +146,7 @@ dependencies = [ "serde", "serde-aux", "serde_json", - "sha2 0.10.7", + "sha2", "thiserror", "tokio", "url", @@ -467,15 +467,6 @@ dependencies = [ "wyz", ] -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -594,7 +585,7 @@ dependencies = [ "secp256k1 0.22.2", "serde", "serde_json", - "sha2 0.10.7", + "sha2", "strum 0.24.1", "strum_macros 0.24.3", "thiserror", @@ -734,6 +725,12 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "convert_case" version = "0.4.0" @@ -842,17 +839,32 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "platforms", + "rustc_version", "subtle", "zeroize", ] +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + [[package]] name = "darling" version = "0.12.4" @@ -900,11 +912,21 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" dependencies = [ - "const-oid", + "const-oid 0.7.1", "crypto-bigint", "pem-rfc7468", ] +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid 0.9.6", + "zeroize", +] + [[package]] name = "derive_builder" version = "0.10.2" @@ -970,7 +992,7 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", "crypto-common", ] @@ -997,24 +1019,25 @@ dependencies = [ [[package]] name = "ed25519" -version = "1.5.3" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ + "pkcs8 0.10.2", "signature", ] [[package]] name = "ed25519-dalek" -version = "1.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", "ed25519", - "rand 0.7.3", "serde", - "sha2 0.9.9", + "sha2", + "subtle", "zeroize", ] @@ -1128,6 +1151,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fiat-crypto" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38793c55593b33412e3ae40c2c9781ffaa6f438f6f8c10f24e71846fbd7ae01e" + [[package]] name = "fixed-hash" version = "0.7.0" @@ -2132,12 +2161,6 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - [[package]] name = "openssl-probe" version = "0.1.5" @@ -2298,8 +2321,8 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a78f66c04ccc83dd4486fd46c33896f4e17b24a7a3a6400dedc48ed0ddd72320" dependencies = [ - "der", - "pkcs8", + "der 0.5.1", + "pkcs8 0.8.0", "zeroize", ] @@ -2309,17 +2332,33 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" dependencies = [ - "der", - "spki", + "der 0.5.1", + "spki 0.5.4", "zeroize", ] +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.9", + "spki 0.7.3", +] + [[package]] name = "pkg-config" version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "platforms" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" + [[package]] name = "polling" version = "2.8.0" @@ -2690,7 +2729,7 @@ dependencies = [ "num-iter", "num-traits", "pkcs1", - "pkcs8", + "pkcs8 0.8.0", "rand_core 0.6.4", "smallvec", "subtle", @@ -2930,19 +2969,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "sha2" version = "0.10.7" @@ -2985,9 +3011,12 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core 0.6.4", +] [[package]] name = "similar" @@ -3060,7 +3089,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" dependencies = [ "base64ct", - "der", + "der 0.5.1", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.9", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 11060e7..735d310 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ clap = { version = "4.4.4", features = ["derive", "env"], optional = true } data-encoding = "2.3.2" derive_builder = "0.10.2" derive_more = "0.99.17" -ed25519-dalek = { version = "1.0.1", optional = true } +ed25519-dalek = { version = "2.1.1", optional = true } futures = "0.3.19" indexmap = "1.9.3" lazy_static = "1.4.0" diff --git a/src/bundlr.rs b/src/bundlr.rs index b002b25..6573433 100644 --- a/src/bundlr.rs +++ b/src/bundlr.rs @@ -125,7 +125,7 @@ where pub fn build(self) -> Result, BuilderError> { let url = self.url.unwrap_or(Url::parse(BUNDLR_DEFAULT_URL).unwrap()); - let client = self.client.unwrap_or_else(reqwest::Client::new); + let client = self.client.unwrap_or_default(); let pub_info = match self.pub_info { Some(p) => p, diff --git a/src/deep_hash.rs b/src/deep_hash.rs index f2c9719..ec1fa03 100644 --- a/src/deep_hash.rs +++ b/src/deep_hash.rs @@ -8,7 +8,7 @@ use crate::{ consts::{BLOB_AS_BUFFER, LIST_AS_BUFFER}, error::BundlrError, }; -use futures::{Stream, TryStream, TryStreamExt}; +use futures::{Stream, TryStreamExt}; pub enum DeepHashChunk<'a> { Chunk(Bytes), @@ -16,8 +16,6 @@ pub enum DeepHashChunk<'a> { Chunks(Vec>), } -trait Foo: Stream> + TryStream {} - pub async fn deep_hash(chunk: DeepHashChunk<'_>) -> Result { match chunk { DeepHashChunk::Chunk(b) => { diff --git a/src/deep_hash_sync.rs b/src/deep_hash_sync.rs index fcb57a5..ec666e1 100644 --- a/src/deep_hash_sync.rs +++ b/src/deep_hash_sync.rs @@ -6,9 +6,6 @@ use crate::{ deep_hash::DeepHashChunk, error::BundlrError, }; -use futures::{Stream, TryStream}; - -trait Foo: Stream> + TryStream {} pub fn deep_hash_sync(chunk: DeepHashChunk) -> Result { match chunk { diff --git a/src/signers/aptos.rs b/src/signers/aptos.rs index 5224af5..7f354c9 100644 --- a/src/signers/aptos.rs +++ b/src/signers/aptos.rs @@ -1,10 +1,13 @@ use crate::error::BundlrError; +use crate::utils::bytes_to_fixed_array; use crate::Signer as SignerTrait; use crate::Verifier as VerifierTrait; use crate::{index::SignerMap, Ed25519Signer}; use bytes::Bytes; -use ed25519_dalek::{Keypair, Verifier, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH}; +use ed25519_dalek::Verifier; +use ed25519_dalek::VerifyingKey; +use ed25519_dalek::{SigningKey, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH}; use num::Integer; pub struct AptosSigner { @@ -12,7 +15,7 @@ pub struct AptosSigner { } impl AptosSigner { - pub fn new(keypair: Keypair) -> Self { + pub fn new(keypair: SigningKey) -> Self { Self { signer: Ed25519Signer::new(keypair), } @@ -59,17 +62,15 @@ impl VerifierTrait for AptosSigner { message: Bytes, signature: Bytes, ) -> Result<(), crate::error::BundlrError> { - let public_key = - ed25519_dalek::PublicKey::from_bytes(&pk).map_err(BundlrError::ED25519Error)?; - let sig = - ed25519_dalek::Signature::from_bytes(&signature).map_err(BundlrError::ED25519Error)?; + let public_key = ed25519_dalek::VerifyingKey::from_bytes(&bytes_to_fixed_array(&pk)?) + .map_err(BundlrError::ED25519Error)?; + let sig = ed25519_dalek::Signature::from_bytes(&bytes_to_fixed_array(&signature)?); let aptos_message = Bytes::copy_from_slice(&[b"APTOS\nmessage: ".as_ref(), &message[..]].concat()); let nonce = Bytes::from(b"\nnonce: bundlr".to_vec()); let full_msg = Bytes::from([aptos_message, nonce].concat()); - public_key - .verify(&full_msg, &sig) + VerifyingKey::verify(&public_key, &full_msg, &sig) .map_err(|_err| BundlrError::InvalidSignature) } } @@ -93,7 +94,7 @@ impl MultiAptosSigner { } impl MultiAptosSigner { - pub fn new(keypair: Keypair) -> Self { + pub fn new(keypair: SigningKey) -> Self { Self { signer: Ed25519Signer::new(keypair), } @@ -148,10 +149,10 @@ impl VerifierTrait for MultiAptosSigner { if sig_included { let signature = signatures.slice((i * 64)..((i + 1) * 64)); let pub_key_slc = pk.slice((i * 32)..((i + 1) * 32)); - let public_key = ed25519_dalek::PublicKey::from_bytes(&pub_key_slc) - .map_err(BundlrError::ED25519Error)?; - let sig = ed25519_dalek::Signature::from_bytes(&signature) - .map_err(BundlrError::ED25519Error)?; + let public_key = + ed25519_dalek::VerifyingKey::from_bytes(&bytes_to_fixed_array(&pub_key_slc)?) + .map_err(BundlrError::ED25519Error)?; + let sig = ed25519_dalek::Signature::from_bytes(&bytes_to_fixed_array(&signature)?); match public_key.verify(&message, &sig) { Ok(()) => (), Err(_err) => one_false = false, @@ -171,7 +172,7 @@ impl VerifierTrait for MultiAptosSigner { mod tests { use crate::{AptosSigner, Signer, Verifier}; use bytes::Bytes; - use ed25519_dalek::Keypair; + use ed25519_dalek::SigningKey; #[test] fn should_sign_and_verify() { @@ -184,7 +185,7 @@ mod tests { println!("{:?}", pub_key.to_vec()); assert!(AptosSigner::verify(pub_key, msg.clone(), sig).is_ok()); - let keypair = Keypair::from_bytes(&[ + let keypair = SigningKey::from_keypair_bytes(&[ 237, 158, 92, 107, 132, 192, 1, 57, 8, 20, 213, 108, 29, 227, 37, 8, 3, 105, 196, 244, 8, 221, 184, 199, 62, 253, 98, 131, 33, 165, 165, 215, 14, 7, 46, 23, 221, 242, 240, 226, 94, 79, 161, 31, 192, 163, 13, 25, 106, 53, 34, 215, 83, 124, 162, 156, 8, 97, diff --git a/src/signers/ed25519.rs b/src/signers/ed25519.rs index 1bb4231..7cda168 100644 --- a/src/signers/ed25519.rs +++ b/src/signers/ed25519.rs @@ -2,19 +2,19 @@ use std::array::TryFromSliceError; use crate::error::BundlrError; use crate::index::SignerMap; +use crate::utils::bytes_to_fixed_array; use crate::Signer as SignerTrait; use crate::Verifier as VerifierTrait; use bytes::Bytes; -use ed25519_dalek::{Keypair, Signer, Verifier, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH}; - +use ed25519_dalek::{Signer, SigningKey, Verifier, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH}; pub struct Ed25519Signer { - keypair: Keypair, + keypair: SigningKey, } //TODO: add validation for secret keys impl Ed25519Signer { - pub fn new(keypair: Keypair) -> Ed25519Signer { + pub fn new(keypair: SigningKey) -> Ed25519Signer { Ed25519Signer { keypair } } @@ -28,7 +28,7 @@ impl Ed25519Signer { .map_err(|err: TryFromSliceError| BundlrError::ParseError(err.to_string()))?; Ok(Self { - keypair: Keypair::from_bytes(key).map_err(BundlrError::ED25519Error)?, + keypair: SigningKey::from_keypair_bytes(key).map_err(BundlrError::ED25519Error)?, }) } } @@ -45,7 +45,7 @@ impl SignerTrait for Ed25519Signer { } fn pub_key(&self) -> bytes::Bytes { - Bytes::copy_from_slice(&self.keypair.public.to_bytes()) + Bytes::copy_from_slice(&self.keypair.verifying_key().to_bytes()) } fn sig_type(&self) -> SignerMap { @@ -65,10 +65,10 @@ impl VerifierTrait for Ed25519Signer { message: Bytes, signature: Bytes, ) -> Result<(), crate::error::BundlrError> { - let public_key = - ed25519_dalek::PublicKey::from_bytes(&pk).map_err(BundlrError::ED25519Error)?; - let sig = - ed25519_dalek::Signature::from_bytes(&signature).map_err(BundlrError::ED25519Error)?; + let public_key = ed25519_dalek::VerifyingKey::from_bytes(&bytes_to_fixed_array(&pk)?) + .map_err(BundlrError::ED25519Error)?; + + let sig = ed25519_dalek::Signature::from_bytes(&bytes_to_fixed_array(&signature)?); public_key .verify(&message, &sig) .map_err(|_| BundlrError::InvalidSignature) @@ -79,7 +79,7 @@ impl VerifierTrait for Ed25519Signer { mod tests { use crate::{Ed25519Signer, Signer, Verifier}; use bytes::Bytes; - use ed25519_dalek::Keypair; + use ed25519_dalek::SigningKey; #[test] fn should_sign_and_verify() { @@ -92,7 +92,7 @@ mod tests { println!("{:?}", pub_key.to_vec()); assert!(Ed25519Signer::verify(pub_key, msg.clone(), sig).is_ok()); - let keypair = Keypair::from_bytes(&[ + let keypair = SigningKey::from_keypair_bytes(&[ 237, 158, 92, 107, 132, 192, 1, 57, 8, 20, 213, 108, 29, 227, 37, 8, 3, 105, 196, 244, 8, 221, 184, 199, 62, 253, 98, 131, 33, 165, 165, 215, 14, 7, 46, 23, 221, 242, 240, 226, 94, 79, 161, 31, 192, 163, 13, 25, 106, 53, 34, 215, 83, 124, 162, 156, 8, 97, diff --git a/src/signers/mod.rs b/src/signers/mod.rs index c24266c..6319d1b 100644 --- a/src/signers/mod.rs +++ b/src/signers/mod.rs @@ -14,8 +14,6 @@ pub mod secp256k1; #[cfg(any(feature = "ethereum", feature = "erc20"))] pub mod typed_ethereum; -pub trait ToPem {} - pub trait Signer: Send + Sync { fn sign(&self, message: Bytes) -> Result; fn sig_type(&self) -> SignerMap; diff --git a/src/utils/eip712/encode.rs b/src/utils/eip712/encode.rs index da65291..f09a122 100644 --- a/src/utils/eip712/encode.rs +++ b/src/utils/eip712/encode.rs @@ -107,8 +107,8 @@ fn encode_data( // check if the type definition actually matches // the length of items to be encoded if length.is_some() && Some(values.len() as u64) != *length { - let array_type = format!("{}[{}]", inner.to_string(), length.unwrap()); - return Err(Eip712Error::UnequalArrayItems( + let array_type = format!("{}[{}]", inner, length.unwrap()); + Err(Eip712Error::UnequalArrayItems( length.unwrap(), array_type, values.len() as u64, @@ -178,7 +178,7 @@ fn encode_data( Type::Address => { let addr = value.as_str().ok_or(serde_error("string", field_name))?; if addr.len() != 42 { - return Err(Eip712Error::InvalidAddressLength(addr.len()))?; + Err(Eip712Error::InvalidAddressLength(addr.len()))?; } let address = EthAddress::from_str(&addr[2..]) .map_err(|err| Eip712Error::HexParseError(format!("{}", err)))?; diff --git a/src/utils/eip712/parser.rs b/src/utils/eip712/parser.rs index 181dbb0..f257fa6 100644 --- a/src/utils/eip712/parser.rs +++ b/src/utils/eip712/parser.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + use logos::Logos; use crate::utils::eip712::{error::Eip712Error, lexer::Token}; @@ -18,9 +20,9 @@ pub enum Type { }, } -impl ToString for Type { - fn to_string(&self) -> String { - match self { +impl Display for Type { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let data = match self { Type::Address => "address".to_owned(), Type::Uint => "uint".to_owned(), Type::Int => "int".to_owned(), @@ -36,10 +38,33 @@ impl ToString for Type { Some(length) => format!("{}[{}]", inner, length), } } - } + }; + write!(f, "{}", data) } } +// impl ToString for Type { +// fn to_string(&self) -> String { +// match self { +// Type::Address => "address".to_owned(), +// Type::Uint => "uint".to_owned(), +// Type::Int => "int".to_owned(), +// Type::String => "string".to_owned(), +// Type::Bool => "bool".to_owned(), +// Type::Bytes => "bytes".to_owned(), +// Type::Byte(len) => format!("bytes{}", len), +// Type::Custom(custom) => custom.to_string(), +// Type::Array { inner, length } => { +// let inner: String = (*inner).to_string(); +// match length { +// None => format!("{}[]", inner), +// Some(length) => format!("{}[{}]", inner, length), +// } +// } +// } +// } +// } + /// the type string is being validated before it's parsed. pub fn parse_type(field_type: &str) -> Result { #[derive(PartialEq)] diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 4ba0e57..aa57d49 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -16,11 +16,9 @@ use serde::Deserialize; use crate::error::BundlrError; -pub async fn check_and_return Deserialize<'de>>( - res: Result, -) -> Result +pub async fn check_and_return(res: Result) -> Result where - T: Default, + T: for<'de> Deserialize<'de> + Default, { match res { Ok(r) => { @@ -72,3 +70,13 @@ pub fn read_offset(file: &mut File, offset: u64, length: usize) -> Result( + input: &Bytes, +) -> Result<[u8; SIZE], crate::utils::BundlrError> { + let slice = input.get(0..SIZE).ok_or_else(|| { + BundlrError::BytesError("Not enough bytes to get expected count".to_string()) + })?; + + Ok(slice.try_into().unwrap()) // safe to unwrap as we know that slice has enough bytes +}