diff --git a/Cargo.lock b/Cargo.lock index ea545d9bf..fe7d6986c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -269,7 +269,7 @@ dependencies = [ "rand 0.9.2", "safelog", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", "tor-async-utils", "tor-basic-utils", @@ -316,7 +316,7 @@ dependencies = [ "nom", "num-traits", "rusticata-macros", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", ] @@ -1040,9 +1040,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.52" +version = "1.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" dependencies = [ "find-msvc-tools", "jobserver", @@ -1181,9 +1181,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.54" +version = "4.5.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" +checksum = "a75ca66430e33a14957acc24c5077b503e7d374151b2b4b3a10c83b4ceb4be0e" dependencies = [ "clap_builder", "clap_derive", @@ -1191,9 +1191,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.54" +version = "4.5.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" +checksum = "793207c7fa6300a0608d1080b858e5fdbe713cdc1c8db9fb17777d8a13e63df0" dependencies = [ "anstream", "anstyle", @@ -1203,9 +1203,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.5.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -1560,7 +1560,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.54", + "clap 4.5.56", "criterion-plot 0.6.0", "itertools 0.13.0", "num-traits", @@ -1584,7 +1584,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.5.54", + "clap 4.5.56", "criterion-plot 0.8.1", "itertools 0.13.0", "num-traits", @@ -1830,7 +1830,7 @@ dependencies = [ "async-trait", "blake3", "bs58", - "clap 4.5.54", + "clap 4.5.56", "criterion 0.8.1", "crypto_api_chachapoly", "darkfi-sdk", @@ -1866,7 +1866,7 @@ dependencies = [ "socket2", "structopt", "structopt-toml", - "thiserror 2.0.17", + "thiserror 2.0.18", "tiny-keccak", "tinyjson", "toml 0.9.11+spec-1.1.0", @@ -1948,7 +1948,7 @@ dependencies = [ "sha2", "sled-overlay", "subtle", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -2000,7 +2000,7 @@ dependencies = [ "halo2_proofs", "rand 0.8.5", "smol", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", ] @@ -2015,7 +2015,7 @@ dependencies = [ "getrandom 0.2.17", "rand 0.8.5", "smol", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", "wasmparser 0.243.0", ] @@ -2036,7 +2036,7 @@ dependencies = [ "lazy_static", "rand 0.8.5", "smol", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", ] @@ -2783,7 +2783,7 @@ dependencies = [ "arrayvec", "hashx", "num-traits", - "thiserror 2.0.17", + "thiserror 2.0.18", "visibility", ] @@ -2917,21 +2917,20 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.26" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys 0.60.2", ] [[package]] name = "find-msvc-tools" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fixed-capacity-vec" @@ -3088,7 +3087,7 @@ dependencies = [ "libc", "pwd-grp", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", "walkdir", ] @@ -3129,7 +3128,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22b287767724e1657e53f0af6f8964b8e54494ddd2bfbfa05a6ccade2aa5aa47" dependencies = [ "fslock-arti-fork", - "thiserror 2.0.17", + "thiserror 2.0.18", "winapi", ] @@ -3137,7 +3136,7 @@ dependencies = [ name = "fu" version = "0.5.0" dependencies = [ - "clap 4.5.54", + "clap 4.5.56", "darkfi", "fud", "smol", @@ -3321,7 +3320,7 @@ dependencies = [ name = "genev" version = "0.5.0" dependencies = [ - "clap 4.5.54", + "clap 4.5.56", "darkfi", "darkfi-serial", "genevd", @@ -3604,7 +3603,7 @@ dependencies = [ "fixed-capacity-vec", "hex", "rand_core 0.9.5", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -3719,9 +3718,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.64" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -4164,9 +4163,9 @@ dependencies = [ [[package]] name = "liblzma-sys" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b9596486f6d60c3bbe644c0e1be1aa6ccc472ad630fe8927b456973d7cb736" +checksum = "9f2db66f3268487b5033077f266da6777d057949b8f93c8ad82e441df25e6186" dependencies = [ "cc", "libc", @@ -4175,9 +4174,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" @@ -4291,7 +4290,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb4bdc8b0ce69932332cf76d24af69c3a155242af95c226b2ab6c2e371ed1149" dependencies = [ - "thiserror 2.0.17", + "thiserror 2.0.18", "zerocopy", "zerocopy-derive", ] @@ -4506,9 +4505,12 @@ dependencies = [ [[package]] name = "notify-types" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d" +checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" +dependencies = [ + "bitflags 2.10.0", +] [[package]] name = "ntapi" @@ -4579,9 +4581,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num-derive" @@ -4832,9 +4834,9 @@ dependencies = [ [[package]] name = "openssl-src" -version = "300.5.4+3.5.4" +version = "300.5.5+3.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507b3792995dae9b0df8a1c1e3771e8418b7c2d9f0baeba32e6fe8b06c7cb72" +checksum = "3f1787d533e03597a7934fd0a765f0d28e94ecc5fb7789f8053b1e699a56f709" dependencies = [ "cc", ] @@ -5441,9 +5443,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.105" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -5620,7 +5622,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.17", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -5644,7 +5646,7 @@ dependencies = [ "rustls", "smol", "socket2", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", "web-time", ] @@ -5663,9 +5665,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] @@ -5802,9 +5804,9 @@ dependencies = [ [[package]] name = "rcgen" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ec0a99f2de91c3cddc84b37e7db80e4d96b743e05607f647eb236fc0455907f" +checksum = "10b99e0098aa4082912d4c649628623db6aba77335e4f4569ff5083a6448b32e" dependencies = [ "pem", "ring", @@ -5869,7 +5871,7 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.17", "libredox", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -6144,9 +6146,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ "web-time", "zeroize", @@ -6154,9 +6156,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.8" +version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ "ring", "rustls-pki-types", @@ -6208,7 +6210,7 @@ dependencies = [ "educe", "either", "fluid-let", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -6513,9 +6515,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a37d01603c37b5466f808de79f845c7116049b0579adb70a6b7d47c1fa3a952" +checksum = "3b57709da74f9ff9f4a27dce9526eec25ca8407c45a7887243b031a58935fb8e" dependencies = [ "libc", "signal-hook-registry", @@ -6578,9 +6580,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" [[package]] name = "skeptic" @@ -6653,7 +6655,7 @@ dependencies = [ "paste", "serde", "slotmap", - "thiserror 2.0.17", + "thiserror 2.0.18", "void", ] @@ -6682,9 +6684,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" dependencies = [ "libc", "windows-sys 0.60.2", @@ -7040,7 +7042,7 @@ dependencies = [ "smol", "structopt", "structopt-toml", - "thiserror 2.0.17", + "thiserror 2.0.18", "tinyjson", "toml 0.9.11+spec-1.1.0", "tracing", @@ -7102,11 +7104,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.18", ] [[package]] @@ -7122,9 +7124,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", @@ -7142,9 +7144,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.45" +version = "0.3.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd" +checksum = "9da98b7d9b7dad93488a84b8248efc35352b0b2657397d4167e7ad67e5d535e5" dependencies = [ "deranged", "itoa", @@ -7157,15 +7159,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.25" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd" +checksum = "78cc610bac2dcee56805c99642447d4c5dbde4d01f752ffea0199aee1f601dc4" dependencies = [ "num-conv", "time-core", @@ -7335,7 +7337,7 @@ dependencies = [ "oneshot-fused-workaround", "pin-project", "postage", - "thiserror 2.0.17", + "thiserror 2.0.18", "void", ] @@ -7355,7 +7357,7 @@ dependencies = [ "serde", "slab", "smallvec", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -7370,7 +7372,7 @@ dependencies = [ "educe", "getrandom 0.3.4", "safelog", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-error", "tor-llcrypto", "zeroize", @@ -7393,7 +7395,7 @@ dependencies = [ "paste", "rand 0.9.2", "smallvec", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-basic-utils", "tor-bytes", "tor-cert", @@ -7417,7 +7419,7 @@ dependencies = [ "derive_builder_fork_arti", "derive_more 2.1.1", "digest", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-bytes", "tor-checkable", "tor-error", @@ -7441,7 +7443,7 @@ dependencies = [ "rand 0.9.2", "safelog", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-async-utils", "tor-basic-utils", "tor-cell", @@ -7468,7 +7470,7 @@ checksum = "7138faa6842243d206ccc7ec0c18f8c6c9dade20355d1ce39b57c77ab34fc68d" dependencies = [ "humantime", "signature", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-llcrypto", ] @@ -7497,7 +7499,7 @@ dependencies = [ "retry-error", "safelog", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-async-utils", "tor-basic-utils", "tor-cell", @@ -7545,7 +7547,7 @@ dependencies = [ "serde-value", "serde_ignored", "strum", - "thiserror 2.0.17", + "thiserror 2.0.18", "toml 0.9.11+spec-1.1.0", "tor-basic-utils", "tor-error", @@ -7563,7 +7565,7 @@ dependencies = [ "directories", "serde", "shellexpand", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-error", "tor-general-addr", ] @@ -7576,7 +7578,7 @@ checksum = "784995ce4d4a0309f204416fb66a7ed9e891705d6aef86f94577d768e3d5abf7" dependencies = [ "digest", "hex", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-llcrypto", ] @@ -7596,7 +7598,7 @@ dependencies = [ "httpdate", "itertools 0.14.0", "memchr", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-circmgr", "tor-error", "tor-hscrypto", @@ -7662,7 +7664,7 @@ dependencies = [ "signature", "static_assertions", "strum", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", "tor-async-utils", "tor-basic-utils", @@ -7696,7 +7698,7 @@ dependencies = [ "retry-error", "static_assertions", "strum", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", "void", ] @@ -7708,7 +7710,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dea60caf9dd38bfb87f0f534448123dbd2e14b6064eabb31e398a988dd67bda" dependencies = [ "derive_more 2.1.1", - "thiserror 2.0.17", + "thiserror 2.0.18", "void", ] @@ -7737,7 +7739,7 @@ dependencies = [ "safelog", "serde", "strum", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-async-utils", "tor-basic-utils", "tor-config", @@ -7775,7 +7777,7 @@ dependencies = [ "safelog", "slotmap-careful", "strum", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-async-utils", "tor-basic-utils", "tor-bytes", @@ -7819,7 +7821,7 @@ dependencies = [ "serde", "signature", "subtle", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-basic-utils", "tor-bytes", "tor-error", @@ -7863,7 +7865,7 @@ dependencies = [ "serde", "serde_with", "strum", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-async-utils", "tor-basic-utils", "tor-bytes", @@ -7903,7 +7905,7 @@ dependencies = [ "rsa", "signature", "ssh-key", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-bytes", "tor-cert", "tor-checkable", @@ -7935,7 +7937,7 @@ dependencies = [ "serde", "signature", "ssh-key", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-basic-utils", "tor-bytes", "tor-config", @@ -7969,7 +7971,7 @@ dependencies = [ "serde", "serde_with", "strum", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-basic-utils", "tor-bytes", "tor-config", @@ -8010,7 +8012,7 @@ dependencies = [ "sha3", "signature", "subtle", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-error", "tor-memquota", "visibility", @@ -8026,7 +8028,7 @@ checksum = "7df11f36560011e98b159dad0b5bb8a76ec6ff289e9a6119250ea3b4939be028" dependencies = [ "futures", "humantime", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-error", "tor-rtcompat", "tracing", @@ -8052,7 +8054,7 @@ dependencies = [ "slotmap-careful", "static_assertions", "sysinfo", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-async-utils", "tor-basic-utils", "tor-config", @@ -8081,7 +8083,7 @@ dependencies = [ "rand 0.9.2", "serde", "strum", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", "tor-basic-utils", "tor-error", @@ -8123,7 +8125,7 @@ dependencies = [ "smallvec", "strum", "subtle", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", "tinystr", "tor-basic-utils", @@ -8162,7 +8164,7 @@ dependencies = [ "sanitize-filename", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", "tor-async-utils", "tor-basic-utils", @@ -8209,7 +8211,7 @@ dependencies = [ "static_assertions", "subtle", "sync_wrapper", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-async-utils", "tor-basic-utils", "tor-bytes", @@ -8244,7 +8246,7 @@ dependencies = [ "caret", "paste", "serde_with", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-bytes", ] @@ -8304,7 +8306,7 @@ dependencies = [ "rustls-pki-types", "rustls-webpki", "socket2", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-error", "tor-general-addr", "tracing", @@ -8331,7 +8333,7 @@ dependencies = [ "priority-queue", "slotmap-careful", "strum", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-error", "tor-general-addr", "tor-rtcompat", @@ -8352,7 +8354,7 @@ dependencies = [ "educe", "safelog", "subtle", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-bytes", "tor-error", ] @@ -8366,7 +8368,7 @@ dependencies = [ "derive-deftly", "derive_more 2.1.1", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", "tor-memquota", ] @@ -8388,7 +8390,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" dependencies = [ "crossbeam-channel", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", "tracing-subscriber", ] @@ -8482,9 +8484,9 @@ dependencies = [ [[package]] name = "typed-index-collections" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5318ee4ce62a4e948a33915574021a7a953d83e84fba6e25c72ffcfd7dad35ff" +checksum = "898160f1dfd383b4e92e17f0512a7d62f3c51c44937b23b6ffc3a1614a8eaccd" dependencies = [ "bincode", "serde", @@ -8625,9 +8627,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" dependencies = [ "js-sys", "wasm-bindgen", @@ -9572,7 +9574,7 @@ dependencies = [ "oid-registry", "ring", "rusticata-macros", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", ] @@ -9637,18 +9639,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.33" +version = "0.8.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" +checksum = "7456cf00f0685ad319c5b1693f291a650eaf345e941d082fc4e03df8a03996ac" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.33" +version = "0.8.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" +checksum = "1328722bbf2115db7e19d69ebcc15e795719e2d66b60827c6a69a117365e37a0" dependencies = [ "proc-macro2", "quote", @@ -9740,9 +9742,9 @@ dependencies = [ [[package]] name = "zmij" -version = "1.0.14" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd8f3f50b848df28f887acb68e41201b5aea6bc8a8dacc00fb40635ff9a72fea" +checksum = "1966f8ac2c1f76987d69a74d0e0f929241c10e78136434e3be70ff7f58f64214" [[package]] name = "zstd" diff --git a/bin/darkirc/Makefile b/bin/darkirc/Makefile index 85fa83c25..2d5d65ee8 100644 --- a/bin/darkirc/Makefile +++ b/bin/darkirc/Makefile @@ -15,7 +15,7 @@ RUST_TARGET = $(shell rustc -Vv | grep '^host: ' | cut -d' ' -f2) ZKAS = ../../zkas # zkas circuits -PROOFS_SRC = $(shell find proof -type f -name '*.zk') +PROOFS_SRC = $(shell find ../../src/event_graph -type f -name '*.zk') PROOFS_BIN = $(PROOFS_SRC:=.bin) SRC = \ diff --git a/bin/darkirc/proof/rlnv2-diff-signal.zk b/bin/darkirc/proof/rlnv2-diff-signal.zk deleted file mode 100644 index e84f1d823..000000000 --- a/bin/darkirc/proof/rlnv2-diff-signal.zk +++ /dev/null @@ -1,48 +0,0 @@ -k = 14; -field = "pallas"; - -constant "Rlnv2Diff_Signal" {} - -witness "Rlnv2Diff_Signal" { - Base identity_nullifier, - Base identity_trapdoor, - Base user_message_limit, - - # Inclusion proof, the leaf is the identity_commitment - SparseMerklePath path, - - # The message hash - Base x, - Base message_id, - - Base epoch, -} - -circuit "Rlnv2Diff_Signal" { - # Identity inclusion proof - identity_secret = poseidon_hash(identity_nullifier, identity_trapdoor); - identity_secret_hash = poseidon_hash(identity_secret, user_message_limit); - identity_commitment = poseidon_hash(identity_secret_hash); - root = sparse_merkle_root(identity_commitment, path, identity_commitment); - constrain_instance(root); - - # External nullifier is created from epoch and app identifier - app_id = witness_base(1000); - external_nullifier = poseidon_hash(epoch, app_id); - constrain_instance(external_nullifier); - - # Calculating internal nullifier - # a_0 = identity_secret_hash - a_0 = poseidon_hash(identity_nullifier, identity_trapdoor); - a_1 = poseidon_hash(a_0, external_nullifier, message_id); - x_a_1 = base_mul(x, a_1); - y = base_add(a_0, x_a_1); - constrain_instance(x); - constrain_instance(y); - - # Constrain message_id to be lower than actual message limit. - less_than_strict(message_id, user_message_limit); - - internal_nullifier = poseidon_hash(a_1); - constrain_instance(internal_nullifier); -} diff --git a/bin/darkirc/proof/rlnv2-diff-slash.zk b/bin/darkirc/proof/rlnv2-diff-slash.zk deleted file mode 100644 index 19bc0f192..000000000 --- a/bin/darkirc/proof/rlnv2-diff-slash.zk +++ /dev/null @@ -1,18 +0,0 @@ -k = 13; -field = "pallas"; - -constant "RlnSlash" {} - -witness "RlnSlash" { - Base secret_key, - MerklePath identity_path, - Uint32 identity_leaf_pos, -} - -circuit "RlnSlash" { - identity_derivation_path = witness_base(11); - - identity_commit = poseidon_hash(identity_derivation_path, secret_key); - root = merkle_root(identity_leaf_pos, identity_path, identity_commit); - constrain_instance(root); -} diff --git a/bin/darkirc/src/crypto/rln.rs b/bin/darkirc/src/crypto/rln.rs index 95db7118c..ab6fdabf6 100644 --- a/bin/darkirc/src/crypto/rln.rs +++ b/bin/darkirc/src/crypto/rln.rs @@ -35,17 +35,18 @@ use darkfi_serial::{async_trait, SerialDecodable, SerialEncodable}; use rand::{rngs::OsRng, CryptoRng, RngCore}; use tracing::info; -pub const RLN_APP_IDENTIFIER: pallas::Base = pallas::Base::from_raw([4242, 0, 0, 0]); pub const RLN_TRAPDOOR_DERIVATION_PATH: pallas::Base = pallas::Base::from_raw([4211, 0, 0, 0]); pub const RLN_NULLIFIER_DERIVATION_PATH: pallas::Base = pallas::Base::from_raw([4212, 0, 0, 0]); -/// RLN epoch genesis -pub const RLN_GENESIS: u64 = 1738688400; -/// RLN epoch length in seconds -pub const RLN_EPOCH_LEN: u64 = 600; // 10 min +/// RLN epoch genesis in millis +pub const RLN_GENESIS: u64 = 1_738_688_400_000; +/// RLN epoch length in millis +pub const RLN_EPOCH_LEN: u64 = 600_000; // 10 min -pub const RLN2_SIGNAL_ZKBIN: &[u8] = include_bytes!("../../proof/rlnv2-diff-signal.zk.bin"); -pub const RLN2_SLASH_ZKBIN: &[u8] = include_bytes!("../../proof/rlnv2-diff-slash.zk.bin"); +pub const RLN2_SIGNAL_ZKBIN: &[u8] = + include_bytes!("../../../../src/event_graph/proofs/rlnv2-diff-signal.zk.bin"); +pub const RLN2_SLASH_ZKBIN: &[u8] = + include_bytes!("../../../../src/event_graph/proofs/rlnv2-diff-slash.zk.bin"); /// TODO: this should be configurable pub const USER_MSG_LIMIT: u64 = 6; @@ -86,7 +87,7 @@ impl RlnIdentity { trapdoor: poseidon_hash([RLN_TRAPDOOR_DERIVATION_PATH, pallas::Base::random(&mut rng)]), user_message_limit: USER_MSG_LIMIT, message_id: 1, - last_epoch: closest_epoch(UNIX_EPOCH.elapsed().unwrap().as_secs()), + last_epoch: closest_epoch(UNIX_EPOCH.elapsed().unwrap().as_millis() as u64), } } @@ -97,44 +98,17 @@ impl RlnIdentity { poseidon_hash([identity_secret_hash]) } - // pub fn _create_register_proof( - // &self, - // event: &Event, - // identity_tree: &mut SmtMemoryFp, - // register_pk: &ProvingKey, - // ) -> Result { - // let witnesses = vec![ - // Witness::Base(Value::known(self.nullifier)), - // Witness::Base(Value::known(self.trapdoor)), - // Witness::Base(Value::known(pallas::Base::from(self.user_message_limit))), - // ]; - - // let public_inputs = vec![self.commitment(), pallas::Base::from(self.user_message_limit)]; - - // info!(target: "crypto::rln::create_register_proof", "[RLN] Creating register proof for event {}", event.header.id()); - // let register_zkbin = ZkBinary::decode(RLN2_REGISTER_ZKBIN)?; - // let register_circuit = ZkCircuit::new(witnesses, ®ister_zkbin); - - // let proof = - // Proof::create(®ister_pk, &[register_circuit], &public_inputs, &mut OsRng).unwrap(); - - // let leaf = vec![self.commitment()]; - // let leaf: Vec<_> = leaf.into_iter().map(|l| (l, l)).collect(); - // // TODO: Recipients should verify that identity doesn't exist already before insert. - // identity_tree.insert_batch(leaf.clone()).unwrap(); // leaf == pos - // Ok(proof) - // } - pub fn create_signal_proof( &self, event: &Event, identity_tree: &SmtMemoryFp, signal_pk: &ProvingKey, - ) -> Result<(Proof, Vec)> { + ) -> Result<(Proof, pallas::Base, pallas::Base, pallas::Base)> { // 1. Construct share + let rln_app_identifier = pallas::Base::from(1000); let epoch = pallas::Base::from(closest_epoch(event.header.timestamp)); let message_id = pallas::Base::from(self.message_id); - let external_nullifier = poseidon_hash([epoch, RLN_APP_IDENTIFIER]); + let external_nullifier = poseidon_hash([epoch, rln_app_identifier]); let a_0 = poseidon_hash([self.nullifier, self.trapdoor]); let a_1 = poseidon_hash([a_0, external_nullifier, message_id]); let x = hash_event(event); @@ -163,29 +137,10 @@ impl RlnIdentity { info!(target: "crypto::rln::create_signal_proof", "[RLN] Creating signal proof for event {}", event.header.id()); let signal_zkbin = ZkBinary::decode(RLN2_SIGNAL_ZKBIN, false)?; - let signal_circuit = ZkCircuit::new(witnesses, &signal_zkbin); + let signal_circuit = ZkCircuit::new(witnesses.clone(), &signal_zkbin); let proof = Proof::create(signal_pk, &[signal_circuit], &public_inputs, &mut OsRng)?; - // Ok((proof, vec![y, internal_nullifier])) - Ok((proof, public_inputs)) + Ok((proof, y, internal_nullifier, identity_root)) + // Ok((proof, public_inputs)) } } - -/// Recover a secret from given secret shares -#[allow(dead_code)] -pub fn sss_recover(shares: &[(pallas::Base, pallas::Base)]) -> pallas::Base { - let mut secret = pallas::Base::zero(); - for (j, share_j) in shares.iter().enumerate() { - let mut prod = pallas::Base::one(); - for (i, share_i) in shares.iter().enumerate() { - if i != j { - prod *= share_i.0 * (share_i.0 - share_j.0).invert().unwrap(); - } - } - - prod *= share_j.1; - secret += prod; - } - - secret -} diff --git a/bin/darkirc/src/irc/client.rs b/bin/darkirc/src/irc/client.rs index 6547d391b..733626701 100644 --- a/bin/darkirc/src/irc/client.rs +++ b/bin/darkirc/src/irc/client.rs @@ -29,14 +29,11 @@ use std::{ use darkfi::{ event_graph::{proto::EventPut, Event, NULL_ID}, system::Subscription, - zk::{empty_witnesses, Proof, ProvingKey, VerifyingKey, ZkCircuit}, + zk::{empty_witnesses, Proof, ProvingKey, ZkCircuit}, zkas::ZkBinary, Error, Result, }; -use darkfi_sdk::{ - crypto::util::FieldElemAsStr, - pasta::{pallas, Fp}, -}; +use darkfi_sdk::pasta::{pallas, Fp}; use darkfi_serial::{deserialize_async_partial, serialize_async}; use futures::FutureExt; use sled_overlay::sled; @@ -226,49 +223,17 @@ impl Client { rln_identity.message_id += 1; - let (proof, public_inputs) = match self.create_rln_signal_proof(&rln_identity, &event).await { + let (proof, y, internal_nullifier, identity_root) = match self.create_rln_signal_proof(&rln_identity, &event).await { Ok(v) => v, Err(e) => { // TODO: Send a message to the IRC client telling that sending went wrong error!("[IRC CLIENT] Failed creating RLN signal proof: {e}"); // Just use an empty "proof" - (Proof::new(vec![]), vec![]) + (Proof::new(vec![]), pallas::Base::from(0), pallas::Base::from(0), pallas::Base::from(0)) } }; - ///////// Temporary ///////// - let signal_zkbin = ZkBinary::decode(RLN2_SIGNAL_ZKBIN, false)?; - let signal_circuit = ZkCircuit::new(empty_witnesses(&signal_zkbin)?, &signal_zkbin); - let Some(signal_vk) = self.server.server_store.get("rlnv2-diff-signal-vk")? else { - return Err(Error::DatabaseError( - "RLN signal verifying key not found in server store".to_string(), - )) - }; - let mut reader = Cursor::new(signal_vk); - let signal_vk = VerifyingKey::read(&mut reader, signal_circuit)?; - - // let epoch = pallas::Base::from(closest_epoch(event.header.timestamp)); - // let external_nullifier = poseidon_hash([epoch, RLN_APP_IDENTIFIER]); - // let x = hash_event(&event); - // let y = public_inputs[0]; - // let internal_nullifier = public_inputs[1]; - - // // Fetch SMT root - // let identity_tree = self.server.rln_identity_tree.read().await; - // let identity_root = identity_tree.root(); - - // let public_inputs = - // vec![epoch, external_nullifier, x, y, internal_nullifier, identity_root]; - - // Ok(proof.verify(&self.server.rln_signal_vk, &public_inputs)? - - match proof.verify(&signal_vk, &public_inputs) { - Ok(_) => info!("it works"), - Err(e) => panic!("it doesn't work because {e}") - } - ///////////////////////////// - - let blob = serialize_async(&(proof, public_inputs)).await; + let blob = serialize_async(&(proof, y, internal_nullifier, identity_root)).await; self.server.darkirc.p2p.broadcast(&EventPut(event, blob)).await; } else { @@ -409,57 +374,9 @@ impl Client { continue } }; - - info!("multiplex commitment: {}",fetched_rln_commitment.to_string()); - let commitment = vec![fetched_rln_commitment]; let commitment: Vec<_> = commitment.into_iter().map(|l| (l, l)).collect(); identities_tree.insert_batch(commitment)?; - info!("multiplex root: {}",identities_tree.root().to_string()); - - // Mark the message as seen for this USER - if let Err(e) = self.mark_seen(&event_id).await { - error!("[IRC CLIENT] (multiplex_connection) self.mark_seen({event_id}) failed: {e}"); - return Err(e) - } - } - - // Process message from the network. These should only be RLN identities. - r = self.incoming_st.receive().fuse() => { - - // We will skip this if it's our own message. - let event_id = r.header.id(); - if *self.last_sent.read().await == event_id { - continue - } - - // If this event was seen, skip it - match self.is_seen(&event_id).await { - Ok(true) => continue, - Ok(false) => {}, - Err(e) => { - error!("[IRC CLIENT] (multiplex_connection) self.is_seen({}) failed: {}", event_id, e); - return Err(e) - } - } - - // Update SMT - let mut identities_tree = self.server.rln_identity_tree.write().await; - let fetched_rln_commitment: Fp = match deserialize_async_partial(r.content()).await - { - Ok((v, _)) => v, - Err(e) => { - error!(target: "irc::server", "[RLN] Failed deserializing incoming RLN Identity events: {}", e); - continue - } - }; - - info!("multiplex commitment: {}",fetched_rln_commitment.to_string()); - - let commitment = vec![fetched_rln_commitment]; - let commitment: Vec<_> = commitment.into_iter().map(|l| (l, l)).collect(); - identities_tree.insert_batch(commitment)?; - info!("multiplex root: {}",identities_tree.root().to_string()); // Mark the message as seen for this USER if let Err(e) = self.mark_seen(&event_id).await { @@ -666,45 +583,12 @@ impl Client { Ok(db.contains_key(event_id.as_bytes())?) } - /// Abstraction for RLN register proof creation - // async fn _create_rln_register_proof( - // &self, - // rln_identity: &RlnIdentity, - // event: &Event, - // ) -> Result { - // let mut identity_tree = self.server.rln_identity_tree.write().await; - - // // Retrieve the ZK proving key from the db - // let register_zkbin = ZkBinary::decode(RLN2_REGISTER_ZKBIN)?; - // let register_circuit = ZkCircuit::new(empty_witnesses(®ister_zkbin)?, ®ister_zkbin); - // let Some(register_pk) = self.server.server_store.get("rlnv2-diff-register-pk")? else { - // return Err(Error::DatabaseError( - // "RLN register proving key not found in server store".to_string(), - // )) - // }; - // let mut reader = Cursor::new(register_pk); - // let register_pk = ProvingKey::read(&mut reader, register_circuit)?; - - // rln_identity._create_register_proof(event, &mut identity_tree, ®ister_pk) - // } - - // /// Abstraction for RLN register proof verification - // async fn _verify_rln_register_proof( - // &self, - // _event: &Event, - // proof: Proof, - // public_inputs: [pallas::Base; 2], - // register_vk: VerifyingKey, - // ) -> Result<()> { - // Ok(proof.verify(®ister_vk, &public_inputs)?) - // } - /// Abstraction for RLN signal proof creation async fn create_rln_signal_proof( &self, rln_identity: &RlnIdentity, event: &Event, - ) -> Result<(Proof, Vec)> { + ) -> Result<(Proof, pallas::Base, pallas::Base, pallas::Base)> { let identity_tree = self.server.rln_identity_tree.read().await; // Retrieve the ZK proving key from the db @@ -720,32 +604,4 @@ impl Client { rln_identity.create_signal_proof(event, &identity_tree, &proving_key) } - - // /// Abstraction for RLN signal proof verification - // async fn _verify_rln_signal_proof( - // &self, - // event: &Event, - // proof: Proof, - // public_inputs: [pallas::Base; 2], - // ) -> Result<()> { - // let epoch = pallas::Base::from(closest_epoch(event.header.timestamp)); - // let external_nullifier = poseidon_hash([epoch, RLN_APP_IDENTIFIER]); - // let x = hash_event(event); - // let y = public_inputs[0]; - // let internal_nullifier = public_inputs[1]; - - // // Fetch the latest commitment Merkle tree - // let Some(identity_tree) = self.server.server_store.get("rln_identity_tree")? else { - // return Err(Error::DatabaseError( - // "RLN Identity tree not found in server store".to_string(), - // )) - // }; - // let identity_tree: MerkleTree = deserialize_async(&identity_tree).await?; - // let identity_root = identity_tree.root(0).unwrap(); - - // let public_inputs = - // vec![epoch, external_nullifier, x, y, internal_nullifier, identity_root.inner()]; - - // Ok(proof.verify(&self.server.rln_signal_vk, &public_inputs)?) - // } } diff --git a/bin/darkirc/src/irc/services/nickserv.rs b/bin/darkirc/src/irc/services/nickserv.rs index 6e1e3dcc4..663376116 100644 --- a/bin/darkirc/src/irc/services/nickserv.rs +++ b/bin/darkirc/src/irc/services/nickserv.rs @@ -206,12 +206,10 @@ impl NickServ { // Update SMT, DAG and broadcast let mut identities_tree = self.server.rln_identity_tree.write().await; let rln_commitment = new_rln_identity.commitment(); - // info!("register commitment: {}", rln_commitment.to_string()); let commitment = vec![rln_commitment]; let commitment: Vec<_> = commitment.into_iter().map(|l| (l, l)).collect(); identities_tree.insert_batch(commitment)?; - // info!("root: {}", identities_tree.root().to_string()); let evgr = &self.server.darkirc.event_graph; let event = Event::new_static(serialize_async(&rln_commitment).await, evgr).await; diff --git a/src/event_graph/event.rs b/src/event_graph/event.rs index 9b6b1cf57..83d92ad11 100644 --- a/src/event_graph/event.rs +++ b/src/event_graph/event.rs @@ -33,7 +33,7 @@ use super::{ pub struct Header { /// Event version // pub version: u8, - /// Timestamp of the event in whole seconds + /// Timestamp of the event in milliseconds pub timestamp: u64, /// Parent nodes in the event DAG pub parents: [blake3::Hash; N_EVENT_PARENTS], diff --git a/src/event_graph/proofs/rlnv2-diff-signal.zk b/src/event_graph/proofs/rlnv2-diff-signal.zk index e84f1d823..166930721 100644 --- a/src/event_graph/proofs/rlnv2-diff-signal.zk +++ b/src/event_graph/proofs/rlnv2-diff-signal.zk @@ -32,7 +32,7 @@ circuit "Rlnv2Diff_Signal" { constrain_instance(external_nullifier); # Calculating internal nullifier - # a_0 = identity_secret_hash + # a_0 = identity_secret a_0 = poseidon_hash(identity_nullifier, identity_trapdoor); a_1 = poseidon_hash(a_0, external_nullifier, message_id); x_a_1 = base_mul(x, a_1); diff --git a/src/event_graph/proofs/rlnv2-diff-slash.zk b/src/event_graph/proofs/rlnv2-diff-slash.zk new file mode 100644 index 000000000..74907d3a4 --- /dev/null +++ b/src/event_graph/proofs/rlnv2-diff-slash.zk @@ -0,0 +1,18 @@ +k = 14; +field = "pallas"; + +constant "Rlnv2Diff_Slash" {} + +witness "Rlnv2Diff_Slash" { + Base secret_key, + Base user_message_limit, + # Inclusion proof, the leaf is the identity_commitment + SparseMerklePath path, +} + +circuit "Rlnv2Diff_Slash" { + identity_secret_hash = poseidon_hash(secret_key, user_message_limit); + identity_commitment = poseidon_hash(identity_secret_hash); + root = sparse_merkle_root(identity_commitment, path, identity_commitment); + constrain_instance(root); +} diff --git a/src/event_graph/proto.rs b/src/event_graph/proto.rs index 9734c8450..4401d7b24 100644 --- a/src/event_graph/proto.rs +++ b/src/event_graph/proto.rs @@ -26,7 +26,7 @@ use std::{ }, }; -use darkfi_sdk::pasta::pallas; +use darkfi_sdk::{crypto::poseidon_hash, pasta::pallas}; use darkfi_serial::{ async_trait, deserialize_async, deserialize_async_partial, SerialDecodable, SerialEncodable, }; @@ -35,6 +35,7 @@ use tracing::{debug, error, info, trace, warn}; use super::{event::Header, Event, EventGraphPtr, LayerUTips, NULL_ID, NULL_PARENTS}; use crate::{ + event_graph::util::{closest_epoch, hash_event, sss_recover, MessageMetadata}, impl_p2p_message, net::{ metering::{MeteringConfiguration, DEFAULT_METERING_CONFIGURATION}, @@ -273,6 +274,8 @@ impl ProtocolEventGraph { async fn handle_event_put(self: Arc) -> Result<()> { // Rolling window of event timestamps on this channel let mut bantimes = MovingWindow::new(WINDOW_EXPIRY_TIME); + let mut metadata = MessageMetadata::new(); + let mut current_epoch = 0; loop { let (event, blob) = match self.ev_put_sub.receive().await { @@ -293,52 +296,67 @@ impl ProtocolEventGraph { continue } - //////////////////// let mut verification_failed = false; #[allow(clippy::never_loop)] loop { - let (proof, public_inputs): (Proof, Vec) = - match deserialize_async_partial(&blob).await { - Ok((v, _)) => v, - Err(e) => { - error!(target: "event_graph::protocol::handle_event_put()","[EVENTGRAPH] Failed deserializing event ephemeral data: {}", e); - break - } - }; + let (proof, y, internal_nullifier, identity_root): ( + Proof, + pallas::Base, + pallas::Base, + pallas::Base, + ) = match deserialize_async_partial(&blob).await { + Ok((v, _)) => v, + Err(e) => { + error!(target: "event_graph::protocol::handle_event_put()","[EVENTGRAPH] Failed deserializing event ephemeral data: {}", e); + break + } + }; - if public_inputs.len() != 2 { - error!(target: "event_graph::protocol::handle_event_put()", "[EVENTGRAPH] Received event has the wrong number of public inputs"); + // If the current epoch is different, we reset the stored shares + if current_epoch != closest_epoch(event.header.timestamp) { + metadata = MessageMetadata::new() + } + + let rln_app_identifier = pallas::Base::from(1000); + current_epoch = closest_epoch(event.header.timestamp); + let epoch = pallas::Base::from(current_epoch); + let external_nullifier = poseidon_hash([epoch, rln_app_identifier]); + let x = hash_event(&event); + let public_inputs = + vec![identity_root, external_nullifier, x, y, internal_nullifier]; + + metadata.add_share(external_nullifier, internal_nullifier, x, y)?; + + if metadata.is_duplicate(&external_nullifier, &internal_nullifier, &x, &y) { + error!("[Signal] Duplicate Message!"); verification_failed = true; break } - // info!("public_inputs: {:?}", public_inputs); + if metadata.is_reused(&external_nullifier, &internal_nullifier) { + let shares = metadata.get_shares(&external_nullifier, &internal_nullifier); + let _secret = sss_recover(&shares); + + // TODO: broadcast slashing event + // let evgr = &self.event_graph; + // let st_event = Event::new_static(serialize_async(&secret).await, evgr).await; + // evgr.static_insert(&st_event).await?; + // evgr.static_broadcast(st_event); + verification_failed = true; + break + } info!(target: "event_graph::protocol::handle_event_put()", "[EVENTGRAPH] Verifying incoming Event RLN proof"); - // let epoch = pallas::Base::from(closest_epoch(event.header.timestamp)); - // let external_nullifier = poseidon_hash([epoch, RLN_APP_IDENTIFIER]); - // let x = hash_event(event); - // let y = public_inputs[0]; - // let internal_nullifier = public_inputs[1]; - - // verification_failed = - // proof.verify(&self.event_graph.signal_vk, &public_inputs).is_err(); verification_failed = - match proof.verify(&self.event_graph.signal_vk, &public_inputs) { - Ok(()) => false, - Err(e) => { - error!("error: {e}"); - true - } - }; + proof.verify(&self.event_graph.signal_vk, &public_inputs).is_err(); + break } if verification_failed { - error!(target: "event_graph::protocol::handle_event_put()", "[EVENTGRAPH] Incoming Event proof verification failed"); + error!(target: "event_graph::protocol::handle_event_put()", "[EVENTGRAPH] Incoming Event RLN proof verification failed"); continue } - //////////////////// // If we have already seen the event, we'll stay quiet. let current_genesis = self.event_graph.current_genesis.read().await; diff --git a/src/event_graph/util.rs b/src/event_graph/util.rs index 15450fdf9..e0669edb2 100644 --- a/src/event_graph/util.rs +++ b/src/event_graph/util.rs @@ -17,12 +17,20 @@ */ use std::{ + collections::{BTreeMap, HashMap}, fs::{self, File, OpenOptions}, io::Write, path::Path, time::UNIX_EPOCH, }; +use darkfi_sdk::{crypto::pasta_prelude::FromUniformBytes, pasta::pallas}; +use darkfi_serial::{deserialize, deserialize_async, serialize}; +use halo2_proofs::arithmetic::Field; +use sled_overlay::sled; +use tinyjson::JsonValue; +use tracing::error; + use crate::{ event_graph::{Event, GENESIS_CONTENTS, INITIAL_GENESIS, NULL_ID, N_EVENT_PARENTS}, util::encoding::base64, @@ -30,23 +38,21 @@ use crate::{ }; #[cfg(feature = "rpc")] -use { - crate::{ - rpc::{ - jsonrpc::{ErrorCode, JsonError, JsonResponse, JsonResult}, - util::json_map, - }, - util::file::load_file, +use crate::{ + rpc::{ + jsonrpc::{ErrorCode, JsonError, JsonResponse, JsonResult}, + util::json_map, }, - darkfi_serial::{deserialize, deserialize_async, serialize}, - sled_overlay::sled, - std::collections::HashMap, - tinyjson::JsonValue, - tracing::error, + util::file::load_file, }; use super::event::Header; +/// RLN epoch genesis in millis +pub const RLN_GENESIS: u64 = 1_738_688_400_000; +/// RLN epoch length in millis +pub const RLN_EPOCH_LEN: u64 = 600_000; // 10 min + /// MilliSeconds in an hour pub(super) const HOUR: i64 = 3_600_000; @@ -203,6 +209,128 @@ pub async fn recreate_from_replayer_log(datastore: &Path) -> JsonResult { JsonResponse::new(result, 1).into() } +/// Hash message/event modulo `Fp` +pub fn hash_event(event: &Event) -> pallas::Base { + let mut buf = [0u8; 64]; + buf[..blake3::OUT_LEN].copy_from_slice(event.header.id().as_bytes()); + pallas::Base::from_uniform_bytes(&buf) +} + +/// Find closest epoch to given timestamp +pub fn closest_epoch(timestamp: u64) -> u64 { + let time_diff = timestamp - RLN_GENESIS; + let epoch_idx = time_diff as f64 / RLN_EPOCH_LEN as f64; + let rounded = epoch_idx.round() as i64; + RLN_GENESIS + (rounded * RLN_EPOCH_LEN as i64) as u64 +} + +#[derive(Debug, Clone)] +struct ShareData { + pub x_shares: Vec, + pub y_shares: Vec, +} + +impl ShareData { + fn new() -> Self { + Self { x_shares: vec![], y_shares: vec![] } + } +} + +#[derive(Debug, Default)] +pub struct MessageMetadata { + data: BTreeMap>, +} + +impl MessageMetadata { + pub fn new() -> Self { + Self { data: BTreeMap::new() } + } + + pub fn add_share( + &mut self, + external_nullifier: pallas::Base, + internal_nullifier: pallas::Base, + x: pallas::Base, + y: pallas::Base, + ) -> Result<()> { + let inner_map = self.data.entry(external_nullifier).or_insert_with(BTreeMap::new); + let share_data = inner_map.entry(internal_nullifier).or_insert_with(ShareData::new); + + share_data.x_shares.push(x); + share_data.y_shares.push(y); + + Ok(()) + } + + pub fn get_shares( + &self, + external_nullifier: &pallas::Base, + internal_nullifier: &pallas::Base, + ) -> Vec<(pallas::Base, pallas::Base)> { + if let Some(inner_map) = self.data.get(external_nullifier) { + if let Some(share_data) = inner_map.get(internal_nullifier) { + return share_data + .x_shares + .iter() + .cloned() + .zip(share_data.y_shares.iter().cloned()) + .collect() + } + } + + vec![] + } + + /// Check if the recieved message and its metadata are duplicated + pub fn is_duplicate( + &self, + external_nullifier: &pallas::Base, + internal_nullifier: &pallas::Base, + x: &pallas::Base, + y: &pallas::Base, + ) -> bool { + if let Some(inner_map) = self.data.get(external_nullifier) { + if let Some(share_data) = inner_map.get(internal_nullifier) { + return share_data.x_shares.contains(x) && share_data.y_shares.contains(y); + } + } + + false + } + + /// Check if the message has reused the nullifiers + pub fn is_reused( + &self, + external_nullifier: &pallas::Base, + internal_nullifier: &pallas::Base, + ) -> bool { + let inner_map = self.data.get(external_nullifier); + if inner_map.is_some() { + return inner_map.unwrap().get(internal_nullifier).is_some() + } + + false + } +} + +/// Recover secret using Shamir's secret sharing scheme +pub fn sss_recover(shares: &[(pallas::Base, pallas::Base)]) -> pallas::Base { + let mut secret = pallas::Base::zero(); + for (j, share_j) in shares.iter().enumerate() { + let mut prod = pallas::Base::one(); + for (i, share_i) in shares.iter().enumerate() { + if i != j { + prod *= share_i.0 * (share_i.0 - share_j.0).invert().unwrap(); + } + } + + prod *= share_j.1; + secret += prod; + } + + secret +} + #[cfg(test)] mod tests { use super::*;