diff --git a/.cargo/audit.toml b/.cargo/audit.toml index bf2d2237..c36407a0 100644 --- a/.cargo/audit.toml +++ b/.cargo/audit.toml @@ -4,6 +4,4 @@ ignore = [ "RUSTSEC-2019-0036", # failure: type confusion if __private_get_type_id__ is overridden "RUSTSEC-2020-0036", # failure is officially deprecated/unmaintained - "RUSTSEC-2022-0093", # ed25519-dalek: double public key signing function oracle attack - "RUSTSEC-2023-0033", # borsh: parsing borsh messages with ZST which are not-copy/clone is unsound ] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b3f8bda7..744f3e8e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,7 +50,7 @@ jobs: matrix: toolchain: - stable - - 1.70.0 # MSRV + - 1.72.0 # MSRV runs-on: ubuntu-latest steps: - name: Checkout sources @@ -95,7 +95,7 @@ jobs: matrix: toolchain: - stable - - 1.70.0 # MSRV + - 1.72.0 # MSRV runs-on: ubuntu-latest steps: - name: Checkout sources @@ -222,7 +222,7 @@ jobs: - name: Install stable toolchain uses: actions-rs/toolchain@v1 with: - toolchain: 1.70.0 # MSRV + toolchain: 1.72.0 # MSRV override: true - name: Install libudev-dev diff --git a/Cargo.lock b/Cargo.lock index 42d1bc56..254ed0ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -199,9 +199,9 @@ dependencies = [ [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" @@ -223,15 +223,13 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bip32" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" +checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" dependencies = [ "bs58", - "hmac 0.12.1", + "hmac", "k256", - "once_cell", - "pbkdf2", "rand_core 0.6.4", "ripemd", "sha2 0.10.8", @@ -280,11 +278,11 @@ dependencies = [ [[package]] name = "bs58" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" dependencies = [ - "sha2 0.9.9", + "sha2 0.10.8", ] [[package]] @@ -514,9 +512,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cosmos-sdk-proto" -version = "0.16.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4776e787b24d9568dd61d3237eeb4eb321d622fb881b858c7b82806420e87d4" +checksum = "32560304ab4c365791fd307282f76637213d8083c1a98490c35159cd67852237" dependencies = [ "prost", "prost-types", @@ -525,19 +523,19 @@ dependencies = [ [[package]] name = "cosmrs" -version = "0.11.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "424675b6cf29795e5db8a808a78dd4229f0fdf90f64d9286dec0490f62534003" +checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea" dependencies = [ "bip32", "cosmos-sdk-proto", "ecdsa", "eyre", - "getrandom 0.2.10", "k256", "rand_core 0.6.4", "serde", "serde_json", + "signature", "subtle-encoding", "tendermint", "thiserror", @@ -563,9 +561,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.4.9" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -584,16 +582,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" -dependencies = [ - "generic-array", - "subtle", -] - [[package]] name = "ctr" version = "0.9.2" @@ -616,6 +604,47 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures 0.2.9", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "subtle-ng", + "zeroize", +] + [[package]] name = "dbl" version = "0.3.2" @@ -627,9 +656,9 @@ dependencies = [ [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -660,42 +689,61 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] name = "ed25519" -version = "1.5.3" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" dependencies = [ + "pkcs8", "signature", ] +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" +dependencies = [ + "curve25519-dalek-ng", + "hex 0.4.3", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "thiserror", + "zeroize", +] + [[package]] name = "ed25519-dalek" -version = "1.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" dependencies = [ - "curve25519-dalek", + "curve25519-dalek 4.1.1", "ed25519", - "rand", + "rand_core 0.6.4", "serde", - "sha2 0.9.9", + "sha2 0.10.8", "zeroize", ] @@ -707,13 +755,12 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", "digest 0.10.7", "ff", "generic-array", @@ -786,14 +833,20 @@ checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", ] +[[package]] +name = "fiat-crypto" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" + [[package]] name = "flex-error" version = "0.4.4" @@ -930,6 +983,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -950,10 +1004,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if 1.0.0", - "js-sys", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", ] [[package]] @@ -964,9 +1016,9 @@ checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", @@ -1034,6 +1086,12 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "hidapi" version = "0.5.2" @@ -1053,40 +1111,20 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e013a4f0b8772418eee1fc462e74017aba13c364a7b61bd3df1ddcbfe47b065" dependencies = [ - "hmac 0.12.1", + "hmac", "once_cell", "rand_core 0.6.4", "sha2 0.10.8", "zeroize", ] -[[package]] -name = "hkdf" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ab2f639c231793c5f6114bdb9bbe50a7dbbfcd7c7c6bd8475dec2d991e964f" -dependencies = [ - "digest 0.9.0", - "hmac 0.10.1", -] - [[package]] name = "hkdf" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" dependencies = [ - "hmac 0.12.1", -] - -[[package]] -name = "hmac" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" -dependencies = [ - "crypto-mac", - "digest 0.9.0", + "hmac", ] [[package]] @@ -1257,15 +1295,16 @@ dependencies = [ [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if 1.0.0", "ecdsa", "elliptic-curve", + "once_cell", "sha2 0.10.8", - "sha3", + "signature", ] [[package]] @@ -1291,7 +1330,7 @@ checksum = "6c9a2f47929b010a64a4bf9cdfe03b0d02175d44db0b91e16283f5a4a731d52c" dependencies = [ "byteorder", "cfg-if 0.1.10", - "hex", + "hex 0.3.2", "hidapi", "lazy_static", "libc", @@ -1538,23 +1577,25 @@ checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" [[package]] name = "p256" -version = "0.11.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ "ecdsa", "elliptic-curve", + "primeorder", "sha2 0.10.8", ] [[package]] name = "p384" -version = "0.11.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" dependencies = [ "ecdsa", "elliptic-curve", + "primeorder", "sha2 0.10.8", ] @@ -1566,11 +1607,12 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "pbkdf2" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", + "hmac", ] [[package]] @@ -1599,9 +1641,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -1613,6 +1655,12 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "platforms" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4503fa043bf02cee09a9582e9554b4c6403b2ef55e4612e96561d294419429f8" + [[package]] name = "poly1305" version = "0.7.2" @@ -1630,6 +1678,15 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "primeorder" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c2fcef82c0ec6eefcc179b978446c399b3cdf73c392c35604e399eee6df1ee3" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro2" version = "1.0.67" @@ -1641,9 +1698,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.9" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +checksum = "f4fdd22f3b9c31b53c060df4a0613a1c7f062d4115a2b984dd15b1858f7e340d" dependencies = [ "bytes", "prost-derive", @@ -1651,22 +1708,22 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.11.9" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32" dependencies = [ "anyhow", "itertools", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.37", ] [[package]] name = "prost-types" -version = "0.11.9" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +checksum = "e081b29f63d83a4bc75cfc9f3fe424f9156cf92d8a4f0c9407cce9a1b67327cf" dependencies = [ "prost", ] @@ -1688,25 +1745,23 @@ dependencies = [ [[package]] name = "rand" -version = "0.7.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "getrandom 0.1.16", "libc", "rand_chacha", - "rand_core 0.5.1", - "rand_hc", + "rand_core 0.6.4", ] [[package]] name = "rand_chacha" -version = "0.2.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.5.1", + "rand_core 0.6.4", ] [[package]] @@ -1727,15 +1782,6 @@ dependencies = [ "getrandom 0.2.10", ] -[[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - [[package]] name = "redox_syscall" version = "0.3.5" @@ -1791,13 +1837,12 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", - "hmac 0.12.1", - "zeroize", + "hmac", + "subtle", ] [[package]] @@ -1810,25 +1855,23 @@ dependencies = [ ] [[package]] -name = "ripemd160" -version = "0.9.1" +name = "rpassword" +version = "7.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322" dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug", + "libc", + "rtoolbox", + "winapi", ] [[package]] -name = "rpassword" -version = "6.0.1" +name = "rtoolbox" +version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf099a1888612545b683d2661a1940089f6c2e5a8e38979b2159da876bfd956" +checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a" dependencies = [ "libc", - "serde", - "serde_json", "winapi", ] @@ -1848,6 +1891,15 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.15" @@ -1903,9 +1955,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -2043,16 +2095,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - [[package]] name = "sharded-slab" version = "0.1.6" @@ -2064,9 +2106,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", @@ -2075,13 +2117,13 @@ dependencies = [ [[package]] name = "signature_derive" -version = "1.0.0-pre.7" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96e6310f022b5c02b3bba689166e833f6b96994a6ce1f138b653d2fd0519920f" +checksum = "acdf373908a51854e3c302a3cad677fadcf719255d4d3bd844405e379e9415fc" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.37", ] [[package]] @@ -2135,9 +2177,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -2164,6 +2206,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + [[package]] name = "syn" version = "1.0.109" @@ -2213,13 +2261,14 @@ dependencies = [ [[package]] name = "tendermint" -version = "0.27.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeb6f9c129bc9f1a3c38bc91c63a5e8d3c00ed998e7fa4ca44e06467466d0e77" +checksum = "bc2294fa667c8b548ee27a9ba59115472d0a09c2ba255771092a7f1dcf03a789" dependencies = [ "bytes", + "digest 0.10.7", "ed25519", - "ed25519-dalek", + "ed25519-consensus", "flex-error", "futures", "k256", @@ -2227,12 +2276,12 @@ dependencies = [ "once_cell", "prost", "prost-types", - "ripemd160", + "ripemd", "serde", "serde_bytes", "serde_json", "serde_repr", - "sha2 0.9.9", + "sha2 0.10.8", "signature", "subtle", "subtle-encoding", @@ -2243,9 +2292,9 @@ dependencies = [ [[package]] name = "tendermint-config" -version = "0.27.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414d0e7b47e20accc2e950fa623e76269eb0daeb8a20b6d7af2a61211f2806bf" +checksum = "5a25dbe8b953e80f3d61789fbdb83bf9ad6c0ef16df5ca6546f49912542cc137" dependencies = [ "flex-error", "serde", @@ -2257,21 +2306,21 @@ dependencies = [ [[package]] name = "tendermint-p2p" -version = "0.27.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8edfb0bd5755b9a0ac6b7c9c719861871c06979232c24b7dd6e39bedee0b1b7a" +checksum = "a890bd3d4a81345f1d114deca51f8f23c9faa5a9a20aed7adc0606a37f568c8d" dependencies = [ "aead 0.4.3", "chacha20poly1305", - "ed25519-dalek", + "ed25519-consensus", "eyre", "flex-error", "flume", - "hkdf 0.10.0", + "hkdf", "merlin", "prost", "rand_core 0.5.1", - "sha2 0.9.9", + "sha2 0.10.8", "signature", "subtle", "tendermint", @@ -2283,9 +2332,9 @@ dependencies = [ [[package]] name = "tendermint-proto" -version = "0.27.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5895470f28c530f8ae8c4071bf8190304ce00bd131d25e81730453124a3375c" +checksum = "2cc728a4f9e891d71adf66af6ecaece146f9c7a11312288a3107b3e1d6979aaf" dependencies = [ "bytes", "flex-error", @@ -2301,9 +2350,9 @@ dependencies = [ [[package]] name = "tendermint-std-ext" -version = "0.27.0" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15845aa4e492117f90ffaa3d86c71a3670029618b05ace7029d6228bd1e8f01e" +checksum = "e6324de19005740c3a6acf046fb17a8e69157415c7a9a4b679802d5edb78cb60" [[package]] name = "termcolor" @@ -2374,15 +2423,14 @@ dependencies = [ [[package]] name = "tiny_http" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d6ef4e10d23c1efb862eecad25c5054429a71958b4eeef85eb5e7170b477ca" +checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82" dependencies = [ "ascii", "chunked_transfer", + "httpdate", "log", - "time", - "url 2.4.1", ] [[package]] @@ -2410,12 +2458,13 @@ dependencies = [ "chrono", "clap", "cosmrs", - "ed25519-dalek", + "ed25519", + "ed25519-consensus", "elliptic-curve", "eyre", "getrandom 0.2.10", "hkd32", - "hkdf 0.12.3", + "hkdf", "k256", "ledger", "once_cell", @@ -2891,19 +2940,19 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" dependencies = [ - "curve25519-dalek", + "curve25519-dalek 3.2.0", "rand_core 0.5.1", "zeroize", ] [[package]] name = "yubihsm" -version = "0.41.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d479bdaa16917b3ff94bd09e72536369cdb2e167126ec908dae4cf934c19eb01" +checksum = "467a4c054be41ff657a6823246b0194cd727fadc3c539b265d7bc125ac6d4884" dependencies = [ "aes", - "bitflags 1.3.2", + "bitflags 2.4.0", "cbc", "ccm", "cmac", @@ -2911,7 +2960,7 @@ dependencies = [ "ecdsa", "ed25519", "ed25519-dalek", - "hmac 0.12.1", + "hmac", "k256", "log", "p256", diff --git a/Cargo.toml b/Cargo.toml index 21a02df8..69819ed3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,50 +13,51 @@ readme = "README.md" categories = ["cryptography::cryptocurrencies"] keywords = ["cosmos", "ed25519", "kms", "key-management", "yubihsm"] edition = "2021" -rust-version = "1.65" +rust-version = "1.72" [dependencies] abscissa_core = "0.7" bytes = "1" chrono = "0.4" clap = "4" -cosmrs = "0.11" -ed25519-dalek = "1" -elliptic-curve = { version = "0.12", features = ["pkcs8"], optional = true } +cosmrs = "0.15" +ed25519 = "2" +ed25519-consensus = "2" +elliptic-curve = { version = "0.13", features = ["pkcs8"], optional = true } eyre = "0.6" getrandom = "0.2" hkd32 = { version = "0.7", default-features = false, features = ["mnemonic"] } hkdf = "0.12" -k256 = { version = "0.11", features = ["ecdsa", "sha256"] } +k256 = { version = "0.13", features = ["ecdsa", "sha256"] } ledger = { version = "0.2", optional = true } once_cell = "1.5" -prost = "0.11" -prost-derive = "0.11" +prost = "0.12" +prost-derive = "0.12" rand_core = { version = "0.6", features = ["std"] } -rpassword = { version = "6", optional = true } +rpassword = { version = "7", optional = true } sdkms = { version = "0.5", optional = true } serde = { version = "1", features = ["serde_derive"] } serde_json = "1" sha2 = "0.10" -signature = { version = "1.5", features = ["std"] } +signature = { version = "2", features = ["std"] } subtle = "2" subtle-encoding = { version = "0.5", features = ["bech32-preview"] } tempfile = "3" -tendermint = { version = "0.27", features = ["secp256k1"] } -tendermint-config = "0.27" -tendermint-proto = "0.27" -tendermint-p2p = "0.27" +tendermint = { version = "0.34", features = ["secp256k1"] } +tendermint-config = "0.34" +tendermint-proto = "0.34" +tendermint-p2p = "0.34" thiserror = "1" url = { version = "2.2.2", features = ["serde"], optional = true } uuid = { version = "1", features = ["serde"], optional = true } wait-timeout = "0.2" -yubihsm = { version = "0.41", features = ["secp256k1", "setup", "usb"], optional = true } +yubihsm = { version = "0.42", features = ["secp256k1", "setup", "usb"], optional = true } zeroize = "1" [dev-dependencies] abscissa_core = { version = "0.7", features = ["testing"] } byteorder = "1" -rand = "0.7" +rand = "0.8" [features] softsign = [] diff --git a/README.md b/README.md index b5240c58..a82ea4c9 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ prerequisites for support. You will need the following prerequisites: -- **Rust** (stable; **1.65+**): https://rustup.rs/ +- **Rust** (stable; **1.72+**): https://rustup.rs/ - **C compiler**: e.g. gcc, clang - **pkg-config** - **libusb** (1.0+). Install instructions for common platforms: @@ -234,7 +234,7 @@ limitations under the License. [build-link]: https://github.com/iqlusioninc/tmkms/actions [license-image]: https://img.shields.io/badge/license-Apache2.0-blue.svg [license-link]: https://github.com/iqlusioninc/tmkms/blob/main/LICENSE -[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.72+-blue.svg [//]: # (general links) diff --git a/img/tx-signer.png b/img/tx-signer.png deleted file mode 100644 index 35d34850..00000000 Binary files a/img/tx-signer.png and /dev/null differ diff --git a/img/tx-signer.svg b/img/tx-signer.svg deleted file mode 100644 index e2f4f4c9..00000000 --- a/img/tx-signer.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/commands/softsign/import.rs b/src/commands/softsign/import.rs index 756b266c..63a8ac37 100644 --- a/src/commands/softsign/import.rs +++ b/src/commands/softsign/import.rs @@ -47,21 +47,19 @@ impl Runnable for ImportCommand { process::exit(1); } - let private_key = PrivValidatorKey::load_json_file(input_path) + let secret_key = PrivValidatorKey::load_json_file(input_path) .unwrap_or_else(|e| { status_err!("couldn't load {}: {}", input_path.display(), e); process::exit(1); }) .priv_key; - match private_key { - PrivateKey::Ed25519(pk) => { - key_utils::write_base64_secret(output_path, pk.secret.as_bytes()).unwrap_or_else( - |e| { - status_err!("{}", e); - process::exit(1); - }, - ); + match secret_key { + PrivateKey::Ed25519(sk) => { + key_utils::write_base64_secret(output_path, sk.as_bytes()).unwrap_or_else(|e| { + status_err!("{}", e); + process::exit(1); + }); } _ => unreachable!("unsupported priv_validator.json algorithm"), } diff --git a/src/commands/softsign/keygen.rs b/src/commands/softsign/keygen.rs index 5d5c6c75..bfbde05d 100644 --- a/src/commands/softsign/keygen.rs +++ b/src/commands/softsign/keygen.rs @@ -1,9 +1,8 @@ //! `tmkms softsign keygen` subcommand -use crate::{key_utils, prelude::*}; +use crate::{key_utils, keyring::ed25519, prelude::*}; use abscissa_core::{Command, Runnable}; use clap::Parser; -use ed25519_dalek as ed25519; use k256::ecdsa; use rand_core::{OsRng, RngCore}; use std::{path::Path, path::PathBuf, process}; @@ -71,15 +70,9 @@ fn generate_secp256k1_key(output_path: &Path) { fn generate_ed25519_key(output_path: &Path) { let mut sk_bytes = [0u8; 32]; OsRng.fill_bytes(&mut sk_bytes); - let sk = ed25519::SecretKey::from_bytes(&sk_bytes).unwrap(); - let pk = ed25519::PublicKey::from(&sk); + let sk = ed25519::SigningKey::from(sk_bytes); - let keypair = ed25519::Keypair { - public: pk, - secret: sk, - }; - - key_utils::write_base64_secret(output_path, keypair.secret.as_ref()).unwrap_or_else(|e| { + key_utils::write_base64_secret(output_path, sk.as_bytes()).unwrap_or_else(|e| { status_err!("{}", e); process::exit(1); }); diff --git a/src/commands/yubihsm/keys/import.rs b/src/commands/yubihsm/keys/import.rs index 483eef38..585ab6b3 100644 --- a/src/commands/yubihsm/keys/import.rs +++ b/src/commands/yubihsm/keys/import.rs @@ -1,10 +1,9 @@ //! Import keys either from encrypted backups or existing plaintext keys use super::*; -use crate::prelude::*; +use crate::{keyring::ed25519, prelude::*}; use abscissa_core::{Command, Runnable}; use clap::Parser; -use ed25519_dalek as ed25519; use std::{fs, path::PathBuf, process}; use subtle_encoding::base64; use tendermint::{PrivateKey, PublicKey}; @@ -173,7 +172,7 @@ impl ImportCommand { .priv_key; let seed = match private_key { - PrivateKey::Ed25519(pk) => pk.secret, + PrivateKey::Ed25519(pk) => pk, _ => unreachable!(), }; @@ -218,7 +217,7 @@ impl ImportCommand { process::exit(1); })); - let secret = ed25519::SecretKey::from_bytes(&key_bytes).unwrap_or_else(|e| { + let secret = ed25519::SigningKey::try_from(key_bytes.as_ref()).unwrap_or_else(|e| { status_err!("invalid Ed25519 key: {}", e); process::exit(1); }); diff --git a/src/commands/yubihsm/keys/list.rs b/src/commands/yubihsm/keys/list.rs index b605d7cb..f04ae5ae 100644 --- a/src/commands/yubihsm/keys/list.rs +++ b/src/commands/yubihsm/keys/list.rs @@ -151,7 +151,10 @@ fn display_key_info( let key_serialized = match key_formatters.get(&key.object_id) { Some(key_formatter) => key_formatter.serialize(tendermint_key), - None => tendermint_key.to_hex(), + None => match tendermint_key { + TendermintKey::AccountKey(k) => k.to_hex(), + TendermintKey::ConsensusKey(k) => k.to_hex(), + }, }; status_attr_ok!(key_id, "[{}] {}", key_type, key_serialized); diff --git a/src/connection/tcp.rs b/src/connection/tcp.rs index 55353682..d538c312 100644 --- a/src/connection/tcp.rs +++ b/src/connection/tcp.rs @@ -42,7 +42,7 @@ pub fn open_secret_connection( socket.set_read_timeout(Some(timeout))?; socket.set_write_timeout(Some(timeout))?; - let connection = match SecretConnection::new(socket, identity_key, protocol_version) { + let connection = match SecretConnection::new(socket, identity_key.into(), protocol_version) { Ok(conn) => conn, Err(error) => match error.detail() { TmError::Crypto(_) => fail!(CryptoError, format!("{error}")), diff --git a/src/error.rs b/src/error.rs index 46742805..c0e694e3 100644 --- a/src/error.rs +++ b/src/error.rs @@ -25,6 +25,10 @@ pub enum ErrorKind { #[error("config error")] ConfigError, + /// Cryptographic operation failed + #[error("cryptographic error")] + CryptoError, + /// Double sign attempted #[error("attempted double sign")] DoubleSign, @@ -33,10 +37,6 @@ pub enum ErrorKind { #[error("requested signature above stop height")] ExceedMaxHeight, - /// Cryptographic operation failed - #[error("cryptographic error")] - CryptoError, - /// Fortanix DSM related error #[cfg(feature = "fortanixdsm")] #[error("Fortanix DSM error")] @@ -46,7 +46,7 @@ pub enum ErrorKind { #[error("subcommand hook failed")] HookError, - /// Malformatted or otherwise invalid cryptographic key + /// Malformed or otherwise invalid cryptographic key #[error("invalid key")] InvalidKey, diff --git a/src/key_utils.rs b/src/key_utils.rs index 3e88c4b1..2f0701ca 100644 --- a/src/key_utils.rs +++ b/src/key_utils.rs @@ -1,24 +1,21 @@ //! Utilities +use crate::{ + error::{Error, ErrorKind::*}, + keyring::ed25519, + prelude::*, +}; +use k256::ecdsa; +use rand_core::{OsRng, RngCore}; use std::{ fs::{self, OpenOptions}, io::Write, os::unix::fs::OpenOptionsExt, path::Path, }; - -use ed25519_dalek as ed25519; -use ed25519_dalek::SECRET_KEY_LENGTH; -use k256::ecdsa; -use rand_core::{OsRng, RngCore}; use subtle_encoding::base64; use zeroize::Zeroizing; -use crate::{ - error::{Error, ErrorKind::*}, - prelude::*, -}; - /// File permissions for secret data pub const SECRET_FILE_PERMS: u32 = 0o600; @@ -48,14 +45,11 @@ pub fn load_base64_secret(path: impl AsRef) -> Result>, } /// Load a Base64-encoded Ed25519 secret key -pub fn load_base64_ed25519_key(path: impl AsRef) -> Result { +pub fn load_base64_ed25519_key(path: impl AsRef) -> Result { let key_bytes = load_base64_secret(path)?; - let secret = ed25519::SecretKey::from_bytes(&key_bytes) - .map_err(|e| format_err!(InvalidKey, "invalid Ed25519 key: {}", e))?; - - let public = ed25519::PublicKey::from(&secret); - Ok(ed25519::Keypair { secret, public }) + Ok(ed25519::SigningKey::try_from(key_bytes.as_ref()) + .map_err(|e| format_err!(InvalidKey, "invalid Ed25519 key: {}", e))?) } /// Load a Base64-encoded Secp256k1 secret key @@ -64,7 +58,7 @@ pub fn load_base64_secp256k1_key( ) -> Result<(ecdsa::SigningKey, ecdsa::VerifyingKey), Error> { let key_bytes = load_base64_secret(path)?; - let signing = ecdsa::SigningKey::from_bytes(&key_bytes) + let signing = ecdsa::SigningKey::try_from(key_bytes.as_slice()) .map_err(|e| format_err!(InvalidKey, "invalid ECDSA key: {}", e))?; let veryfing = ecdsa::VerifyingKey::from(&signing); @@ -96,7 +90,7 @@ pub fn write_base64_secret(path: impl AsRef, data: &[u8]) -> Result<(), Er /// Generate a Secret Connection key at the given path pub fn generate_key(path: impl AsRef) -> Result<(), Error> { - let mut secret_key = Zeroizing::new([0u8; SECRET_KEY_LENGTH]); + let mut secret_key = Zeroizing::new([0u8; ed25519::SigningKey::BYTE_SIZE]); OsRng.fill_bytes(&mut *secret_key); write_base64_secret(path, &*secret_key) } diff --git a/src/keyring.rs b/src/keyring.rs index 7eafff12..364c658b 100644 --- a/src/keyring.rs +++ b/src/keyring.rs @@ -172,7 +172,14 @@ impl KeyRing { if !self.ed25519_keys.is_empty() { let signer = match public_key { Some(public_key) => self.ed25519_keys.get(public_key).ok_or_else(|| { - format_err!(InvalidKey, "not in keyring: {}", public_key.to_bech32("")) + format_err!( + InvalidKey, + "not in keyring: {}", + match public_key { + TendermintKey::AccountKey(pk) => pk.to_bech32(""), + TendermintKey::ConsensusKey(pk) => pk.to_bech32(""), + } + ) }), None => self .ed25519_keys @@ -185,7 +192,14 @@ impl KeyRing { } else if !self.ecdsa_keys.is_empty() { let signer = match public_key { Some(public_key) => self.ecdsa_keys.get(public_key).ok_or_else(|| { - format_err!(InvalidKey, "not in keyring: {}", public_key.to_bech32("")) + format_err!( + InvalidKey, + "not in keyring: {}", + match public_key { + TendermintKey::AccountKey(pk) => pk.to_bech32(""), + TendermintKey::ConsensusKey(pk) => pk.to_bech32(""), + } + ) }), None => self .ecdsa_keys diff --git a/src/keyring/ed25519.rs b/src/keyring/ed25519.rs index 1f22fb34..cc091e62 100644 --- a/src/keyring/ed25519.rs +++ b/src/keyring/ed25519.rs @@ -1,6 +1,10 @@ //! Ed25519 signing keys -pub use ed25519_dalek::{Keypair, PublicKey, SecretKey, Signature}; +mod signing_key; +mod verifying_key; + +pub use self::{signing_key::SigningKey, verifying_key::VerifyingKey}; +pub use ed25519::Signature; use crate::{ error::{Error, ErrorKind::*}, diff --git a/src/keyring/ed25519/signing_key.rs b/src/keyring/ed25519/signing_key.rs new file mode 100644 index 00000000..ef76000a --- /dev/null +++ b/src/keyring/ed25519/signing_key.rs @@ -0,0 +1,75 @@ +use super::{Signature, VerifyingKey}; +use crate::error::{Error, ErrorKind}; +use signature::Signer; + +/// Signing key serialized as bytes. +type SigningKeyBytes = [u8; SigningKey::BYTE_SIZE]; + +/// Ed25519 signing key. +#[derive(Clone, Debug)] +pub struct SigningKey(ed25519_consensus::SigningKey); + +impl SigningKey { + /// Size of an encoded Ed25519 signing key in bytes. + pub const BYTE_SIZE: usize = 32; + + /// Borrow the serialized signing key as bytes. + pub fn as_bytes(&self) -> &SigningKeyBytes { + self.0.as_bytes() + } + + /// Get the verifying key for this signing key. + pub fn verifying_key(&self) -> VerifyingKey { + VerifyingKey(self.0.verification_key()) + } +} + +impl From for SigningKey { + fn from(bytes: SigningKeyBytes) -> Self { + Self(bytes.into()) + } +} + +impl From for ed25519_consensus::SigningKey { + fn from(signing_key: SigningKey) -> ed25519_consensus::SigningKey { + signing_key.0 + } +} + +impl From<&SigningKey> for tendermint_p2p::secret_connection::PublicKey { + fn from(signing_key: &SigningKey) -> tendermint_p2p::secret_connection::PublicKey { + Self::from(&signing_key.0) + } +} + +impl From for SigningKey { + fn from(signing_key: ed25519_consensus::SigningKey) -> SigningKey { + SigningKey(signing_key) + } +} + +impl From for SigningKey { + fn from(signing_key: tendermint::private_key::Ed25519) -> SigningKey { + signing_key + .as_bytes() + .try_into() + .expect("invalid Ed25519 signing key") + } +} + +impl Signer for SigningKey { + fn try_sign(&self, msg: &[u8]) -> signature::Result { + Ok(self.0.sign(msg).to_bytes().into()) + } +} + +impl TryFrom<&[u8]> for SigningKey { + type Error = Error; + + fn try_from(slice: &[u8]) -> Result { + slice + .try_into() + .map(Self) + .map_err(|_| ErrorKind::InvalidKey.into()) + } +} diff --git a/src/keyring/ed25519/verifying_key.rs b/src/keyring/ed25519/verifying_key.rs new file mode 100644 index 00000000..3681f257 --- /dev/null +++ b/src/keyring/ed25519/verifying_key.rs @@ -0,0 +1,64 @@ +use super::Signature; +use super::SigningKey; +use crate::error::{Error, ErrorKind}; +use signature::Verifier; + +/// Ed25519 verification key. +#[derive(Clone, Debug)] +pub struct VerifyingKey(pub(super) ed25519_consensus::VerificationKey); + +impl VerifyingKey { + /// Size of an encoded Ed25519 verifying key in bytes. + pub const BYTE_SIZE: usize = 32; + + /// Borrow the serialized verification key as bytes. + pub fn as_bytes(&self) -> &[u8; Self::BYTE_SIZE] { + self.0.as_bytes() + } +} + +impl From<&SigningKey> for VerifyingKey { + fn from(signing_key: &SigningKey) -> VerifyingKey { + signing_key.verifying_key() + } +} + +impl From for tendermint::PublicKey { + fn from(verifying_key: VerifyingKey) -> tendermint::PublicKey { + tendermint::PublicKey::from_raw_ed25519(verifying_key.as_bytes()) + .expect("invalid Ed25519 key") + } +} + +impl From for tendermint_p2p::secret_connection::PublicKey { + #[inline] + fn from(verifying_key: VerifyingKey) -> tendermint_p2p::secret_connection::PublicKey { + Self::from(&verifying_key) + } +} + +impl From<&VerifyingKey> for tendermint_p2p::secret_connection::PublicKey { + fn from(verifying_key: &VerifyingKey) -> tendermint_p2p::secret_connection::PublicKey { + verifying_key.0.into() + } +} + +impl Verifier for VerifyingKey { + fn verify(&self, msg: &[u8], sig: &Signature) -> signature::Result<()> { + let sig = ed25519_consensus::Signature::from(sig.to_bytes()); + self.0 + .verify(&sig, msg) + .map_err(|_| signature::Error::new()) + } +} + +impl TryFrom<&[u8]> for VerifyingKey { + type Error = Error; + + fn try_from(slice: &[u8]) -> Result { + slice + .try_into() + .map(Self) + .map_err(|_| ErrorKind::InvalidKey.into()) + } +} diff --git a/src/keyring/format.rs b/src/keyring/format.rs index 28b69faf..001aefe9 100644 --- a/src/keyring/format.rs +++ b/src/keyring/format.rs @@ -42,7 +42,10 @@ impl Format { TendermintKey::ConsensusKey(pk) => pk.to_bech32(consensus_key_prefix), }, Format::CosmosJson => PublicKey::from(*public_key.public_key()).to_json(), - Format::Hex => public_key.to_hex(), + Format::Hex => match public_key { + TendermintKey::AccountKey(pk) => pk.to_hex(), + TendermintKey::ConsensusKey(pk) => pk.to_hex(), + }, } } } diff --git a/src/keyring/providers/fortanixdsm.rs b/src/keyring/providers/fortanixdsm.rs index 47f9e08b..be811728 100644 --- a/src/keyring/providers/fortanixdsm.rs +++ b/src/keyring/providers/fortanixdsm.rs @@ -5,12 +5,11 @@ use crate::{ config::provider::fortanixdsm::{FortanixDsmConfig, KeyDescriptor, SigningKeyConfig}, config::provider::KeyType, error::{Error, ErrorKind::*}, - keyring::{self, SigningProvider}, + keyring::{self, ed25519, SigningProvider}, prelude::*, }; -use ed25519_dalek::{Signature as Ed25519Signature, Signer}; use elliptic_curve::pkcs8::{ - spki::Error as SpkiError, DecodePublicKey, ObjectIdentifier, SubjectPublicKeyInfo, + spki::Error as SpkiError, DecodePublicKey, ObjectIdentifier, SubjectPublicKeyInfoRef, }; use elliptic_curve::PublicKey as EcPublicKey; use k256::ecdsa::{Error as SignError, Signature as EcdsaSignature}; @@ -18,6 +17,7 @@ use sdkms::api_model::{ DigestAlgorithm, EllipticCurve, ObjectType, SignRequest, SignResponse, SobjectDescriptor, }; use sdkms::{Error as SdkmsError, SdkmsClient}; +use signature::Signer; use std::sync::Arc; use tendermint::public_key::{Ed25519, Secp256k1}; use tendermint::{PublicKey, TendermintKey}; @@ -166,11 +166,11 @@ impl Signer for SigningKey { } } -impl Signer for SigningKey { - fn try_sign(&self, msg: &[u8]) -> Result { +impl Signer for SigningKey { + fn try_sign(&self, msg: &[u8]) -> Result { assert_eq!(self.elliptic_curve, EllipticCurve::Ed25519); let resp = self.sign(msg, DigestAlgorithm::Sha512)?; - Ed25519Signature::from_bytes(&resp.signature) + ed25519::Signature::from_slice(&resp.signature) } } @@ -213,12 +213,10 @@ const ED_25519_OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.101.112 struct Ed25519PublicKey(Ed25519); -impl DecodePublicKey for Ed25519PublicKey {} - -impl<'a> TryFrom> for Ed25519PublicKey { +impl<'a> TryFrom> for Ed25519PublicKey { type Error = SpkiError; - fn try_from(spki: SubjectPublicKeyInfo<'_>) -> Result { + fn try_from(spki: SubjectPublicKeyInfoRef<'_>) -> Result { spki.algorithm.assert_algorithm_oid(ED_25519_OID)?; if spki.algorithm.parameters.is_some() { @@ -226,7 +224,7 @@ impl<'a> TryFrom> for Ed25519PublicKey { return Err(SpkiError::KeyMalformed); } - Ed25519::from_bytes(spki.subject_public_key) + Ed25519::try_from(spki.subject_public_key.as_bytes().unwrap()) .map_err(|_| SpkiError::KeyMalformed) .map(Ed25519PublicKey) } diff --git a/src/keyring/providers/ledgertm.rs b/src/keyring/providers/ledgertm.rs index d4750426..d200b065 100644 --- a/src/keyring/providers/ledgertm.rs +++ b/src/keyring/providers/ledgertm.rs @@ -36,7 +36,7 @@ pub fn init( let provider = Ed25519LedgerTmAppSigner::connect().map_err(|_| Error::from(SigningError))?; - let public_key = PublicKey::from_raw_ed25519(ed25519::PublicKey::from(&provider).as_bytes()) + let public_key = PublicKey::from_raw_ed25519(ed25519::VerifyingKey::from(&provider).as_bytes()) .expect("invalid Ed25519 public key"); let signer = Signer::new( diff --git a/src/keyring/providers/ledgertm/client.rs b/src/keyring/providers/ledgertm/client.rs index 668130e9..ed0fa119 100644 --- a/src/keyring/providers/ledgertm/client.rs +++ b/src/keyring/providers/ledgertm/client.rs @@ -160,8 +160,8 @@ impl TendermintValidatorApp { #[cfg(test)] mod tests { - use ed25519_dalek::ed25519::signature::Verifier; use once_cell::sync::Lazy; + use signature::Verifier; use std::sync::Mutex; use std::time::Instant; @@ -265,15 +265,15 @@ mod tests { let some_message2 = get_fake_proposal(6, 0); match app.sign(&some_message2) { Ok(sig) => { - use ed25519_dalek::PublicKey; - use ed25519_dalek::Signature; + use crate::keyring::ed25519; println!("{:#?}", sig.to_vec()); // First, get public key let public_key_bytes = app.public_key().unwrap(); - let public_key = PublicKey::from_bytes(&public_key_bytes).unwrap(); - let signature = Signature::from_bytes(&sig).unwrap(); + let public_key = + ed25519::VerifyingKey::try_from(public_key_bytes.as_ref()).unwrap(); + let signature = ed25519::Signature::try_from(sig.as_ref()).unwrap(); // Verify signature assert!(public_key.verify(&some_message2, &signature).is_ok()); diff --git a/src/keyring/providers/ledgertm/signer.rs b/src/keyring/providers/ledgertm/signer.rs index 22ccf40e..3d7cd796 100644 --- a/src/keyring/providers/ledgertm/signer.rs +++ b/src/keyring/providers/ledgertm/signer.rs @@ -15,7 +15,7 @@ ********************************************************************************/ use super::client::TendermintValidatorApp; -use crate::keyring::ed25519::{PublicKey, Signature}; +use crate::keyring::ed25519::{Signature, VerifyingKey}; use signature::{Error, Signer}; use std::sync::{Arc, Mutex}; @@ -33,11 +33,12 @@ impl Ed25519LedgerTmAppSigner { } } -impl From<&Ed25519LedgerTmAppSigner> for PublicKey { +impl From<&Ed25519LedgerTmAppSigner> for VerifyingKey { /// Returns the public key that corresponds to the Tendermint Validator app connected to this signer - fn from(signer: &Ed25519LedgerTmAppSigner) -> PublicKey { + fn from(signer: &Ed25519LedgerTmAppSigner) -> VerifyingKey { let app = signer.app.lock().unwrap(); - PublicKey::from_bytes(&app.public_key().unwrap()).expect("invalid Ed25519 public key") + VerifyingKey::try_from(app.public_key().unwrap().as_ref()) + .expect("invalid Ed25519 public key") } } @@ -52,14 +53,14 @@ impl Signer for Ed25519LedgerTmAppSigner { #[cfg(test)] mod tests { - use super::{Ed25519LedgerTmAppSigner, PublicKey}; + use super::{Ed25519LedgerTmAppSigner, VerifyingKey}; use signature::Signer; #[test] #[ignore] fn public_key() { let signer = Ed25519LedgerTmAppSigner::connect().unwrap(); - let pk = PublicKey::from(&signer); + let pk = VerifyingKey::from(&signer); println!("PK {pk:0X?}"); } @@ -126,7 +127,7 @@ mod tests { let signer = Ed25519LedgerTmAppSigner::connect().unwrap(); // Get public key to initialize - let pk = PublicKey::from(&signer); + let pk = VerifyingKey::from(&signer); println!("PK {pk:0X?}"); for index in 50u8..254u8 { diff --git a/src/keyring/providers/softsign.rs b/src/keyring/providers/softsign.rs index 1f9a746f..0c4167ba 100644 --- a/src/keyring/providers/softsign.rs +++ b/src/keyring/providers/softsign.rs @@ -10,10 +10,9 @@ use crate::{ }, error::{Error, ErrorKind::*}, key_utils, - keyring::{self, SigningProvider}, + keyring::{self, ed25519, SigningProvider}, prelude::*, }; -use ed25519_dalek as ed25519; use k256::ecdsa; use tendermint::{PrivateKey, TendermintKey}; use tendermint_config::PrivValidatorKey; @@ -30,9 +29,10 @@ pub fn init(chain_registry: &mut chain::Registry, configs: &[SoftsignConfig]) -> match config.key_type { KeyType::Account => { let signer = load_secp256k1_key(config)?; - let public_key = - tendermint::PublicKey::from_raw_secp256k1(&signer.verifying_key().to_bytes()) - .unwrap(); + let public_key = tendermint::PublicKey::from_raw_secp256k1( + &signer.verifying_key().to_sec1_bytes(), + ) + .unwrap(); let account_pubkey = TendermintKey::AccountKey(public_key); @@ -57,7 +57,8 @@ pub fn init(chain_registry: &mut chain::Registry, configs: &[SoftsignConfig]) -> loaded_consensus_key = true; let signing_key = load_ed25519_key(config)?; - let consensus_pubkey = TendermintKey::ConsensusKey(signing_key.public.into()); + let consensus_pubkey = + TendermintKey::ConsensusKey(signing_key.verifying_key().into()); let signer = keyring::ed25519::Signer::new( SigningProvider::SoftSign, @@ -76,7 +77,7 @@ pub fn init(chain_registry: &mut chain::Registry, configs: &[SoftsignConfig]) -> } /// Load an Ed25519 key according to the provided configuration -fn load_ed25519_key(config: &SoftsignConfig) -> Result { +fn load_ed25519_key(config: &SoftsignConfig) -> Result { let key_format = config.key_format.as_ref().cloned().unwrap_or_default(); match key_format { @@ -94,7 +95,7 @@ fn load_ed25519_key(config: &SoftsignConfig) -> Result .priv_key; if let PrivateKey::Ed25519(pk) = private_key { - Ok(pk) + Ok(pk.into()) } else { unreachable!("unsupported priv_validator.json algorithm"); } @@ -113,7 +114,7 @@ fn load_secp256k1_key(config: &SoftsignConfig) -> Result for Signature { - fn as_ref(&self) -> &[u8] { - match &self { - Signature::Ed25519(sig) => sig.as_ref(), - Signature::Ecdsa(sig) => sig.as_ref(), +impl Signature { + /// Serialize this signature as a byte vector. + pub fn to_vec(&self) -> Vec { + match self { + Self::Ed25519(sig) => sig.to_vec(), + Self::Ecdsa(sig) => sig.to_vec(), } } } diff --git a/src/signing.rs b/src/signing.rs index 46ebf4ef..7bccb9ba 100644 --- a/src/signing.rs +++ b/src/signing.rs @@ -171,7 +171,7 @@ impl SignableMsg { pub fn add_signature(self, sig: Signature) -> Result { match self { Self::Proposal(mut proposal) => { - proposal.signature = sig.as_ref().to_vec(); + proposal.signature = sig.to_vec(); Ok(Response::SignedProposal( proto::privval::SignedProposalResponse { proposal: Some(proposal), @@ -180,7 +180,7 @@ impl SignableMsg { )) } Self::Vote(mut vote) => { - vote.signature = sig.as_ref().to_vec(); + vote.signature = sig.to_vec(); Ok(Response::SignedVote(proto::privval::SignedVoteResponse { vote: Some(vote), error: None, diff --git a/tests/integration.rs b/tests/integration.rs index c2fec4a3..7eac38c0 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -2,9 +2,9 @@ use abscissa_core::prelude::warn; use chrono::{DateTime, Utc}; -use ed25519_dalek::{self as ed25519, Verifier}; use prost::Message; use rand::Rng; +use signature::Verifier; use std::{ fs, io::{self, Cursor, Read, Write}, @@ -15,10 +15,10 @@ use std::{ use tempfile::NamedTempFile; use tendermint_p2p::secret_connection::{self, SecretConnection}; use tendermint_proto as proto; - use tmkms::{ config::provider::KeyType, connection::unix::UnixConnection, + keyring::ed25519, signing::{SignableMsg, SignedMsgType}, }; @@ -86,7 +86,7 @@ impl KmsProcess { /// Spawn the KMS process and wait for an incoming TCP connection pub fn create_tcp(key_type: &KeyType) -> Self { // Generate a random port and a config file - let port: u16 = rand::thread_rng().gen_range(60000, 65535); + let port: u16 = rand::thread_rng().gen_range(60000..=65535); let config = KmsProcess::create_tcp_config(port, key_type); // Listen on a random port @@ -106,8 +106,8 @@ impl KmsProcess { pub fn create_unix(key_type: &KeyType) -> Self { // Create a random socket path and a config file let mut rng = rand::thread_rng(); - let letter: char = rng.gen_range(b'a', b'z') as char; - let number: u32 = rng.gen_range(0, 999999); + let letter: char = rng.gen_range(b'a'..=b'z') as char; + let number: u32 = rng.gen_range(0..=999999); let socket_path = format!("/tmp/tmkms-{letter}{number:06}.sock"); let config = KmsProcess::create_unix_config(&socket_path, key_type); @@ -128,7 +128,7 @@ impl KmsProcess { /// Create a config file for a TCP KMS and return its path fn create_tcp_config(port: u16, key_type: &KeyType) -> NamedTempFile { let mut config_file = NamedTempFile::new().unwrap(); - let pub_key = test_ed25519_keypair().public; + let pub_key = test_ed25519_keypair().verifying_key(); let peer_id = secret_connection::PublicKey::from(pub_key).peer_id(); writeln!( @@ -193,7 +193,7 @@ impl KmsProcess { match self.socket { KmsSocket::TCP(ref sock) => { // we use the same key for both sides: - let identity_keypair = test_ed25519_keypair(); + let identity_key = test_ed25519_keypair(); // Here we reply to the kms with a "remote" ephermal key, auth signature etc: let socket_cp = sock.try_clone().unwrap(); @@ -201,7 +201,7 @@ impl KmsProcess { KmsConnection::Tcp( SecretConnection::new( socket_cp, - identity_keypair, + identity_key.into(), secret_connection::Version::V0_34, ) .unwrap(), @@ -292,7 +292,7 @@ impl io::Read for ProtocolTester { } /// Get the Ed25519 signing keypair used by the tests -fn test_ed25519_keypair() -> ed25519::Keypair { +fn test_ed25519_keypair() -> ed25519::SigningKey { tmkms::key_utils::load_base64_ed25519_key(signing_key_path(&KeyType::Consensus)).unwrap() } @@ -384,7 +384,9 @@ fn handle_and_sign_proposal(key_type: KeyType) { } KeyType::Consensus => { let signature = ed25519::Signature::try_from(prop.signature.as_slice()).unwrap(); - test_ed25519_keypair().public.verify(msg, &signature) + test_ed25519_keypair() + .verifying_key() + .verify(msg, &signature) } }; assert!(r.is_ok()); @@ -429,6 +431,8 @@ fn handle_and_sign_vote(key_type: KeyType) { ], validator_index: 56789, signature: vec![], + extension: vec![], + extension_signature: vec![], }; let signable_msg = SignableMsg::Vote(vote_msg.clone()); @@ -466,7 +470,9 @@ fn handle_and_sign_vote(key_type: KeyType) { } KeyType::Consensus => { let signature = ed25519::Signature::try_from(sig.as_slice()).unwrap(); - test_ed25519_keypair().public.verify(msg, &signature) + test_ed25519_keypair() + .verifying_key() + .verify(msg, &signature) } }; assert!(r.is_ok()); @@ -513,6 +519,8 @@ fn exceed_max_height(key_type: KeyType) { ], validator_index: 56789, signature: vec![], + extension: vec![], + extension_signature: vec![], }; let signable_msg = SignableMsg::Vote(vote_msg.clone()); @@ -550,7 +558,9 @@ fn exceed_max_height(key_type: KeyType) { } KeyType::Consensus => { let signature = ed25519::Signature::try_from(sig.as_slice()).unwrap(); - test_ed25519_keypair().public.verify(msg, &signature) + test_ed25519_keypair() + .verifying_key() + .verify(msg, &signature) } }; assert!(r.is_ok());