diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 7aa15e8f..00000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,15 +0,0 @@ -# These are supported funding model platforms - -github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] -patreon: # Replace with a single Patreon username -open_collective: # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry -polar: # Replace with a single Polar username -buy_me_a_coffee: # Replace with a single Buy Me a Coffee username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] -celestia: celestia12u2ejw7p74dz3540zltvhh6vml0ssz444ptska diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a159f67..3009f29f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,7 +88,7 @@ jobs: awk '/Configuration finished. Running a bridge node/ {print;exit}' - name: Run integration tests - run: cargo test --lib --release --features mock_prover --test integration_tests + run: cargo test -p prism-tests --lib --release --features mock_prover unused-deps: runs-on: ubuntu-latest diff --git a/Cargo.lock b/Cargo.lock index 29d29a7a..953b09c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -96,9 +96,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy-primitives" @@ -143,7 +143,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -159,7 +159,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", "syn-solidity", "tiny-keccak", ] @@ -175,7 +175,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", "syn-solidity", ] @@ -202,9 +202,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -217,9 +217,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" @@ -251,9 +251,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.91" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "ark-ff" @@ -405,7 +405,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -433,7 +433,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -476,9 +476,9 @@ dependencies = [ [[package]] name = "axum" -version = "0.7.7" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", "axum-core 0.4.5", @@ -487,7 +487,7 @@ dependencies = [ "http 1.1.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.0", + "hyper 1.5.1", "hyper-util", "itoa", "matchit", @@ -500,7 +500,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tokio", "tower 0.5.1", "tower-layer", @@ -540,7 +540,7 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "tower-layer", "tower-service", "tracing", @@ -619,27 +619,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bindgen" -version = "0.65.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" -dependencies = [ - "bitflags 1.3.2", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash 1.1.0", - "shlex", - "syn 2.0.85", -] - [[package]] name = "bindgen" version = "0.70.1" @@ -657,7 +636,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -724,9 +703,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7" +checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e" dependencies = [ "arrayref", "arrayvec", @@ -762,7 +741,7 @@ dependencies = [ "cid", "dashmap", "multihash", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -773,29 +752,16 @@ checksum = "a3c196a77437e7cc2fb515ce413a6401291578b5afc8ecb29a3c7ab957f05941" dependencies = [ "ff 0.12.1", "group 0.12.1", - "pairing 0.22.0", - "rand_core", - "subtle", -] - -[[package]] -name = "bls12_381" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc6d6292be3a19e6379786dac800f551e5865a5bb51ebbe3064ab80433f403" -dependencies = [ - "ff 0.13.0", - "group 0.13.0", - "pairing 0.23.0", + "pairing", "rand_core", "subtle", ] [[package]] name = "borsh" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" +checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03" dependencies = [ "borsh-derive", "cfg_aliases", @@ -803,16 +769,15 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" +checksum = "c2593a3b8b938bd68373196c9832f516be11fa487ef4ae745eb282e6a56a7244" dependencies = [ "once_cell", "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.85", - "syn_derive", + "syn 2.0.90", ] [[package]] @@ -839,9 +804,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytemuck" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" [[package]] name = "byteorder" @@ -851,24 +816,13 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" dependencies = [ "serde", ] -[[package]] -name = "bzip2-sys" -version = "0.1.11+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - [[package]] name = "camino" version = "1.1.9" @@ -880,9 +834,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ "serde", ] @@ -898,14 +852,14 @@ dependencies = [ "semver 1.0.23", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "cc" -version = "1.1.31" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" dependencies = [ "jobserver", "libc", @@ -937,7 +891,7 @@ dependencies = [ "http 1.1.0", "jsonrpsee", "serde", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -1013,7 +967,7 @@ dependencies = [ "serde", "serde_repr", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -1088,9 +1042,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", "clap_derive", @@ -1098,9 +1052,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstream", "anstyle", @@ -1117,14 +1071,14 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" [[package]] name = "coins-bip32" @@ -1139,7 +1093,7 @@ dependencies = [ "k256", "serde", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1155,7 +1109,7 @@ dependencies = [ "pbkdf2 0.12.2", "rand", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1175,7 +1129,7 @@ dependencies = [ "serde_derive", "sha2 0.10.8", "sha3", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1222,15 +1176,15 @@ dependencies = [ "encode_unicode", "lazy_static", "libc", - "unicode-width", + "unicode-width 0.1.14", "windows-sys 0.52.0", ] [[package]] name = "const-hex" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586" +checksum = "4b0485bab839b018a8f1723fc5391819fea5f8f0f32288ef8a735fd096b6160c" dependencies = [ "cfg-if", "cpufeatures", @@ -1333,9 +1287,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -1412,32 +1366,6 @@ dependencies = [ "cipher", ] -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "fiat-crypto", - "rustc_version 0.4.1", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.85", -] - [[package]] name = "curve25519-dalek-ng" version = "4.1.1" @@ -1612,7 +1540,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -1632,7 +1560,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -1697,6 +1625,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "dlv-list" version = "0.5.2" @@ -1780,7 +1719,7 @@ dependencies = [ "rand_core", "serde", "sha2 0.9.9", - "thiserror", + "thiserror 1.0.69", "zeroize", ] @@ -1868,7 +1807,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -1880,7 +1819,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -1904,12 +1843,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1930,7 +1869,7 @@ dependencies = [ "serde_json", "sha2 0.10.8", "sha3", - "thiserror", + "thiserror 1.0.69", "uuid", ] @@ -1947,7 +1886,7 @@ dependencies = [ "serde", "serde_json", "sha3", - "thiserror", + "thiserror 1.0.69", "uint", ] @@ -2024,7 +1963,7 @@ dependencies = [ "pin-project", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2044,7 +1983,7 @@ dependencies = [ "regex", "serde", "serde_json", - "syn 2.0.85", + "syn 2.0.90", "toml", "walkdir", ] @@ -2062,7 +2001,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -2088,9 +2027,9 @@ dependencies = [ "serde", "serde_json", "strum", - "syn 2.0.85", + "syn 2.0.90", "tempfile", - "thiserror", + "thiserror 1.0.69", "tiny-keccak", "unicode-xid", ] @@ -2114,7 +2053,7 @@ dependencies = [ "reqwest 0.11.27", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "tracing-futures", @@ -2146,7 +2085,7 @@ dependencies = [ "reqwest 0.11.27", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "tracing-futures", @@ -2172,7 +2111,7 @@ dependencies = [ "ethers-core", "rand", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -2188,9 +2127,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "fastrlp" @@ -2243,12 +2182,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - [[package]] name = "fixed-hash" version = "0.8.0" @@ -2269,9 +2202,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.34" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -2401,7 +2334,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -2472,9 +2405,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96512db27971c2c3eece70a1e106fbe6c87760234e31e8f7e5634912fe52794a" +checksum = "2cb8bc4c28d15ade99c7e90b219f30da4be5c88e586277e8cbe886beeb868ab2" dependencies = [ "serde", "typenum", @@ -2487,8 +2420,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -2582,9 +2517,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ "atomic-waker", "bytes", @@ -2644,9 +2579,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "allocator-api2", "equivalent", @@ -2816,7 +2751,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "tower-service", "tracing", @@ -2825,14 +2760,14 @@ dependencies = [ [[package]] name = "hyper" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.6", + "h2 0.4.7", "http 1.1.0", "http-body 1.0.1", "httparse", @@ -2852,7 +2787,7 @@ checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http 1.1.0", - "hyper 1.5.0", + "hyper 1.5.1", "hyper-util", "log", "rustls", @@ -2884,7 +2819,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.5.0", + "hyper 1.5.1", "hyper-util", "native-tls", "tokio", @@ -2903,9 +2838,9 @@ dependencies = [ "futures-util", "http 1.1.0", "http-body 1.0.1", - "hyper 1.5.0", + "hyper 1.5.1", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "tower-service", "tracing", @@ -2930,14 +2865,143 @@ dependencies = [ "sha3", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", ] [[package]] @@ -2969,13 +3033,13 @@ dependencies = [ [[package]] name = "impl-trait-for-tuples" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.90", ] [[package]] @@ -2984,45 +3048,28 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" -[[package]] -name = "indexed-merkle-tree" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86e7e0a70243eb602dba292003d26682c23cff528c5b3c06c002d242a26d865" -dependencies = [ - "anyhow", - "bls12_381 0.8.0", - "borsh", - "hex", - "num", - "num-bigint 0.4.6", - "num-traits", - "serde", - "sha2 0.10.8", -] - [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.2", "serde", ] [[package]] name = "indicatif" -version = "0.17.8" +version = "0.17.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +checksum = "cbf675b85ed934d3c67b5c5469701eec7db22689d0a2139d856e0925fa28b281" dependencies = [ "console", - "instant", "number_prefix", "portable-atomic", - "unicode-width", + "unicode-width 0.2.0", + "web-time", ] [[package]] @@ -3105,9 +3152,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jmt" @@ -3128,7 +3175,7 @@ dependencies = [ "parking_lot", "serde", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -3142,7 +3189,7 @@ dependencies = [ "combine", "jni-sys", "log", - "thiserror", + "thiserror 1.0.69", "walkdir", ] @@ -3163,10 +3210,11 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -3210,7 +3258,7 @@ dependencies = [ "rustls-pki-types", "rustls-platform-verifier", "soketto", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-rustls", "tokio-util", @@ -3233,10 +3281,10 @@ dependencies = [ "http-body-util", "jsonrpsee-types", "pin-project", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-stream", "tracing", @@ -3251,7 +3299,7 @@ dependencies = [ "async-trait", "base64 0.22.1", "http-body 1.0.1", - "hyper 1.5.0", + "hyper 1.5.1", "hyper-rustls", "hyper-util", "jsonrpsee-core", @@ -3260,7 +3308,7 @@ dependencies = [ "rustls-platform-verifier", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tower 0.4.13", "tracing", @@ -3277,7 +3325,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -3289,7 +3337,7 @@ dependencies = [ "http 1.1.0", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -3326,7 +3374,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a575df5f985fe1cd5b2b05664ff6accfc46559032b954529fd225a2168d27b0f" dependencies = [ "bitvec", - "bls12_381 0.7.1", + "bls12_381", "ff 0.12.1", "group 0.12.1", "rand_core", @@ -3401,12 +3449,6 @@ dependencies = [ "spin 0.9.8", ] -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "leopard-codec" version = "0.1.0" @@ -3415,14 +3457,14 @@ checksum = "ee58dbc414bd23885d7da915e0457618b36d1fc950a6169ef2cb29829d1b1a1d" dependencies = [ "bytes", "lazy_static", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "libc" -version = "0.2.161" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" [[package]] name = "libgit2-sys" @@ -3438,9 +3480,9 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -3454,16 +3496,16 @@ checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" [[package]] name = "libp2p-identity" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cca1eb2bc1fd29f099f3daaab7effd01e1a54b7c577d0ed082521034d912e8" +checksum = "257b5621d159b32282eac446bed6670c39c7dc68a200a992d8f056afa0066f6d" dependencies = [ "bs58", "hkdf", "multihash", "quick-protobuf", "sha2 0.10.8", - "thiserror", + "thiserror 1.0.69", "tracing", ] @@ -3477,22 +3519,6 @@ dependencies = [ "libc", ] -[[package]] -name = "librocksdb-sys" -version = "0.11.0+8.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" -dependencies = [ - "bindgen 0.65.1", - "bzip2-sys", - "cc", - "glob", - "libc", - "libz-sys", - "lz4-sys", - "zstd-sys", -] - [[package]] name = "libz-sys" version = "1.1.20" @@ -3511,6 +3537,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "lock_api" version = "0.4.12" @@ -3533,17 +3565,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.0", -] - -[[package]] -name = "lz4-sys" -version = "1.11.1+lz4-1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bd8c0d6c6ed0cd30b3652886bb8711dc4bb01d637a68105a3d5158039b418e6" -dependencies = [ - "cc", - "libc", + "hashbrown 0.15.2", ] [[package]] @@ -3606,11 +3628,10 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi 0.3.9", "libc", "wasi", "windows-sys 0.52.0", @@ -3646,7 +3667,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -3925,7 +3946,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -4012,7 +4033,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -4336,15 +4357,6 @@ dependencies = [ "group 0.12.1", ] -[[package]] -name = "pairing" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" -dependencies = [ - "group 0.13.0", -] - [[package]] name = "parity-scale-codec" version = "3.6.12" @@ -4432,9 +4444,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pathdiff" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "pbkdf2" @@ -4455,12 +4467,6 @@ dependencies = [ "hmac", ] -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - [[package]] name = "pem" version = "1.1.1" @@ -4492,7 +4498,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.69", "ucd-trie", ] @@ -4516,7 +4522,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -4567,7 +4573,7 @@ checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -4612,9 +4618,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "powerfmt" @@ -4674,7 +4680,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -4707,39 +4713,22 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "auto_impl", - "axum 0.6.20", - "base64 0.22.1", - "bincode", - "bls12_381 0.8.0", "clap", "config", "dirs 5.0.1", "dotenvy", - "ed25519-consensus", - "hex", - "indexed-merkle-tree", - "jmt", "keystore-rs", "log", - "mockall", "pretty_env_logger", - "prism-common", "prism-da", "prism-errors", + "prism-keys", "prism-lightclient", "prism-prover", "prism-storage", - "rand", - "redis", "serde", - "serde_json", - "sp1-sdk", "tokio", "toml", - "tower-http", - "utoipa", - "utoipa-swagger-ui", ] [[package]] @@ -4747,19 +4736,15 @@ name = "prism-common" version = "0.1.0" dependencies = [ "anyhow", - "base64 0.22.1", "bincode", - "bls12_381 0.8.0", "celestia-types", - "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", - "ed25519-consensus", "hex", "jmt", "log", - "p256", "prism-errors", + "prism-keys", + "prism-serde", "rand", - "secp256k1", "serde", "sha2 0.10.8", ] @@ -4788,33 +4773,37 @@ name = "prism-errors" version = "0.1.0" dependencies = [ "anyhow", - "thiserror", + "thiserror 1.0.69", ] [[package]] -name = "prism-lightclient" +name = "prism-keys" version = "0.1.0" dependencies = [ "anyhow", - "async-trait", - "auto_impl", "base64 0.22.1", - "bincode", - "bls12_381 0.8.0", - "dirs 5.0.1", + "ecdsa 0.16.9 (registry+https://github.com/rust-lang/crates.io-index)", + "ed25519-consensus", + "p256", + "prism-serde", + "rand", + "secp256k1", + "serde", + "sha2 0.10.8", +] + +[[package]] +name = "prism-lightclient" +version = "0.1.0" +dependencies = [ + "anyhow", "ed25519-consensus", - "hex", - "jmt", "log", "prism-common", "prism-da", "prism-errors", - "rand", - "serde", - "serde_json", "sp1-sdk", "tokio", - "toml", ] [[package]] @@ -4822,36 +4811,33 @@ name = "prism-prover" version = "0.1.0" dependencies = [ "anyhow", - "async-trait", - "auto_impl", "axum 0.6.20", - "base64 0.22.1", - "bincode", - "bls12_381 0.8.0", - "dirs 5.0.1", - "dotenvy", "ed25519-consensus", - "hex", - "indexed-merkle-tree", "jmt", "keystore-rs", "log", "prism-common", "prism-da", "prism-errors", + "prism-keys", "prism-storage", - "rand", - "redis", "serde", - "serde_json", "sp1-sdk", "tokio", - "toml", "tower-http", "utoipa", "utoipa-swagger-ui", ] +[[package]] +name = "prism-serde" +version = "0.1.0" +dependencies = [ + "base64 0.22.1", + "hex", + "serde", +] + [[package]] name = "prism-sp1" version = "0.1.0" @@ -4870,13 +4856,10 @@ dependencies = [ "hex", "jmt", "log", - "mockall", "prism-common", "prism-errors", "redis", - "rocksdb", "serde", - "tempfile", ] [[package]] @@ -4884,13 +4867,11 @@ name = "prism-tests" version = "0.1.0" dependencies = [ "anyhow", - "jmt", "keystore-rs", "log", "pretty_env_logger", "prism-common", "prism-da", - "prism-errors", "prism-lightclient", "prism-prover", "prism-storage", @@ -4943,9 +4924,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -5007,7 +4988,7 @@ dependencies = [ "prost 0.12.6", "prost-types", "regex", - "syn 2.0.85", + "syn 2.0.90", "tempfile", ] @@ -5021,7 +5002,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -5034,7 +5015,7 @@ dependencies = [ "itertools 0.13.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -5063,49 +5044,52 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" +checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" dependencies = [ "bytes", "pin-project-lite", "quinn-proto", "quinn-udp", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "rustls", - "socket2 0.5.7", - "thiserror", + "socket2 0.5.8", + "thiserror 2.0.3", "tokio", "tracing", ] [[package]] name = "quinn-proto" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" +checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" dependencies = [ "bytes", + "getrandom", "rand", "ring 0.17.8", - "rustc-hash 2.0.0", + "rustc-hash 2.1.0", "rustls", + "rustls-pki-types", "slab", - "thiserror", + "thiserror 2.0.3", "tinyvec", "tracing", + "web-time", ] [[package]] name = "quinn-udp" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e346e016eacfff12233c243718197ca12f148c84e1e84268a896699b41c71780" +checksum = "7d5a626c6807713b15cac82a6acaccd6043c9a5408c24baae07611fec3f243da" dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.5.7", + "socket2 0.5.8", "tracing", "windows-sys 0.59.0", ] @@ -5225,7 +5209,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -5236,7 +5220,7 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -5251,9 +5235,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -5323,11 +5307,11 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.4.6", + "h2 0.4.7", "http 1.1.0", "http-body 1.0.1", "http-body-util", - "hyper 1.5.0", + "hyper 1.5.1", "hyper-rustls", "hyper-tls 0.6.0", "hyper-util", @@ -5346,7 +5330,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 1.0.1", + "sync_wrapper 1.0.2", "system-configuration 0.6.1", "tokio", "tokio-native-tls", @@ -5373,7 +5357,7 @@ dependencies = [ "http 1.1.0", "reqwest 0.12.9", "serde", - "thiserror", + "thiserror 1.0.69", "tower-service", ] @@ -5448,16 +5432,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "rocksdb" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" -dependencies = [ - "libc", - "librocksdb-sys", -] - [[package]] name = "ron" version = "0.8.1" @@ -5532,7 +5506,7 @@ dependencies = [ "quote", "rust-embed-utils", "shellexpand", - "syn 2.0.85", + "syn 2.0.90", "walkdir", ] @@ -5570,9 +5544,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" [[package]] name = "rustc-hex" @@ -5600,9 +5574,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.38" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa260229e6538e52293eeb577aabd09945a09d6d9cc0fc550ed7529056c2e32a" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", @@ -5613,9 +5587,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.16" +version = "0.23.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "log", "once_cell", @@ -5662,6 +5636,9 @@ name = "rustls-pki-types" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +dependencies = [ + "web-time", +] [[package]] name = "rustls-platform-verifier" @@ -5745,9 +5722,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.11.5" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aa7ffc1c0ef49b0452c6e2986abf2b07743320641ffd5fc63d552458e3b779b" +checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" dependencies = [ "cfg-if", "derive_more 1.0.0", @@ -5757,30 +5734,30 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.11.5" +version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46385cc24172cf615450267463f937c10072516359b3ff1cb24228a4a08bf951" +checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] name = "scc" -version = "2.2.4" +version = "2.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8d25269dd3a12467afe2e510f69fb0b46b698e5afb296b59f2145259deaf8e8" +checksum = "66b202022bb57c049555430e11fc22fea12909276a80a4c3d368da36ac1d88ed" dependencies = [ "sdd", ] [[package]] name = "schannel" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ "windows-sys 0.59.0", ] @@ -5827,7 +5804,7 @@ dependencies = [ [[package]] name = "secp256k1" version = "0.29.0" -source = "git+https://github.com/sp1-patches/rust-secp256k1?branch=patch-secp256k1-v0.29.0#13910d476dbdaf436312a9f096ee312593028557" +source = "git+https://github.com/sp1-patches/rust-secp256k1?branch=patch-secp256k1-v0.29.0#c78195abe3c5bc11163d69588a5559ef21bdff31" dependencies = [ "cfg-if", "ecdsa 0.16.9 (git+https://github.com/sp1-patches/signatures?branch=patch-ecdsa-v0.16.9)", @@ -5841,7 +5818,7 @@ dependencies = [ [[package]] name = "secp256k1-sys" version = "0.10.0" -source = "git+https://github.com/sp1-patches/rust-secp256k1?branch=patch-secp256k1-v0.29.0#13910d476dbdaf436312a9f096ee312593028557" +source = "git+https://github.com/sp1-patches/rust-secp256k1?branch=patch-secp256k1-v0.29.0#c78195abe3c5bc11163d69588a5559ef21bdff31" dependencies = [ "cc", ] @@ -5862,9 +5839,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" dependencies = [ "core-foundation-sys", "libc", @@ -5890,9 +5867,9 @@ dependencies = [ [[package]] name = "semver-parser" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" dependencies = [ "pest", ] @@ -5911,9 +5888,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] @@ -5929,20 +5906,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -5968,7 +5945,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -6004,9 +5981,9 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.1.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b4b487fe2acf240a021cf57c6b2b4903b1e78ca0ecd862a71b71d2a51fed77d" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" dependencies = [ "futures", "log", @@ -6018,13 +5995,13 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "3.1.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -6138,7 +6115,7 @@ checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" dependencies = [ "num-bigint 0.4.6", "num-traits", - "thiserror", + "thiserror 1.0.69", "time", ] @@ -6185,9 +6162,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -6195,9 +6172,9 @@ dependencies = [ [[package]] name = "soketto" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37468c595637c10857701c990f93a40ce0e357cedb0953d1c26c8d8027f9bb53" +checksum = "2e859df029d160cb88608f5d7df7fb4753fd20fdfb4de5644f3d8b8440841721" dependencies = [ "base64 0.22.1", "bytes", @@ -6210,9 +6187,9 @@ dependencies = [ [[package]] name = "sp1-core-executor" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff9718f87f207404aee3f447c4438e2a35791092dc24ce65ff95db699ed49c1" +checksum = "8324d09601526d2ddfb796efb24996d3cc33ea8802bbd085bdefe93a4989b4dd" dependencies = [ "bincode", "bytemuck", @@ -6235,7 +6212,7 @@ dependencies = [ "sp1-stark", "strum", "strum_macros", - "thiserror", + "thiserror 1.0.69", "tiny-keccak", "tracing", "typenum", @@ -6244,14 +6221,14 @@ dependencies = [ [[package]] name = "sp1-core-machine" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ac8b5f2cecb7b2174495fc7a3e004bdb78e1c7ea44577ac0acc0d1e90b817ea" +checksum = "357af5138c7a591d1a612d105d75c1c01cad0ed6cc383d1ae38b7254e85ea227" dependencies = [ "bincode", "cfg-if", "elliptic-curve", - "generic-array 1.1.0", + "generic-array 1.1.1", "hashbrown 0.14.5", "hex", "itertools 0.13.0", @@ -6282,7 +6259,7 @@ dependencies = [ "strum", "strum_macros", "tempfile", - "thiserror", + "thiserror 1.0.69", "tracing", "tracing-forest", "tracing-subscriber", @@ -6292,15 +6269,14 @@ dependencies = [ [[package]] name = "sp1-curves" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1af9ff15e524ebe58286d7ee9bc345657b45b13091b5dc58fdce61542b65a47" +checksum = "f8dd206bc1fc44b7a215be0ae17c9b79e25ecfc2774dcd4e3753c0a03dee784e" dependencies = [ "cfg-if", - "curve25519-dalek", "dashu", "elliptic-curve", - "generic-array 1.1.0", + "generic-array 1.1.1", "itertools 0.13.0", "k256", "num", @@ -6314,9 +6290,9 @@ dependencies = [ [[package]] name = "sp1-derive" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f1490c07bd283f59169eae6e67df355b5de8ba10cc75bf6dbfc05a28fdccfc6" +checksum = "cf59bbd55ee20f0decb602809aadc73f09defb6f6d27067acf16029e84191b4a" dependencies = [ "quote", "syn 1.0.109", @@ -6324,9 +6300,9 @@ dependencies = [ [[package]] name = "sp1-lib" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c372b16988e765af85ccf958b18b26d89c05886f2592d313a285415dcc769cb" +checksum = "7a5729da1b05d56c01457e5ecabdc77f1cc941df23f2921163a2f325aec22428" dependencies = [ "bincode", "serde", @@ -6334,9 +6310,9 @@ dependencies = [ [[package]] name = "sp1-primitives" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "025f06b633588e246308ad5f67b32f0f7d1cbeab38f7a842314699270bc706f5" +checksum = "9d10c2078a5dfc5c3a632da1bc59b57a19dadc9c03968047d8ffb06c0f83b476" dependencies = [ "bincode", "hex", @@ -6352,9 +6328,9 @@ dependencies = [ [[package]] name = "sp1-prover" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bd16530cb12f1cecb1b6902142d8d0d87507f88de84bc714f10c29a7fd3769c" +checksum = "bc363eda811717369513ca72abafbb5cdec0ed16cda12458ca5321e4167e97ff" dependencies = [ "anyhow", "bincode", @@ -6387,16 +6363,16 @@ dependencies = [ "sp1-stark", "subtle-encoding", "tempfile", - "thiserror", + "thiserror 1.0.69", "tracing", "tracing-subscriber", ] [[package]] name = "sp1-recursion-circuit" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98d0a8ceee12600bd14d2e2d31b54db00b7985e30acedbfe8e1c1a9e41d7992f" +checksum = "108607ce729ab2fedb25f039284baaad022c5df242e0530c5b453e89cc8306a3" dependencies = [ "hashbrown 0.14.5", "itertools 0.13.0", @@ -6428,9 +6404,9 @@ dependencies = [ [[package]] name = "sp1-recursion-compiler" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "591d60768948dcef34a1fc16c3c6cf457e32fdee83d55ec14dbb94cd4447c030" +checksum = "673d2c66a48e6d17e1165b5ea38b59de5e80bf64fd45f17ebc9d75e67c4ff414" dependencies = [ "backtrace", "itertools 0.13.0", @@ -6450,9 +6426,9 @@ dependencies = [ [[package]] name = "sp1-recursion-core" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c15a51b675accb41608f7bf7ef5f95c23b47ceac38a9a87833a2b12c3bc190" +checksum = "f2fb84b20d8ffb922d4c05843406c458a6abef296bc31e68cf5eb64fa739c921" dependencies = [ "backtrace", "ff 0.13.0", @@ -6478,7 +6454,7 @@ dependencies = [ "sp1-primitives", "sp1-stark", "static_assertions", - "thiserror", + "thiserror 1.0.69", "tracing", "vec_map", "zkhash", @@ -6486,9 +6462,9 @@ dependencies = [ [[package]] name = "sp1-recursion-derive" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5b2aaa03093afb2b0f58379bb4f0d7898344ef1bb8dd326ec02db7125c1a590" +checksum = "3125726165ff77fb2650ae031075ba747099a6e218e5c10f84ac2715545a2332" dependencies = [ "quote", "syn 1.0.109", @@ -6496,13 +6472,13 @@ dependencies = [ [[package]] name = "sp1-recursion-gnark-ffi" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a12889c662cf64870e72bb3ba8096f3465bf442f5f179c07b50c86f5c47ce80" +checksum = "a049cdff6b64bc1cd2bebdf494fd314bc4b45eff9058ea69dace55a0fa77e483" dependencies = [ "anyhow", "bincode", - "bindgen 0.70.1", + "bindgen", "cc", "cfg-if", "hex", @@ -6522,9 +6498,9 @@ dependencies = [ [[package]] name = "sp1-sdk" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39bab15e962d1218e8ad021b2e9904597d5506d12847ef8be182385d5f3d3a6c" +checksum = "ae8dfb448a10491096db03187af55b8334ac52303c280956d0782a9fe78dd814" dependencies = [ "alloy-sol-types", "anyhow", @@ -6554,7 +6530,7 @@ dependencies = [ "strum", "strum_macros", "tempfile", - "thiserror", + "thiserror 1.0.69", "tokio", "tracing", "twirp-rs", @@ -6563,9 +6539,9 @@ dependencies = [ [[package]] name = "sp1-stark" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec27b60e797a52eed7af54e032498edcaf8f1ab0649077cbaa6f146a740380dd" +checksum = "a597ed68cd03f80d9cdb9f4b50924e3c890c35c39956f7e87dd2262b72b2d12b" dependencies = [ "arrayref", "getrandom", @@ -6593,15 +6569,15 @@ dependencies = [ "strum", "strum_macros", "sysinfo", - "thiserror", + "thiserror 1.0.69", "tracing", ] [[package]] name = "sp1-zkvm" -version = "3.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce08dc324dade0709260b01c76c8eeb665f2ef7c652c2002e2edf5a492ded7f1" +checksum = "8ea02449a9dcaab67219f7b3442ab51b45ae40e7b04f205382295936087fe1d5" dependencies = [ "cfg-if", "getrandom", @@ -6634,6 +6610,12 @@ dependencies = [ "der", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -6665,7 +6647,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -6702,9 +6684,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.85" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -6720,19 +6702,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.85", -] - -[[package]] -name = "syn_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -6743,13 +6713,24 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ "futures-core", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", +] + [[package]] name = "sysinfo" version = "0.30.13" @@ -6815,9 +6796,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -6843,22 +6824,42 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.65" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +dependencies = [ + "thiserror-impl 2.0.3", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "thiserror-impl", + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] name = "thiserror-impl" -version = "1.0.65" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -6873,9 +6874,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -6896,9 +6897,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", @@ -6913,6 +6914,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -6930,9 +6941,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.41.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", @@ -6941,7 +6952,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.7", + "socket2 0.5.8", "tokio-macros", "windows-sys 0.52.0", ] @@ -6954,7 +6965,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -7112,9 +7123,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -7124,20 +7135,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -7151,7 +7162,7 @@ checksum = "ee40835db14ddd1e3ba414292272eddde9dad04d3d4b65509656414d1c42592f" dependencies = [ "ansi_term", "smallvec", - "thiserror", + "thiserror 1.0.69", "tracing", "tracing-subscriber", ] @@ -7179,9 +7190,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "matchers", "nu-ansi-term", @@ -7208,16 +7219,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27dfcc06b8d9262bc2d4b8d1847c56af9971a52dd8a0076876de9db763227d0d" dependencies = [ "async-trait", - "axum 0.7.7", + "axum 0.7.9", "futures", "http 1.1.0", "http-body-util", - "hyper 1.5.0", + "hyper 1.5.1", "prost 0.13.3", "reqwest 0.12.9", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", "tokio", "tower 0.5.1", "url", @@ -7259,26 +7270,11 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" -[[package]] -name = "unicode-bidi" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" - [[package]] name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "unicode-normalization" -version = "0.1.24" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-segmentation" @@ -7292,6 +7288,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "unicode-xid" version = "0.2.6" @@ -7328,15 +7330,27 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -7365,7 +7379,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.85", + "syn 2.0.90", ] [[package]] @@ -7470,9 +7484,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" dependencies = [ "cfg-if", "once_cell", @@ -7481,36 +7495,37 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7518,22 +7533,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" [[package]] name = "wasm-streams" @@ -7550,9 +7565,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" dependencies = [ "js-sys", "wasm-bindgen", @@ -7570,9 +7585,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.6" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" dependencies = [ "rustls-pki-types", ] @@ -7833,6 +7848,18 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "ws_stream_wasm" version = "0.7.4" @@ -7846,7 +7873,7 @@ dependencies = [ "pharos", "rustc_version 0.4.1", "send_wrapper 0.6.0", - "thiserror", + "thiserror 1.0.69", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -7872,6 +7899,30 @@ dependencies = [ "hashlink", ] +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -7890,7 +7941,28 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", + "synstructure", ] [[package]] @@ -7910,7 +7982,29 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.85", + "syn 2.0.90", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] @@ -7935,7 +8029,7 @@ dependencies = [ "ark-std 0.4.0", "bitvec", "blake2", - "bls12_381 0.7.1", + "bls12_381", "byteorder", "cfg-if", "group 0.12.1", @@ -7951,13 +8045,3 @@ dependencies = [ "sha3", "subtle", ] - -[[package]] -name = "zstd-sys" -version = "2.0.13+zstd.1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/Cargo.toml b/Cargo.toml index dacb4d42..4d8400fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" authors = [ "Sebastian Pusch ", "Ryan Ford ", + "Jonas Pusch ", ] edition = "2021" description = "prism is the first trust-minimized key-transparency solution, allowing for automatic verification of service providers via light clients. Powered by Celestia." @@ -23,6 +24,8 @@ default-members = [ "crates/errors", "crates/storage", "crates/da", + "crates/serde", + "crates/keys", ] members = [ @@ -35,72 +38,84 @@ members = [ "crates/zk/sp1", "crates/storage", "crates/da", + "crates/serde", + "crates/keys", ] resolver = "2" [workspace.dependencies] +# serde +serde = { version = "1.0.151", features = ["derive"] } +serde_json = "1.0.79" +base64 = "0.22.0" +bincode = "1.3.3" +hex = "0.4.3" + +# webserver axum = "0.6" -borsh = { version = "1.5.1", features = ["derive"] } tower-http = { version = "0.4", features = ["cors"] } utoipa = { version = "3.3", features = ["axum_extras"] } utoipa-swagger-ui = { version = "3.1", features = ["axum"] } -async-trait = "0.1.68" -serde = { version = "1.0.151", features = ["derive"] } -serde_json = "1.0.79" + +# database redis = "0.24.0" -base64 = "0.22.0" +# rocksdb = { version = "0.21.0", features = ["multi-threaded-cf"] } commented until impl is finished + +# async +async-trait = "0.1.68" tokio = { version = "1.16.1", features = ["full"] } -num = "0.4.0" -bellman = "0.14.0" -bls12_381 = "0.8.0" -rand = "0.8.5" -hex = "0.4.3" -ff = "0.13.0" + +# errors +thiserror = "1.0.62" +anyhow = "1.0.44" + +# cli +keystore-rs = "0.1.2" log = "0.4" pretty_env_logger = "0.5.0" clap = { version = "4.3.2", features = ["derive"] } config = "0.14.0" -thiserror = "1.0.62" -indexed-merkle-tree = "0.6.2" -dotenvy = "0.15.7" -celestia-rpc = "=0.4.0" -celestia-types = "=0.4.0" -mockall = "0.12.1" -keystore-rs = "0.1.2" toml = "0.8.14" dirs = "5.0.1" -anyhow = "1.0.44" -jmt = { git = "https://github.com/deltadevsde/jmt", branch = "rehashing-circuit", features = [ - "mocks", -] } -bellpepper-core = { version = "0.4.0", default-features = false } -bellpepper = "0.4.1" -itertools = "0.13.0" # zip_eq -arecibo = { git = "https://github.com/deltadevsde/arecibo" } -sha2 = "0.10.8" -auto_impl = "1.2.0" -bincode = "1.3.3" +dotenvy = "0.15.7" + +# zk +rand = "0.8.5" +sp1-zkvm = { version = "3.0.0-rc1" } +sp1-sdk = { version = "3.0.0-rc1" } + +# curves ed25519-consensus = "2.1.0" secp256k1 = { version = "0.29.0", features = [ "global-context", "rand-std", "serde", ] } -sp1-zkvm = { version = "3.0.0-rc1" } -sp1-sdk = { version = "3.0.0-rc1" } +p256 = { version = "0.13.2", features = ["serde", "ecdsa"] } +ecdsa = { version = "0.16.0", features = ["der"] } + +# celestia +celestia-rpc = "=0.4.0" +celestia-types = "=0.4.0" + +# misc +jmt = { git = "https://github.com/deltadevsde/jmt", branch = "rehashing-circuit", features = [ + "mocks", +] } +sha2 = "0.10.8" +auto_impl = "1.2.0" + +# prism prism-common = { path = "crates/common" } prism-storage = { path = "crates/storage" } -prism-nova = { path = "crates/zk/nova" } prism-da = { path = "crates/da" } prism-errors = { path = "crates/errors" } prism-cli = { path = "crates/cli" } -prism-groth16 = { path = "crates/zk/groth16" } prism-prover = { path = "crates/node_types/prover" } prism-tests = { path = "crates/tests" } +prism-keys = { path = "crates/keys" } +prism-serde = { path = "crates/serde" } prism-lightclient = { path = "crates/node_types/lightclient" } -rocksdb = { version = "0.21.0", features = ["multi-threaded-cf"] } -p256 = { version = "0.13.2", features = ["serde", "ecdsa"] } -ecdsa = { version = "0.16.0", features = ["der"] } [patch.crates-io] sha2-v0-10-8 = { git = "https://github.com/sp1-patches/RustCrypto-hashes", package = "sha2", branch = "patch-sha2-v0.10.8" } @@ -111,12 +126,3 @@ secp256k1 = { git = "https://github.com/sp1-patches/rust-secp256k1", branch = "p default = [] test_utils = [] mock_prover = [] -secp256k1 = [] - -# [workspace.dev-dependencies] -# serial_test = "3.1.1" -# criterion = "0.5.1" - -# [[bench]] -# name = "zk_benchmarks" -# harness = false diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index ba2a9ad3..d4e0f000 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -14,38 +14,21 @@ test_utils = [] mock_prover = [] [dependencies] -axum = { workspace = true } -tower-http = { workspace = true } -utoipa = { workspace = true } -utoipa-swagger-ui = { workspace = true } async-trait = { workspace = true } serde = { workspace = true } -serde_json = { workspace = true } -redis = { workspace = true } -ed25519-consensus = { workspace = true } -base64 = { workspace = true } tokio = { workspace = true } -bincode = { workspace = true } -bls12_381 = { workspace = true } -hex = { workspace = true } log = { workspace = true } pretty_env_logger = { workspace = true } clap = { workspace = true } config = { workspace = true } -indexed-merkle-tree = { workspace = true } dotenvy = { workspace = true } -mockall = { workspace = true } keystore-rs = { workspace = true } toml = { workspace = true } dirs = { workspace = true } anyhow = { workspace = true } -jmt = { workspace = true } -auto_impl = { workspace = true } -prism-common = { workspace = true, features = ["test_utils"] } prism-storage = { workspace = true } prism-errors = { workspace = true } prism-prover = { workspace = true } prism-lightclient = { workspace = true } prism-da = { workspace = true } -sp1-sdk = { workspace = true } -rand = { workspace = true } +prism-keys = { workspace = true } diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index a582a9b5..b1a84552 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -4,7 +4,7 @@ mod node_types; use cfg::{initialize_da_layer, load_config, Cli, Commands}; use clap::Parser; use keystore_rs::{KeyChain, KeyStore, KeyStoreType}; -use prism_common::keys::VerifyingKey; +use prism_keys::VerifyingKey; use node_types::NodeType; use prism_lightclient::LightClient; diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml index 78457ddc..b10576ae 100644 --- a/crates/common/Cargo.toml +++ b/crates/common/Cargo.toml @@ -7,24 +7,28 @@ homepage.workspace = true repository.workspace = true [dependencies] +# prism prism-errors.workspace = true -anyhow.workspace = true -bls12_381.workspace = true -jmt.workspace = true +prism-keys.workspace = true + +# serde +prism-serde.workspace = true serde.workspace = true hex.workspace = true -sha2.workspace = true -celestia-types.workspace = true bincode.workspace = true + +# celestia +celestia-types.workspace = true + +# tree +jmt.workspace = true +sha2.workspace = true + +# misc +anyhow.workspace = true log.workspace = true -ed25519-consensus.workspace = true -ecdsa.workspace = true -secp256k1.workspace = true -base64.workspace = true rand.workspace = true -p256.workspace = true [features] default = [] test_utils = [] -secp256k1 = ["secp256k1/global-context", "secp256k1/rand-std"] diff --git a/crates/common/src/digest.rs b/crates/common/src/digest.rs index a3d30c95..3d7eb533 100644 --- a/crates/common/src/digest.rs +++ b/crates/common/src/digest.rs @@ -1,9 +1,9 @@ use anyhow::{anyhow, Result}; -use bls12_381::Scalar; use jmt::RootHash; use serde::{Deserialize, Serialize}; -use crate::{hasher::Hasher, serde::raw_or_hex_fixed}; +use crate::hasher::Hasher; +use prism_serde::raw_or_hex_fixed; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Copy)] pub struct Digest(#[serde(with = "raw_or_hex_fixed")] pub [u8; 32]); @@ -40,35 +40,6 @@ impl From<[u8; N]> for Digest { } } -// implementing it for now to get things to compile, curve choice will be made later -impl TryFrom for Scalar { - type Error = anyhow::Error; - - fn try_from(value: Digest) -> Result { - let mut byte_array = [0u8; 32]; - byte_array.copy_from_slice(value.as_ref()); - byte_array.reverse(); - - let val = - [ - u64::from_le_bytes(byte_array[0..8].try_into().map_err(|_| { - anyhow!(format!("slice to array: [0..8] for digest: {value:?}")) - })?), - u64::from_le_bytes(byte_array[8..16].try_into().map_err(|_| { - anyhow!(format!("slice to array: [8..16] for digest: {value:?}")) - })?), - u64::from_le_bytes(byte_array[16..24].try_into().map_err(|_| { - anyhow!(format!("slice to array: [16..24] for digest: {value:?}")) - })?), - u64::from_le_bytes(byte_array[24..32].try_into().map_err(|_| { - anyhow!(format!("slice to array: [24..32] for digest: {value:?}")) - })?), - ]; - - Ok(Scalar::from_raw(val)) - } -} - impl From for RootHash { fn from(val: Digest) -> RootHash { RootHash::from(val.0) diff --git a/crates/common/src/hashchain.rs b/crates/common/src/hashchain.rs index d9bd9adc..8693fcd3 100644 --- a/crates/common/src/hashchain.rs +++ b/crates/common/src/hashchain.rs @@ -1,10 +1,10 @@ use anyhow::{anyhow, bail, ensure, Result}; +use prism_keys::{Signature, SigningKey, VerifyingKey}; use serde::{Deserialize, Serialize}; use std::ops::{Deref, DerefMut}; use crate::{ digest::Digest, - keys::{Signature, SigningKey, VerifyingKey}, operation::{ HashchainSignatureBundle, Operation, ServiceChallenge, ServiceChallengeInput, SignatureBundle, @@ -102,6 +102,8 @@ impl Hashchain { self.last().map_or(Digest::zero(), |entry| entry.hash) } + /// Validates and adds a new entry to the hashchain. + /// This method is ran in circuit. pub fn add_entry(&mut self, entry: HashchainEntry) -> Result<()> { self.validate_new_entry(&entry)?; self.entries.push(entry); @@ -173,6 +175,8 @@ impl Hashchain { Ok(entry) } + /// Validates that the new entry is valid and can be added to the hashchain. + /// This method is ran in circuit. fn validate_new_entry(&self, entry: &HashchainEntry) -> Result<()> { entry.validate_operation()?; diff --git a/crates/common/src/keys.rs b/crates/common/src/keys.rs deleted file mode 100644 index 6c8f3e59..00000000 --- a/crates/common/src/keys.rs +++ /dev/null @@ -1,520 +0,0 @@ -use anyhow::{anyhow, bail, Result}; -use base64::{engine::general_purpose::STANDARD as engine, Engine as _}; -use ed25519_consensus::{ - Signature as Ed25519Signature, SigningKey as Ed25519SigningKey, - VerificationKey as Ed25519VerifyingKey, -}; -use p256::ecdsa::{ - signature::{DigestSigner, DigestVerifier}, - Signature as Secp256r1Signature, SigningKey as Secp256r1SigningKey, - VerifyingKey as Secp256r1VerifyingKey, -}; -use rand::rngs::OsRng; -use secp256k1::{ - ecdsa::Signature as Secp256k1Signature, Message as Secp256k1Message, - PublicKey as Secp256k1VerifyingKey, SecretKey as Secp256k1SigningKey, SECP256K1, -}; - -use crate::serde::CryptoPayload; -use serde::{Deserialize, Serialize}; -use sha2::Digest as _; -use std::{ - self, - hash::{Hash, Hasher}, -}; - -use crate::digest::Digest; - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)] -#[serde(try_from = "CryptoPayload", into = "CryptoPayload")] -pub enum Signature { - Secp256k1(Secp256k1Signature), - Ed25519(Ed25519Signature), - Secp256r1(Secp256r1Signature), - #[default] - Placeholder, -} - -impl Signature { - pub fn to_bytes(&self) -> Vec { - match self { - Signature::Ed25519(sig) => sig.to_bytes().to_vec(), - Signature::Secp256k1(sig) => sig.serialize_der().to_vec(), - Signature::Secp256r1(sig) => sig.to_der().as_bytes().to_vec(), - Signature::Placeholder => vec![], - } - } - - pub fn from_algorithm_and_bytes(algorithm: &str, bytes: &[u8]) -> Result { - match algorithm { - "ed25519" => { - Ed25519Signature::try_from(bytes).map(Signature::Ed25519).map_err(|e| e.into()) - } - "secp256k1" => { - Secp256k1Signature::from_der(bytes).map(Signature::Secp256k1).map_err(|e| e.into()) - } - "secp256r1" => { - Secp256r1Signature::from_der(bytes).map(Signature::Secp256r1).map_err(|e| e.into()) - } - _ => bail!("Unexpected algorithm for Signature"), - } - } - - pub fn algorithm(&self) -> &'static str { - match self { - Signature::Ed25519(_) => "ed25519", - Signature::Secp256k1(_) => "secp256k1", - Signature::Secp256r1(_) => "secp256r1", - Signature::Placeholder => "placeholder", - } - } -} - -impl TryFrom for Signature { - type Error = anyhow::Error; - - fn try_from(value: CryptoPayload) -> std::result::Result { - Signature::from_algorithm_and_bytes(&value.algorithm, &value.bytes) - } -} - -impl From for CryptoPayload { - fn from(signature: Signature) -> Self { - CryptoPayload { - algorithm: signature.algorithm().to_string(), - bytes: signature.to_bytes(), - } - } -} - -#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)] -#[serde(try_from = "CryptoPayload", into = "CryptoPayload")] -/// Represents a public key supported by the system. -pub enum VerifyingKey { - /// Bitcoin, Ethereum - Secp256k1(Secp256k1VerifyingKey), - /// Cosmos, OpenSSH, GnuPG - Ed25519(Ed25519VerifyingKey), - // TLS, X.509 PKI, Passkeys - Secp256r1(Secp256r1VerifyingKey), -} - -impl Hash for VerifyingKey { - fn hash(&self, state: &mut H) { - match self { - VerifyingKey::Ed25519(_) => { - state.write_u8(0); - self.to_bytes().hash(state); - } - VerifyingKey::Secp256k1(_) => { - state.write_u8(1); - self.to_bytes().hash(state); - } - VerifyingKey::Secp256r1(_) => { - state.write_u8(2); - self.to_bytes().hash(state); - } - } - } -} - -impl VerifyingKey { - /// Returns the byte representation of the public key. - pub fn to_bytes(&self) -> Vec { - match self { - VerifyingKey::Ed25519(vk) => vk.to_bytes().to_vec(), - VerifyingKey::Secp256k1(vk) => vk.serialize().to_vec(), - VerifyingKey::Secp256r1(vk) => vk.to_sec1_bytes().to_vec(), - } - } - - pub fn from_algorithm_and_bytes(algorithm: &str, bytes: &[u8]) -> Result { - match algorithm { - "ed25519" => Ed25519VerifyingKey::try_from(bytes) - .map(VerifyingKey::Ed25519) - .map_err(|e| e.into()), - "secp256k1" => Secp256k1VerifyingKey::from_slice(bytes) - .map(VerifyingKey::Secp256k1) - .map_err(|e| e.into()), - "secp256r1" => Secp256r1VerifyingKey::from_sec1_bytes(bytes) - .map(VerifyingKey::Secp256r1) - .map_err(|e| e.into()), - _ => bail!("Unexpected algorithm for VerifyingKey"), - } - } - - pub fn algorithm(&self) -> &'static str { - match self { - VerifyingKey::Ed25519(_) => "ed25519", - VerifyingKey::Secp256k1(_) => "secp256k1", - VerifyingKey::Secp256r1(_) => "secp256r1", - } - } - - pub fn verify_signature(&self, message: &[u8], signature: &Signature) -> Result<()> { - match self { - VerifyingKey::Ed25519(vk) => { - let Signature::Ed25519(signature) = signature else { - bail!("Invalid signature type"); - }; - - vk.verify(signature, message) - .map_err(|e| anyhow!("Failed to verify signature: {}", e)) - } - VerifyingKey::Secp256k1(vk) => { - let Signature::Secp256k1(signature) = signature else { - bail!("Invalid signature type"); - }; - let hashed_message = Digest::hash(message).to_bytes(); - let message = Secp256k1Message::from_digest(hashed_message); - vk.verify(SECP256K1, &message, signature) - .map_err(|e| anyhow!("Failed to verify signature: {}", e)) - } - VerifyingKey::Secp256r1(vk) => { - let Signature::Secp256r1(signature) = signature else { - bail!("Invalid signature type"); - }; - let mut digest = sha2::Sha256::new(); - digest.update(message); - - let der_sig = signature.to_der(); - vk.verify_digest(digest, &der_sig) - .map_err(|e| anyhow!("Failed to verify signature: {}", e)) - } - } - } -} - -impl TryFrom for VerifyingKey { - type Error = anyhow::Error; - - fn try_from(value: CryptoPayload) -> std::result::Result { - VerifyingKey::from_algorithm_and_bytes(&value.algorithm, &value.bytes) - } -} - -impl From for CryptoPayload { - fn from(signature: VerifyingKey) -> Self { - CryptoPayload { - algorithm: signature.algorithm().to_string(), - bytes: signature.to_bytes(), - } - } -} - -impl From for VerifyingKey { - fn from(vk: Ed25519VerifyingKey) -> Self { - VerifyingKey::Ed25519(vk) - } -} - -impl From for VerifyingKey { - fn from(vk: Secp256k1VerifyingKey) -> Self { - VerifyingKey::Secp256k1(vk) - } -} - -impl From for VerifyingKey { - fn from(vk: Secp256r1VerifyingKey) -> Self { - VerifyingKey::Secp256r1(vk) - } -} - -impl From for VerifyingKey { - fn from(sk: Ed25519SigningKey) -> Self { - VerifyingKey::Ed25519(sk.verification_key()) - } -} - -impl From for VerifyingKey { - fn from(sk: Secp256k1SigningKey) -> Self { - sk.public_key(SECP256K1).into() - } -} - -impl From for VerifyingKey { - fn from(sk: Secp256r1SigningKey) -> Self { - VerifyingKey::Secp256r1(sk.verifying_key().to_owned()) - } -} - -impl From for VerifyingKey { - fn from(sk: SigningKey) -> Self { - match sk { - SigningKey::Ed25519(sk) => (*sk).into(), - SigningKey::Secp256k1(sk) => sk.into(), - SigningKey::Secp256r1(sk) => sk.into(), - } - } -} - -impl TryFrom for VerifyingKey { - type Error = anyhow::Error; - - /// Attempts to create a `VerifyingKey` from a base64-encoded string. - /// - /// # Arguments - /// - /// * `s` - The base64-encoded string representation of the public key. - /// - /// Depending on the length of the input string, the function will attempt to - /// decode it and create a `VerifyingKey` instance. According to the specifications, - /// the input string should be either [32 bytes (Ed25519)](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.5) or [33/65 bytes (Secp256k1)](https://www.secg.org/sec1-v2.pdf). - /// The secp256k1 key can be either compressed (33 bytes) or uncompressed (65 bytes). - /// - /// # Returns - /// - /// * `Ok(VerifyingKey)` if the conversion was successful. - /// * `Err` if the input is invalid or the conversion failed. - fn try_from(s: String) -> std::result::Result { - let bytes = - engine.decode(s).map_err(|e| anyhow!("Failed to decode base64 string: {}", e))?; - - match bytes.len() { - 32 => { - let vk = Ed25519VerifyingKey::try_from(bytes.as_slice()) - .map_err(|e| anyhow!("Invalid Ed25519 key: {}", e))?; - Ok(VerifyingKey::Ed25519(vk)) - } - 33 | 65 => { - let vk = Secp256k1VerifyingKey::from_slice(bytes.as_slice()) - .map_err(|e| anyhow!("Invalid Secp256k1 key: {}", e))?; - Ok(VerifyingKey::Secp256k1(vk)) - } - _ => Err(anyhow!("Invalid public key length")), - } - } -} - -impl std::fmt::Display for VerifyingKey { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - let encoded = engine.encode(self.to_bytes()); - write!(f, "{}", encoded) - } -} - -#[derive(Clone, Debug)] -pub enum SigningKey { - Ed25519(Box), - Secp256k1(Secp256k1SigningKey), - Secp256r1(Secp256r1SigningKey), -} - -impl SigningKey { - pub fn new_ed25519() -> Self { - SigningKey::Ed25519(Box::new(Ed25519SigningKey::new(OsRng))) - } - - pub fn new_secp256k1() -> Self { - SigningKey::Secp256k1(Secp256k1SigningKey::new(&mut OsRng)) - } - - pub fn new_secp256r1() -> Self { - SigningKey::Secp256r1(Secp256r1SigningKey::random(&mut OsRng)) - } - - pub fn verifying_key(&self) -> VerifyingKey { - self.clone().into() - } - - pub fn to_bytes(&self) -> Vec { - match self { - SigningKey::Ed25519(sk) => sk.to_bytes().to_vec(), - SigningKey::Secp256k1(sk) => sk.secret_bytes().to_vec(), - SigningKey::Secp256r1(sk) => sk.to_bytes().to_vec(), - } - } - - pub fn from_algorithm_and_bytes(algorithm: &str, bytes: &[u8]) -> Result { - match algorithm { - "ed25519" => Ed25519SigningKey::try_from(bytes) - .map(|sk| SigningKey::Ed25519(Box::new(sk))) - .map_err(|e| e.into()), - "secp256k1" => Secp256k1SigningKey::from_slice(bytes) - .map(SigningKey::Secp256k1) - .map_err(|e| e.into()), - "secp256r1" => Secp256r1SigningKey::from_slice(bytes) - .map(SigningKey::Secp256r1) - .map_err(|e| e.into()), - _ => bail!("Unexpected algorithm for VerifyingKey"), - } - } - - pub fn algorithm(&self) -> &'static str { - match self { - SigningKey::Ed25519(_) => "ed25519", - SigningKey::Secp256k1(_) => "secp256k1", - SigningKey::Secp256r1(_) => "secp256r1", - } - } - - pub fn sign(&self, message: &[u8]) -> Signature { - match self { - SigningKey::Ed25519(sk) => Signature::Ed25519(sk.sign(message)), - SigningKey::Secp256k1(sk) => { - let hashed_message = Digest::hash(message).to_bytes(); - let message = Secp256k1Message::from_digest(hashed_message); - let signature = SECP256K1.sign_ecdsa(&message, sk); - Signature::Secp256k1(signature) - } - SigningKey::Secp256r1(sk) => { - let mut digest = sha2::Sha256::new(); - digest.update(message); - let sig: Secp256r1Signature = sk.sign_digest(digest); - Signature::Secp256r1(sig) - } - } - } -} - -impl PartialEq for SigningKey { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - (SigningKey::Ed25519(a), SigningKey::Ed25519(b)) => a.as_bytes() == b.as_bytes(), - (SigningKey::Secp256k1(a), SigningKey::Secp256k1(b)) => a == b, - (SigningKey::Secp256r1(a), SigningKey::Secp256r1(b)) => a == b, - _ => false, - } - } -} - -impl TryFrom for SigningKey { - type Error = anyhow::Error; - - fn try_from(value: CryptoPayload) -> std::result::Result { - SigningKey::from_algorithm_and_bytes(&value.algorithm, &value.bytes) - } -} - -impl From for CryptoPayload { - fn from(signing_key: SigningKey) -> Self { - CryptoPayload { - algorithm: signing_key.algorithm().to_string(), - bytes: signing_key.to_bytes(), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use rand::rngs::OsRng; - - #[test] - fn test_reparsed_verifying_keys_are_equal_to_original() { - let verifying_key_ed25519 = SigningKey::new_ed25519().verifying_key(); - let re_parsed_verifying_key = VerifyingKey::from_algorithm_and_bytes( - verifying_key_ed25519.algorithm(), - &verifying_key_ed25519.to_bytes(), - ) - .unwrap(); - assert_eq!(re_parsed_verifying_key, verifying_key_ed25519); - - let verifying_key_secp256k1 = SigningKey::new_secp256k1().verifying_key(); - let re_parsed_verifying_key = VerifyingKey::from_algorithm_and_bytes( - verifying_key_secp256k1.algorithm(), - &verifying_key_secp256k1.to_bytes(), - ) - .unwrap(); - assert_eq!(re_parsed_verifying_key, verifying_key_secp256k1); - - let verifying_key_secp256r1 = SigningKey::new_secp256r1().verifying_key(); - let re_parsed_verifying_key = VerifyingKey::from_algorithm_and_bytes( - verifying_key_secp256r1.algorithm(), - &verifying_key_secp256r1.to_bytes(), - ) - .unwrap(); - assert_eq!(re_parsed_verifying_key, verifying_key_secp256r1); - } - - #[test] - fn test_reparsed_signing_keys_are_equal_to_original() { - let signing_key_ed25519 = SigningKey::new_ed25519(); - let re_parsed_signing_key = SigningKey::from_algorithm_and_bytes( - signing_key_ed25519.algorithm(), - &signing_key_ed25519.to_bytes(), - ) - .unwrap(); - assert_eq!(re_parsed_signing_key, signing_key_ed25519); - - let signing_key_secp256k1 = SigningKey::new_secp256k1(); - let re_parsed_signing_key = SigningKey::from_algorithm_and_bytes( - signing_key_secp256k1.algorithm(), - &signing_key_secp256k1.to_bytes(), - ) - .unwrap(); - assert_eq!(re_parsed_signing_key, signing_key_secp256k1); - - let signing_key_secp256r1 = SigningKey::new_secp256r1(); - let re_parsed_signing_key = SigningKey::from_algorithm_and_bytes( - signing_key_secp256r1.algorithm(), - &signing_key_secp256r1.to_bytes(), - ) - .unwrap(); - assert_eq!(re_parsed_signing_key, signing_key_secp256r1); - } - - #[test] - fn test_reparsed_signatures_are_equal_to_original() { - let message = b"test message"; - - let signature_ed25519 = SigningKey::new_ed25519().sign(message); - let re_parsed_signature = Signature::from_algorithm_and_bytes( - signature_ed25519.algorithm(), - &signature_ed25519.to_bytes(), - ) - .unwrap(); - assert_eq!(re_parsed_signature, signature_ed25519); - - let signature_secp256k1 = SigningKey::new_secp256k1().sign(message); - let re_parsed_signature = Signature::from_algorithm_and_bytes( - signature_secp256k1.algorithm(), - &signature_secp256k1.to_bytes(), - ) - .unwrap(); - assert_eq!(re_parsed_signature, signature_secp256k1); - - let signature_secp256r1 = SigningKey::new_secp256r1().sign(message); - let re_parsed_signature = Signature::from_algorithm_and_bytes( - signature_secp256r1.algorithm(), - &signature_secp256r1.to_bytes(), - ) - .unwrap(); - assert_eq!(re_parsed_signature, signature_secp256r1); - } - - #[test] - fn test_verifying_key_from_string_ed25519() { - let original_key: VerifyingKey = - SigningKey::Ed25519(Box::new(Ed25519SigningKey::new(OsRng))).into(); - let encoded = engine.encode(original_key.to_bytes()); - - let result = VerifyingKey::try_from(encoded); - assert!(result.is_ok()); - - let decoded_key = result.unwrap(); - assert_eq!(decoded_key.to_bytes(), original_key.to_bytes()); - } - - #[test] - fn test_verifying_key_from_string_secp256k1() { - let original_key: VerifyingKey = - SigningKey::Secp256k1(Secp256k1SigningKey::new(&mut OsRng)).into(); - let encoded = engine.encode(original_key.to_bytes()); - - let result = VerifyingKey::try_from(encoded); - assert!(result.is_ok()); - - let decoded_key = result.unwrap(); - assert_eq!(decoded_key.to_bytes(), original_key.to_bytes()); - } - - #[test] - fn test_verifying_key_from_string_invalid_length() { - let invalid_bytes: [u8; 31] = [1; 31]; - let encoded = engine.encode(invalid_bytes); - - let result = VerifyingKey::try_from(encoded); - assert!(result.is_err()); - } -} diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs index 1a587b34..912f5a5e 100644 --- a/crates/common/src/lib.rs +++ b/crates/common/src/lib.rs @@ -1,9 +1,7 @@ pub mod digest; pub mod hashchain; pub mod hasher; -pub mod keys; pub mod operation; -pub mod serde; pub mod transaction; pub mod tree; diff --git a/crates/common/src/operation.rs b/crates/common/src/operation.rs index d83b1e8e..d62c424f 100644 --- a/crates/common/src/operation.rs +++ b/crates/common/src/operation.rs @@ -3,10 +3,8 @@ use anyhow::{bail, ensure, Result}; use serde::{Deserialize, Serialize}; use std::{self, fmt::Display}; -use crate::{ - keys::{Signature, SigningKey, VerifyingKey}, - serde::raw_or_b64, -}; +use prism_keys::{Signature, SigningKey, VerifyingKey}; +use prism_serde::raw_or_b64; #[derive(Clone, Serialize, Deserialize, Debug, PartialEq)] /// An [`Operation`] represents a state transition in the system. diff --git a/crates/common/src/test_utils.rs b/crates/common/src/test_utils.rs index e25fca64..82b4611e 100644 --- a/crates/common/src/test_utils.rs +++ b/crates/common/src/test_utils.rs @@ -2,7 +2,6 @@ use crate::{ digest::Digest, hashchain::Hashchain, hasher::Hasher, - keys::{SigningKey, VerifyingKey}, operation::{ServiceChallenge, ServiceChallengeInput, SignatureBundle}, transaction::Transaction, tree::{ @@ -10,15 +9,9 @@ use crate::{ }, }; use anyhow::{anyhow, Result}; -#[cfg(not(feature = "secp256k1"))] -use ed25519_consensus::SigningKey as Ed25519SigningKey; use jmt::{mock::MockTreeStore, KeyHash}; -use rand::{ - rngs::{OsRng, StdRng}, - Rng, -}; -#[cfg(feature = "secp256k1")] -use secp256k1::SecretKey as Secp256k1SigningKey; +use prism_keys::{SigningKey, VerifyingKey}; +use rand::{rngs::StdRng, Rng}; use std::{ collections::{HashMap, HashSet}, sync::Arc, @@ -52,8 +45,8 @@ impl TestTreeState { } pub fn register_service(&mut self, service_id: String) -> Service { - let service_challenge_key = create_mock_signing_key(); - let service_signing_key = create_mock_signing_key(); + let service_challenge_key = SigningKey::new_ed25519(); + let service_signing_key = SigningKey::new_ed25519(); let service_vk: VerifyingKey = service_signing_key.clone().into(); let mut hashchain = Hashchain::empty(); @@ -83,7 +76,7 @@ impl TestTreeState { } pub fn create_account(&mut self, id: String, service: Service) -> TestAccount { - let signing_key = create_mock_signing_key(); + let signing_key = SigningKey::new_ed25519(); let vk: VerifyingKey = signing_key.clone().into(); self.signing_keys.insert(id.clone(), signing_key.clone()); @@ -148,7 +141,7 @@ impl TestTreeState { } pub fn add_key_to_account(&mut self, account: &mut TestAccount) -> Result<(), anyhow::Error> { - let signing_key_to_add = create_mock_signing_key(); + let signing_key_to_add = SigningKey::new_ed25519(); let key_to_add = signing_key_to_add.into(); account @@ -171,7 +164,7 @@ impl TestTreeState { data: &[u8], account: &mut TestAccount, ) -> Result<()> { - let random_signing_key = create_mock_signing_key(); + let random_signing_key = SigningKey::new_ed25519(); self.add_data_to_account(data, account, Some(&random_signing_key)) } @@ -210,7 +203,7 @@ pub fn create_random_insert(state: &mut TestTreeState, rng: &mut StdRng) -> Inse loop { let random_string: String = (0..10).map(|_| rng.sample(rand::distributions::Alphanumeric) as char).collect(); - let sk = create_mock_signing_key(); + let sk = SigningKey::new_ed25519(); let (_, service) = state.services.iter().nth(rng.gen_range(0..state.services.len())).unwrap(); @@ -261,7 +254,7 @@ pub fn create_random_update(state: &mut TestTreeState, rng: &mut StdRng) -> Upda panic!("No response found for key. Cannot perform update."); }; - let signing_key = create_mock_signing_key(); + let signing_key = SigningKey::new_ed25519(); let verifying_key = signing_key.into(); let signer = state @@ -284,13 +277,3 @@ pub fn create_random_update(state: &mut TestTreeState, rng: &mut StdRng) -> Upda *update_proof } - -#[cfg(not(feature = "secp256k1"))] -pub fn create_mock_signing_key() -> SigningKey { - SigningKey::Ed25519(Box::new(Ed25519SigningKey::new(OsRng))) -} - -#[cfg(feature = "secp256k1")] -pub fn create_mock_signing_key() -> SigningKey { - SigningKey::Secp256k1(Secp256k1SigningKey::new(&mut OsRng)) -} diff --git a/crates/common/src/transaction_builder.rs b/crates/common/src/transaction_builder.rs index f7962fe0..d6c606ef 100644 --- a/crates/common/src/transaction_builder.rs +++ b/crates/common/src/transaction_builder.rs @@ -6,12 +6,11 @@ use crate::{ digest::Digest, hashchain::HashchainEntry, hasher::Hasher, - keys::{SigningKey, VerifyingKey}, operation::{ServiceChallenge, ServiceChallengeInput, SignatureBundle}, - test_utils::create_mock_signing_key, transaction::Transaction, tree::{HashchainResponse::*, KeyDirectoryTree, SnarkableTree}, }; +use prism_keys::{SigningKey, VerifyingKey}; enum PostCommitAction { UpdateStorageOnly, RememberServiceKey(String, SigningKey), @@ -83,8 +82,8 @@ impl TransactionBuilder { } pub fn register_service_with_random_keys(&mut self, id: &str) -> UncommittedTransaction { - let random_service_challenge_key = create_mock_signing_key(); - let random_service_signing_key = create_mock_signing_key(); + let random_service_challenge_key = SigningKey::new_ed25519(); + let random_service_signing_key = SigningKey::new_ed25519(); self.register_service(id, random_service_challenge_key, random_service_signing_key) } @@ -117,7 +116,7 @@ impl TransactionBuilder { id: &str, service_id: &str, ) -> UncommittedTransaction { - let random_signing_key = create_mock_signing_key(); + let random_signing_key = SigningKey::new_ed25519(); self.create_account(id, service_id, random_signing_key) } @@ -168,7 +167,7 @@ impl TransactionBuilder { signing_key: &SigningKey, key_idx: usize, ) -> UncommittedTransaction { - let random_key = create_mock_signing_key().into(); + let random_key = SigningKey::new_ed25519().into(); self.add_key(id, random_key, signing_key, key_idx) } diff --git a/crates/common/src/tree.rs b/crates/common/src/tree.rs deleted file mode 100644 index d62d3aa9..00000000 --- a/crates/common/src/tree.rs +++ /dev/null @@ -1,634 +0,0 @@ -use anyhow::{anyhow, bail, ensure, Context, Result}; -use bincode; -use jmt::{ - proof::{SparseMerkleProof, UpdateMerkleProof}, - storage::{NodeBatch, TreeReader, TreeUpdateBatch, TreeWriter}, - JellyfishMerkleTree, KeyHash, RootHash, -}; -use prism_errors::DatabaseError; -use serde::{Deserialize, Serialize}; -use std::{convert::Into, sync::Arc}; - -use crate::{ - digest::Digest, - hashchain::{Hashchain, HashchainEntry}, - hasher::Hasher, - operation::{Operation, ServiceChallenge, ServiceChallengeInput}, - transaction::Transaction, -}; - -use HashchainResponse::*; - -pub const SPARSE_MERKLE_PLACEHOLDER_HASH: Digest = - Digest::new(*b"SPARSE_MERKLE_PLACEHOLDER_HASH__"); - -#[derive(Serialize, Deserialize)] -pub struct Batch { - pub prev_root: Digest, - pub new_root: Digest, - - pub proofs: Vec, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum Proof { - Update(Box), - Insert(Box), -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct MembershipProof { - pub root: Digest, - pub proof: SparseMerkleProof, - pub key: KeyHash, - pub value: Hashchain, -} - -impl MembershipProof { - pub fn verify(&self) -> Result<()> { - let value = bincode::serialize(&self.value)?; - self.proof.verify_existence(self.root.into(), self.key, value) - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct NonMembershipProof { - pub root: Digest, - pub proof: SparseMerkleProof, - pub key: KeyHash, -} - -impl NonMembershipProof { - pub fn verify(&self) -> Result<()> { - self.proof.verify_nonexistence(self.root.into(), self.key) - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct InsertProof { - pub non_membership_proof: NonMembershipProof, - - pub new_root: Digest, - pub membership_proof: SparseMerkleProof, - pub new_entry: HashchainEntry, -} - -impl InsertProof { - pub fn verify(&self) -> Result<()> { - self.non_membership_proof.verify().context("Invalid NonMembershipProof")?; - - let hashchain = Hashchain::from_entry(self.new_entry.clone())?; - let serialized_hashchain = bincode::serialize(&hashchain)?; - - self.membership_proof.clone().verify_existence( - self.new_root.into(), - self.non_membership_proof.key, - serialized_hashchain, - )?; - - Ok(()) - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct UpdateProof { - pub old_root: RootHash, - pub new_root: RootHash, - - pub key: KeyHash, - pub old_hashchain: Hashchain, - pub new_entry: HashchainEntry, - - /// Inclusion proof of [`old_value`] - pub inclusion_proof: SparseMerkleProof, - /// Update proof for [`key`] to be updated with [`new_entry`] - pub update_proof: UpdateMerkleProof, -} - -impl UpdateProof { - pub fn verify(&self) -> Result<()> { - // Verify existence of old value. - // Otherwise, any arbitrary hashchain could be set - let old_serialized_hashchain = bincode::serialize(&self.old_hashchain)?; - self.inclusion_proof.verify_existence(self.old_root, self.key, old_serialized_hashchain)?; - - let mut hashchain_after_update = self.old_hashchain.clone(); - // Append the new entry and verify it's validity - hashchain_after_update.add_entry(self.new_entry.clone())?; - - // Ensure the update proof corresponds to the new hashchain value - let new_serialized_hashchain = bincode::serialize(&hashchain_after_update)?; - self.update_proof.clone().verify_update( - self.old_root, - self.new_root, - vec![(self.key, Some(new_serialized_hashchain))], - )?; - - Ok(()) - } -} - -/// Enumerates possible responses when fetching tree values -#[derive(Debug)] -pub enum HashchainResponse { - /// When a hashchain was found, provides the value and its corresponding membership-proof - Found(Hashchain, MembershipProof), - - /// When no hashchain was found for a specific key, provides the corresponding non-membership-proof - NotFound(NonMembershipProof), -} - -pub trait SnarkableTree: Send + Sync { - fn process_transaction(&mut self, transaction: Transaction) -> Result; - fn insert(&mut self, key: KeyHash, entry: HashchainEntry) -> Result; - fn update(&mut self, key: KeyHash, entry: HashchainEntry) -> Result; - fn get(&self, key: KeyHash) -> Result; -} - -pub struct KeyDirectoryTree -where - S: TreeReader + TreeWriter, -{ - jmt: JellyfishMerkleTree, Hasher>, - pending_batch: Option, - epoch: u64, - db: Arc, -} - -impl KeyDirectoryTree -where - S: TreeReader + TreeWriter, -{ - pub fn new(store: Arc) -> Self { - let tree = Self { - db: store.clone(), - jmt: JellyfishMerkleTree::, Hasher>::new(store), - pending_batch: None, - epoch: 0, - }; - let (_, batch) = tree - .jmt - .put_value_set(vec![(KeyHash(SPARSE_MERKLE_PLACEHOLDER_HASH.0), None)], 0) - .unwrap(); - tree.db.write_node_batch(&batch.node_batch).unwrap(); - tree - } - - pub fn load(store: Arc, epoch: u64) -> Self { - if epoch == 0 { - return KeyDirectoryTree::new(store); - } - Self { - db: store.clone(), - jmt: JellyfishMerkleTree::, Hasher>::new(store), - pending_batch: None, - epoch, - } - } - - pub fn get_commitment(&self) -> Result { - let root = self.get_current_root()?; - Ok(Digest(root.0)) - } - - fn queue_batch(&mut self, batch: TreeUpdateBatch) { - match self.pending_batch { - Some(ref mut pending_batch) => pending_batch.merge(batch.node_batch), - None => self.pending_batch = Some(batch.node_batch), - } - } - - fn write_batch(&mut self) -> Result<()> { - if let Some(batch) = self.pending_batch.take() { - self.db.write_node_batch(&batch)?; - self.epoch += 1; - } - Ok(()) - } - - pub fn get_current_root(&self) -> Result { - self.jmt.get_root_hash(self.epoch).map_err(|e| anyhow!("Failed to get root hash: {}", e)) - } - - fn serialize_value(value: &Hashchain) -> Result> { - bincode::serialize(value).map_err(|e| anyhow!("Failed to serialize value: {}", e)) - } - - fn deserialize_value(bytes: &[u8]) -> Result { - bincode::deserialize::(bytes) - .map_err(|e| anyhow!("Failed to deserialize value: {}", e)) - } -} - -impl SnarkableTree for KeyDirectoryTree -where - S: Send + Sync + TreeReader + TreeWriter, -{ - fn process_transaction(&mut self, transaction: Transaction) -> Result { - match &transaction.entry.operation { - Operation::AddKey { .. } | Operation::RevokeKey { .. } | Operation::AddData { .. } => { - let hashed_id = Digest::hash(&transaction.id); - let key_hash = KeyHash::with::(hashed_id); - - debug!("updating hashchain for user id {}", transaction.id); - let proof = self.update(key_hash, transaction.entry)?; - - Ok(Proof::Update(Box::new(proof))) - } - Operation::CreateAccount { - id, - service_id, - challenge, - key, - } => { - ensure!( - transaction.id == id.as_str(), - "Id of transaction needs to be equal to operation id" - ); - - let hashed_id = Digest::hash(id); - let account_key_hash = KeyHash::with::(hashed_id); - - // Verify that the account doesn't already exist - if matches!(self.get(account_key_hash)?, Found(_, _)) { - bail!(DatabaseError::NotFoundError(format!( - "Account already exists for ID {}", - id - ))); - } - - let service_key_hash = KeyHash::with::(Digest::hash(service_id.as_bytes())); - - let Found(service_hashchain, _) = self.get(service_key_hash)? else { - bail!("Failed to get hashchain for service ID {}", service_id); - }; - - let Some(service_last_entry) = service_hashchain.last() else { - bail!("Service hashchain is empty, could not retrieve challenge key"); - }; - - let creation_gate = match &service_last_entry.operation { - Operation::RegisterService { creation_gate, .. } => creation_gate, - _ => { - bail!("Service hashchain's last entry was not a RegisterService operation") - } - }; - - // Hash and sign credentials that have been signed by the external service - let hash = - Digest::hash_items(&[id.as_bytes(), service_id.as_bytes(), &key.to_bytes()]); - - let ServiceChallenge::Signed(service_pubkey) = creation_gate; - let ServiceChallengeInput::Signed(challenge_signature) = &challenge; - - service_pubkey.verify_signature(&hash.to_bytes(), challenge_signature)?; - - debug!("creating new hashchain for user ID {}", id); - - let insert_proof = self.insert(account_key_hash, transaction.entry)?; - Ok(Proof::Insert(Box::new(insert_proof))) - } - Operation::RegisterService { id, .. } => { - ensure!( - transaction.id == id.as_str(), - "Id of transaction needs to be equal to operation id" - ); - - let hashed_id = Digest::hash(id); - let key_hash = KeyHash::with::(hashed_id); - - debug!("creating new hashchain for service id {}", id); - - let insert_proof = self.insert(key_hash, transaction.entry)?; - Ok(Proof::Insert(Box::new(insert_proof))) - } - } - } - - fn insert(&mut self, key: KeyHash, entry: HashchainEntry) -> Result { - let old_root = self.get_current_root()?; - let (None, non_membership_merkle_proof) = self.jmt.get_with_proof(key, self.epoch)? else { - bail!("Key already exists"); - }; - - let non_membership_proof = NonMembershipProof { - root: old_root.into(), - proof: non_membership_merkle_proof, - key, - }; - - let hashchain = Hashchain::from_entry(entry.clone())?; - let serialized_hashchain = Self::serialize_value(&hashchain)?; - - // the update proof just contains another nm proof - let (new_root, _, tree_update_batch) = self - .jmt - .put_value_set_with_proof(vec![(key, Some(serialized_hashchain))], self.epoch + 1)?; - self.queue_batch(tree_update_batch); - self.write_batch()?; - - let (_, membership_proof) = self.jmt.get_with_proof(key, self.epoch)?; - - Ok(InsertProof { - new_root: new_root.into(), - new_entry: entry, - non_membership_proof, - membership_proof, - }) - } - - fn update(&mut self, key: KeyHash, entry: HashchainEntry) -> Result { - let old_root = self.get_current_root()?; - let (Some(old_serialized_hashchain), inclusion_proof) = - self.jmt.get_with_proof(key, self.epoch)? - else { - bail!("Key does not exist"); - }; - - let old_hashchain: Hashchain = bincode::deserialize(old_serialized_hashchain.as_slice())?; - - let mut new_hashchain = old_hashchain.clone(); - new_hashchain.add_entry(entry.clone())?; - - let serialized_value = Self::serialize_value(&new_hashchain)?; - - let (new_root, update_proof, tree_update_batch) = self.jmt.put_value_set_with_proof( - vec![(key, Some(serialized_value.clone()))], - self.epoch + 1, - )?; - self.queue_batch(tree_update_batch); - self.write_batch()?; - - Ok(UpdateProof { - old_root, - new_root, - inclusion_proof, - old_hashchain, - key, - update_proof, - new_entry: entry, - }) - } - - fn get(&self, key: KeyHash) -> Result { - let root = self.get_current_root()?.into(); - let (value, proof) = self.jmt.get_with_proof(key, self.epoch)?; - - match value { - Some(serialized_value) => { - let deserialized_value = Self::deserialize_value(&serialized_value)?; - let membership_proof = MembershipProof { - root, - proof, - key, - value: deserialized_value.clone(), - }; - Ok(Found(deserialized_value, membership_proof)) - } - None => { - let non_membership_proof = NonMembershipProof { root, proof, key }; - Ok(NotFound(non_membership_proof)) - } - } - } -} - -#[cfg(all(test, feature = "test_utils"))] -mod tests { - use super::*; - use crate::test_utils::{create_mock_signing_key, TestTreeState}; - - #[test] - fn test_insert_and_get() { - let mut tree_state = TestTreeState::default(); - let service = tree_state.register_service("service_1".to_string()); - let account = tree_state.create_account("key_1".to_string(), service.clone()); - - let insert_proof = tree_state.insert_account(service.registration.clone()).unwrap(); - assert!(insert_proof.verify().is_ok()); - - let insert_proof = tree_state.insert_account(account.clone()).unwrap(); - assert!(insert_proof.verify().is_ok()); - - let Found(hashchain, membership_proof) = tree_state.tree.get(account.key_hash).unwrap() - else { - panic!("Expected hashchain to be found, but was not found.") - }; - - assert_eq!(hashchain, account.hashchain); - assert!(membership_proof.verify().is_ok()); - } - - #[test] - fn test_insert_for_nonexistent_service_fails() { - let mut tree_state = TestTreeState::default(); - let service = tree_state.register_service("service_1".to_string()); - let account = tree_state.create_account("key_1".to_string(), service.clone()); - - let insert_proof = tree_state.insert_account(account.clone()); - assert!(insert_proof.is_err()); - } - - #[test] - fn test_insert_with_invalid_service_challenge_fails() { - let mut tree_state = TestTreeState::default(); - let service = tree_state.register_service("service_1".to_string()); - - let mut falsified_service = service.clone(); - falsified_service.sk = create_mock_signing_key(); - - let account = tree_state.create_account("key_1".to_string(), falsified_service.clone()); - - let insert_proof = tree_state.insert_account(service.registration.clone()).unwrap(); - assert!(insert_proof.verify().is_ok()); - - let insert_proof = tree_state.insert_account(account.clone()); - assert!(insert_proof.is_err()); - } - - #[test] - fn test_insert_duplicate_key() { - let mut tree_state = TestTreeState::default(); - let service = tree_state.register_service("service_1".to_string()); - let account = tree_state.create_account("key_1".to_string(), service.clone()); - - let insert_proof = tree_state.insert_account(service.registration.clone()).unwrap(); - assert!(insert_proof.verify().is_ok()); - - tree_state.insert_account(account.clone()).unwrap(); - - let result = tree_state.insert_account(account.clone()); - assert!(result.is_err()); - } - - #[test] - fn test_update_existing_key() { - let mut tree_state = TestTreeState::default(); - - let service = tree_state.register_service("service_1".to_string()); - let mut account = tree_state.create_account("key_1".to_string(), service.clone()); - tree_state.insert_account(service.registration.clone()).unwrap(); - tree_state.insert_account(account.clone()).unwrap(); - - // Add a new key - tree_state.add_key_to_account(&mut account).unwrap(); - - // Update the account using the correct key index - let update_proof = tree_state.update_account(account.clone()).unwrap(); - assert!(update_proof.verify().is_ok()); - - let get_result = tree_state.tree.get(account.key_hash); - assert!(matches!(get_result.unwrap(), Found(hc, _) if hc == account.hashchain)); - } - - #[test] - fn test_update_non_existing_key() { - let mut tree_state = TestTreeState::default(); - let service = tree_state.register_service("service_1".to_string()); - let account = tree_state.create_account("key_1".to_string(), service.clone()); - tree_state.insert_account(service.registration.clone()).unwrap(); - - let result = tree_state.update_account(account); - assert!(result.is_err()); - } - - #[test] - fn test_get_non_existing_key() { - let tree_state = TestTreeState::default(); - let key = KeyHash::with::(b"non_existing_key"); - - let result = tree_state.tree.get(key).unwrap(); - - let NotFound(non_membership_proof) = result else { - panic!("Hashchain found for key while it was expected to be missing"); - }; - - assert!(non_membership_proof.verify().is_ok()); - } - - #[test] - fn test_multiple_inserts_and_updates() { - let mut tree_state = TestTreeState::default(); - - let service = tree_state.register_service("service_1".to_string()); - let mut account1 = tree_state.create_account("key_1".to_string(), service.clone()); - let mut account2 = tree_state.create_account("key_2".to_string(), service.clone()); - - tree_state.insert_account(service.registration).unwrap(); - - tree_state.insert_account(account1.clone()).unwrap(); - tree_state.insert_account(account2.clone()).unwrap(); - - // Do insert and update accounts using the correct key indices - tree_state.add_key_to_account(&mut account1).unwrap(); - tree_state.update_account(account1.clone()).unwrap(); - - tree_state.add_unsigned_data_to_account(b"unsigned", &mut account2).unwrap(); - tree_state.update_account(account2.clone()).unwrap(); - tree_state.add_signed_data_to_account(b"signed", &mut account2).unwrap(); - tree_state.update_account(account2.clone()).unwrap(); - - let get_result1 = tree_state.tree.get(account1.key_hash); - let get_result2 = tree_state.tree.get(account2.key_hash); - - assert!(matches!(get_result1.unwrap(), Found(hc, _) if hc == account1.hashchain)); - assert!(matches!(get_result2.unwrap(), Found(hc, _) if hc == account2.hashchain)); - } - - #[test] - fn test_interleaved_inserts_and_updates() { - let mut test_tree = TestTreeState::default(); - - let service = test_tree.register_service("service_1".to_string()); - let mut account_1 = test_tree.create_account("key_1".to_string(), service.clone()); - let mut account_2 = test_tree.create_account("key_2".to_string(), service.clone()); - - test_tree.insert_account(service.registration).unwrap(); - - test_tree.insert_account(account_1.clone()).unwrap(); - - test_tree.add_key_to_account(&mut account_1).unwrap(); - // Update account_1 using the correct key index - test_tree.update_account(account_1.clone()).unwrap(); - - test_tree.insert_account(account_2.clone()).unwrap(); - - test_tree.add_key_to_account(&mut account_2).unwrap(); - - // Update account_2 using the correct key index - let last_proof = test_tree.update_account(account_2.clone()).unwrap(); - - let get_result1 = test_tree.tree.get(account_1.key_hash); - let get_result2 = test_tree.tree.get(account_2.key_hash); - - assert!(matches!(get_result1.unwrap(), Found(hc, _) if hc == account_1.hashchain)); - assert!(matches!(get_result2.unwrap(), Found(hc, _) if hc == account_2.hashchain)); - assert_eq!( - last_proof.new_root, - test_tree.tree.get_current_root().unwrap() - ); - } - - #[test] - fn test_root_hash_changes() { - let mut tree_state = TestTreeState::default(); - let service = tree_state.register_service("service_1".to_string()); - let account = tree_state.create_account("key_1".to_string(), service.clone()); - - tree_state.insert_account(service.registration).unwrap(); - - let root_before = tree_state.tree.get_current_root().unwrap(); - tree_state.insert_account(account).unwrap(); - let root_after = tree_state.tree.get_current_root().unwrap(); - - assert_ne!(root_before, root_after); - } - - #[test] - fn test_batch_writing() { - let mut tree_state = TestTreeState::default(); - let service = tree_state.register_service("service_1".to_string()); - - let account1 = tree_state.create_account("key_1".to_string(), service.clone()); - let account2 = tree_state.create_account("key_2".to_string(), service.clone()); - tree_state.insert_account(service.registration).unwrap(); - - println!("Inserting key1: {:?}", account1.key_hash); - tree_state.insert_account(account1.clone()).unwrap(); - - println!( - "Tree state after first insert: {:?}", - tree_state.tree.get_commitment() - ); - println!( - "Tree state after first write_batch: {:?}", - tree_state.tree.get_commitment() - ); - - // Try to get the first value immediately - let get_result1 = tree_state.tree.get(account1.key_hash); - println!("Get result for key1 after first write: {:?}", get_result1); - - println!("Inserting key2: {:?}", account2.key_hash); - tree_state.insert_account(account2.clone()).unwrap(); - - println!( - "Tree state after second insert: {:?}", - tree_state.tree.get_commitment() - ); - println!( - "Tree state after second write_batch: {:?}", - tree_state.tree.get_commitment() - ); - - // Try to get both values - let get_result1 = tree_state.tree.get(account1.key_hash); - let get_result2 = tree_state.tree.get(account2.key_hash); - - println!("Final get result for key1: {:?}", get_result1); - println!("Final get result for key2: {:?}", get_result2); - - assert!(matches!(get_result1.unwrap(), Found(hc, _) if hc == account1.hashchain)); - assert!(matches!(get_result2.unwrap(), Found(hc, _) if hc == account2.hashchain)); - } -} diff --git a/crates/common/src/tree/key_directory_tree.rs b/crates/common/src/tree/key_directory_tree.rs new file mode 100644 index 00000000..2045a241 --- /dev/null +++ b/crates/common/src/tree/key_directory_tree.rs @@ -0,0 +1,90 @@ +use anyhow::{anyhow, Result}; +use bincode; +use jmt::{ + self, + storage::{NodeBatch, TreeReader, TreeUpdateBatch, TreeWriter}, + JellyfishMerkleTree, KeyHash, RootHash, +}; +use std::sync::Arc; + +use crate::{digest::Digest, hashchain::Hashchain, hasher::Hasher}; + +pub const SPARSE_MERKLE_PLACEHOLDER_HASH: Digest = + Digest::new(*b"SPARSE_MERKLE_PLACEHOLDER_HASH__"); + +/// Wraps a [`JellyfishMerkleTree`] to provide a key-value store for [`Hashchain`]s with batched insertions. +/// This is prism's primary data structure for storing and retrieving [`Hashchain`]s. +pub struct KeyDirectoryTree +where + S: TreeReader + TreeWriter, +{ + pub(crate) jmt: JellyfishMerkleTree, Hasher>, + pub(crate) epoch: u64, + pending_batch: Option, + db: Arc, +} + +impl KeyDirectoryTree +where + S: TreeReader + TreeWriter, +{ + pub fn new(store: Arc) -> Self { + let tree = Self { + db: store.clone(), + jmt: JellyfishMerkleTree::, Hasher>::new(store), + pending_batch: None, + epoch: 0, + }; + let (_, batch) = tree + .jmt + .put_value_set(vec![(KeyHash(SPARSE_MERKLE_PLACEHOLDER_HASH.0), None)], 0) + .unwrap(); + tree.db.write_node_batch(&batch.node_batch).unwrap(); + tree + } + + pub fn load(store: Arc, epoch: u64) -> Self { + if epoch == 0 { + return KeyDirectoryTree::new(store); + } + Self { + db: store.clone(), + jmt: JellyfishMerkleTree::, Hasher>::new(store), + pending_batch: None, + epoch, + } + } + + pub fn get_commitment(&self) -> Result { + let root = self.get_current_root()?; + Ok(Digest(root.0)) + } + + pub(crate) fn queue_batch(&mut self, batch: TreeUpdateBatch) { + match self.pending_batch { + Some(ref mut pending_batch) => pending_batch.merge(batch.node_batch), + None => self.pending_batch = Some(batch.node_batch), + } + } + + pub(crate) fn write_batch(&mut self) -> Result<()> { + if let Some(batch) = self.pending_batch.take() { + self.db.write_node_batch(&batch)?; + self.epoch += 1; + } + Ok(()) + } + + pub fn get_current_root(&self) -> Result { + self.jmt.get_root_hash(self.epoch).map_err(|e| anyhow!("Failed to get root hash: {}", e)) + } + + pub(crate) fn serialize_value(value: &Hashchain) -> Result> { + bincode::serialize(value).map_err(|e| anyhow!("Failed to serialize value: {}", e)) + } + + pub(crate) fn deserialize_value(bytes: &[u8]) -> Result { + bincode::deserialize::(bytes) + .map_err(|e| anyhow!("Failed to deserialize value: {}", e)) + } +} diff --git a/crates/common/src/tree/mod.rs b/crates/common/src/tree/mod.rs new file mode 100644 index 00000000..aae20067 --- /dev/null +++ b/crates/common/src/tree/mod.rs @@ -0,0 +1,263 @@ +use crate::hashchain::Hashchain; + +mod key_directory_tree; +mod proofs; +mod snarkable_tree; + +pub use key_directory_tree::*; +pub use proofs::*; +pub use snarkable_tree::*; + +/// Enumerates possible responses when fetching tree values +#[derive(Debug)] +pub enum HashchainResponse { + /// When a hashchain was found, provides the value and its corresponding membership-proof + Found(Hashchain, MembershipProof), + + /// When no hashchain was found for a specific key, provides the corresponding non-membership-proof + NotFound(NonMembershipProof), +} + +#[cfg(all(test, feature = "test_utils"))] +mod tests { + use super::*; + use crate::{test_utils::TestTreeState, tree::HashchainResponse::*}; + use jmt::KeyHash; + use prism_keys::SigningKey; + + use crate::hasher::Hasher; + + #[test] + fn test_insert_and_get() { + let mut tree_state = TestTreeState::default(); + let service = tree_state.register_service("service_1".to_string()); + let account = tree_state.create_account("key_1".to_string(), service.clone()); + + let insert_proof = tree_state.insert_account(service.registration.clone()).unwrap(); + assert!(insert_proof.verify().is_ok()); + + let insert_proof = tree_state.insert_account(account.clone()).unwrap(); + assert!(insert_proof.verify().is_ok()); + + let Found(hashchain, membership_proof) = tree_state.tree.get(account.key_hash).unwrap() + else { + panic!("Expected hashchain to be found, but was not found.") + }; + + assert_eq!(hashchain, account.hashchain); + assert!(membership_proof.verify().is_ok()); + } + + #[test] + fn test_insert_for_nonexistent_service_fails() { + let mut tree_state = TestTreeState::default(); + let service = tree_state.register_service("service_1".to_string()); + let account = tree_state.create_account("key_1".to_string(), service.clone()); + + let insert_proof = tree_state.insert_account(account.clone()); + assert!(insert_proof.is_err()); + } + + #[test] + fn test_insert_with_invalid_service_challenge_fails() { + let mut tree_state = TestTreeState::default(); + let service = tree_state.register_service("service_1".to_string()); + + let mut falsified_service = service.clone(); + falsified_service.sk = SigningKey::new_ed25519(); + + let account = tree_state.create_account("key_1".to_string(), falsified_service.clone()); + + let insert_proof = tree_state.insert_account(service.registration.clone()).unwrap(); + assert!(insert_proof.verify().is_ok()); + + let insert_proof = tree_state.insert_account(account.clone()); + assert!(insert_proof.is_err()); + } + + #[test] + fn test_insert_duplicate_key() { + let mut tree_state = TestTreeState::default(); + let service = tree_state.register_service("service_1".to_string()); + let account = tree_state.create_account("key_1".to_string(), service.clone()); + + let insert_proof = tree_state.insert_account(service.registration.clone()).unwrap(); + assert!(insert_proof.verify().is_ok()); + + tree_state.insert_account(account.clone()).unwrap(); + + let result = tree_state.insert_account(account.clone()); + assert!(result.is_err()); + } + + #[test] + fn test_update_existing_key() { + let mut tree_state = TestTreeState::default(); + + let service = tree_state.register_service("service_1".to_string()); + let mut account = tree_state.create_account("key_1".to_string(), service.clone()); + tree_state.insert_account(service.registration.clone()).unwrap(); + tree_state.insert_account(account.clone()).unwrap(); + + // Add a new key + tree_state.add_key_to_account(&mut account).unwrap(); + + // Update the account using the correct key index + let update_proof = tree_state.update_account(account.clone()).unwrap(); + assert!(update_proof.verify().is_ok()); + + let get_result = tree_state.tree.get(account.key_hash); + assert!(matches!(get_result.unwrap(), Found(hc, _) if hc == account.hashchain)); + } + + #[test] + fn test_update_non_existing_key() { + let mut tree_state = TestTreeState::default(); + let service = tree_state.register_service("service_1".to_string()); + let account = tree_state.create_account("key_1".to_string(), service.clone()); + tree_state.insert_account(service.registration.clone()).unwrap(); + + let result = tree_state.update_account(account); + assert!(result.is_err()); + } + + #[test] + fn test_get_non_existing_key() { + let tree_state = TestTreeState::default(); + let key = KeyHash::with::(b"non_existing_key"); + + let result = tree_state.tree.get(key).unwrap(); + + let NotFound(non_membership_proof) = result else { + panic!("Hashchain found for key while it was expected to be missing"); + }; + + assert!(non_membership_proof.verify().is_ok()); + } + + #[test] + fn test_multiple_inserts_and_updates() { + let mut tree_state = TestTreeState::default(); + + let service = tree_state.register_service("service_1".to_string()); + let mut account1 = tree_state.create_account("key_1".to_string(), service.clone()); + let mut account2 = tree_state.create_account("key_2".to_string(), service.clone()); + + tree_state.insert_account(service.registration).unwrap(); + + tree_state.insert_account(account1.clone()).unwrap(); + tree_state.insert_account(account2.clone()).unwrap(); + + // Do insert and update accounts using the correct key indices + tree_state.add_key_to_account(&mut account1).unwrap(); + tree_state.update_account(account1.clone()).unwrap(); + + tree_state.add_unsigned_data_to_account(b"unsigned", &mut account2).unwrap(); + tree_state.update_account(account2.clone()).unwrap(); + tree_state.add_signed_data_to_account(b"signed", &mut account2).unwrap(); + tree_state.update_account(account2.clone()).unwrap(); + + let get_result1 = tree_state.tree.get(account1.key_hash); + let get_result2 = tree_state.tree.get(account2.key_hash); + + assert!(matches!(get_result1.unwrap(), Found(hc, _) if hc == account1.hashchain)); + assert!(matches!(get_result2.unwrap(), Found(hc, _) if hc == account2.hashchain)); + } + + #[test] + fn test_interleaved_inserts_and_updates() { + let mut test_tree = TestTreeState::default(); + + let service = test_tree.register_service("service_1".to_string()); + let mut account_1 = test_tree.create_account("key_1".to_string(), service.clone()); + let mut account_2 = test_tree.create_account("key_2".to_string(), service.clone()); + + test_tree.insert_account(service.registration).unwrap(); + + test_tree.insert_account(account_1.clone()).unwrap(); + + test_tree.add_key_to_account(&mut account_1).unwrap(); + // Update account_1 using the correct key index + test_tree.update_account(account_1.clone()).unwrap(); + + test_tree.insert_account(account_2.clone()).unwrap(); + + test_tree.add_key_to_account(&mut account_2).unwrap(); + + // Update account_2 using the correct key index + let last_proof = test_tree.update_account(account_2.clone()).unwrap(); + + let get_result1 = test_tree.tree.get(account_1.key_hash); + let get_result2 = test_tree.tree.get(account_2.key_hash); + + assert!(matches!(get_result1.unwrap(), Found(hc, _) if hc == account_1.hashchain)); + assert!(matches!(get_result2.unwrap(), Found(hc, _) if hc == account_2.hashchain)); + assert_eq!( + last_proof.new_root, + test_tree.tree.get_current_root().unwrap() + ); + } + + #[test] + fn test_root_hash_changes() { + let mut tree_state = TestTreeState::default(); + let service = tree_state.register_service("service_1".to_string()); + let account = tree_state.create_account("key_1".to_string(), service.clone()); + + tree_state.insert_account(service.registration).unwrap(); + + let root_before = tree_state.tree.get_current_root().unwrap(); + tree_state.insert_account(account).unwrap(); + let root_after = tree_state.tree.get_current_root().unwrap(); + + assert_ne!(root_before, root_after); + } + + #[test] + fn test_batch_writing() { + let mut tree_state = TestTreeState::default(); + let service = tree_state.register_service("service_1".to_string()); + + let account1 = tree_state.create_account("key_1".to_string(), service.clone()); + let account2 = tree_state.create_account("key_2".to_string(), service.clone()); + tree_state.insert_account(service.registration).unwrap(); + + println!("Inserting key1: {:?}", account1.key_hash); + tree_state.insert_account(account1.clone()).unwrap(); + + println!( + "Tree state after first insert: {:?}", + tree_state.tree.get_commitment() + ); + println!( + "Tree state after first write_batch: {:?}", + tree_state.tree.get_commitment() + ); + + // Try to get the first value immediately + let get_result1 = tree_state.tree.get(account1.key_hash); + println!("Get result for key1 after first write: {:?}", get_result1); + + println!("Inserting key2: {:?}", account2.key_hash); + tree_state.insert_account(account2.clone()).unwrap(); + + println!( + "Tree state after second insert: {:?}", + tree_state.tree.get_commitment() + ); + println!( + "Tree state after second write_batch: {:?}", + tree_state.tree.get_commitment() + ); + + // Try to get both values + let get_result1 = tree_state.tree.get(account1.key_hash); + let get_result2 = tree_state.tree.get(account2.key_hash); + + println!("Final get result for key1: {:?}", get_result1); + println!("Final get result for key2: {:?}", get_result2); + + assert!(matches!(get_result1.unwrap(), Found(hc, _) if hc == account1.hashchain)); + assert!(matches!(get_result2.unwrap(), Found(hc, _) if hc == account2.hashchain)); + } +} diff --git a/crates/common/src/tree/proofs.rs b/crates/common/src/tree/proofs.rs new file mode 100644 index 00000000..6f9088da --- /dev/null +++ b/crates/common/src/tree/proofs.rs @@ -0,0 +1,136 @@ +use anyhow::{Context, Result}; +use bincode; +use jmt::{ + proof::{SparseMerkleProof, UpdateMerkleProof}, + KeyHash, RootHash, +}; +use serde::{Deserialize, Serialize}; +use std::convert::Into; + +use crate::{ + digest::Digest, + hashchain::{Hashchain, HashchainEntry}, + hasher::Hasher, +}; + +#[derive(Serialize, Deserialize)] +/// Represents a contiguous stream of [`Proof`]s leading from [`Batch::prev_root`] to [`Batch::new_root`]. +/// Used as the input to the circuit. +pub struct Batch { + pub prev_root: Digest, + pub new_root: Digest, + + pub proofs: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Proof { + Update(Box), + Insert(Box), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +/// Represents an insertion proof for a newly created hashchain. +/// Currently, this proof is generated by +/// [`crate::operation::Operation::CreateAccount`] and +/// [`crate::operation::Operation::RegisterService`] operations. +// TODO(CRITICAL): Verify service's challenge input via a merkle proof of +// the service, and then signature verification with the contained VK. +pub struct InsertProof { + /// Proof that the key does not already exist in the tree (i.e. it's not overwriting an existing key) + pub non_membership_proof: NonMembershipProof, + + /// Post-insertion root hash of the tree + pub new_root: Digest, + /// Proof that the new hashchain is correctly inserted into the tree + pub membership_proof: SparseMerkleProof, + + /// The new hashchain entry that was inserted. + pub new_entry: HashchainEntry, +} + +impl InsertProof { + /// The method called in circuit to verify the state transition to the new root. + pub fn verify(&self) -> Result<()> { + self.non_membership_proof.verify().context("Invalid NonMembershipProof")?; + + let hashchain = Hashchain::from_entry(self.new_entry.clone())?; + let serialized_hashchain = bincode::serialize(&hashchain)?; + + self.membership_proof.clone().verify_existence( + self.new_root.into(), + self.non_membership_proof.key, + serialized_hashchain, + )?; + + Ok(()) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +/// Represents an update proof for an existing [`Hashchain`], updating it with a new [`HashchainEntry`]. +pub struct UpdateProof { + pub old_root: RootHash, + pub new_root: RootHash, + + pub key: KeyHash, + pub old_hashchain: Hashchain, + pub new_entry: HashchainEntry, + + /// Inclusion proof of [`UpdateProof::old_hashchain`] + pub inclusion_proof: SparseMerkleProof, + /// Update proof for [`UpdateProof::key`] to be updated with [`UpdateProof::new_entry`] + pub update_proof: UpdateMerkleProof, +} + +impl UpdateProof { + /// The method called in circuit to verify the state transition to the new root. + pub fn verify(&self) -> Result<()> { + // Verify existence of old value. + // Otherwise, any arbitrary hashchain could be set as old_hashchain. + let old_serialized_hashchain = bincode::serialize(&self.old_hashchain)?; + self.inclusion_proof.verify_existence(self.old_root, self.key, old_serialized_hashchain)?; + + let mut hashchain_after_update = self.old_hashchain.clone(); + // Append the new entry and verify it's validity + hashchain_after_update.add_entry(self.new_entry.clone())?; + + // Ensure the update proof corresponds to the new hashchain value + let new_serialized_hashchain = bincode::serialize(&hashchain_after_update)?; + self.update_proof.clone().verify_update( + self.old_root, + self.new_root, + vec![(self.key, Some(new_serialized_hashchain))], + )?; + + Ok(()) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct MembershipProof { + pub root: Digest, + pub proof: SparseMerkleProof, + pub key: KeyHash, + pub value: Hashchain, +} + +impl MembershipProof { + pub fn verify(&self) -> Result<()> { + let value = bincode::serialize(&self.value)?; + self.proof.verify_existence(self.root.into(), self.key, value) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct NonMembershipProof { + pub root: Digest, + pub proof: SparseMerkleProof, + pub key: KeyHash, +} + +impl NonMembershipProof { + pub fn verify(&self) -> Result<()> { + self.proof.verify_nonexistence(self.root.into(), self.key) + } +} diff --git a/crates/common/src/tree/snarkable_tree.rs b/crates/common/src/tree/snarkable_tree.rs new file mode 100644 index 00000000..e51f29b1 --- /dev/null +++ b/crates/common/src/tree/snarkable_tree.rs @@ -0,0 +1,200 @@ +use anyhow::{bail, ensure, Result}; +use bincode; +use jmt::{ + storage::{TreeReader, TreeWriter}, + KeyHash, +}; +use prism_errors::DatabaseError; +use std::convert::Into; + +use crate::{ + digest::Digest, + hashchain::{Hashchain, HashchainEntry}, + hasher::Hasher, + operation::{Operation, ServiceChallenge, ServiceChallengeInput}, + transaction::Transaction, + tree::{HashchainResponse::*, *}, +}; + +/// Represents a tree that can be used to verifiably store and retrieve [`Hashchain`]s. +/// The methods of this trait are NOT run in circuit: they are used to create verifiable inputs for the circuit. +/// This distinction is critical because the returned proofs must contain all information necessary to verify the operations. +pub trait SnarkableTree: Send + Sync { + fn process_transaction(&mut self, transaction: Transaction) -> Result; + fn insert(&mut self, key: KeyHash, entry: HashchainEntry) -> Result; + fn update(&mut self, key: KeyHash, entry: HashchainEntry) -> Result; + fn get(&self, key: KeyHash) -> Result; +} + +impl SnarkableTree for KeyDirectoryTree +where + S: Send + Sync + TreeReader + TreeWriter, +{ + fn process_transaction(&mut self, transaction: Transaction) -> Result { + match &transaction.entry.operation { + Operation::AddKey { .. } | Operation::RevokeKey { .. } | Operation::AddData { .. } => { + let hashed_id = Digest::hash(&transaction.id); + let key_hash = KeyHash::with::(hashed_id); + + debug!("updating hashchain for user id {}", transaction.id); + let proof = self.update(key_hash, transaction.entry)?; + + Ok(Proof::Update(Box::new(proof))) + } + Operation::CreateAccount { + id, + service_id, + challenge, + key, + } => { + ensure!( + transaction.id == id.as_str(), + "Id of transaction needs to be equal to operation id" + ); + + let hashed_id = Digest::hash(id); + let account_key_hash = KeyHash::with::(hashed_id); + + // Verify that the account doesn't already exist + if matches!(self.get(account_key_hash)?, Found(_, _)) { + bail!(DatabaseError::NotFoundError(format!( + "Account already exists for ID {}", + id + ))); + } + + let service_key_hash = KeyHash::with::(Digest::hash(service_id.as_bytes())); + + let Found(service_hashchain, _) = self.get(service_key_hash)? else { + bail!("Failed to get hashchain for service ID {}", service_id); + }; + + let Some(service_last_entry) = service_hashchain.last() else { + bail!("Service hashchain is empty, could not retrieve challenge key"); + }; + + let creation_gate = match &service_last_entry.operation { + Operation::RegisterService { creation_gate, .. } => creation_gate, + _ => { + bail!("Service hashchain's last entry was not a RegisterService operation") + } + }; + + // Hash and sign credentials that have been signed by the external service + let hash = + Digest::hash_items(&[id.as_bytes(), service_id.as_bytes(), &key.to_bytes()]); + + let ServiceChallenge::Signed(service_pubkey) = creation_gate; + let ServiceChallengeInput::Signed(challenge_signature) = &challenge; + + service_pubkey.verify_signature(&hash.to_bytes(), challenge_signature)?; + + debug!("creating new hashchain for user ID {}", id); + + let insert_proof = self.insert(account_key_hash, transaction.entry)?; + Ok(Proof::Insert(Box::new(insert_proof))) + } + Operation::RegisterService { id, .. } => { + ensure!( + transaction.id == id.as_str(), + "Id of transaction needs to be equal to operation id" + ); + + let hashed_id = Digest::hash(id); + let key_hash = KeyHash::with::(hashed_id); + + debug!("creating new hashchain for service id {}", id); + + let insert_proof = self.insert(key_hash, transaction.entry)?; + Ok(Proof::Insert(Box::new(insert_proof))) + } + } + } + + fn insert(&mut self, key: KeyHash, entry: HashchainEntry) -> Result { + let old_root = self.get_current_root()?; + let (None, non_membership_merkle_proof) = self.jmt.get_with_proof(key, self.epoch)? else { + bail!("Key already exists"); + }; + + let non_membership_proof = NonMembershipProof { + root: old_root.into(), + proof: non_membership_merkle_proof, + key, + }; + + let hashchain = Hashchain::from_entry(entry.clone())?; + let serialized_hashchain = Self::serialize_value(&hashchain)?; + + // the update proof just contains another nm proof + let (new_root, _, tree_update_batch) = self + .jmt + .put_value_set_with_proof(vec![(key, Some(serialized_hashchain))], self.epoch + 1)?; + self.queue_batch(tree_update_batch); + self.write_batch()?; + + let (_, membership_proof) = self.jmt.get_with_proof(key, self.epoch)?; + + Ok(InsertProof { + new_root: new_root.into(), + new_entry: entry, + non_membership_proof, + membership_proof, + }) + } + + fn update(&mut self, key: KeyHash, entry: HashchainEntry) -> Result { + let old_root = self.get_current_root()?; + let (Some(old_serialized_hashchain), inclusion_proof) = + self.jmt.get_with_proof(key, self.epoch)? + else { + bail!("Key does not exist"); + }; + + let old_hashchain: Hashchain = bincode::deserialize(old_serialized_hashchain.as_slice())?; + + let mut new_hashchain = old_hashchain.clone(); + new_hashchain.add_entry(entry.clone())?; + + let serialized_value = Self::serialize_value(&new_hashchain)?; + + let (new_root, update_proof, tree_update_batch) = self.jmt.put_value_set_with_proof( + vec![(key, Some(serialized_value.clone()))], + self.epoch + 1, + )?; + self.queue_batch(tree_update_batch); + self.write_batch()?; + + Ok(UpdateProof { + old_root, + new_root, + inclusion_proof, + old_hashchain, + key, + update_proof, + new_entry: entry, + }) + } + + fn get(&self, key: KeyHash) -> Result { + let root = self.get_current_root()?.into(); + let (value, proof) = self.jmt.get_with_proof(key, self.epoch)?; + + match value { + Some(serialized_value) => { + let deserialized_value = Self::deserialize_value(&serialized_value)?; + let membership_proof = MembershipProof { + root, + proof, + key, + value: deserialized_value.clone(), + }; + Ok(Found(deserialized_value, membership_proof)) + } + None => { + let non_membership_proof = NonMembershipProof { root, proof, key }; + Ok(NotFound(non_membership_proof)) + } + } + } +} diff --git a/crates/keys/Cargo.toml b/crates/keys/Cargo.toml new file mode 100644 index 00000000..1ce3b400 --- /dev/null +++ b/crates/keys/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "prism-keys" +version.workspace = true +edition.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +# serde +prism-serde.workspace = true +base64.workspace = true +serde.workspace = true + +# curves +ed25519-consensus.workspace = true +secp256k1.workspace = true +p256.workspace = true +ecdsa.workspace = true # needed transitively to enable der feature + +# misc +anyhow.workspace = true +sha2.workspace = true +rand.workspace = true + +[features] +default = [] +test_utils = [] +secp256k1 = ["secp256k1/global-context", "secp256k1/rand-std"] diff --git a/crates/keys/src/lib.rs b/crates/keys/src/lib.rs new file mode 100644 index 00000000..7969d667 --- /dev/null +++ b/crates/keys/src/lib.rs @@ -0,0 +1,134 @@ +mod signatures; +mod signing_keys; +mod verifying_keys; + +pub use signatures::*; +pub use signing_keys::*; +pub use verifying_keys::*; + +#[cfg(test)] +mod tests { + use super::*; + use base64::{engine::general_purpose::STANDARD as engine, Engine as _}; + use ed25519_consensus::SigningKey as Ed25519SigningKey; + use rand::rngs::OsRng; + use secp256k1::SecretKey as Secp256k1SigningKey; + + #[test] + fn test_reparsed_verifying_keys_are_equal_to_original() { + let verifying_key_ed25519 = SigningKey::new_ed25519().verifying_key(); + let re_parsed_verifying_key = VerifyingKey::from_algorithm_and_bytes( + verifying_key_ed25519.algorithm(), + &verifying_key_ed25519.to_bytes(), + ) + .unwrap(); + assert_eq!(re_parsed_verifying_key, verifying_key_ed25519); + + let verifying_key_secp256k1 = SigningKey::new_secp256k1().verifying_key(); + let re_parsed_verifying_key = VerifyingKey::from_algorithm_and_bytes( + verifying_key_secp256k1.algorithm(), + &verifying_key_secp256k1.to_bytes(), + ) + .unwrap(); + assert_eq!(re_parsed_verifying_key, verifying_key_secp256k1); + + let verifying_key_secp256r1 = SigningKey::new_secp256r1().verifying_key(); + let re_parsed_verifying_key = VerifyingKey::from_algorithm_and_bytes( + verifying_key_secp256r1.algorithm(), + &verifying_key_secp256r1.to_bytes(), + ) + .unwrap(); + assert_eq!(re_parsed_verifying_key, verifying_key_secp256r1); + } + + #[test] + fn test_reparsed_signing_keys_are_equal_to_original() { + let signing_key_ed25519 = SigningKey::new_ed25519(); + let re_parsed_signing_key = SigningKey::from_algorithm_and_bytes( + signing_key_ed25519.algorithm(), + &signing_key_ed25519.to_bytes(), + ) + .unwrap(); + assert_eq!(re_parsed_signing_key, signing_key_ed25519); + + let signing_key_secp256k1 = SigningKey::new_secp256k1(); + let re_parsed_signing_key = SigningKey::from_algorithm_and_bytes( + signing_key_secp256k1.algorithm(), + &signing_key_secp256k1.to_bytes(), + ) + .unwrap(); + assert_eq!(re_parsed_signing_key, signing_key_secp256k1); + + let signing_key_secp256r1 = SigningKey::new_secp256r1(); + let re_parsed_signing_key = SigningKey::from_algorithm_and_bytes( + signing_key_secp256r1.algorithm(), + &signing_key_secp256r1.to_bytes(), + ) + .unwrap(); + assert_eq!(re_parsed_signing_key, signing_key_secp256r1); + } + + #[test] + fn test_reparsed_signatures_are_equal_to_original() { + let message = b"test message"; + + let signature_ed25519 = SigningKey::new_ed25519().sign(message); + let re_parsed_signature = Signature::from_algorithm_and_bytes( + signature_ed25519.algorithm(), + &signature_ed25519.to_bytes(), + ) + .unwrap(); + assert_eq!(re_parsed_signature, signature_ed25519); + + let signature_secp256k1 = SigningKey::new_secp256k1().sign(message); + let re_parsed_signature = Signature::from_algorithm_and_bytes( + signature_secp256k1.algorithm(), + &signature_secp256k1.to_bytes(), + ) + .unwrap(); + assert_eq!(re_parsed_signature, signature_secp256k1); + + let signature_secp256r1 = SigningKey::new_secp256r1().sign(message); + let re_parsed_signature = Signature::from_algorithm_and_bytes( + signature_secp256r1.algorithm(), + &signature_secp256r1.to_bytes(), + ) + .unwrap(); + assert_eq!(re_parsed_signature, signature_secp256r1); + } + + #[test] + fn test_verifying_key_from_string_ed25519() { + let original_key: VerifyingKey = + SigningKey::Ed25519(Box::new(Ed25519SigningKey::new(OsRng))).into(); + let encoded = engine.encode(original_key.to_bytes()); + + let result = VerifyingKey::try_from(encoded); + assert!(result.is_ok()); + + let decoded_key = result.unwrap(); + assert_eq!(decoded_key.to_bytes(), original_key.to_bytes()); + } + + #[test] + fn test_verifying_key_from_string_secp256k1() { + let original_key: VerifyingKey = + SigningKey::Secp256k1(Secp256k1SigningKey::new(&mut OsRng)).into(); + let encoded = engine.encode(original_key.to_bytes()); + + let result = VerifyingKey::try_from(encoded); + assert!(result.is_ok()); + + let decoded_key = result.unwrap(); + assert_eq!(decoded_key.to_bytes(), original_key.to_bytes()); + } + + #[test] + fn test_verifying_key_from_string_invalid_length() { + let invalid_bytes: [u8; 31] = [1; 31]; + let encoded = engine.encode(invalid_bytes); + + let result = VerifyingKey::try_from(encoded); + assert!(result.is_err()); + } +} diff --git a/crates/keys/src/signatures.rs b/crates/keys/src/signatures.rs new file mode 100644 index 00000000..54ce3fc4 --- /dev/null +++ b/crates/keys/src/signatures.rs @@ -0,0 +1,70 @@ +use anyhow::{bail, Result}; +use ed25519_consensus::Signature as Ed25519Signature; +use p256::ecdsa::Signature as Secp256r1Signature; +use secp256k1::ecdsa::Signature as Secp256k1Signature; + +use prism_serde::CryptoPayload; +use serde::{Deserialize, Serialize}; +use std::{self}; + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, Default)] +#[serde(try_from = "CryptoPayload", into = "CryptoPayload")] +pub enum Signature { + Secp256k1(Secp256k1Signature), + Ed25519(Ed25519Signature), + Secp256r1(Secp256r1Signature), + #[default] + Placeholder, +} + +impl Signature { + pub fn to_bytes(&self) -> Vec { + match self { + Signature::Ed25519(sig) => sig.to_bytes().to_vec(), + Signature::Secp256k1(sig) => sig.serialize_der().to_vec(), + Signature::Secp256r1(sig) => sig.to_der().as_bytes().to_vec(), + Signature::Placeholder => vec![], + } + } + + pub fn from_algorithm_and_bytes(algorithm: &str, bytes: &[u8]) -> Result { + match algorithm { + "ed25519" => { + Ed25519Signature::try_from(bytes).map(Signature::Ed25519).map_err(|e| e.into()) + } + "secp256k1" => { + Secp256k1Signature::from_der(bytes).map(Signature::Secp256k1).map_err(|e| e.into()) + } + "secp256r1" => { + Secp256r1Signature::from_der(bytes).map(Signature::Secp256r1).map_err(|e| e.into()) + } + _ => bail!("Unexpected algorithm for Signature"), + } + } + + pub fn algorithm(&self) -> &'static str { + match self { + Signature::Ed25519(_) => "ed25519", + Signature::Secp256k1(_) => "secp256k1", + Signature::Secp256r1(_) => "secp256r1", + Signature::Placeholder => "placeholder", + } + } +} + +impl TryFrom for Signature { + type Error = anyhow::Error; + + fn try_from(value: CryptoPayload) -> std::result::Result { + Signature::from_algorithm_and_bytes(&value.algorithm, &value.bytes) + } +} + +impl From for CryptoPayload { + fn from(signature: Signature) -> Self { + CryptoPayload { + algorithm: signature.algorithm().to_string(), + bytes: signature.to_bytes(), + } + } +} diff --git a/crates/keys/src/signing_keys.rs b/crates/keys/src/signing_keys.rs new file mode 100644 index 00000000..5153ba3c --- /dev/null +++ b/crates/keys/src/signing_keys.rs @@ -0,0 +1,114 @@ +use anyhow::{bail, Result}; +use ed25519_consensus::SigningKey as Ed25519SigningKey; +use p256::ecdsa::{ + signature::DigestSigner, Signature as Secp256r1Signature, SigningKey as Secp256r1SigningKey, +}; +use rand::rngs::OsRng; +use secp256k1::{Message as Secp256k1Message, SecretKey as Secp256k1SigningKey, SECP256K1}; + +use sha2::Digest as _; + +use crate::{Signature, VerifyingKey}; +use prism_serde::CryptoPayload; + +#[derive(Clone, Debug)] +pub enum SigningKey { + Ed25519(Box), + Secp256k1(Secp256k1SigningKey), + Secp256r1(Secp256r1SigningKey), +} + +impl SigningKey { + pub fn new_ed25519() -> Self { + SigningKey::Ed25519(Box::new(Ed25519SigningKey::new(OsRng))) + } + + pub fn new_secp256k1() -> Self { + SigningKey::Secp256k1(Secp256k1SigningKey::new(&mut OsRng)) + } + + pub fn new_secp256r1() -> Self { + SigningKey::Secp256r1(Secp256r1SigningKey::random(&mut OsRng)) + } + + pub fn verifying_key(&self) -> VerifyingKey { + self.clone().into() + } + + pub fn to_bytes(&self) -> Vec { + match self { + SigningKey::Ed25519(sk) => sk.to_bytes().to_vec(), + SigningKey::Secp256k1(sk) => sk.secret_bytes().to_vec(), + SigningKey::Secp256r1(sk) => sk.to_bytes().to_vec(), + } + } + + pub fn from_algorithm_and_bytes(algorithm: &str, bytes: &[u8]) -> Result { + match algorithm { + "ed25519" => Ed25519SigningKey::try_from(bytes) + .map(|sk| SigningKey::Ed25519(Box::new(sk))) + .map_err(|e| e.into()), + "secp256k1" => Secp256k1SigningKey::from_slice(bytes) + .map(SigningKey::Secp256k1) + .map_err(|e| e.into()), + "secp256r1" => Secp256r1SigningKey::from_slice(bytes) + .map(SigningKey::Secp256r1) + .map_err(|e| e.into()), + _ => bail!("Unexpected algorithm for VerifyingKey"), + } + } + + pub fn algorithm(&self) -> &'static str { + match self { + SigningKey::Ed25519(_) => "ed25519", + SigningKey::Secp256k1(_) => "secp256k1", + SigningKey::Secp256r1(_) => "secp256r1", + } + } + + pub fn sign(&self, message: &[u8]) -> Signature { + match self { + SigningKey::Ed25519(sk) => Signature::Ed25519(sk.sign(message)), + SigningKey::Secp256k1(sk) => { + let digest = sha2::Sha256::digest(message); + let message = Secp256k1Message::from_digest(digest.into()); + let signature = SECP256K1.sign_ecdsa(&message, sk); + Signature::Secp256k1(signature) + } + SigningKey::Secp256r1(sk) => { + let mut digest = sha2::Sha256::new(); + digest.update(message); + let sig: Secp256r1Signature = sk.sign_digest(digest); + Signature::Secp256r1(sig) + } + } + } +} + +impl PartialEq for SigningKey { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (SigningKey::Ed25519(a), SigningKey::Ed25519(b)) => a.as_bytes() == b.as_bytes(), + (SigningKey::Secp256k1(a), SigningKey::Secp256k1(b)) => a == b, + (SigningKey::Secp256r1(a), SigningKey::Secp256r1(b)) => a == b, + _ => false, + } + } +} + +impl TryFrom for SigningKey { + type Error = anyhow::Error; + + fn try_from(value: CryptoPayload) -> std::result::Result { + SigningKey::from_algorithm_and_bytes(&value.algorithm, &value.bytes) + } +} + +impl From for CryptoPayload { + fn from(signing_key: SigningKey) -> Self { + CryptoPayload { + algorithm: signing_key.algorithm().to_string(), + bytes: signing_key.to_bytes(), + } + } +} diff --git a/crates/keys/src/verifying_keys.rs b/crates/keys/src/verifying_keys.rs new file mode 100644 index 00000000..d53399fd --- /dev/null +++ b/crates/keys/src/verifying_keys.rs @@ -0,0 +1,228 @@ +use anyhow::{anyhow, bail, Result}; +use base64::{engine::general_purpose::STANDARD as engine, Engine as _}; +use ed25519_consensus::{SigningKey as Ed25519SigningKey, VerificationKey as Ed25519VerifyingKey}; +use p256::ecdsa::{ + signature::DigestVerifier, SigningKey as Secp256r1SigningKey, + VerifyingKey as Secp256r1VerifyingKey, +}; +use secp256k1::{ + Message as Secp256k1Message, PublicKey as Secp256k1VerifyingKey, + SecretKey as Secp256k1SigningKey, SECP256K1, +}; + +use serde::{Deserialize, Serialize}; +use sha2::Digest as _; +use std::{ + self, + hash::{Hash, Hasher}, +}; + +use crate::{Signature, SigningKey}; +use prism_serde::CryptoPayload; + +#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)] +#[serde(try_from = "CryptoPayload", into = "CryptoPayload")] +/// Represents a public key. +pub enum VerifyingKey { + /// Bitcoin, Ethereum + Secp256k1(Secp256k1VerifyingKey), + /// Cosmos, OpenSSH, GnuPG + Ed25519(Ed25519VerifyingKey), + // TLS, X.509 PKI, Passkeys + Secp256r1(Secp256r1VerifyingKey), +} + +impl Hash for VerifyingKey { + fn hash(&self, state: &mut H) { + match self { + VerifyingKey::Ed25519(_) => { + state.write_u8(0); + self.to_bytes().hash(state); + } + VerifyingKey::Secp256k1(_) => { + state.write_u8(1); + self.to_bytes().hash(state); + } + VerifyingKey::Secp256r1(_) => { + state.write_u8(2); + self.to_bytes().hash(state); + } + } + } +} + +impl VerifyingKey { + /// Returns the byte representation of the public key. + pub fn to_bytes(&self) -> Vec { + match self { + VerifyingKey::Ed25519(vk) => vk.to_bytes().to_vec(), + VerifyingKey::Secp256k1(vk) => vk.serialize().to_vec(), + VerifyingKey::Secp256r1(vk) => vk.to_sec1_bytes().to_vec(), + } + } + + pub fn from_algorithm_and_bytes(algorithm: &str, bytes: &[u8]) -> Result { + match algorithm { + "ed25519" => Ed25519VerifyingKey::try_from(bytes) + .map(VerifyingKey::Ed25519) + .map_err(|e| e.into()), + "secp256k1" => Secp256k1VerifyingKey::from_slice(bytes) + .map(VerifyingKey::Secp256k1) + .map_err(|e| e.into()), + "secp256r1" => Secp256r1VerifyingKey::from_sec1_bytes(bytes) + .map(VerifyingKey::Secp256r1) + .map_err(|e| e.into()), + _ => bail!("Unexpected algorithm for VerifyingKey"), + } + } + + pub fn algorithm(&self) -> &'static str { + match self { + VerifyingKey::Ed25519(_) => "ed25519", + VerifyingKey::Secp256k1(_) => "secp256k1", + VerifyingKey::Secp256r1(_) => "secp256r1", + } + } + + pub fn verify_signature(&self, message: &[u8], signature: &Signature) -> Result<()> { + match self { + VerifyingKey::Ed25519(vk) => { + let Signature::Ed25519(signature) = signature else { + bail!("Invalid signature type"); + }; + + vk.verify(signature, message) + .map_err(|e| anyhow!("Failed to verify signature: {}", e)) + } + VerifyingKey::Secp256k1(vk) => { + let Signature::Secp256k1(signature) = signature else { + bail!("Invalid signature type"); + }; + + let digest = sha2::Sha256::digest(message); + let message = Secp256k1Message::from_digest(digest.into()); + vk.verify(SECP256K1, &message, signature) + .map_err(|e| anyhow!("Failed to verify signature: {}", e)) + } + VerifyingKey::Secp256r1(vk) => { + let Signature::Secp256r1(signature) = signature else { + bail!("Invalid signature type"); + }; + let mut digest = sha2::Sha256::new(); + digest.update(message); + + let der_sig = signature.to_der(); + vk.verify_digest(digest, &der_sig) + .map_err(|e| anyhow!("Failed to verify signature: {}", e)) + } + } + } +} + +impl TryFrom for VerifyingKey { + type Error = anyhow::Error; + + fn try_from(value: CryptoPayload) -> std::result::Result { + VerifyingKey::from_algorithm_and_bytes(&value.algorithm, &value.bytes) + } +} + +impl From for CryptoPayload { + fn from(signature: VerifyingKey) -> Self { + CryptoPayload { + algorithm: signature.algorithm().to_string(), + bytes: signature.to_bytes(), + } + } +} + +impl From for VerifyingKey { + fn from(vk: Ed25519VerifyingKey) -> Self { + VerifyingKey::Ed25519(vk) + } +} + +impl From for VerifyingKey { + fn from(vk: Secp256k1VerifyingKey) -> Self { + VerifyingKey::Secp256k1(vk) + } +} + +impl From for VerifyingKey { + fn from(vk: Secp256r1VerifyingKey) -> Self { + VerifyingKey::Secp256r1(vk) + } +} + +impl From for VerifyingKey { + fn from(sk: Ed25519SigningKey) -> Self { + VerifyingKey::Ed25519(sk.verification_key()) + } +} + +impl From for VerifyingKey { + fn from(sk: Secp256k1SigningKey) -> Self { + sk.public_key(SECP256K1).into() + } +} + +impl From for VerifyingKey { + fn from(sk: Secp256r1SigningKey) -> Self { + VerifyingKey::Secp256r1(sk.verifying_key().to_owned()) + } +} + +impl From for VerifyingKey { + fn from(sk: SigningKey) -> Self { + match sk { + SigningKey::Ed25519(sk) => (*sk).into(), + SigningKey::Secp256k1(sk) => sk.into(), + SigningKey::Secp256r1(sk) => sk.into(), + } + } +} + +impl TryFrom for VerifyingKey { + type Error = anyhow::Error; + + /// Attempts to create a `VerifyingKey` from a base64-encoded string. + /// + /// # Arguments + /// + /// * `s` - The base64-encoded string representation of the public key. + /// + /// Depending on the length of the input string, the function will attempt to + /// decode it and create a `VerifyingKey` instance. According to the specifications, + /// the input string should be either [32 bytes (Ed25519)](https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.5) or [33/65 bytes (Secp256k1)](https://www.secg.org/sec1-v2.pdf). + /// The secp256k1 key can be either compressed (33 bytes) or uncompressed (65 bytes). + /// + /// # Returns + /// + /// * `Ok(VerifyingKey)` if the conversion was successful. + /// * `Err` if the input is invalid or the conversion failed. + fn try_from(s: String) -> std::result::Result { + let bytes = + engine.decode(s).map_err(|e| anyhow!("Failed to decode base64 string: {}", e))?; + + match bytes.len() { + 32 => { + let vk = Ed25519VerifyingKey::try_from(bytes.as_slice()) + .map_err(|e| anyhow!("Invalid Ed25519 key: {}", e))?; + Ok(VerifyingKey::Ed25519(vk)) + } + 33 | 65 => { + let vk = Secp256k1VerifyingKey::from_slice(bytes.as_slice()) + .map_err(|e| anyhow!("Invalid Secp256k1 key: {}", e))?; + Ok(VerifyingKey::Secp256k1(vk)) + } + _ => Err(anyhow!("Invalid public key length")), + } + } +} + +impl std::fmt::Display for VerifyingKey { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + let encoded = engine.encode(self.to_bytes()); + write!(f, "{}", encoded) + } +} diff --git a/crates/node_types/lightclient/Cargo.toml b/crates/node_types/lightclient/Cargo.toml index 73dcafc6..e1cecfd8 100644 --- a/crates/node_types/lightclient/Cargo.toml +++ b/crates/node_types/lightclient/Cargo.toml @@ -13,23 +13,11 @@ test_utils = [] mock_prover = [] [dependencies] -async-trait = { workspace = true } -serde = { workspace = true } -serde_json = { workspace = true } ed25519-consensus = { workspace = true } -base64 = { workspace = true } tokio = { workspace = true } -bincode = { workspace = true } -bls12_381 = { workspace = true } -hex = { workspace = true } log = { workspace = true } -toml = { workspace = true } -dirs = { workspace = true } anyhow = { workspace = true } -jmt = { workspace = true } -auto_impl = { workspace = true } prism-common = { workspace = true, features = ["test_utils"] } prism-errors = { workspace = true } prism-da = { workspace = true } sp1-sdk = { workspace = true } -rand = { workspace = true } diff --git a/crates/node_types/prover/Cargo.toml b/crates/node_types/prover/Cargo.toml index a0855efc..f2cc323f 100644 --- a/crates/node_types/prover/Cargo.toml +++ b/crates/node_types/prover/Cargo.toml @@ -17,28 +17,16 @@ axum = { workspace = true } tower-http = { workspace = true } utoipa = { workspace = true } utoipa-swagger-ui = { workspace = true } -async-trait = { workspace = true } serde = { workspace = true } -serde_json = { workspace = true } -redis = { workspace = true } ed25519-consensus = { workspace = true } -base64 = { workspace = true } tokio = { workspace = true } -bincode = { workspace = true } -bls12_381 = { workspace = true } -hex = { workspace = true } log = { workspace = true } -indexed-merkle-tree = { workspace = true } -dotenvy = { workspace = true } keystore-rs = { workspace = true } -toml = { workspace = true } -dirs = { workspace = true } anyhow = { workspace = true } jmt = { workspace = true } -auto_impl = { workspace = true } prism-common = { workspace = true, features = ["test_utils"] } prism-storage = { workspace = true } prism-errors = { workspace = true } +prism-keys = { workspace = true } prism-da = { workspace = true } sp1-sdk = { workspace = true } -rand = { workspace = true } diff --git a/crates/node_types/prover/src/prover/tests.rs b/crates/node_types/prover/src/prover/tests.rs index 544e4b76..61560dbe 100644 --- a/crates/node_types/prover/src/prover/tests.rs +++ b/crates/node_types/prover/src/prover/tests.rs @@ -1,9 +1,9 @@ use super::*; -use prism_common::{keys::VerifyingKey, transaction_builder::TransactionBuilder, tree::Proof}; +use prism_common::{transaction_builder::TransactionBuilder, tree::Proof}; +use prism_keys::{SigningKey, VerifyingKey}; use std::{self, sync::Arc, time::Duration}; use tokio::spawn; -use prism_common::test_utils::create_mock_signing_key; use prism_da::memory::InMemoryDataAvailabilityLayer; use prism_storage::{inmemory::InMemoryDatabase, Database}; @@ -63,7 +63,7 @@ async fn test_process_transactions() { let proof = prover.process_transaction(create_account_transaction.clone()).await.unwrap(); assert!(matches!(proof, Proof::Insert(_))); - let new_key = create_mock_signing_key(); + let new_key = SigningKey::new_ed25519(); let add_key_transaction = transaction_builder .add_key_verified_with_root("test_account", new_key.clone().into()) .commit(); @@ -91,7 +91,7 @@ async fn test_execute_block_with_invalid_tx() { let mut tx_builder = TransactionBuilder::new(); - let new_key_1 = create_mock_signing_key(); + let new_key_1 = SigningKey::new_ed25519(); let new_key_vk: VerifyingKey = new_key_1.clone().into(); let transactions = vec![ diff --git a/crates/node_types/prover/src/webserver.rs b/crates/node_types/prover/src/webserver.rs index 32e34abc..59444e48 100644 --- a/crates/node_types/prover/src/webserver.rs +++ b/crates/node_types/prover/src/webserver.rs @@ -7,16 +7,13 @@ use axum::{ routing::{get, post}, Json, Router, }; -use indexed_merkle_tree::{ - tree::{Proof, UpdateProof}, - Hash as TreeHash, -}; use jmt::proof::SparseMerkleProof; use prism_common::{ + digest::Digest, hashchain::{Hashchain, HashchainEntry}, hasher::Hasher, transaction::Transaction, - tree::HashchainResponse, + tree::{HashchainResponse, Proof, UpdateProof}, }; use serde::{Deserialize, Serialize}; use std::{self, sync::Arc}; @@ -64,7 +61,7 @@ pub struct TransactionRequest { pub struct UpdateProofResponse(UpdateProof); #[derive(Serialize, Deserialize, ToSchema)] -pub struct Hash(TreeHash); +pub struct Hash(Digest); #[derive(Serialize, Deserialize, ToSchema)] pub struct UserKeyRequest { diff --git a/crates/serde/Cargo.toml b/crates/serde/Cargo.toml new file mode 100644 index 00000000..3a1ae061 --- /dev/null +++ b/crates/serde/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "prism-serde" +version.workspace = true +edition.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +# serde +base64.workspace = true +serde.workspace = true +hex.workspace = true diff --git a/crates/common/src/serde.rs b/crates/serde/src/lib.rs similarity index 99% rename from crates/common/src/serde.rs rename to crates/serde/src/lib.rs index dfd21c19..43113b92 100644 --- a/crates/common/src/serde.rs +++ b/crates/serde/src/lib.rs @@ -1,3 +1,4 @@ +#![allow(dead_code)] use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] diff --git a/crates/storage/Cargo.toml b/crates/storage/Cargo.toml index fd0beb15..1ebd9133 100644 --- a/crates/storage/Cargo.toml +++ b/crates/storage/Cargo.toml @@ -13,7 +13,6 @@ readme.workspace = true [dependencies] serde = { workspace = true } redis = { workspace = true } -mockall = { workspace = true } log = { workspace = true } anyhow = { workspace = true } bincode = { workspace = true } @@ -22,8 +21,4 @@ jmt = { workspace = true } prism-errors = { workspace = true } prism-common = { workspace = true } auto_impl = { workspace = true } -rocksdb = { workspace = true } - - -[dev-dependencies] -tempfile = "3" +# rocksdb = { workspace = true } diff --git a/crates/storage/src/redis.rs b/crates/storage/src/redis.rs index b2fd9c0b..6cf32a55 100644 --- a/crates/storage/src/redis.rs +++ b/crates/storage/src/redis.rs @@ -3,7 +3,6 @@ use jmt::{ storage::{LeafNode, Node, NodeBatch, NodeKey, TreeReader, TreeWriter}, KeyHash, OwnedValue, Version, }; -use mockall::predicate::*; use prism_common::digest::Digest; use redis::{Client, Commands, Connection}; use serde::{Deserialize, Serialize}; diff --git a/crates/storage/src/rocksdb.rs b/crates/storage/src/rocksdb.rs index ec0d7946..22f458a1 100644 --- a/crates/storage/src/rocksdb.rs +++ b/crates/storage/src/rocksdb.rs @@ -1,158 +1,158 @@ -use crate::Database; -use anyhow::Result; -use jmt::{ - storage::{LeafNode, Node, NodeBatch, NodeKey, TreeReader, TreeWriter}, - KeyHash, OwnedValue, Version, -}; -use prism_common::digest::Digest; -use prism_errors::DatabaseError; -use rocksdb::{DBWithThreadMode, MultiThreaded, Options, DB}; - -type RocksDB = DBWithThreadMode; - -pub struct RocksDBConnection { - connection: RocksDB, - path: String, -} - -impl RocksDBConnection { - pub fn new(path: &str) -> Result { - let db = DB::open_default(path)?; - - Ok(Self { - connection: db, - path: path.to_string(), - }) - } -} - -impl Database for RocksDBConnection { - fn get_commitment(&self, epoch: &u64) -> anyhow::Result { - let key = format!("commitments:epoch_{}", epoch); - let raw_bytes = self.connection.get(key.as_bytes())?.ok_or_else(|| { - DatabaseError::NotFoundError(format!("commitment from epoch_{}", epoch)) - })?; - - let value: [u8; 32] = - raw_bytes.try_into().expect("commitment digest should always be 32 bytes"); - - Ok(Digest(value)) - } - - fn set_commitment(&self, epoch: &u64, commitment: &Digest) -> anyhow::Result<()> { - Ok(self.connection.put::<&[u8], [u8; 32]>( - format!("commitments:epoch_{}", epoch).as_bytes(), - commitment.0, - )?) - } - - fn get_last_synced_height(&self) -> anyhow::Result { - let res = self - .connection - .get(b"app_state:sync_height")? - .ok_or_else(|| DatabaseError::NotFoundError("current sync height".to_string()))?; - - Ok(u64::from_be_bytes(res.try_into().unwrap())) - } - - fn set_last_synced_height(&self, height: &u64) -> anyhow::Result<()> { - Ok(self.connection.put(b"app_state:sync_height", height.to_be_bytes())?) - } - - fn get_epoch(&self) -> anyhow::Result { - let res = self - .connection - .get(b"app_state:epoch")? - .ok_or_else(|| DatabaseError::NotFoundError("current epoch".to_string()))?; - - Ok(u64::from_be_bytes(res.try_into().unwrap())) - } - - fn set_epoch(&self, epoch: &u64) -> anyhow::Result<()> { - Ok(self.connection.put(b"app_state:epoch", epoch.to_be_bytes())?) - } - - fn flush_database(&self) -> Result<()> { - Ok(DB::destroy(&Options::default(), &self.path)?) - } -} - -impl TreeWriter for RocksDBConnection { - fn write_node_batch(&self, _node_batch: &NodeBatch) -> Result<()> { - todo!() - } -} - -impl TreeReader for RocksDBConnection { - fn get_node_option(&self, _node_key: &NodeKey) -> Result> { - todo!() - } - - fn get_value_option( - &self, - _max_version: Version, - _key_hash: KeyHash, - ) -> Result> { - todo!() - } - - fn get_rightmost_leaf(&self) -> Result> { - todo!() - } -} - -#[cfg(test)] -mod tests { - use super::*; - use tempfile::TempDir; - - #[test] - fn test_get_commitment() { - let temp_dir = TempDir::new().unwrap(); - let db = RocksDBConnection::new(temp_dir.path().to_str().unwrap()).unwrap(); - - let epoch = 1; - let commitment = Digest::from([0u8; 32]); - db.set_commitment(&epoch, &commitment).unwrap(); - - let result = db.get_commitment(&epoch).unwrap(); - assert_eq!(result, commitment); - } - - #[test] - fn test_set_commitment() { - let temp_dir = TempDir::new().unwrap(); - let db = RocksDBConnection::new(temp_dir.path().to_str().unwrap()).unwrap(); - - let epoch = 1; - let commitment = Digest::from([0u8; 32]); - db.set_commitment(&epoch, &commitment).unwrap(); - - let result = db.get_commitment(&epoch).unwrap(); - assert_eq!(result, commitment); - } - - #[test] - fn test_get_epoch() { - let temp_dir = TempDir::new().unwrap(); - let db = RocksDBConnection::new(temp_dir.path().to_str().unwrap()).unwrap(); - - let epoch = 1; - db.set_epoch(&epoch).unwrap(); - - let result = db.get_epoch().unwrap(); - assert_eq!(result, epoch); - } - - #[test] - fn test_set_epoch() { - let temp_dir = TempDir::new().unwrap(); - let db = RocksDBConnection::new(temp_dir.path().to_str().unwrap()).unwrap(); - - let epoch = 1; - db.set_epoch(&epoch).unwrap(); - - let result = db.get_epoch().unwrap(); - assert_eq!(result, epoch); - } -} +// use crate::Database; +// use anyhow::Result; +// use jmt::{ +// storage::{LeafNode, Node, NodeBatch, NodeKey, TreeReader, TreeWriter}, +// KeyHash, OwnedValue, Version, +// }; +// use prism_common::digest::Digest; +// use prism_errors::DatabaseError; +// use rocksdb::{DBWithThreadMode, MultiThreaded, Options, DB}; + +// type RocksDB = DBWithThreadMode; + +// pub struct RocksDBConnection { +// connection: RocksDB, +// path: String, +// } + +// impl RocksDBConnection { +// pub fn new(path: &str) -> Result { +// let db = DB::open_default(path)?; + +// Ok(Self { +// connection: db, +// path: path.to_string(), +// }) +// } +// } + +// impl Database for RocksDBConnection { +// fn get_commitment(&self, epoch: &u64) -> anyhow::Result { +// let key = format!("commitments:epoch_{}", epoch); +// let raw_bytes = self.connection.get(key.as_bytes())?.ok_or_else(|| { +// DatabaseError::NotFoundError(format!("commitment from epoch_{}", epoch)) +// })?; + +// let value: [u8; 32] = +// raw_bytes.try_into().expect("commitment digest should always be 32 bytes"); + +// Ok(Digest(value)) +// } + +// fn set_commitment(&self, epoch: &u64, commitment: &Digest) -> anyhow::Result<()> { +// Ok(self.connection.put::<&[u8], [u8; 32]>( +// format!("commitments:epoch_{}", epoch).as_bytes(), +// commitment.0, +// )?) +// } + +// fn get_last_synced_height(&self) -> anyhow::Result { +// let res = self +// .connection +// .get(b"app_state:sync_height")? +// .ok_or_else(|| DatabaseError::NotFoundError("current sync height".to_string()))?; + +// Ok(u64::from_be_bytes(res.try_into().unwrap())) +// } + +// fn set_last_synced_height(&self, height: &u64) -> anyhow::Result<()> { +// Ok(self.connection.put(b"app_state:sync_height", height.to_be_bytes())?) +// } + +// fn get_epoch(&self) -> anyhow::Result { +// let res = self +// .connection +// .get(b"app_state:epoch")? +// .ok_or_else(|| DatabaseError::NotFoundError("current epoch".to_string()))?; + +// Ok(u64::from_be_bytes(res.try_into().unwrap())) +// } + +// fn set_epoch(&self, epoch: &u64) -> anyhow::Result<()> { +// Ok(self.connection.put(b"app_state:epoch", epoch.to_be_bytes())?) +// } + +// fn flush_database(&self) -> Result<()> { +// Ok(DB::destroy(&Options::default(), &self.path)?) +// } +// } + +// impl TreeWriter for RocksDBConnection { +// fn write_node_batch(&self, _node_batch: &NodeBatch) -> Result<()> { +// todo!() +// } +// } + +// impl TreeReader for RocksDBConnection { +// fn get_node_option(&self, _node_key: &NodeKey) -> Result> { +// todo!() +// } + +// fn get_value_option( +// &self, +// _max_version: Version, +// _key_hash: KeyHash, +// ) -> Result> { +// todo!() +// } + +// fn get_rightmost_leaf(&self) -> Result> { +// todo!() +// } +// } + +// #[cfg(test)] +// mod tests { +// use super::*; +// use tempfile::TempDir; + +// #[test] +// fn test_get_commitment() { +// let temp_dir = TempDir::new().unwrap(); +// let db = RocksDBConnection::new(temp_dir.path().to_str().unwrap()).unwrap(); + +// let epoch = 1; +// let commitment = Digest::from([0u8; 32]); +// db.set_commitment(&epoch, &commitment).unwrap(); + +// let result = db.get_commitment(&epoch).unwrap(); +// assert_eq!(result, commitment); +// } + +// #[test] +// fn test_set_commitment() { +// let temp_dir = TempDir::new().unwrap(); +// let db = RocksDBConnection::new(temp_dir.path().to_str().unwrap()).unwrap(); + +// let epoch = 1; +// let commitment = Digest::from([0u8; 32]); +// db.set_commitment(&epoch, &commitment).unwrap(); + +// let result = db.get_commitment(&epoch).unwrap(); +// assert_eq!(result, commitment); +// } + +// #[test] +// fn test_get_epoch() { +// let temp_dir = TempDir::new().unwrap(); +// let db = RocksDBConnection::new(temp_dir.path().to_str().unwrap()).unwrap(); + +// let epoch = 1; +// db.set_epoch(&epoch).unwrap(); + +// let result = db.get_epoch().unwrap(); +// assert_eq!(result, epoch); +// } + +// #[test] +// fn test_set_epoch() { +// let temp_dir = TempDir::new().unwrap(); +// let db = RocksDBConnection::new(temp_dir.path().to_str().unwrap()).unwrap(); + +// let epoch = 1; +// db.set_epoch(&epoch).unwrap(); + +// let result = db.get_epoch().unwrap(); +// assert_eq!(result, epoch); +// } +// } diff --git a/crates/tests/Cargo.toml b/crates/tests/Cargo.toml index 4d88f506..19030551 100644 --- a/crates/tests/Cargo.toml +++ b/crates/tests/Cargo.toml @@ -17,18 +17,11 @@ mock_prover = [] log = { workspace = true } pretty_env_logger = { workspace = true } anyhow = { workspace = true } -jmt = { workspace = true } keystore-rs = { workspace = true } prism-common = { workspace = true, features = ["test_utils"] } prism-storage = { workspace = true } -prism-errors = { workspace = true } prism-prover = { workspace = true, features = ["mock_prover"] } prism-lightclient = { workspace = true } prism-da = { workspace = true } rand = { workspace = true } tokio = { workspace = true } - -[[test]] -name = "integration_tests" -path = "src/lib.rs" -harness = true diff --git a/crates/zk/groth16/Cargo.toml b/crates/zk/groth16/Cargo.toml index f511a5a2..d6f9dce7 100644 --- a/crates/zk/groth16/Cargo.toml +++ b/crates/zk/groth16/Cargo.toml @@ -7,13 +7,13 @@ homepage.workspace = true repository.workspace = true [dependencies] -bellman = { workspace = true } -bls12_381 = { workspace = true } -rand = { workspace = true } -hex = { workspace = true } -ff = { workspace = true } -log = { workspace = true } -indexed-merkle-tree = { workspace = true } -anyhow = { workspace = true } -prism-common = { workspace = true } -prism-errors = { workspace = true } +# bellman = { workspace = true } +# bls12_381 = { workspace = true } +# rand = { workspace = true } +# hex = { workspace = true } +# ff = { workspace = true } +# log = { workspace = true } +# indexed-merkle-tree = { workspace = true } +# anyhow = { workspace = true } +# prism-common = { workspace = true } +# prism-errors = { workspace = true } diff --git a/crates/zk/nova/Cargo.toml b/crates/zk/nova/Cargo.toml index bc71331c..e7b09ec8 100644 --- a/crates/zk/nova/Cargo.toml +++ b/crates/zk/nova/Cargo.toml @@ -7,15 +7,15 @@ homepage.workspace = true repository.workspace = true [dependencies] -num = { workspace = true } -rand = { workspace = true } -ff = { workspace = true } -thiserror = { workspace = true } -celestia-types = { workspace = true } -anyhow = { workspace = true } -jmt = { workspace = true } -bellpepper-core = { workspace = true } -bellpepper = { workspace = true } -arecibo = { workspace = true } -itertools = { workspace = true } -prism-common = { workspace = true, features = ["test_utils"] } +# num = { workspace = true } +# rand = { workspace = true } +# ff = { workspace = true } +# thiserror = { workspace = true } +# celestia-types = { workspace = true } +# anyhow = { workspace = true } +# jmt = { workspace = true } +# bellpepper-core = { workspace = true } +# bellpepper = { workspace = true } +# arecibo = { workspace = true } +# itertools = { workspace = true } +# prism-common = { workspace = true, features = ["test_utils"] } diff --git a/elf/riscv32im-succinct-zkvm-elf b/elf/riscv32im-succinct-zkvm-elf index 8ec0b3fd..d440de0f 100755 Binary files a/elf/riscv32im-succinct-zkvm-elf and b/elf/riscv32im-succinct-zkvm-elf differ diff --git a/justfile b/justfile index 934de0d7..322cc7ce 100644 --- a/justfile +++ b/justfile @@ -65,7 +65,7 @@ integration-test: just celestia-up echo "Running integration tests..." - cargo test --release --test integration_tests --features mock_prover + cargo test -p prism-tests --lib --release --features mock_prover just celestia-down