From c5a943b8a35842a575bd7a9028e870d65510ab02 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Mon, 5 Feb 2024 17:21:47 +0100 Subject: [PATCH] Update to k256 pre-release to allow high-S in recover pubkey --- Cargo.lock | 128 +++++++++++++++++-------- packages/crypto/Cargo.toml | 4 +- packages/crypto/benches/main.rs | 3 +- packages/crypto/src/identity_digest.rs | 9 +- packages/crypto/src/secp256k1.rs | 23 ++--- 5 files changed, 105 insertions(+), 62 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c431fd603f..1e11cc8754 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -221,6 +221,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.11.0-pre.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded684142010808eb980d9974ef794da2bcf97d13396143b1515e9f0fb4a10e" +dependencies = [ + "crypto-common 0.2.0-pre.5", +] + [[package]] name = "bnum" version = "0.10.0" @@ -387,9 +396,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.2" +version = "0.10.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" +checksum = "f7e3352a27098ba6b09546e5f13b15165e6a88b5c2723afecb3ea9576b27e3ea" [[package]] name = "corosensei" @@ -422,7 +431,7 @@ name = "cosmwasm-crypto" version = "2.0.0-beta.1" dependencies = [ "criterion", - "digest 0.10.7", + "digest 0.11.0-pre.8", "ed25519-zebra", "english-numbers", "hex", @@ -720,11 +729,12 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.5.2" +version = "0.6.0-pre.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +checksum = "1943d7beadd9ce2b25f3bae73b9e9336fccc1edf38bdec1ed58d3aa183989e11" dependencies = [ - "generic-array", + "hybrid-array", + "num-traits", "rand_core 0.6.4", "subtle", "zeroize", @@ -740,6 +750,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.0-pre.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7aa2ec04f5120b830272a481e8d9d8ba4dda140d2cda59b0f1110d5eb93c38e" +dependencies = [ + "hybrid-array", +] + [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -802,9 +821,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.7" +version = "0.8.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +checksum = "b489fd2221710c1dd46637d66b984161fb66134f81437a8489800306bcc2ecea" dependencies = [ "const-oid", "zeroize", @@ -868,8 +887,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", + "crypto-common 0.1.6", +] + +[[package]] +name = "digest" +version = "0.11.0-pre.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065d93ead7c220b85d5b4be4795d8398eac4ff68b5ee63895de0a3c1fb6edf25" +dependencies = [ + "block-buffer 0.11.0-pre.5", "const-oid", - "crypto-common", + "crypto-common 0.2.0-pre.5", "subtle", ] @@ -913,12 +942,12 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.17.0-pre.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "d7e045ee5c360512162782f3d4cb07d2f4ce8c4ef9bf7c77ec16d1cf60b3d5ca" dependencies = [ "der", - "digest 0.10.7", + "digest 0.11.0-pre.8", "elliptic-curve", "rfc6979", "signature", @@ -948,16 +977,16 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" -version = "0.13.8" +version = "0.14.0-pre.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "4a1775af172997a40c14854c3a9fde9e03e5772084b334b6a0bb18bf7f93ac16" dependencies = [ "base16ct", "crypto-bigint", - "digest 0.10.7", + "digest 0.11.0-pre.8", "ff", - "generic-array", "group", + "hybrid-array", "pkcs8", "rand_core 0.6.4", "sec1", @@ -1111,7 +1140,6 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", - "zeroize", ] [[package]] @@ -1230,11 +1258,21 @@ checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" [[package]] name = "hmac" -version = "0.12.1" +version = "0.13.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "ffd790a0795ee332ed3e8959e5b177beb70d7112eb7d345428ec17427897d5ce" dependencies = [ - "digest 0.10.7", + "digest 0.11.0-pre.8", +] + +[[package]] +name = "hybrid-array" +version = "0.2.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e63b66aee2df5599ba69b17a48113dfc68d2e143ea387ef836509e433bbd7e" +dependencies = [ + "typenum", + "zeroize", ] [[package]] @@ -1327,15 +1365,14 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +version = "0.14.0-pre" +source = "git+https://github.com/RustCrypto/elliptic-curves.git#5d1c252c2defb5808f55329f3e2955ca72d7f8b5" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", "once_cell", - "sha2 0.10.6", + "sha2 0.11.0-pre.3", "signature", ] @@ -1566,9 +1603,9 @@ checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pkcs8" -version = "0.10.2" +version = "0.11.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "935c09e0aecb0cb8f8907b57438b19a068cb74a25189b06724f061170b2465ff" dependencies = [ "der", "spki", @@ -1847,9 +1884,9 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.4.0" +version = "0.5.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "045972f2f66b9467a2f6834b7fd0f9b23ca214b4a8700b880c36edb726e96da6" dependencies = [ "hmac", "subtle", @@ -1969,13 +2006,13 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.7.3" +version = "0.8.0-pre.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "02dc081ed777a3bab68583b52ffb8221677b6e90d483b320963a247e2c07f328" dependencies = [ "base16ct", "der", - "generic-array", + "hybrid-array", "pkcs8", "subtle", "zeroize", @@ -2079,6 +2116,17 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha2" +version = "0.11.0-pre.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f33549bf3064b62478926aa89cbfc7c109aab66ae8f0d5d2ef839e482cc30d6" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.11.0-pre.8", +] + [[package]] name = "sha3" version = "0.10.8" @@ -2101,11 +2149,11 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" +version = "2.3.0-pre.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "1700c22ba9ce32c7b0a1495068a906c3552e7db386af7cf865162e0dea498523" dependencies = [ - "digest 0.10.7", + "digest 0.11.0-pre.8", "rand_core 0.6.4", ] @@ -2129,9 +2177,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "spki" -version = "0.7.2" +version = "0.8.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "cb2b56670f5ef52934c97efad30bf42585de0c33ec3e2a886e38b80d2db67243" dependencies = [ "base64ct", "der", @@ -2179,9 +2227,9 @@ dependencies = [ [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" @@ -2360,9 +2408,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" diff --git a/packages/crypto/Cargo.toml b/packages/crypto/Cargo.toml index 473349b0e0..4de54ce95a 100644 --- a/packages/crypto/Cargo.toml +++ b/packages/crypto/Cargo.toml @@ -15,9 +15,9 @@ default = [] bench = false [dependencies] -k256 = { version = "0.13.3", features = ["ecdsa"] } +k256 = { git = "https://github.com/RustCrypto/elliptic-curves.git", features = ["ecdsa"] } ed25519-zebra = "3" -digest = "0.10" +digest = "0.11.0-pre.8" rand_core = { version = "0.6", features = ["getrandom"] } thiserror = "1.0.38" diff --git a/packages/crypto/benches/main.rs b/packages/crypto/benches/main.rs index ce4b8d2eb3..120fee3cbf 100644 --- a/packages/crypto/benches/main.rs +++ b/packages/crypto/benches/main.rs @@ -6,9 +6,8 @@ use hex_literal::hex; use serde::Deserialize; // Crypto stuff -use digest::Digest; use k256::ecdsa::SigningKey; // type alias -use sha2::Sha256; +use sha2::{Digest, Sha256}; use cosmwasm_crypto::{ ed25519_batch_verify, ed25519_verify, secp256k1_recover_pubkey, secp256k1_verify, diff --git a/packages/crypto/src/identity_digest.rs b/packages/crypto/src/identity_digest.rs index c043f2d763..895a82dec0 100644 --- a/packages/crypto/src/identity_digest.rs +++ b/packages/crypto/src/identity_digest.rs @@ -4,19 +4,18 @@ //! //! Adapted from `sha2` [sha256.rs](https://github.com/RustCrypto/hashes/blob/master/sha2/src/sha256.rs) use digest::consts::U32; -use digest::generic_array::GenericArray; use digest::{FixedOutput, HashMarker, Output, OutputSizeUser, Reset, Update}; /// The 256-bits identity container #[derive(Clone, Default)] pub struct Identity256 { - array: GenericArray, + array: [u8; 32], } impl Update for Identity256 { fn update(&mut self, hash: &[u8]) { - assert_eq!(hash.as_ref().len(), 32); - self.array = *GenericArray::from_slice(hash); + // copy_from_slice panicks if input is not 32 bytes long + self.array.copy_from_slice(hash); } } @@ -26,7 +25,7 @@ impl OutputSizeUser for Identity256 { impl FixedOutput for Identity256 { fn finalize_into(self, out: &mut Output) { - *out = self.array; + *out = self.array.into(); } } diff --git a/packages/crypto/src/secp256k1.rs b/packages/crypto/src/secp256k1.rs index cf1d8a6187..8e1df3ccfa 100644 --- a/packages/crypto/src/secp256k1.rs +++ b/packages/crypto/src/secp256k1.rs @@ -1,7 +1,8 @@ -use digest::{Digest, Update}; // trait +use digest::{Digest, Update}; use k256::{ - ecdsa::signature::DigestVerifier, // traits - ecdsa::{RecoveryId, Signature, VerifyingKey}, // type aliases + ecdsa::signature::DigestVerifier, + ecdsa::{RecoveryId, Signature, VerifyingKey}, + elliptic_curve::scalar::IsHigh, // type aliases }; use crate::errors::{CryptoError, CryptoResult}; @@ -56,8 +57,8 @@ pub fn secp256k1_verify( // High-S signatures require normalization since our verification implementation // rejects them by default. If we had a verifier that does not restrict to // low-S only, this step was not needed. - if let Some(normalized) = signature.normalize_s() { - signature = normalized; + if signature.s().is_high().into() { + signature = signature.normalize_s(); } let public_key = VerifyingKey::from_sec1_bytes(public_key) @@ -105,24 +106,19 @@ pub fn secp256k1_recover_pubkey( let signature = read_signature(signature)?; // params other than 0 and 1 are explicitly not supported - let mut id = match recovery_param { + let id = match recovery_param { 0 => RecoveryId::new(false, false), 1 => RecoveryId::new(true, false), _ => return Err(CryptoError::invalid_recovery_param()), }; // Compose extended signature - let mut signature = Signature::from_bytes(&signature.into()) + let signature = Signature::from_bytes(&signature.into()) .map_err(|e| CryptoError::generic_err(e.to_string()))?; // Recover let message_digest = Identity256::new().chain(message_hash); - if let Some(normalized) = signature.normalize_s() { - signature = normalized; - id = RecoveryId::new(!id.is_y_odd(), id.is_x_reduced()); - } - let pubkey = VerifyingKey::recover_from_digest(message_digest, &signature, id) .map_err(|e| CryptoError::generic_err(e.to_string()))?; let encoded: Vec = pubkey.to_encoded_point(false).as_bytes().into(); @@ -183,14 +179,15 @@ fn check_pubkey(data: &[u8]) -> Result<(), InvalidSecp256k1PubkeyFormat> { mod tests { use super::*; + use digest::Digest; use hex_literal::hex; + use k256::sha2::Sha256; use k256::{ ecdsa::signature::DigestSigner, // trait ecdsa::SigningKey, // type alias elliptic_curve::rand_core::OsRng, }; use serde::Deserialize; - use sha2::Sha256; use std::fs::File; use std::io::BufReader;