diff --git a/Cargo.lock b/Cargo.lock index 8f80240ebd..367b5ff0e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,6 +35,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" + [[package]] name = "autocfg" version = "1.0.1" @@ -71,6 +77,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitcoin_hashes" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0aaf87b776808e26ae93289bc7d025092b6d909c193f0cdee0b3a86e7bd3c776" + [[package]] name = "bitflags" version = "1.2.1" @@ -221,6 +233,7 @@ dependencies = [ name = "cosmwasm-vm" version = "0.13.2" dependencies = [ + "base64", "clap", "clru", "cosmwasm-std", @@ -228,6 +241,7 @@ dependencies = [ "hex", "parity-wasm", "schemars", + "secp256k1", "serde", "serde_json", "sha2", @@ -395,7 +409,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" dependencies = [ - "autocfg", + "autocfg 1.0.1", "cfg-if 1.0.0", "lazy_static", ] @@ -587,7 +601,7 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b" dependencies = [ - "autocfg", + "autocfg 1.0.1", "hashbrown", "serde", ] @@ -693,7 +707,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" dependencies = [ - "autocfg", + "autocfg 1.0.1", ] [[package]] @@ -703,7 +717,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" dependencies = [ "adler", - "autocfg", + "autocfg 1.0.1", ] [[package]] @@ -718,7 +732,7 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ - "autocfg", + "autocfg 1.0.1", "num-traits", ] @@ -728,7 +742,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ - "autocfg", + "autocfg 1.0.1", ] [[package]] @@ -835,6 +849,24 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.7", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_pcg", + "rand_xorshift", + "winapi", +] + [[package]] name = "rand" version = "0.7.3" @@ -843,9 +875,19 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ "getrandom", "libc", - "rand_chacha", - "rand_core", - "rand_hc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] + +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.3.1", ] [[package]] @@ -855,9 +897,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", ] +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.5.1" @@ -867,13 +924,61 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "rand_hc" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", ] [[package]] @@ -893,7 +998,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674" dependencies = [ - "autocfg", + "autocfg 1.0.1", "crossbeam-deque", "either", "rayon-core", @@ -1039,6 +1144,26 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "secp256k1" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733b114f058f260c0af7591434eef4272ae1a8ec2751766d3cb89c6df8d5e450" +dependencies = [ + "bitcoin_hashes", + "rand 0.6.5", + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e4b6455ee49f5901c8985b88f98fb0a0e1d90a6661f5a03f4888bd987dad29" +dependencies = [ + "cc", +] + [[package]] name = "semver" version = "0.9.0" @@ -1186,7 +1311,7 @@ checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" dependencies = [ "cfg-if 0.1.10", "libc", - "rand", + "rand 0.7.3", "redox_syscall", "remove_dir_all", "winapi", diff --git a/contracts/burner/Cargo.lock b/contracts/burner/Cargo.lock index d2817bacd0..3e7455e6f7 100644 --- a/contracts/burner/Cargo.lock +++ b/contracts/burner/Cargo.lock @@ -151,6 +151,7 @@ dependencies = [ "hex", "parity-wasm", "schemars", + "secp256k1", "serde", "serde_json", "sha2", @@ -811,6 +812,24 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "secp256k1" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733b114f058f260c0af7591434eef4272ae1a8ec2751766d3cb89c6df8d5e450" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e4b6455ee49f5901c8985b88f98fb0a0e1d90a6661f5a03f4888bd987dad29" +dependencies = [ + "cc", +] + [[package]] name = "semver" version = "0.9.0" diff --git a/contracts/hackatom/Cargo.lock b/contracts/hackatom/Cargo.lock index 3ab4e201ea..246fda567c 100644 --- a/contracts/hackatom/Cargo.lock +++ b/contracts/hackatom/Cargo.lock @@ -148,6 +148,7 @@ dependencies = [ "hex", "parity-wasm", "schemars", + "secp256k1", "serde", "serde_json", "sha2", @@ -822,6 +823,24 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "secp256k1" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733b114f058f260c0af7591434eef4272ae1a8ec2751766d3cb89c6df8d5e450" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e4b6455ee49f5901c8985b88f98fb0a0e1d90a6661f5a03f4888bd987dad29" +dependencies = [ + "cc", +] + [[package]] name = "semver" version = "0.9.0" diff --git a/contracts/ibc-reflect-send/Cargo.lock b/contracts/ibc-reflect-send/Cargo.lock index c9a352135f..15d8e3926f 100644 --- a/contracts/ibc-reflect-send/Cargo.lock +++ b/contracts/ibc-reflect-send/Cargo.lock @@ -148,6 +148,7 @@ dependencies = [ "hex", "parity-wasm", "schemars", + "secp256k1", "serde", "serde_json", "sha2", @@ -820,6 +821,24 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "secp256k1" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733b114f058f260c0af7591434eef4272ae1a8ec2751766d3cb89c6df8d5e450" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e4b6455ee49f5901c8985b88f98fb0a0e1d90a6661f5a03f4888bd987dad29" +dependencies = [ + "cc", +] + [[package]] name = "semver" version = "0.9.0" diff --git a/contracts/ibc-reflect/Cargo.lock b/contracts/ibc-reflect/Cargo.lock index c8f66228cc..a0cbf14e2e 100644 --- a/contracts/ibc-reflect/Cargo.lock +++ b/contracts/ibc-reflect/Cargo.lock @@ -148,6 +148,7 @@ dependencies = [ "hex", "parity-wasm", "schemars", + "secp256k1", "serde", "serde_json", "sha2", @@ -820,6 +821,24 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "secp256k1" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733b114f058f260c0af7591434eef4272ae1a8ec2751766d3cb89c6df8d5e450" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e4b6455ee49f5901c8985b88f98fb0a0e1d90a6661f5a03f4888bd987dad29" +dependencies = [ + "cc", +] + [[package]] name = "semver" version = "0.9.0" diff --git a/contracts/queue/Cargo.lock b/contracts/queue/Cargo.lock index b131d3a011..9c545d2b2f 100644 --- a/contracts/queue/Cargo.lock +++ b/contracts/queue/Cargo.lock @@ -140,6 +140,7 @@ dependencies = [ "hex", "parity-wasm", "schemars", + "secp256k1", "serde", "serde_json", "sha2", @@ -811,6 +812,24 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "secp256k1" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733b114f058f260c0af7591434eef4272ae1a8ec2751766d3cb89c6df8d5e450" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e4b6455ee49f5901c8985b88f98fb0a0e1d90a6661f5a03f4888bd987dad29" +dependencies = [ + "cc", +] + [[package]] name = "semver" version = "0.9.0" diff --git a/contracts/reflect/Cargo.lock b/contracts/reflect/Cargo.lock index d70045c7d9..5d157dae2c 100644 --- a/contracts/reflect/Cargo.lock +++ b/contracts/reflect/Cargo.lock @@ -148,6 +148,7 @@ dependencies = [ "hex", "parity-wasm", "schemars", + "secp256k1", "serde", "serde_json", "sha2", @@ -821,6 +822,24 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "secp256k1" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733b114f058f260c0af7591434eef4272ae1a8ec2751766d3cb89c6df8d5e450" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e4b6455ee49f5901c8985b88f98fb0a0e1d90a6661f5a03f4888bd987dad29" +dependencies = [ + "cc", +] + [[package]] name = "semver" version = "0.9.0" diff --git a/contracts/staking/Cargo.lock b/contracts/staking/Cargo.lock index 0b2cb2869f..5dbee94421 100644 --- a/contracts/staking/Cargo.lock +++ b/contracts/staking/Cargo.lock @@ -148,6 +148,7 @@ dependencies = [ "hex", "parity-wasm", "schemars", + "secp256k1", "serde", "serde_json", "sha2", @@ -814,6 +815,24 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "secp256k1" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733b114f058f260c0af7591434eef4272ae1a8ec2751766d3cb89c6df8d5e450" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e4b6455ee49f5901c8985b88f98fb0a0e1d90a6661f5a03f4888bd987dad29" +dependencies = [ + "cc", +] + [[package]] name = "semver" version = "0.9.0" diff --git a/packages/vm/Cargo.toml b/packages/vm/Cargo.toml index 85af245fd4..776c1fa5e1 100644 --- a/packages/vm/Cargo.toml +++ b/packages/vm/Cargo.toml @@ -43,6 +43,7 @@ sha2 = "0.9.1" thiserror = "1.0" wasmer = { version = "1.0.1", default-features = false, features = ["jit", "singlepass"] } wasmer-middlewares = { version = "1.0.1" } +secp256k1 = "0.20.1" # Wasmer git/local (used for quick local debugging or patching) # wasmer = { git = "https://github.com/wasmerio/wasmer", rev = "1.0.1", default-features = false, features = ["jit", "singlepass"] } @@ -55,6 +56,8 @@ criterion = "0.3" tempfile = "3.1.0" wat = "1.0" clap = "2.33.3" +secp256k1 = { version = "0.20.1", features = ["bitcoin_hashes", "rand"] } +base64 = "0.13.0" [[bench]] name = "main" diff --git a/packages/vm/src/crypto.rs b/packages/vm/src/crypto.rs new file mode 100644 index 0000000000..ecf80b9231 --- /dev/null +++ b/packages/vm/src/crypto.rs @@ -0,0 +1,163 @@ +use secp256k1::{Message, PublicKey, Secp256k1, Signature}; + +use crate::errors::{VmError, VmResult}; + +pub fn secp256k1_verify(message_hash: &[u8], signature: &[u8], public_key: &[u8]) -> VmResult<()> { + // Deserialize stuff + // TODO: VmError::CryptoErr + let message = + Message::from_slice(message_hash).map_err(|e| VmError::generic_err(e.to_string()))?; + let signature = + Signature::from_compact(signature).map_err(|e| VmError::generic_err(e.to_string()))?; + let public_key = + PublicKey::from_slice(public_key).map_err(|e| VmError::generic_err(e.to_string()))?; + + // Create a verification-only context + let verify_ctx = Secp256k1::verification_only(); + + verify_ctx + .verify(&message, &signature, &public_key) + .map_err(|e| VmError::generic_err(e.to_string())) +} + +#[cfg(test)] +mod tests { + use super::*; + use secp256k1::bitcoin_hashes::{sha256, Hash}; + use secp256k1::rand::rngs::SmallRng; + use secp256k1::rand::SeedableRng; + + // Create small fast (insecure) RNG with a fixed seed (just for testing) + const SEED: [u8; 16] = [1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0]; + + // Generic signature verification + const MSG: &str = "Hello World!"; + + // Cosmos signature verification + // tendermint/PubKeySecp256k1 pubkey + const COSMOS_PUBKEY_BASE64: &str = "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ"; + + const COSMOS_MSG_HEX1: &str = "0a93010a90010a1c2f636f736d6f732e62616e6b2e763162657461312e4d736753656e6412700a2d636f736d6f7331706b707472653766646b6c366766727a6c65736a6a766878686c63337234676d6d6b38727336122d636f736d6f7331717970717870713971637273737a673270767871367273307a716733797963356c7a763778751a100a0575636f736d12073132333435363712650a4e0a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a21034f04181eeba35391b858633a765c4a0c189697b40d216354d50890d350c7029012040a02080112130a0d0a0575636f736d12043230303010c09a0c1a0c73696d642d74657374696e672001"; + const COSMOS_MSG_HEX2: &str = "0a93010a90010a1c2f636f736d6f732e62616e6b2e763162657461312e4d736753656e6412700a2d636f736d6f7331706b707472653766646b6c366766727a6c65736a6a766878686c63337234676d6d6b38727336122d636f736d6f7331717970717870713971637273737a673270767871367273307a716733797963356c7a763778751a100a0575636f736d12073132333435363712670a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a21034f04181eeba35391b858633a765c4a0c189697b40d216354d50890d350c7029012040a020801180112130a0d0a0575636f736d12043230303010c09a0c1a0c73696d642d74657374696e672001"; + const COSMOS_MSG_HEX3: &str = "0a93010a90010a1c2f636f736d6f732e62616e6b2e763162657461312e4d736753656e6412700a2d636f736d6f7331706b707472653766646b6c366766727a6c65736a6a766878686c63337234676d6d6b38727336122d636f736d6f7331717970717870713971637273737a673270767871367273307a716733797963356c7a763778751a100a0575636f736d12073132333435363712670a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a21034f04181eeba35391b858633a765c4a0c189697b40d216354d50890d350c7029012040a020801180212130a0d0a0575636f736d12043230303010c09a0c1a0c73696d642d74657374696e672001"; + + const COSMOS_SIGNATURE_HEX1: &str = "c9dd20e07464d3a688ff4b710b1fbc027e495e797cfa0b4804da2ed117959227772de059808f765aa29b8f92edf30f4c2c5a438e30d3fe6897daa7141e3ce6f9"; + const COSMOS_SIGNATURE_HEX2: &str = "525adc7e61565a509c60497b798c549fbf217bb5cd31b24cc9b419d098cc95330c99ecc4bc72448f85c365a4e3f91299a3d40412fb3751bab82f1940a83a0a4c"; + const COSMOS_SIGNATURE_HEX3: &str = "f3f2ca73806f2abbf6e0fe85f9b8af66f0e9f7f79051fdb8abe5bb8633b17da132e82d577b9d5f7a6dae57a144efc9ccc6eef15167b44b3b22a57240109762af"; + + // Test data originally from https://github.com/cosmos/cosmjs/blob/v0.24.0-alpha.22/packages/crypto/src/secp256k1.spec.ts#L195-L394 + const COSMOS_TESTS_JSON: &str = "./testdata/secp256k1_tests.json"; + + #[test] + fn test_secp256k1_verify() { + let mut rng = SmallRng::from_seed(SEED); + + let message_hash = sha256::Hash::hash(MSG.as_bytes()); + + // Create full-featured secp context (just for test helpers) + let secp = Secp256k1::new(); + let (secret_key, public_key) = secp.generate_keypair(&mut rng); + let message = Message::from_slice(message_hash.as_inner()).unwrap(); + let signature = secp.sign(&message, &secret_key); + + // Our verify wrapper works + assert!(secp256k1_verify( + message_hash.as_inner(), + &signature.serialize_compact(), + &public_key.serialize() + ) + .is_ok()); + + // Wrong message fails + let message_bad_hash = sha256::Hash::hash(&[MSG, "\0"].concat().as_bytes()); + assert!(secp256k1_verify( + message_bad_hash.as_inner(), + &signature.serialize_compact(), + &public_key.serialize() + ) + .is_err()); + + // Wrong pubkey fails + let (_, public_key_other) = secp.generate_keypair(&mut rng); + assert!(secp256k1_verify( + message_hash.as_inner(), + &signature.serialize_compact(), + &public_key_other.serialize() + ) + .is_err()); + } + + #[test] + fn test_cosmos_secp256k1_verify() { + let public_key = + PublicKey::from_slice(&base64::decode(COSMOS_PUBKEY_BASE64).unwrap()).unwrap(); + + for (msg, sig) in [COSMOS_MSG_HEX1, COSMOS_MSG_HEX2, COSMOS_MSG_HEX3] + .iter() + .zip(&[ + COSMOS_SIGNATURE_HEX1, + COSMOS_SIGNATURE_HEX2, + COSMOS_SIGNATURE_HEX3, + ]) + { + let message_hash = sha256::Hash::hash(&hex::decode(msg).unwrap()); + let signature = Signature::from_compact(&hex::decode(sig).unwrap()).unwrap(); + + // Verify works + assert!(secp256k1_verify( + message_hash.as_inner(), + &signature.serialize_compact(), + &public_key.serialize() + ) + .is_ok()); + } + } + + #[test] + fn test_cosmos_extra_secp256k1_verify() { + use std::fs::File; + use std::io::BufReader; + + use serde::Deserialize; + + #[derive(Deserialize, Debug)] + struct Encoded { + message: String, + message_hash: String, + signature: String, + #[serde(rename = "pubkey")] + public_key: String, + }; + + // Open the file in read-only mode with buffer. + let file = File::open(COSMOS_TESTS_JSON).unwrap(); + let reader = BufReader::new(file); + + let codes: Vec = serde_json::from_reader(reader).unwrap(); + + for (i, encoded) in (1..).zip(codes) { + let hash = hex::decode(&encoded.message_hash).unwrap(); + let message_hash = sha256::Hash::hash(&hex::decode(&encoded.message).unwrap()); + assert_eq!(hash.as_slice(), message_hash.into_inner()); + + let public_key = + PublicKey::from_slice(&hex::decode(&encoded.public_key).unwrap()).unwrap(); + + let mut signature = + Signature::from_compact(&hex::decode(&encoded.signature).unwrap()).unwrap(); + // Non low-S signatures require normalization + signature.normalize_s(); + + // Verify works + assert!( + secp256k1_verify( + message_hash.as_inner(), + &signature.serialize_compact(), + &public_key.serialize() + ) + .is_ok(), + format!("verify() failed (test case {})", i) + ); + } + } +} diff --git a/packages/vm/src/lib.rs b/packages/vm/src/lib.rs index 8316352475..e3c866e71e 100644 --- a/packages/vm/src/lib.rs +++ b/packages/vm/src/lib.rs @@ -6,6 +6,7 @@ mod calls; mod checksum; mod compatibility; mod conversion; +mod crypto; mod environment; mod errors; mod features; @@ -30,6 +31,7 @@ pub use crate::calls::{ call_query, call_query_raw, }; pub use crate::checksum::Checksum; +pub use crate::crypto::secp256k1_verify; pub use crate::errors::{ CommunicationError, CommunicationResult, RegionValidationError, RegionValidationResult, VmError, VmResult, diff --git a/packages/vm/testdata/secp256k1_tests.json b/packages/vm/testdata/secp256k1_tests.json new file mode 100644 index 0000000000..223c6938e1 --- /dev/null +++ b/packages/vm/testdata/secp256k1_tests.json @@ -0,0 +1,122 @@ +[ + { + "message": "5c868fedb8026979ebd26f1ba07c27eedf4ff6d10443505a96ecaf21ba8c4f0937b3cd23ffdc3dd429d4cd1905fb8dbcceeff1350020e18b58d2ba70887baa3a9b783ad30d3fbf210331cdd7df8d77defa398cdacdfc2e359c7ba4cae46bb74401deb417f8b912a1aa966aeeba9c39c7dd22479ae2b30719dca2f2206c5eb4b7", + "message_hash": "5ae8317d34d1e595e3fa7247db80c0af4320cce1116de187f8f7e2e099c0d8d0", + "signature": "207082eb2c3dfa0b454e0906051270ba4074ac93760ba9e7110cd9471475111151eb0dbbc9920e72146fb564f99d039802bf6ef2561446eb126ef364d21ee9c4", + "pubkey": "04051c1ee2190ecfb174bfe4f90763f2b4ff7517b70a2aec1876ebcfd644c4633fb03f3cfbd94b1f376e34592d9d41ccaf640bb751b00a1fadeb0c01157769eb73" + }, + { + "message": "17cd4a74d724d55355b6fb2b0759ca095298e3fd1856b87ca1cb2df5409058022736d21be071d820b16dfc441be97fbcea5df787edc886e759475469e2128b22f26b82ca993be6695ab190e673285d561d3b6d42fcc1edd6d12db12dcda0823e9d6079e7bc5ff54cd452dad308d52a15ce9c7edd6ef3dad6a27becd8e001e80f", + "message_hash": "586052916fb6f746e1d417766cceffbe1baf95579bab67ad49addaaa6e798862", + "signature": "626d61b7be1488b563e8a85bfb623b2331903964b5c0476c9f9ad29144f076fe2002a2c0ab5e48626bf761cf677dfeede9c7309d2436d4b8c2b89f21ee2ebc6a", + "pubkey": "04ff28290d214a783da7d76098b632c387b3dd5fd33677df8ca7109e3c941e5df2e5a6530c0bb58fbba14ecbc3d76a2a3d5017c66fc260f9214a028b8b3a7b2dce" + }, + { + "message": "db0d31717b04802adbbae1997487da8773440923c09b869e12a57c36dda34af11b8897f266cd81c02a762c6b74ea6aaf45aaa3c52867eb8f270f5092a36b498f88b65b2ebda24afe675da6f25379d1e194d093e7a2f66e450568dbdffebff97c4597a00c96a5be9ba26deefcca8761c1354429622c8db269d6a0ec0cc7a8585c", + "message_hash": "c36d0ecf4bfd178835c97aae7585f6a87de7dfa23cc927944f99a8d60feff68b", + "signature": "83de9be443bcf480892b8c8ca1d5ee65c79a315642c3f7b5305aff3065fda2789747932122b93cec42cad8ee4630a8f6cbe127578b8c495b4ab927275f657658", + "pubkey": "048f83776cbb355dbe59756c6b3d9b40a3470b6c64d49d9361a73bafcc1e7ba69beb05acb126fc4358b3c7008e1e864b4327086157412a84700d82672de27cb627" + }, + { + "message": "47c9deddfd8c841a63a99be96e972e40fa035ae10d929babfc86c437b9d5d495577a45b7f8a35ce3f880e7d8ae8cd8eb685cf41f0506e68046ccf5559232c674abb9c3683829dcc8002683c4f4ca3a29a7bfde20d96dd0f1a0ead847dea18f297f220f94932536ca4deacedc2c6701c3ee50e28e358dcc54cdbf69daf0eb87f6", + "message_hash": "a761293b02c5d8327f909d61a38173556c1f1f770c488810a9b360cf7786c148", + "signature": "723da69da81c8f6b081a9a728b9bba785d2067e0ed769675f8a7563d22ed8a163a993793cf39b96b3cd625df0e06f206e17579cd8ebcb7e704174c3d94dba684", + "pubkey": "0429b0c44bd3887a9ab60fd1c9bb81c9ab421e51b4736cedfa75e4cf960e6098315eab750d173d20842dfdebf861ea7898fdea0527211f8c86f31d9d48b6b65e63" + }, + { + "message": "f15433188c2bbc93b2150bb2f34d36ba8ae49f8f7e4e81aed651c8fb2022b2a7e851c4dbbbc21c14e27380316bfdebb0a049246349537dba687581c1344e40f75afd2735bb21ea074861de6801d28b22e8beb76fdd25598812b2061ca3fba229daf59a4ab416704543b02e16b8136c22acc7e197748ae19b5cbbc160fdc3a8cd", + "message_hash": "08ec76ab0f1bc9dc27b3b3bd4f949c60ecc8bbf27678b28f2ee8de055ee8bf59", + "signature": "0e0c5228e6783bee4d0406f4f7b7d79f705f0dbb55126966f79e631bd8b23079faae33aec5b0fafd3413c14bfdef9c7c9ac6abd06c923c48ab136a2c56826118", + "pubkey": "04441ef6e211e3fa6cffce9d34b4765487bc0d98d95b21ccfaeef42d7de2fef9a57886a20b6b10f97f5d05caa904ca3e287b92955658566639031e67cd243d8657" + }, + { + "message": "1bc796124b87793b7f7fdd53b896f8f0d0f2d2be36d1944e3c2a0ac5c6b2839f59a4b4fad200f8035ec98630c51ef0d40863a5ddd69b703d73f06b4afae8ad1a88e19b1b26e8c10b7bff953c05eccc82fd771b220910165f3a906b7c931683e431998d1fd06c32dd11b4f872bf980d547942f22124c7e50c9523321aee23a36d", + "message_hash": "ffbe3fd342a1a991848d02258cf5e3df301974b7a8f0fe10a88222a9503f67e0", + "signature": "b9d3962edadc893f8eeff379f136c7b8fc6ea824a5afc6cbda7e3cb4c7a1e860bb1c1f901cf450edfdce20686352bb0cf0a643301123140ec87c92480d7f9d6a", + "pubkey": "04ad98fbf6748401963e4c732b0ba4c4b5016f1d87935c5edf84b55c38b28eb3cf35f91b470e007cc5f5c2e12c9b8725bc92a6feb259968436881c72906a14ca84" + }, + { + "message": "18e55ac264031da435b613fc9dc6c4aafc49aae8ddf6f220d523415896ff915fae5c5b2e6aed61d88e5721823f089c46173afc5d9b47fd917834c85284f62dda6ed2d7a6ff10eb553b9312b05dad7decf7f73b69479c02f14ea0a2aa9e05ec07396cd37c28795c90e590631137102315635d702278e352aa41d0826adadff5e1", + "message_hash": "434fea583df79f781e41f18735a24409cf404f28e930290cc97c67ef158e5789", + "signature": "9369ab86afae5e22ed5f4012964804d2a19c36b8b58cf2855205b1cfcc937422a27dfc38d899b78edcf38a1b2b53578e72270b083d7d69424c4b4a7d25d39f4d", + "pubkey": "04061d7152dc6263a6764c6e810ee02f6333c844d90d70043b2bb6d4efacfac78e4391f7f17063bd69bd0d19061cc09eeb429561f3d88a3b38019ac82ca152c35c" + }, + { + "message": "a5290666c97294d090f8da898e555cbd33990579e5e95498444bfb318b4aa1643e0d4348425e21c7c6f99f9955f3048f56c22b68c4a516af5c90ed5268acc9c5a20fec0200c2a282a90e20d3c46d4ecdda18ba18b803b19263de2b79238da921707a0864799cdee9f02913b40681c02c6923070688844b58fe415b7d71ea6845", + "message_hash": "c352f58e118fc0d7810b8020bdb306b7dc115b41bbb0b642c7ea73a60cc2a4eb", + "signature": "c5e439cef76b28dc0fe9d260763bec05b5e795ac8d90b25d9fccbc1918bc32f31b06144e6b191224d5eda822a5b3b2026af6aa7f25a9061c9e81c312728aa94a", + "pubkey": "043eab98ab69bca21ad18136a092a4f398cb0a7d34c4bf18bbe9c81bdfce3dde752f8a82a4c1cbe5535d4acd9218ba6df4a96db88963d36108d562795473dedeae" + }, + { + "message": "13ad0600229c2a66b2f11617f69c7210ad044c49265dc98ec3c64f56e56a083234d277d404e2c40523c414ad23af5cc2f91a47fe59e7ca572f7fe1d3d3cfceaedadac4396749a292a38e92727273272335f12b2acea21cf069682e67d7e7d7a31ab5bb8e472298a9451aeae6f160f36e6623c9b632b9c93371a002818addc243", + "message_hash": "6ff9153ede285fc0e486f1dd4dd9e32a0fb23e9653c55841b67c2e5a090aac63", + "signature": "ee8615a5fab6fc674e6d3d9cde8da2b18dece076ae94d96662e16109db12d7203171705cdab2b3d34c58e556c80358c105807e98243f5754b70b771071308b94", + "pubkey": "042aaf49401b01083bf0657a379530f1b2b5db414e3fe91fca07048c89df05a4dae584ef2fe20d2f3293ff46df73155a76218349336977250055dc9ae7f28e57e0" + }, + { + "message": "51ad843da5eafc177d49a50a82609555e52773c5dfa14d7c02db5879c11a6b6e2e0860df38452dc579d763f91a83ade23b73f4fcbd703f35dd6ecfbb4c9578d5b604ed809c8633e6ac5679a5f742ce94fea3b97b5ba8a29ea28101a7b35f9eaa894dda54e3431f2464d18faf8342b7c59dfe0598c0ab29a14622a08eea70126b", + "message_hash": "8e19143e34fee546fab3d56e816f2e21586e27912a2ad7d80af75942e0ff585a", + "signature": "f753c447161aa3a58e5deeca31797f21484fb0ec3a7fe6e464ab1914896f253b99640fbcce1f25fd66744b046e0dfd57fa23070555f438af6c5e5828d47e9fa7", + "pubkey": "048c59a63c27b0b4e1e1b67f6e97180d5fa679791cde6af650271a274c369361421b42e36a7029f8982d346264f81f46cbc2e8c823568b2ad15649794fc835f87e" + }, + { + "message": "678b505467d55ce01aec23fd4851957137c3a1de3ff2c673ec95a577aa9fb011b4b4a8eb7a0e6f391d4236a35b7e769692ace5851d7c53700e180fa522d3d37dbaa496163f3de6d96391e38ff83271e621f2458729ff74de462cdce6b3029f308d4eb8aef036357b9de06d68558e0388a6e88af91340c875050b8c91c4e26fc8", + "message_hash": "6fe86a3b533114e1db444217999ce5907237e69acc47cfb8d30b4e14ee58817a", + "signature": "439fd0423bde36a1616a6fa4343bb7e07a6b3f6dc629aa8c93c91831055e476c20998a26ae4b96ef36d48d83e8af0288f0bbc2db5ca5c8271a42f3fdc478fcb2", + "pubkey": "04817e21214a40f8135e2053656dc3d9a66eade80f9428f347d11ea249095e9513df446f64d7db0e8161fc1c03c60ddae5d73a8d80ad134600acefc06b3c8c9eda" + }, + { + "message": "9bf457159f0d44b78d0e151ee53c41cecd98fb4e4129fcda8cc84a758636f84dcad9032f3ec422219d8a7ec61ea89f45d19cab3c3d451de1a634e3d2532231bc03031973d7150cf8e83d8b6a34f25fc136446878e3851b780abdca069c8e981b3ea3f1bf1ff6e47a03f97aed64c1cc90dd00389fa21bb973f142af5e8ceccef4", + "message_hash": "03b3e33ade25fad2eeb530433b6785fb1e977228e0049e572437caa33baa059e", + "signature": "4ce72a83cf1d148db4d1e46e2f773c677f72933c40d7100b9192750a1c8222a89d5fbd67ce89ba8c79df9dc3b42922026a8498921c2bdb4ea8f36496d88c2cfb", + "pubkey": "04571a598076a318dcd7af6ff35c2ab35198197faa1df9612f951d516456c97ef7a30a1405958f554fdf1bad22d22333acb4fe4c968c74a281c524020ad949c9ef" + }, + { + "message": "2469172b7a046e6112dfe365590dfddb7c045cccd4ab353edc3076091aad1c780a9a73ff93f3dbf9e2189c5d1fdd6f6167d0ae8cc0f53dc8950e60dd0410e23589999d4ce4fa49e268774defd4edce01c05b205014b63591a041745bfffc6ae4d72d3add353e49478106653cc735b07b0fe665c42d0e6766e525bb9718264c87", + "message_hash": "b90651535080381884a0917c02fdf9e176798c4d65bed76568ec1de95e3c9641", + "signature": "1f1e1fb673e9a7dee09961c6824b473189904deb4f0d8e28da51f77f4de2efe6ae8df1fcdb226fac8b46e494720e45f6d9a5350174faaf22e47b6329ee6c5e1b", + "pubkey": "048db80c468a88ffb4bcdb5ccddbfc9da8cf728a651ab937edf729ad279d9375b50b97422368aa4b3ac13aa18c89ca2af86c14b1948325f1477d5ea9f5156bcc52" + }, + { + "message": "6f8983e74f304c3657cffde0682b42699cb2c3475b925058ff37292c40a0aa296690ad129730339ac60cf784225b2fd3db58297c8ce5889df7a48d3e74a363ae4135e8a234cab53ca4c11c031d561a6cf7dd47b925ed5bc4c2794ba7b74a868b0c3da31ff1e4540d0768612192a236d86f74fb8c73f375b71c62f1648c0e6126", + "message_hash": "1095c90de2734d4b9dfedefbdd3f76f592f0a3e1697d1321f0eab3f78129c8ce", + "signature": "9cf7d941dcbbbe61c2a6f5112cb518094e79e5d203891de2247e75fd532c3f21fc5a04579b2526f2543efd2a57e82b647da08b6924bff39cf021398a56ad70de", + "pubkey": "0406e22a39ec06c32bcb4d235f23630a198a884a43e8c200a7c3b3f68ef4002de902c574035c08d39857caa492088d35cff9b1d4e1b73e8414b7d71fe53167f7cf" + }, + { + "message": "6fbe6f0f178fdc8a3ad1a8eecb02d37108c5831281fe85e3ff8eeb66ca1082a217b6d602439948f828e140140412544f994da75b6efc203b295235deca060ecfc7b71f05e5af2acc564596772ddbfb4078b4665f6b85f4e70641af26e31f6a14e5c88604459df4eeeed9b77b33c4b82a3c1458bd2fd1dc7214c04f9c79c8f09b", + "message_hash": "164025d15dfec124cd37db98daf196cfbe44716968112dc8a4be24e350abd559", + "signature": "59cd6c2a30227afbd693d87b201d0989435d6e116c144276a5223466a822c0f2b01495efda969b3fd3a2c05aa098a4e04b0d0e748726fc6174627da15b143799", + "pubkey": "04db6816cec58836ef290e39429f506f00c5541376128bedea089b88094f42cd950b23e68cd57203d9fedeeacef680c26baf25be682ad808f308d2ddd5828fdeae" + }, + { + "message": "2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e", + "message_hash": "00c6fc53c1986d19a8a8b580ee553dc1240745d760647d1c0adf442c133c7f56", + "signature": "9eaf69170aeba44966afe957295526ee9852b5034c18dc5aeef3255c8567838aebd4c8de2c22b5cb8803d6e070186786f6d5dae2202b9f899276fa31a66cb3bb", + "pubkey": "04d2a23e34dcb8e1fbaaf2c3c0e83500824b3a122e83737f1251fa34ccf0d2fb8719030b3d567ed019ba62ee392990a9a23f88ee990f26ed50783e4f671572371f" + }, + { + "message": "1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea19ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8bd37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c09ab159f3a00ed7b930f628c3c48257e92fc7407", + "message_hash": "fb5dd3b8d280fe7c4838f01b2a5c28493ed3084f46b40642600ba39e43fbff7b", + "signature": "91058d1b912514940e1002855cc930c01a21234bad88f607f213af495c32b69f005d387ce3de25f1b9bad1fb180de110686d91b461ae2972fa4e4a7018519870", + "pubkey": "048a86bbf4f7014a8ef557ff6a87681b5728957fc68342a1b2b0164eef5a3c7bb1cbe75d53a1a222990470161143bf18b5cec7c75616bbacdddf2f0af45514f9ca" + }, + { + "message": "74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aaee85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b91dc84bbb59b14ec477a1e9d194c137e21c75bbb", + "message_hash": "f4083aebe08c9bdb8c08ff844ffc207f80fa4406fb73bdbc1c6020f71281bdae", + "signature": "fe43eb9c38b506d118e20f8605ac8954fc0406efd306ba7ea5b07577a2735d15d589e91bf5014c7c360342ad135259dd7ae684e2c21234d7a912b43d148fcf19", + "pubkey": "04ab11970c6a01f45f6730b57d8eee6c9e1e7be824b34b27f9b45d2c5f5b6e601d4d946af7e4f5b98647634cfbacb4eecf7507c2fea1b114117902e4bafe9e1eb0" + }, + { + "message": "d10131982dd1a1d839aba383cd72855bf41061c0cb04dfa1acad3181f240341d744ca6002b52f25fb3c63f16d050c4a4ef2c0ebf5f16ce987558f4b9d4a5ad3c6b81b617de00e04ba32282d8bf223bfedbb325b741dfdc8f56fa85c65d42f05f6a1330d8cc6664ad32050dd7b9e3993f4d6c91e5e12cbd9e82196e009ad22560", + "message_hash": "cb017b280093879c4b114b52ea670f14e97b661074abccc8539a23280fe136b4", + "signature": "ccdbbd2500043bf7f705536d5984ab5f05fdc0fa3cf464d8c88f861e3fc8e54cd5c6342c08dcd8242e1daf3595cae968e320a025aa45ec4bc725795da3d1becb", + "pubkey": "040827dce898102fa27e52172e8246368b062ade896d34b7f25d8c24fca4a424f91d283f6ebac2b4f6167477ee624e2249c52a7c321e67b6fef711fba2f90d20d7" + }, + { + "message": "ef9dbd90ded96ad627a0a987ab90537a3e7acc1fdfa991088e9d999fd726e3ce1e1bd89a7df08d8c2bf51085254c89dc67bc21e8a1a93f33a38c18c0ce3880e958ac3e3dbe8aec49f981821c4ac6812dd29fab3a9ebe7fbd799fb50f12021b48d1d9abca8842547b3b99befa612cc8b4ca5f9412e0352e72ab1344a0ac2913db", + "message_hash": "5f1d77f456d7ed30acad33795b50733d54226e57df4281a43d3821d0762f12fe", + "signature": "5c707b6df7667324f950216b933d28e307a0223b24d161bc5887208d7f880b3a4b7bc56586dc51d806ac3ad72807bc62d1d06d0812f121bd91e9770d84885c39", + "pubkey": "0436748f1a531e91a40b9e6bfc502488cfd749c3b9529633d4e4dabdb058708b7ac4b0672c9a7105b6dbf63b8054e5d266d43d37cf51241ce289d8f9140fe28996" + } +] \ No newline at end of file