diff --git a/Cargo.lock b/Cargo.lock index 9c063c6..6d5ba81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,31 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "aead" version = "0.5.2" @@ -44,6 +69,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", + "getrandom", "once_cell", "version_check 0.9.5", "zerocopy", @@ -58,12 +84,24 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" + [[package]] name = "anes" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + [[package]] name = "ark-bls12-377" version = "0.4.0" @@ -75,6 +113,18 @@ dependencies = [ "ark-std", ] +[[package]] +name = "ark-bls12-377-ext" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20c7021f180a0cbea0380eba97c2af3c57074cdaffe0eef7e840e1c9f2841e55" +dependencies = [ + "ark-bls12-377", + "ark-ec", + "ark-models-ext", + "ark-std", +] + [[package]] name = "ark-bls12-381" version = "0.4.0" @@ -87,6 +137,45 @@ dependencies = [ "ark-std", ] +[[package]] +name = "ark-bls12-381-ext" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1dc4b3d08f19e8ec06e949712f95b8361e43f1391d94f65e4234df03480631c" +dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-models-ext", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-bw6-761" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e0605daf0cc5aa2034b78d008aaf159f56901d92a52ee4f6ecdfdac4f426700" +dependencies = [ + "ark-bls12-377", + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-bw6-761-ext" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccee5fba47266f460067588ee1bf070a9c760bf2050c1c509982c5719aadb4f2" +dependencies = [ + "ark-bw6-761", + "ark-ec", + "ark-ff", + "ark-models-ext", + "ark-std", +] + [[package]] name = "ark-ec" version = "0.4.2" @@ -99,11 +188,37 @@ dependencies = [ "ark-std", "derivative", "hashbrown 0.13.2", - "itertools", + "itertools 0.10.5", "num-traits", + "rayon", "zeroize", ] +[[package]] +name = "ark-ed-on-bls12-377" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b10d901b9ac4b38f9c32beacedfadcdd64e46f8d7f8e88c1ae1060022cf6f6c6" +dependencies = [ + "ark-bls12-377", + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ed-on-bls12-377-ext" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524a4fb7540df2e1a8c2e67a83ba1d1e6c3947f4f9342cc2359fc2e789ad731d" +dependencies = [ + "ark-ec", + "ark-ed-on-bls12-377", + "ark-ff", + "ark-models-ext", + "ark-std", +] + [[package]] name = "ark-ed-on-bls12-381" version = "0.4.0" @@ -117,6 +232,31 @@ dependencies = [ "ark-std", ] +[[package]] +name = "ark-ed-on-bls12-381-bandersnatch" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9cde0f2aa063a2a5c28d39b47761aa102bda7c13c84fc118a61b87c7b2f785c" +dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ed-on-bls12-381-bandersnatch-ext" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d15185f1acb49a07ff8cbe5f11a1adc5a93b19e211e325d826ae98e98e124346" +dependencies = [ + "ark-ec", + "ark-ed-on-bls12-381-bandersnatch", + "ark-ff", + "ark-models-ext", + "ark-std", +] + [[package]] name = "ark-ff" version = "0.4.2" @@ -128,8 +268,8 @@ dependencies = [ "ark-serialize", "ark-std", "derivative", - "digest", - "itertools", + "digest 0.10.7", + "itertools 0.10.5", "num-bigint", "num-traits", "paste", @@ -160,6 +300,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ark-models-ext" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e9eab5d4b5ff2f228b763d38442adc9b084b0a465409b059fac5c2308835ec2" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", +] + [[package]] name = "ark-poly" version = "0.4.2" @@ -201,6 +354,35 @@ dependencies = [ "tracing", ] +[[package]] +name = "ark-scale" +version = "0.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f69c00b3b529be29528a6f2fd5fa7b1790f8bed81b9cdca17e326538545a179" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", + "parity-scale-codec", + "scale-info", +] + +[[package]] +name = "ark-secret-scalar" +version = "0.0.2" +source = "git+https://github.com/w3f/ring-vrf?rev=e9782f9#e9782f938629c90f3adb3fff2358bc8d1386af3e" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", + "ark-transcript 0.0.2 (git+https://github.com/w3f/ring-vrf?rev=e9782f9)", + "digest 0.10.7", + "getrandom_or_panic", + "zeroize", +] + [[package]] name = "ark-serialize" version = "0.4.2" @@ -209,7 +391,7 @@ checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ "ark-serialize-derive", "ark-std", - "digest", + "digest 0.10.7", "num-bigint", ] @@ -232,6 +414,34 @@ checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", "rand", + "rayon", +] + +[[package]] +name = "ark-transcript" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "563084372d89271122bd743ef0a608179726f5fad0566008ba55bd0f756489b8" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "digest 0.10.7", + "rand_core", + "sha3", +] + +[[package]] +name = "ark-transcript" +version = "0.0.2" +source = "git+https://github.com/w3f/ring-vrf?rev=e9782f9#e9782f938629c90f3adb3fff2358bc8d1386af3e" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "digest 0.10.7", + "rand_core", + "sha3", ] [[package]] @@ -258,7 +468,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -269,12 +479,90 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "bandersnatch_vrfs" +version = "0.0.4" +source = "git+https://github.com/w3f/ring-vrf?rev=e9782f9#e9782f938629c90f3adb3fff2358bc8d1386af3e" +dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-ed-on-bls12-381-bandersnatch", + "ark-ff", + "ark-serialize", + "ark-std", + "dleq_vrf", + "fflonk", + "merlin", + "rand_chacha", + "rand_core", + "ring", + "sha2 0.10.8", + "sp-ark-bls12-381", + "sp-ark-ed-on-bls12-381-bandersnatch", + "zeroize", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bitcoin-internals" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" + +[[package]] +name = "bitcoin_hashes" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" +dependencies = [ + "bitcoin-internals", + "hex-conservative", +] + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + [[package]] name = "bitvec" version = "1.0.1" @@ -287,6 +575,35 @@ dependencies = [ "wyz", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "blake2b_simd" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -296,6 +613,27 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bounded-collections" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d077619e9c237a5d1875166f5e8033e8f6bff0c96f8caf81e1c2d7738c431bf" +dependencies = [ + "log", + "parity-scale-codec", + "scale-info", + "serde", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -314,12 +652,27 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "bytes" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" + [[package]] name = "cast" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" +[[package]] +name = "cc" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +dependencies = [ + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -394,7 +747,7 @@ version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ - "bitflags", + "bitflags 1.3.2", "clap_lex", "indexmap 1.9.3", "textwrap", @@ -410,14 +763,57 @@ dependencies = [ ] [[package]] -name = "constcat" -version = "0.3.1" +name = "common" +version = "0.1.0" +source = "git+https://github.com/w3f/ring-proof#652286c32f96beb9ce7f5793f5e2c2c923f63b73" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "fflonk", + "getrandom_or_panic", + "rand_core", +] + +[[package]] +name = "common-path" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7e35aee659887cbfb97aaf227ac12cad1a9d7c71e55ff3376839ed4e282d08" +checksum = "2382f75942f4b3be3690fe4f86365e9c853c1587d6ee58212cebf6e2a9ccd101" [[package]] -name = "cpufeatures" -version = "0.2.15" +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "constcat" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd7e35aee659887cbfb97aaf227ac12cad1a9d7c71e55ff3376839ed4e282d08" + +[[package]] +name = "cpufeatures" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" dependencies = [ @@ -436,7 +832,7 @@ dependencies = [ "ciborium", "clap", "criterion-plot", - "itertools", + "itertools 0.10.5", "lazy_static", "num-traits", "oorandom", @@ -457,7 +853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools", + "itertools 0.10.5", ] [[package]] @@ -491,6 +887,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -502,6 +910,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + [[package]] name = "ctr" version = "0.9.2" @@ -511,6 +929,33 @@ 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", + "digest 0.10.7", + "fiat-crypto", + "rustc_version", + "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.87", +] + [[package]] name = "debugit" version = "0.1.2" @@ -520,6 +965,25 @@ dependencies = [ "version_check 0.1.5", ] +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "derivative" version = "2.2.0" @@ -531,6 +995,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive-syn-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65d7ce8132b7c0e54497a4d9a55a1c2a0912a0d786cf894472ba818fba45762" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "derive_more" version = "1.0.0" @@ -553,523 +1028,1839 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.7" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "block-buffer", - "crypto-common", + "generic-array", ] [[package]] -name = "either" -version = "1.13.0" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] [[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +name = "dleq_vrf" +version = "0.0.2" +source = "git+https://github.com/w3f/ring-vrf?rev=e9782f9#e9782f938629c90f3adb3fff2358bc8d1386af3e" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-scale", + "ark-secret-scalar", + "ark-serialize", + "ark-std", + "ark-transcript 0.0.2 (git+https://github.com/w3f/ring-vrf?rev=e9782f9)", + "arrayvec", + "zeroize", +] [[package]] -name = "funty" -version = "2.0.0" +name = "docify" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +checksum = "a772b62b1837c8f060432ddcc10b17aae1453ef17617a99bc07789252d2a5896" +dependencies = [ + "docify_macros", +] [[package]] -name = "generic-array" -version = "0.14.7" +name = "docify_macros" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "60e6be249b0a462a14784a99b19bf35a667bb5e09de611738bb7362fa4c95ff7" dependencies = [ - "typenum", - "version_check 0.9.5", + "common-path", + "derive-syn-parse", + "once_cell", + "proc-macro2", + "quote", + "regex", + "syn 2.0.87", + "termcolor", + "toml", + "walkdir", ] [[package]] -name = "getrandom" -version = "0.2.15" +name = "dyn-clonable" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" dependencies = [ - "cfg-if", - "libc", - "wasi", + "dyn-clonable-impl", + "dyn-clone", ] [[package]] -name = "ghash" -version = "0.5.1" +name = "dyn-clonable-impl" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" dependencies = [ - "opaque-debug", - "polyval", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "half" -version = "1.8.3" +name = "dyn-clone" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] -name = "half" -version = "2.4.1" +name = "ecdsa" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "cfg-if", - "crunchy", + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "serdect", + "signature", + "spki", ] [[package]] -name = "handlebox" -version = "0.3.0" +name = "ed25519" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4726136a7636c738124814f1275dd59a709f4cf4dd7b4b670df95b6bf6c4a0ae" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] [[package]] -name = "hashbrown" -version = "0.12.3" +name = "ed25519-dalek" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2 0.10.8", + "subtle", + "zeroize", +] [[package]] -name = "hashbrown" -version = "0.13.2" +name = "ed25519-zebra" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +checksum = "7d9ce6874da5d4415896cd45ffbc4d1cfc0c4f9c079427bd870742c30f2f65a9" dependencies = [ - "ahash", + "curve25519-dalek", + "ed25519", + "hashbrown 0.14.5", + "hex", + "rand_core", + "sha2 0.10.8", + "zeroize", ] [[package]] -name = "hashbrown" -version = "0.15.1" +name = "either" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "elliptic-curve" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "libc", + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "serdect", + "subtle", + "zeroize", ] [[package]] -name = "hex" -version = "0.4.3" +name = "environmental" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +checksum = "e48c92028aaa870e83d51c64e5d4e0b6981b360c522198c23959f219a4e1b15b" [[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +name = "etf-crypto-primitives" +version = "0.2.4" +source = "git+http://github.com/ideal-lab5/etf-sdk?branch=w3fbls-migration#c6e61a89b94b57bcbde2293208a2875469f4fc5c" dependencies = [ - "autocfg", - "hashbrown 0.12.3", + "aes-gcm", + "ark-bls12-377", + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "array-bytes", + "chacha20poly1305", + "generic-array", + "parity-scale-codec", + "rand_chacha", + "scale-info", + "serde", + "serde_cbor", + "serde_json", + "sha2 0.10.8", + "sha3", + "w3f-bls", ] [[package]] -name = "indexmap" -version = "2.6.0" +name = "expander" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "e2c470c71d91ecbd179935b24170459e926382eaaa86b590b78814e180d8a8e2" dependencies = [ - "equivalent", - "hashbrown 0.15.1", + "blake2", + "file-guard", + "fs-err", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.87", ] [[package]] -name = "inout" -version = "0.1.3" +name = "ff" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "generic-array", + "rand_core", + "subtle", ] [[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +name = "fflonk" +version = "0.1.0" +source = "git+https://github.com/w3f/fflonk#1e854f35e9a65d08b11a86291405cdc95baa0a35" dependencies = [ - "either", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "merlin", ] [[package]] -name = "itoa" -version = "1.0.11" +name = "fiat-crypto" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] -name = "js-sys" -version = "0.3.72" +name = "file-guard" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "21ef72acf95ec3d7dbf61275be556299490a245f017cf084bd23b4f68cf9407c" dependencies = [ - "wasm-bindgen", + "libc", + "winapi", ] [[package]] -name = "keccak" -version = "0.1.5" +name = "fixed-hash" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ - "cpufeatures", + "byteorder", + "rand", + "rustc-hex", + "static_assertions", ] [[package]] -name = "lazy_static" -version = "1.5.0" +name = "frame-metadata" +version = "16.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "87cf1549fba25a6fcac22785b61698317d958e96cac72a59102ea45b9ae64692" +dependencies = [ + "cfg-if", + "parity-scale-codec", + "scale-info", + "serde", +] [[package]] -name = "libc" -version = "0.2.162" +name = "fs-err" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] [[package]] -name = "log" -version = "0.4.22" +name = "funty" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] -name = "memchr" -version = "2.7.4" +name = "futures" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] [[package]] -name = "num-bigint" -version = "0.4.6" +name = "futures-channel" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ - "num-integer", - "num-traits", + "futures-core", + "futures-sink", ] [[package]] -name = "num-integer" -version = "0.1.46" +name = "futures-core" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] -name = "num-traits" -version = "0.2.19" +name = "futures-executor" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ - "autocfg", + "futures-core", + "futures-task", + "futures-util", + "num_cpus", ] [[package]] -name = "once_cell" -version = "1.20.2" +name = "futures-io" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] -name = "oorandom" -version = "11.1.4" +name = "futures-macro" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] [[package]] -name = "opaque-debug" -version = "0.3.1" +name = "futures-sink" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] -name = "os_str_bytes" -version = "6.6.1" +name = "futures-task" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] -name = "parity-scale-codec" -version = "3.6.12" +name = "futures-util" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "arrayvec", - "bitvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] -name = "parity-scale-codec-derive" -version = "3.6.12" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.109", + "typenum", + "version_check 0.9.5", + "zeroize", ] [[package]] -name = "paste" -version = "1.0.15" +name = "getrandom" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] [[package]] -name = "pin-project-lite" -version = "0.2.15" +name = "getrandom_or_panic" +version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +checksum = "6ea1015b5a70616b688dc230cfe50c8af89d972cb132d5a622814d29773b10b9" +dependencies = [ + "rand", + "rand_core", +] [[package]] -name = "plotters" -version = "0.3.7" +name = "ghash" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", + "opaque-debug", + "polyval", ] [[package]] -name = "plotters-backend" -version = "0.3.7" +name = "gimli" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] -name = "plotters-svg" -version = "0.3.7" +name = "group" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "plotters-backend", + "ff", + "rand_core", + "subtle", ] [[package]] -name = "poly1305" -version = "0.8.0" +name = "half" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash", -] +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" [[package]] -name = "polyval" -version = "0.6.2" +name = "half" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" dependencies = [ "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", + "crunchy", ] [[package]] -name = "ppv-lite86" -version = "0.2.20" +name = "handlebox" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] +checksum = "4726136a7636c738124814f1275dd59a709f4cf4dd7b4b670df95b6bf6c4a0ae" [[package]] -name = "proc-macro-crate" -version = "3.2.0" +name = "hash-db" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +checksum = "8e7d7786361d7425ae2fe4f9e407eb0efaa0840f5212d109cc018c40c35c6ab4" + +[[package]] +name = "hash256-std-hasher" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c171d55b98633f4ed3860808f004099b36c1cc29c42cfc53aa8591b21efcf2" dependencies = [ - "toml_edit", + "crunchy", ] [[package]] -name = "proc-macro2" -version = "1.0.89" +name = "hashbrown" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "unicode-ident", + "ahash", ] [[package]] -name = "quote" -version = "1.0.37" +name = "hashbrown" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "proc-macro2", + "ahash", + "allocator-api2", ] [[package]] -name = "radium" -version = "0.7.0" +name = "hashbrown" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" [[package]] -name = "rand" -version = "0.8.5" +name = "heck" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", - "rand_chacha", - "rand_core", ] [[package]] -name = "rand_chacha" -version = "0.3.1" +name = "hermit-abi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] -name = "rand_core" -version = "0.6.4" +name = "hex" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] -name = "rayon" -version = "1.10.0" +name = "hex-conservative" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" dependencies = [ - "either", - "rayon-core", + "crypto-mac", + "digest 0.9.0", ] [[package]] -name = "rayon-core" -version = "1.12.1" +name = "hmac" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "crossbeam-deque", - "crossbeam-utils", + "digest 0.10.7", ] [[package]] -name = "regex" -version = "1.11.1" +name = "hmac-drbg" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", ] [[package]] -name = "regex-automata" -version = "0.4.9" +name = "impl-codec" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "parity-scale-codec", ] [[package]] -name = "regex-syntax" -version = "0.8.5" +name = "impl-codec" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "b67aa010c1e3da95bf151bd8b4c059b2ed7e75387cdb969b4f8f2723a43f9941" +dependencies = [ + "parity-scale-codec", +] [[package]] -name = "rustc_version" -version = "0.4.1" +name = "impl-num-traits" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +checksum = "803d15461ab0dcc56706adf266158acbc44ccf719bf7d0af30705f58b90a4b8c" dependencies = [ - "semver", + "integer-sqrt", + "num-traits", + "uint 0.10.0", ] +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-serde" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a143eada6a1ec4aefa5049037a26a6d597bfd64f8c026d07b77133e02b7dd0b" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.1", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "integer-sqrt" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +dependencies = [ + "num-traits", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "serdect", + "sha2 0.10.8", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.162" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" + +[[package]] +name = "libsecp256k1" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" +dependencies = [ + "arrayref", + "base64", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memory-db" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808b50db46293432a45e63bc15ea51e0ab4c0a1647b8eb114e31a3e698dd6fbe" +dependencies = [ + "hash-db", +] + +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core", + "zeroize", +] + +[[package]] +name = "minicov" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27fe9f1cc3c22e1687f9446c2083c4c5fc7f0bcf1c7a86bdbded14985895b4b" +dependencies = [ + "cc", + "walkdir", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-format" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" +dependencies = [ + "arrayvec", + "itoa", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "oorandom" +version = "11.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parity-bip39" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e69bf016dc406eff7d53a7d3f7cf1c2e72c82b9088aac1118591e36dd2cd3e9" +dependencies = [ + "bitcoin_hashes", + "rand", + "rand_core", + "serde", + "unicode-normalization", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "bytes", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parity-wasm" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1ad0aff30c1da14b1254fcb2af73e1fa9a28670e584a626f53a369d0e157304" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", + "password-hash", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "polkadot-ckb-merkle-mountain-range" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b44320e5f7ce2c18227537a3032ae5b2c476a7e8eddba45333e1011fc31b92" +dependencies = [ + "cfg-if", + "itertools 0.10.5", +] + +[[package]] +name = "polkavm-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d9428a5cfcc85c5d7b9fc4b6a18c4b802d0173d768182a51cc7751640f08b92" + +[[package]] +name = "polkavm-derive" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8c4bea6f3e11cd89bb18bcdddac10bd9a24015399bd1c485ad68a985a19606" +dependencies = [ + "polkavm-derive-impl-macro", +] + +[[package]] +name = "polkavm-derive-impl" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c4fdfc49717fb9a196e74a5d28e0bc764eb394a2c803eb11133a31ac996c60c" +dependencies = [ + "polkavm-common", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "polkavm-derive-impl-macro" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ba81f7b5faac81e528eb6158a6f3c9e0bb1008e0ffa19653bc8dea925ecb429" +dependencies = [ + "polkavm-derive-impl", + "syn 2.0.87", +] + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +dependencies = [ + "proc-macro2", + "syn 2.0.87", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec 0.6.0", + "impl-serde 0.4.0", + "scale-info", + "uint 0.9.5", +] + +[[package]] +name = "primitive-types" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d15600a7d856470b7d278b3fe0e311fe28c2526348549f8ef2ff7db3299c87f5" +dependencies = [ + "fixed-hash", + "impl-codec 0.7.0", + "impl-num-traits", + "uint 0.10.0", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "ref-cast" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle", +] + +[[package]] +name = "ring" +version = "0.1.0" +source = "git+https://github.com/w3f/ring-proof#652286c32f96beb9ce7f5793f5e2c2c923f63b73" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "ark-transcript 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "arrayvec", + "blake2", + "common", + "fflonk", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + [[package]] name = "ryu" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scale-info" +version = "2.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa7ffc1c0ef49b0452c6e2986abf2b07743320641ffd5fc63d552458e3b779b" +dependencies = [ + "bitvec", + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", + "serde", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46385cc24172cf615450267463f937c10072516359b3ff1cb24228a4a08bf951" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "schnellru" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9a8ef13a93c54d20580de1e5c413e624e53121d42fc7e2c11d10ef7f8b02367" +dependencies = [ + "ahash", + "cfg-if", + "hashbrown 0.13.2", +] + +[[package]] +name = "schnorrkel" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de18f6d8ba0aad7045f5feae07ec29899c1112584a38509a84ad7b04451eaa0" +dependencies = [ + "aead", + "arrayref", + "arrayvec", + "curve25519-dalek", + "getrandom_or_panic", + "merlin", + "rand_core", + "serde_bytes", + "sha2 0.10.8", + "subtle", + "zeroize", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "serdect", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.28.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb" +dependencies = [ + "cc", +] + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-big-array" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11fc7cc2c76d73e0f27ee52abbd64eec84d46f370c88371120433196934e4b7f" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_bytes" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half 1.8.3", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "serde_json" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + +[[package]] +name = "simple-mermaid" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "620a1d43d70e142b1d46a929af51d44f383db9c7a2ec122de2cd992ccfcf3c18" + +[[package]] +name = "simulacrum" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6cbc16111f66b2f6e0d5c523221fefbfbc5db82fe53a1797bd0840d20958ce" +dependencies = [ + "simulacrum_macros", + "simulacrum_mock", + "simulacrum_user", +] + +[[package]] +name = "simulacrum_macros" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfdc5aa67bc316dca41675f669d544aea393f6319dd8bf921b03dc113d09adca" +dependencies = [ + "simulacrum_mock", +] + +[[package]] +name = "simulacrum_mock" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0a3be81ab017d792fee7be1faa37f3949ebde8f85351951fa1758ae95baec4a" +dependencies = [ + "debugit", + "handlebox", + "simulacrum_shared", +] [[package]] -name = "same-file" -version = "1.0.6" +name = "simulacrum_shared" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +checksum = "f784fd3a3691ec375a713ee20dff673a45ca221002e7b4e69c7940320b7e316a" dependencies = [ - "winapi-util", + "debugit", ] [[package]] -name = "scale-info" -version = "2.11.5" +name = "simulacrum_user" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aa7ffc1c0ef49b0452c6e2986abf2b07743320641ffd5fc63d552458e3b779b" +checksum = "db58f8fdfe08b9b95bf3ebce8d92091a5d65107da1afdeeb9004e1f6ed2ae81f" dependencies = [ - "bitvec", - "cfg-if", - "derive_more", - "parity-scale-codec", - "scale-info-derive", + "debugit", + "simulacrum_shared", ] [[package]] -name = "scale-info-derive" -version = "2.11.5" +name = "slab" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46385cc24172cf615450267463f937c10072516359b3ff1cb24228a4a08bf951" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "sp-api" +version = "26.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "docify", + "hash-db", + "log", + "parity-scale-codec", + "scale-info", + "sp-api-proc-macro", + "sp-core", + "sp-externalities 0.25.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-metadata-ir", + "sp-runtime", + "sp-runtime-interface 24.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-state-machine", + "sp-std 14.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-trie", + "sp-version", + "thiserror", +] + +[[package]] +name = "sp-api-proc-macro" +version = "15.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "Inflector", + "blake2", + "expander", "proc-macro-crate", "proc-macro2", "quote", @@ -1077,122 +2868,592 @@ dependencies = [ ] [[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +name = "sp-application-crypto" +version = "30.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-std 14.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", +] + +[[package]] +name = "sp-arithmetic" +version = "23.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "docify", + "integer-sqrt", + "num-traits", + "parity-scale-codec", + "scale-info", + "serde", + "sp-std 14.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "static_assertions", +] + +[[package]] +name = "sp-ark-bls12-381" +version = "0.4.2" +source = "git+https://github.com/paritytech/arkworks-substrate#caa2eed74beb885dd07c7db5f916f2281dad818f" +dependencies = [ + "ark-bls12-381-ext", + "sp-crypto-ec-utils", +] + +[[package]] +name = "sp-ark-ed-on-bls12-381-bandersnatch" +version = "0.4.2" +source = "git+https://github.com/paritytech/arkworks-substrate#caa2eed74beb885dd07c7db5f916f2281dad818f" +dependencies = [ + "ark-ed-on-bls12-381-bandersnatch-ext", + "sp-crypto-ec-utils", +] + +[[package]] +name = "sp-consensus-beefy-etf" +version = "13.0.0" +source = "git+https://github.com/ideal-lab5/pallets.git#a8c71dfb9bcd198cfac1071eb37328676ac4f959" +dependencies = [ + "lazy_static", + "parity-scale-codec", + "scale-info", + "serde", + "sp-api", + "sp-application-crypto", + "sp-core", + "sp-crypto-hashing", + "sp-io", + "sp-keystore", + "sp-mmr-primitives", + "sp-runtime", + "strum", +] + +[[package]] +name = "sp-core" +version = "28.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "ark-serialize", + "array-bytes", + "bandersnatch_vrfs", + "bitflags 1.3.2", + "blake2", + "bounded-collections", + "bs58", + "dyn-clonable", + "ed25519-zebra", + "etf-crypto-primitives", + "futures", + "hash-db", + "hash256-std-hasher", + "impl-serde 0.4.0", + "itertools 0.11.0", + "k256", + "libsecp256k1", + "log", + "merlin", + "parity-bip39", + "parity-scale-codec", + "parking_lot", + "paste", + "primitive-types 0.12.2", + "rand", + "scale-info", + "schnorrkel", + "secp256k1", + "secrecy", + "serde", + "sp-crypto-hashing", + "sp-debug-derive 14.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-externalities 0.25.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-runtime-interface 24.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-std 14.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-storage 19.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "ss58-registry", + "substrate-bip39", + "thiserror", + "tracing", + "w3f-bls", + "zeroize", +] + +[[package]] +name = "sp-crypto-ec-utils" +version = "0.10.0" +source = "git+https://github.com/paritytech/polkadot-sdk#a1af8ed63668fc4a553776e381a12d165e7462f8" +dependencies = [ + "ark-bls12-377", + "ark-bls12-377-ext", + "ark-bls12-381", + "ark-bls12-381-ext", + "ark-bw6-761", + "ark-bw6-761-ext", + "ark-ec", + "ark-ed-on-bls12-377", + "ark-ed-on-bls12-377-ext", + "ark-ed-on-bls12-381-bandersnatch", + "ark-ed-on-bls12-381-bandersnatch-ext", + "ark-scale", + "sp-runtime-interface 24.0.0 (git+https://github.com/paritytech/polkadot-sdk)", +] + +[[package]] +name = "sp-crypto-hashing" +version = "0.1.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "blake2b_simd", + "byteorder", + "digest 0.10.7", + "sha2 0.10.8", + "sha3", + "twox-hash", +] + +[[package]] +name = "sp-crypto-hashing-proc-macro" +version = "0.1.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "quote", + "sp-crypto-hashing", + "syn 2.0.87", +] + +[[package]] +name = "sp-debug-derive" +version = "14.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "sp-debug-derive" +version = "14.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk#a1af8ed63668fc4a553776e381a12d165e7462f8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "sp-externalities" +version = "0.25.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "environmental", + "parity-scale-codec", + "sp-storage 19.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", +] + +[[package]] +name = "sp-externalities" +version = "0.25.0" +source = "git+https://github.com/paritytech/polkadot-sdk#a1af8ed63668fc4a553776e381a12d165e7462f8" +dependencies = [ + "environmental", + "parity-scale-codec", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk)", +] + +[[package]] +name = "sp-io" +version = "30.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "bytes", + "docify", + "ed25519-dalek", + "libsecp256k1", + "log", + "parity-scale-codec", + "polkavm-derive", + "rustversion", + "secp256k1", + "sp-core", + "sp-crypto-hashing", + "sp-externalities 0.25.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-keystore", + "sp-runtime-interface 24.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-state-machine", + "sp-std 14.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-tracing 16.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-trie", + "tracing", + "tracing-core", +] + +[[package]] +name = "sp-keystore" +version = "0.34.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "parity-scale-codec", + "parking_lot", + "sp-core", + "sp-externalities 0.25.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", +] + +[[package]] +name = "sp-metadata-ir" +version = "0.6.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "frame-metadata", + "parity-scale-codec", + "scale-info", +] + +[[package]] +name = "sp-mmr-primitives" +version = "26.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "log", + "parity-scale-codec", + "polkadot-ckb-merkle-mountain-range", + "scale-info", + "serde", + "sp-api", + "sp-core", + "sp-debug-derive 14.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-runtime", + "thiserror", +] + +[[package]] +name = "sp-panic-handler" +version = "13.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "backtrace", + "lazy_static", + "regex", +] + +[[package]] +name = "sp-runtime" +version = "31.0.1" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "docify", + "either", + "hash256-std-hasher", + "impl-trait-for-tuples", + "log", + "num-traits", + "parity-scale-codec", + "paste", + "rand", + "scale-info", + "serde", + "simple-mermaid", + "sp-application-crypto", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-std 14.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-weights", +] + +[[package]] +name = "sp-runtime-interface" +version = "24.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "bytes", + "impl-trait-for-tuples", + "parity-scale-codec", + "polkavm-derive", + "primitive-types 0.12.2", + "sp-externalities 0.25.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-runtime-interface-proc-macro 17.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-std 14.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-storage 19.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-tracing 16.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-wasm-interface 20.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface" +version = "24.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk#a1af8ed63668fc4a553776e381a12d165e7462f8" +dependencies = [ + "bytes", + "impl-trait-for-tuples", + "parity-scale-codec", + "polkavm-derive", + "primitive-types 0.13.1", + "sp-externalities 0.25.0 (git+https://github.com/paritytech/polkadot-sdk)", + "sp-runtime-interface-proc-macro 17.0.0 (git+https://github.com/paritytech/polkadot-sdk)", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk)", + "sp-storage 19.0.0 (git+https://github.com/paritytech/polkadot-sdk)", + "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk)", + "sp-wasm-interface 20.0.0 (git+https://github.com/paritytech/polkadot-sdk)", + "static_assertions", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "17.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "Inflector", + "expander", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "sp-runtime-interface-proc-macro" +version = "17.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk#a1af8ed63668fc4a553776e381a12d165e7462f8" +dependencies = [ + "Inflector", + "expander", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.87", +] + +[[package]] +name = "sp-state-machine" +version = "0.35.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "hash-db", + "log", + "parity-scale-codec", + "parking_lot", + "rand", + "smallvec", + "sp-core", + "sp-externalities 0.25.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-panic-handler", + "sp-trie", + "thiserror", + "tracing", + "trie-db", +] + +[[package]] +name = "sp-std" +version = "14.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" + +[[package]] +name = "sp-std" +version = "14.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk#a1af8ed63668fc4a553776e381a12d165e7462f8" + +[[package]] +name = "sp-storage" +version = "19.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "impl-serde 0.4.0", + "parity-scale-codec", + "ref-cast", + "serde", + "sp-debug-derive 14.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", +] + +[[package]] +name = "sp-storage" +version = "19.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk#a1af8ed63668fc4a553776e381a12d165e7462f8" +dependencies = [ + "impl-serde 0.5.0", + "parity-scale-codec", + "ref-cast", + "serde", + "sp-debug-derive 14.0.0 (git+https://github.com/paritytech/polkadot-sdk)", +] + +[[package]] +name = "sp-tracing" +version = "16.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" +dependencies = [ + "parity-scale-codec", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sp-tracing" +version = "16.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk#a1af8ed63668fc4a553776e381a12d165e7462f8" +dependencies = [ + "parity-scale-codec", + "tracing", + "tracing-core", + "tracing-subscriber", +] [[package]] -name = "serde" -version = "1.0.215" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +name = "sp-trie" +version = "29.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" dependencies = [ - "serde_derive", + "ahash", + "hash-db", + "lazy_static", + "memory-db", + "nohash-hasher", + "parity-scale-codec", + "parking_lot", + "rand", + "scale-info", + "schnellru", + "sp-core", + "sp-externalities 0.25.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "thiserror", + "tracing", + "trie-db", + "trie-root", ] [[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +name = "sp-version" +version = "29.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" dependencies = [ - "half 1.8.3", + "impl-serde 0.4.0", + "parity-scale-codec", + "parity-wasm", + "scale-info", "serde", + "sp-crypto-hashing-proc-macro", + "sp-runtime", + "sp-std 14.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", + "sp-version-proc-macro", + "thiserror", ] [[package]] -name = "serde_derive" -version = "1.0.215" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +name = "sp-version-proc-macro" +version = "13.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" dependencies = [ + "parity-scale-codec", "proc-macro2", "quote", "syn 2.0.87", ] [[package]] -name = "serde_json" -version = "1.0.132" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +name = "sp-wasm-interface" +version = "20.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", ] [[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +name = "sp-wasm-interface" +version = "20.0.0" +source = "git+https://github.com/paritytech/polkadot-sdk#a1af8ed63668fc4a553776e381a12d165e7462f8" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "anyhow", + "impl-trait-for-tuples", + "log", + "parity-scale-codec", ] [[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +name = "sp-weights" +version = "27.0.0" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" dependencies = [ - "digest", - "keccak", + "bounded-collections", + "parity-scale-codec", + "scale-info", + "serde", + "smallvec", + "sp-arithmetic", + "sp-debug-derive 14.0.0 (git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing)", ] [[package]] -name = "simulacrum" -version = "0.3.1" +name = "spki" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6cbc16111f66b2f6e0d5c523221fefbfbc5db82fe53a1797bd0840d20958ce" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ - "simulacrum_macros", - "simulacrum_mock", - "simulacrum_user", + "base64ct", + "der", ] [[package]] -name = "simulacrum_macros" -version = "0.3.1" +name = "ss58-registry" +version = "1.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfdc5aa67bc316dca41675f669d544aea393f6319dd8bf921b03dc113d09adca" +checksum = "19409f13998e55816d1c728395af0b52ec066206341d939e22e7766df9b494b8" dependencies = [ - "simulacrum_mock", + "Inflector", + "num-format", + "proc-macro2", + "quote", + "serde", + "serde_json", + "unicode-xid", ] [[package]] -name = "simulacrum_mock" -version = "0.1.0" +name = "static_assertions" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0a3be81ab017d792fee7be1faa37f3949ebde8f85351951fa1758ae95baec4a" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" dependencies = [ - "debugit", - "handlebox", - "simulacrum_shared", + "strum_macros", ] [[package]] -name = "simulacrum_shared" -version = "0.1.0" +name = "strum_macros" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f784fd3a3691ec375a713ee20dff673a45ca221002e7b4e69c7940320b7e316a" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "debugit", + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", ] [[package]] -name = "simulacrum_user" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db58f8fdfe08b9b95bf3ebce8d92091a5d65107da1afdeeb9004e1f6ed2ae81f" +name = "substrate-bip39" +version = "0.4.7" +source = "git+https://github.com/ideal-lab5/polkadot-sdk.git?branch=testing#0bd1f08ed576063e678539edafdf3a589ff3989e" dependencies = [ - "debugit", - "simulacrum_shared", + "hmac 0.12.1", + "pbkdf2", + "schnorrkel", + "sha2 0.10.8", + "zeroize", ] [[package]] @@ -1229,6 +3490,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "textwrap" version = "0.16.1" @@ -1256,18 +3526,49 @@ dependencies = [ ] [[package]] -name = "tinytemplate" -version = "1.2.1" +name = "thread_local" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", "serde", - "serde_json", + "time-core", + "time-macros", ] [[package]] -name = "tle" -version = "0.1.0" +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "timelock" +version = "0.0.1" dependencies = [ "aes-gcm", "ark-bls12-377", @@ -1290,17 +3591,80 @@ dependencies = [ "serde", "serde_cbor", "serde_json", - "sha2", + "sha2 0.10.8", "sha3", "simulacrum", "w3f-bls", ] +[[package]] +name = "timelock-wasm-wrapper" +version = "0.0.1-dev" +dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-serialize", + "ark-std", + "getrandom", + "parity-scale-codec", + "rand_chacha", + "rand_core", + "serde", + "serde-big-array", + "serde-wasm-bindgen", + "sha2 0.10.8", + "sp-consensus-beefy-etf", + "timelock", + "w3f-bls", + "wasm-bindgen", + "wasm-bindgen-test", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + [[package]] name = "toml_datetime" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] [[package]] name = "toml_edit" @@ -1309,6 +3673,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap 2.6.0", + "serde", + "serde_spanned", "toml_datetime", "winnow", ] @@ -1340,6 +3706,73 @@ name = "tracing-core" version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "time", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "trie-db" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c992b4f40c234a074d48a757efeabb1a6be88af84c0c23f7ca158950cb0ae7f" +dependencies = [ + "hash-db", + "log", + "rustc-hex", + "smallvec", +] + +[[package]] +name = "trie-root" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4ed310ef5ab98f5fa467900ed906cb9232dd5376597e00fd4cba2a449d06c0b" +dependencies = [ + "hash-db", +] + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "digest 0.10.7", + "rand", + "static_assertions", +] [[package]] name = "typenum" @@ -1347,12 +3780,51 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "uint" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "909988d098b2f738727b161a106cfc7cab00c539c2687a8836f8e565976fb53e" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + [[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.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "universal-hash" version = "0.5.1" @@ -1363,6 +3835,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "version_check" version = "0.1.5" @@ -1389,11 +3867,11 @@ dependencies = [ "ark-serialize-derive", "arrayref", "constcat", - "digest", + "digest 0.10.7", "rand", "rand_chacha", "rand_core", - "sha2", + "sha2 0.10.8", "sha3", "thiserror", "zeroize", @@ -1441,6 +3919,18 @@ dependencies = [ "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.95" @@ -1470,6 +3960,32 @@ version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +[[package]] +name = "wasm-bindgen-test" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d381749acb0943d357dcbd8f0b100640679883fcdeeef04def49daf8d33a5426" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "minicov", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c97b2ef2c8d627381e51c071c2ab328eac606d3f69dd82bcbca20a9e389d95f0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "web-sys" version = "0.3.72" diff --git a/Cargo.toml b/Cargo.toml index e510334..a4e044c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,74 +1,34 @@ -[package] -name = "tle" -version = "0.1.0" -edition = "2021" -description = "timelock encryption imlementation using BF-IBE" -license = "Apache-2.0" -repository = "https://github.com/ideal-lab5/etf-sdk" -authors = ["Tony Riemer "] -rust-version = "1.63" -homepage = "https://idealabs.network" - -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - -[dependencies] -codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive", "max-encoded-len"] } -scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } -serde = { version = "1.0.204", default-features = false, features = ["derive", "alloc"] } -aes-gcm = { version = "0.10.2", default-features = false, features = ["alloc", "aes", "rand_core"] } -array-bytes = "6.1.0" -generic-array = "0.14.7" -sha2 = { version = "0.10.2", default-features = false } -sha3 = { version = "0.10.0", default-features = false } -# arkworks dependencies -ark-std = { version = "0.4.0", default-features = false } -ark-ff = { version = "0.4.0", default-features = false } -ark-poly = { version = "0.4.0", default-features = false } -ark-ec = { version = "0.4.0", default-features = false } - -ark-serialize = { version = "0.4.0", default-features = false } -ark-bls12-381 = { version = "0.4.0", features = ["curve"], default-features = false } -ark-bls12-377 = { version = "0.4.0", features = ["curve"], default-features = false } - -serde_json = { version = "1.0.108", default-features = false, features = ["alloc"] } -serde_cbor = {version = "0.11.2", default-features = false } -chacha20poly1305 = { version = "0.10.1", default-features = false} - -rand_core = "0.6.4" -rand_chacha = { version = "0.3.1", default-features = false } -w3f-bls = { version = "=0.1.3", default-features = false } - -[dev-dependencies] -hex = "0.4.3" -ark-ed-on-bls12-381 = { version = "^0.4.0", default-features = false, features = [ "r1cs" ] } -simulacrum = "0.3.0" -criterion = { version = "0.4", features = ["html_reports"] } - -[[bench]] -name = "tlock_single_commitee_dynamic_data" -harness = false - -[[bench]] -name = "tlock_dynamic_committee_static_data" -harness = false - -[features] -default = ["std"] -std = [ - "codec/std", - "scale-info/std", - "sha2/std", - "sha3/std", - "ark-std/std", - "ark-ff/std", - "ark-poly/std", - "ark-ec/std", - "ark-serialize/std", - "ark-bls12-381/std", - "serde_json/std", - "serde_cbor/std", - "rand_chacha/std", - "chacha20poly1305/std", - "w3f-bls/std", +[workspace] +members = [ + "timelock", + "wasm", ] +resolver = "2" + +[profile.release] +opt-level = 3 +lto = "thin" +incremental = true +panic = 'abort' + +[profile.bench] +opt-level = 3 +debug = false +rpath = false +lto = "thin" +incremental = true +debug-assertions = false + +[profile.dev] +opt-level = 0 +panic = 'abort' + +[profile.test] +opt-level = 3 +lto = "thin" +incremental = true +debug-assertions = true +debug = true + +[workspace.metadata.release] +dependent-version = "fix" diff --git a/README.md b/README.md index e8ee617..863c6c4 100644 --- a/README.md +++ b/README.md @@ -1,67 +1,26 @@ # Timelock Encryption -This library enables timelock encryption using the Boneh-Franklin IBE scheme. Specifically, it allows timelock encryption to be instantiated on top of a verifiable randomness beacon, such as the [Ideal Network](https://docs.idealabs.network) or [drand](https://drand.love). The library is implemented with [arkworks](https://github.com/arkworks-rs) +Timelock is an implemention of [timelock encryption](https://docs.idealabs.network/docs/learn/crypto/timelock_encryption) using the [Boneh Franklin -Idenity Based Encryption](https://crypto.stanford.edu/~dabo/papers/bfibe.pdf) scheme. Designed for versatility, it provides support for both Rust and JavaScript. In addition, it is capable of supporting multiple types of randomness beacons, including the [Ideal Network](https://docs.idealabs.network) and [drand](https://drand.love). -Currently the scheme supports several flavors of beacons, including the Drand 'quicknet', which uses BLS381 keys, and the Ideal Network beacon, which uses BLS377 keys. Both beacons use a BLS variant with tiny 48 byte signatures and 96 byte public keys, with signatures being elements of $\mathbb{G}_1$ and public keys in $\mathbb{G}_2$. +## Getting Started -This flavor of timelock encryption is a hybrid encryption scheme, using `AES_GCM` to efficiently encrypt and decrypt and size ciphertexts, while secret keys are encrypted for identities of future beacon pulses. +Timelock is organized into core components and language-specific bindings to support WASM and TS: -## Usage +- **Core Library**: The [timelock](./timelock/) crate implements the core encryption algorithms and provides support for native Rust applications. +- **WASM bindings**: The [wasm](./wasm/) lib provides wasm bindings for the timelock encryption implementation, enabling usage of TLE in web or node.js based applications. +- **TypeScript Wrapper**: The [ts](./ts/) library is a typescript wrapper to adapt the wasm for easy integration in JavaScript projects. -### Encrypt a Message +### For Rust developers +Navigate to the core timelock implementation [readme](./timelock/README.md) for details on building and using it in Rust. -This is an example of using the Ideal Network beacon to encrypt message. This same can be accomplished against Drand's quicknet. See the tlock tests [here](./src/tlock.rs) for more examples. +### For Javascript developers +Navigate to the typescript bindings [readme](./ts/README.md) for more information on integration of `@ideallabs/timelock.js` in javascript apps. -``` rust -// gather public parameters for the randomenss beacon -let pk = hex::decode("471ba929a4e2ef2790fb5f2a65ebe86598a28cbb8a58e49c6cc7292cf40cecbdf10152394ba938367ded5355ae373e01a99567467bc816864774e84b984fc16e2ae2232be6481cd4db0e378e1d6b0c2265d2aa8e0fa4e2c76958ce9f12df8e0134c431c181308a68b94b9cfba5176c3a8dd22ead9a68a077ecce7facfe4adb9e0e0a71c94a0c436d8049b03fa5352301").expect("decoding failure"); -let p_pub = ::deserialize_compressed(&*pk).unwrap(); -// construct an identity -// choose a future round number of the randomness beacon -let round_number: u64 = 10; -let identity = Identity::new(b"", vec![round_number.to_be_bytes()]); -// generate an ephemeral secret key 32-byte secret key -let esk = [2;32]; -// encrypt using the identity -let ct = tle::::(p_pub, msk, &message, id, OsRng).unwrap(); -``` -### Decrypt a Message +## Contributing and Code of Conduct -#### Early decryption -Message can be encrypted at any time using the ephemeral secret key used to encrypt it: -``` rust -// use the same esk as in `encrypt` -let early_result = ct.aes_decrypt(esk).unwrap(); -``` +Contributions are welcome! Feel free to open issues for problems or feature requests while we work on setting up our contributors guidelines. -#### Timelock Decryption -Messages can also be decrypted with a signature produced by a beacon on top of the 'identity' used to construct it: -``` rust -// first get a valid siganture from the beacon -let signature = hex::decode(b"f8178b1c3c9477f7b0e37cd3e63ff3a184e1d05df3117438cd05e109b5731a52a96ae344e461bc6cb8e04f5efed34701").expect("decoding failure"); -let result: DecryptionResult = ct.tld(sig).unwrap(); -``` +## License -## Build - -From the root, run `cargo build` - -## Test - - -### Unit tests -From the root, run `cargo test` - -### Coverage -We use [tarpaulin](https://github.com/xd009642/tarpaulin) for test coverage. From the root, run: - -``` -cargo tarpaulin --rustflags="-C opt-level=0" -``` - -### Benchmarks - -``` shell -cargo benchmark -``` \ No newline at end of file +Apache-2.0 \ No newline at end of file diff --git a/benches/tlock_dynamic_committee_static_data.rs b/benches/tlock_dynamic_committee_static_data.rs deleted file mode 100644 index 7a7e635..0000000 --- a/benches/tlock_dynamic_committee_static_data.rs +++ /dev/null @@ -1,56 +0,0 @@ -use criterion::{ - black_box, criterion_group, criterion_main, - Criterion, BenchmarkId, Throughput -}; -use ark_ff::UniformRand; -use w3f_bls::{EngineBLS, TinyBLS377}; -use etf_crypto_primitives::encryption::tlock::*; -use etf_crypto_primitives::ibe::fullident::*; -use rand_core::OsRng; -use ark_ec::Group; - -/// encrypts a message for the identity and then performs decryption on threshold sigs -/// represents the worst case scenario where the threshold equals the size of the committee -fn tlock_tinybls377( - msk: SecretKey, - p_pub: E::PublicKeyGroup, - message: Vec, - id: Identity, - sigs: Vec>, -) { - let ct = msk.encrypt(p_pub, &message, id.clone(), &mut OsRng).unwrap(); - let _m = ct.decrypt(sigs).unwrap(); -} - -fn tlock_dynamic_commitee_static_data(c: &mut Criterion) { - static KB: usize = 1024; - let id = Identity::new(b"", vec![b"test".to_vec()]); - - let mut group = c.benchmark_group("tlock_dynamic_commitee_static_data"); - for size in [3, 5, 10, 20, 50, 100].iter() { - - let (round_secret, shares) = generate_secrets::(*size as u8, *size as u8, &mut OsRng); - let p_pub = ::PublicKeyGroup::generator() * round_secret; - let msk = ::Scalar::rand(&mut OsRng); - - let mut dummy_data = Vec::with_capacity(KB); - (0..KB).for_each(|i| dummy_data.push(i as u8)); - - group.throughput(Throughput::Bytes(KB as u64)); - group.bench_with_input(BenchmarkId::from_parameter(size), size, |b, &size| { - b.iter(|| { - tlock_tinybls377( - black_box(SecretKey::::new(msk)), - black_box(p_pub), - black_box(dummy_data.clone()), - black_box(id.clone()), - black_box(shares.iter().map(|share| id.extract(share.1)).collect()), - ); - }); - }); - } - group.finish(); -} - -criterion_group!(benches, tlock_dynamic_commitee_static_data); -criterion_main!(benches); diff --git a/benches/tlock_single_commitee_dynamic_data.rs b/benches/tlock_single_commitee_dynamic_data.rs deleted file mode 100644 index b191054..0000000 --- a/benches/tlock_single_commitee_dynamic_data.rs +++ /dev/null @@ -1,56 +0,0 @@ -use criterion::{ - black_box, criterion_group, criterion_main, - Criterion, BenchmarkId, Throughput -}; -use ark_ff::UniformRand; -use w3f_bls::{EngineBLS, TinyBLS377}; -use etf_crypto_primitives::encryption::tlock::*; -use etf_crypto_primitives::ibe::fullident::*; -use rand_core::OsRng; -use ark_ec::Group; - -/// encrypts a message for the identity and then decrypts it after preparing a bls sig -/// this expects on a single signature but tests many different input data sizes -fn tlock_tinybls377( - msk: SecretKey, - p_pub: E::PublicKeyGroup, - message: Vec, - id: Identity, - sigs: Vec>, -) { - let ct = msk.encrypt(p_pub, &message, id.clone(), &mut OsRng).unwrap(); - let _m = ct.decrypt(sigs).unwrap(); -} - -fn tlock_single_commitee_dynamic_data(c: &mut Criterion) { - static KB: usize = 1024; - - let s = ::Scalar::rand(&mut OsRng); - let p_pub = ::PublicKeyGroup::generator() * s; - let id = Identity::new(b"", vec![b"test".to_vec()]); - let msk = ::Scalar::rand(&mut OsRng); - - let mut group = c.benchmark_group("tlock_single_commitee_dynamic_data"); - for size in [KB, 2*KB, 4*KB, 8*KB, 16*KB, 128*KB].iter() { - - let mut dummy_data = Vec::with_capacity(*size); - (0..*size).for_each(|i| dummy_data.push(i as u8)); - - group.throughput(Throughput::Bytes(KB as u64)); - group.bench_with_input(BenchmarkId::from_parameter(size), size, |b, &size| { - b.iter(|| { - tlock_tinybls377( - black_box(SecretKey::::new(msk)), - black_box(p_pub), - black_box(dummy_data.clone()), - black_box(id.clone()), - black_box(vec![id.extract(s)]) - ); - }); - }); - } - group.finish(); -} - -criterion_group!(benches, tlock_single_commitee_dynamic_data); -criterion_main!(benches); diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..79e3fcf --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,23 @@ +# Basic +hard_tabs = true +max_width = 80 +use_small_heuristics = "Max" +# Imports +imports_granularity = "Crate" +reorder_imports = true +# Consistency +newline_style = "Unix" +# Format comments +comment_width = 100 +wrap_comments = true +# Misc +chain_width = 80 +spaces_around_ranges = false +binop_separator = "Back" +reorder_impl_items = false +match_arm_leading_pipes = "Preserve" +match_arm_blocks = false +match_block_trailing_comma = true +trailing_comma = "Vertical" +trailing_semicolon = false +use_field_init_shorthand = true diff --git a/src/aes.rs b/src/aes.rs deleted file mode 100644 index 42b2037..0000000 --- a/src/aes.rs +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright 2024 by Ideal Labs, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -use aes_gcm::{ - aead::{Aead, AeadCore, AeadInPlace, KeyInit}, - Aes256Gcm, Nonce, -}; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_std::rand::Rng; - -use serde::{Deserialize, Serialize}; - -use ark_std::rand::CryptoRng; -use ark_std::vec::Vec; - -/// The output of AES Encryption plus the ephemeral secret key -#[derive(Serialize, Deserialize, Debug, CanonicalSerialize, CanonicalDeserialize)] -pub struct AESOutput { - /// the AES ciphertext - pub ciphertext: Vec, - /// the AES nonce - pub nonce: Vec, - pub key: Vec, -} - -#[derive(Debug, PartialEq)] -pub enum Error { - CiphertextTooLarge, - EncryptionError, - DecryptionError, - InvalidKey, - BadNonce, -} - -/// AES-GCM encryption of the message using an ephemeral keypair -/// basically a wrapper around the AEADs library to handle serialization -/// -/// * `message`: The message to encrypt -/// -pub fn encrypt( - message: &[u8], - key: [u8;32], - mut rng: R, -) -> Result { - let cipher = Aes256Gcm::new(generic_array::GenericArray::from_slice(&key)); - let nonce = Aes256Gcm::generate_nonce(&mut rng); // 96-bits; unique per message - - let mut buffer: Vec = Vec::new(); // Note: buffer needs 16-bytes overhead for auth tag - buffer.extend_from_slice(message); - // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext - // will this error ever be thrown here? nonces should always be valid as well as buffer - cipher.encrypt_in_place(&nonce, b"", &mut buffer) - .map_err(|_| Error::CiphertextTooLarge)?; - Ok(AESOutput{ - ciphertext: buffer, - nonce: nonce.to_vec(), - key: key.to_vec(), // TODO: remove key from AESOutput struct - }) -} - -/// AES-GCM decryption -/// -/// * `ciphertext`: the ciphertext to decrypt -/// * `nonce`: the nonce used on encryption -/// * `key`: the key used for encryption -/// -pub fn decrypt( - ct: AESOutput, -) -> Result, Error> { - let cipher = Aes256Gcm::new_from_slice(&ct.key) - .map_err(|_| Error::InvalidKey)?; - // lets check the nonce... not great way to do it but ok for now - // TODO:get a valid nonce size as a constant - if ct.nonce.len() != 12 { - return Err(Error::BadNonce); - } - let nonce = Nonce::from_slice(&ct.nonce); - let plaintext = cipher.decrypt(nonce, ct.ciphertext.as_ref()) - .map_err(|_| Error::DecryptionError)?; - Ok(plaintext) -} - -#[cfg(test)] -mod test { - use super::*; - use alloc::vec; - use ark_std::rand::SeedableRng; - use rand_chacha::ChaCha20Rng; - - #[test] - pub fn aes_encrypt_decrypt_works() { - let msg = b"test"; - let rng = ChaCha20Rng::from_seed([2;32]); - match encrypt(msg, [2;32], rng) { - Ok(aes_out) => { - match decrypt(aes_out) { - Ok(plaintext) => { - assert_eq!(msg.to_vec(), plaintext); - }, - Err(_) => { - panic!("test should pass"); - } - } - }, - Err(_) => { - panic!("test should pass"); - } - } - } - - #[test] - pub fn aes_encrypt_decrypt_fails_with_bad_key() { - let msg = b"test"; - let rng = ChaCha20Rng::from_seed([1;32]); - match encrypt(msg, [2;32], rng) { - Ok(aes_out) => { - let bad = AESOutput { - ciphertext: aes_out.ciphertext, - nonce: aes_out.nonce, - key: b"hi".to_vec(), - }; - match decrypt(bad) { - Ok(_) => { - panic!("should be an error"); - }, - Err(e) => { - assert_eq!(e, Error::InvalidKey); - } - } - }, - Err(_) => { - panic!("test should pass"); - } - } - } - - #[test] - pub fn aes_encrypt_decrypt_fails_with_invalid_nonce() { - let msg = b"test"; - let rng = ChaCha20Rng::from_seed([3;32]); - match encrypt(msg, [2;32], rng) { - Ok(aes_out) => { - let bad = AESOutput { - ciphertext: aes_out.ciphertext, - nonce: vec![0,0,0,0,0,0,0,0,0,0,0,0], - key: aes_out.key, - }; - match decrypt(bad) { - Ok(_) => { - panic!("should be an error"); - }, - Err(e) => { - assert_eq!(e, Error::DecryptionError); - } - } - }, - Err(_) => { - panic!("test should pass"); - } - } - } - - #[test] - pub fn aes_encrypt_decrypt_fails_with_bad_length_nonce() { - let msg = b"test"; - let rng = ChaCha20Rng::from_seed([3;32]); - match encrypt(msg, [2;32], rng) { - Ok(aes_out) => { - let bad = AESOutput { - ciphertext: aes_out.ciphertext, - nonce: vec![0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], - key: aes_out.key, - }; - match decrypt(bad) { - Ok(_) => { - panic!("should be an error"); - }, - Err(e) => { - assert_eq!(e, Error::BadNonce); - } - } - }, - Err(_) => { - panic!("test should pass"); - } - } - } -} \ No newline at end of file diff --git a/src/curves/drand.rs b/src/curves/drand.rs deleted file mode 100644 index ab8cf6f..0000000 --- a/src/curves/drand.rs +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2024 by Ideal Labs, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - use alloc::vec::Vec; - - use ark_ec::hashing::curve_maps::wb::{WBConfig, WBMap}; - use ark_ec::hashing::{ - map_to_curve_hasher::{MapToCurve, MapToCurveBasedHasher}, - HashToCurve, - }; - use ark_ec::{ - pairing::{MillerLoopOutput, Pairing}, - AffineRepr, CurveGroup, - }; - use ark_ff::field_hashers::DefaultFieldHasher; - - use sha2::Sha256; //IETF standard asks for SHA256 - - use ark_ec::bls12::Bls12Config; - use core::marker::PhantomData; - use w3f_bls::EngineBLS; - - pub const QUICKNET_CTX: &[u8] = b"BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_"; - - pub type TinyBLS381 = TinyBLSDrandQuicknet; - - /// Trait to add extra config for a curve which is not in ArkWorks library - pub trait CurveExtraConfig { - const CURVE_NAME: &'static [u8]; - } - - /// Aggregate BLS signature scheme with Signature in G1 for BLS12-381 curve. - impl CurveExtraConfig for ark_bls12_381::Config { - const CURVE_NAME: &'static [u8] = b"BLS12381"; - } - - /// A BLS variant with tiny 48 byte signatures and 96 byte public keys, - /// - /// Specifically, this configuration is used by Drand's QuickNet. - /// - /// Note on performance: verifiers always perform `O(signers)` additions on the `PublicKeyGroup`, - /// or worse 128 bit scalar multiplications with delinearization. - /// Yet, there are specific use cases where this variant performs - /// better. We swapy two group roles relative to zcash here. - #[derive(Default)] - pub struct TinyBLSDrandQuicknet(pub E, PhantomData P>) - where -

::G1Config: WBConfig, - WBMap<

::G1Config>: MapToCurve<::G1>; - - impl EngineBLS for TinyBLSDrandQuicknet - where -

::G1Config: WBConfig, - WBMap<

::G1Config>: MapToCurve<::G1>, - { - type Engine = E; - type Scalar = ::ScalarField; - - type SignatureGroup = E::G1; - type SignatureGroupAffine = E::G1Affine; - type SignaturePrepared = E::G1Prepared; - type SignatureGroupBaseField = <::G1 as CurveGroup>::BaseField; - - const SIGNATURE_SERIALIZED_SIZE: usize = 48; - - type PublicKeyGroup = E::G2; - type PublicKeyGroupAffine = E::G2Affine; - type PublicKeyPrepared = E::G2Prepared; - type PublicKeyGroupBaseField = <::G2 as CurveGroup>::BaseField; - - const PUBLICKEY_SERIALIZED_SIZE: usize = 96; - const SECRET_KEY_SIZE: usize = 32; - - const CURVE_NAME: &'static [u8] = P::CURVE_NAME; - const SIG_GROUP_NAME: &'static [u8] = b"G1"; - const CIPHER_SUIT_DOMAIN_SEPARATION: &'static [u8] = b"_XMD:SHA-256_SSWU_RO_"; - - type HashToSignatureField = DefaultFieldHasher; - type MapToSignatureCurve = WBMap; - - fn miller_loop<'a, I>(i: I) -> MillerLoopOutput - where - I: IntoIterator, - { - // We require an ugly unecessary allocation here because - // zcash's pairing library cnsumes an iterator of references - // to tuples of references, which always requires - let (i_a, i_b): (Vec, Vec) = - i.into_iter().cloned().unzip(); - - E::multi_miller_loop(i_b, i_a) //in Tiny BLS signature is in G1 - } - - fn pairing(p: G2, q: G1) -> E::TargetField - where - G1: Into, - G2: Into, - { - E::pairing(q.into(), p.into()).0 - } - - /// Prepared negative of the generator of the public key curve. - fn minus_generator_of_public_key_group_prepared() -> Self::PublicKeyPrepared { - let g2_minus_generator = ::Affine::generator(); - >::into( - -g2_minus_generator.into_group(), - ) - } - - fn hash_to_curve_map() -> MapToCurveBasedHasher< - Self::SignatureGroup, - Self::HashToSignatureField, - Self::MapToSignatureCurve, - > { - MapToCurveBasedHasher::< - Self::SignatureGroup, - DefaultFieldHasher, - WBMap, - >::new(QUICKNET_CTX) - .unwrap() - } - } - - \ No newline at end of file diff --git a/src/ibe/README.md b/src/ibe/README.md deleted file mode 100644 index 8f9c776..0000000 --- a/src/ibe/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Identity Based Encryption - -This module contains impementations of the FullIdent BF-IBE scheme. - -> The code in this repository has not yet received any security audits, so use at your own risk. - -## License -Apache-2 \ No newline at end of file diff --git a/src/ibe/fullident.rs b/src/ibe/fullident.rs deleted file mode 100644 index 31f8646..0000000 --- a/src/ibe/fullident.rs +++ /dev/null @@ -1,269 +0,0 @@ - -/* - * Copyright 2024 by Ideal Labs, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -use ark_ff::{UniformRand, Zero}; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_ec::Group; -use ark_std::{ - ops::Mul, - rand::Rng, -}; -use ark_std::vec::Vec; -use serde::{Deserialize, Serialize}; -use super::utils::{h2, h3, h4, cross_product_32}; - -use w3f_bls::{EngineBLS, Message}; - -/// represents a ciphertext in the BF-IBE FullIdent scheme -#[derive(Debug, Clone, PartialEq, CanonicalDeserialize, CanonicalSerialize, Serialize, Deserialize)] -pub struct IBECiphertext { - /// U = rP - pub u: E::PublicKeyGroup, - /// V = sigma (+) H_2(g_id^r) - pub v: Vec, - /// W = message (+) H_4(sigma) - pub w: Vec, -} - -#[derive(Debug, Clone, PartialEq)] -pub enum IbeError { - DecryptionFailed, -} - -/// A type to represent an IBE identity (for which we will encrypt message) -#[derive(Debug, Clone)] -pub struct Identity(pub Vec); - -impl Identity { - - /// construct a new identity from a string - pub fn new(ctx: &[u8], identities: Vec>) -> Self { - Self ( - identities.iter() - .map(|identity| Message::new(ctx, &identity)) - .collect::>() - ) - } - - /// the IBE extract function on a given secret key - pub fn extract(&self, sk: E::Scalar) -> IBESecret { - IBESecret(self.public::() * sk) - } - - /// derive the public key for this identity (hash to G1) - pub fn public(&self) -> E::SignatureGroup { - self.0.iter() - .map(|message| message.hash_to_signature_curve::()) - .fold(E::SignatureGroup::zero(), |acc, val| acc + val) - - } - - /// BF-IBE encryption - /// For a message with 32-bytes and a public key (in G2), calculates the BF-IBE ciphertext - /// - /// C = = - /// where r is randomly selected from the finite field (Z_p) and g_{ID} = e(Q_ID, P_pub) - /// - pub fn encrypt( - &self, - message: &[u8;32], - p_pub: E::PublicKeyGroup, - mut rng: R - ) -> IBECiphertext - where E: EngineBLS, R: Rng + Sized { - let t = E::Scalar::rand(&mut rng); - let mut t_bytes = Vec::new(); - t.serialize_compressed(&mut t_bytes) - .expect("compressed size has been allocated"); - let sigma = h4(&t_bytes); - // r= H3(sigma, message) - let r: E::Scalar = h3::(&sigma, message); - let p = <::PublicKeyGroup as Group>::generator(); - // U = rP \in \mathbb{G}_1 - let u = p * r; - // e(P_pub, Q_id) - let g_id = E::pairing(p_pub.mul(r), self.public::()); - // sigma (+) H2(e(P_pub, Q_id)) - let v_rhs = h2(g_id); - let v_out = cross_product_32(&sigma, &v_rhs); - // message (+) H4(sigma) - let w_rhs = h4(&sigma); - let w_out = cross_product_32(message, &w_rhs); - // (rP, sigma (+) H2(e(Q_id, P_pub)), message (+) H4(sigma)) - IBECiphertext:: { - u, - v: v_out.to_vec(), - w: w_out.to_vec(), - } - } -} - -/// The output of the IBE extract algorithm is a BLS signature -#[derive(Debug, Clone, CanonicalDeserialize, CanonicalSerialize, Serialize, Deserialize)] -pub struct IBESecret(pub E::SignatureGroup); - -impl IBESecret { - /// BF-IBE decryption of a ciphertext C = - /// Attempts to decrypt under the given IBESecret (in G1) - pub fn decrypt( - &self, - ciphertext: &IBECiphertext, - ) -> Result, IbeError> { - // sigma = V (+) H2(e(d_id, U)) - let sigma_rhs = h2(E::pairing(ciphertext.u, self.0)); - let sigma = cross_product_32(&ciphertext.v, &sigma_rhs); - // m = W (+) H4(sigma) - let m_rhs = h4(&sigma); - let m = cross_product_32(&ciphertext.w, &m_rhs); - // check: U == rP - let p = <::PublicKeyGroup as Group>::generator(); - let r = h3::(&sigma, &m); - let u_check = p * r; - - if !u_check.eq(&ciphertext.u) { - return Err(IbeError::DecryptionFailed); - } - - Ok(m) - } -} - -#[cfg(test)] -mod test { - - use super::*; - use alloc::vec; - use ark_std::{test_rng, UniformRand}; - use w3f_bls::TinyBLS377; - - // this enum represents the conditions or branches that I want to test - enum TestStatusReport { - DecryptionResult { data: Vec, verify: Vec }, - DecryptionFailure{ error: IbeError } - } - - fn run_test( - identity: Identity, - message: [u8;32], - derive_bad_sk: bool, - insert_bad_ciphertext: bool, - handler: &dyn Fn(TestStatusReport) -> () - ) { - let (msk, sk) = extract::(identity.clone(), derive_bad_sk); - - let p_pub = <::PublicKeyGroup as Group>::generator() * msk; - - let mut ct = IBECiphertext { - u: EB::PublicKeyGroup::generator(), - v: vec![], - w: vec![], - }; - - if !insert_bad_ciphertext { - ct = identity.encrypt(&message, p_pub, &mut test_rng()); - } - - match sk.decrypt(&ct) { - Ok(data) => { - handler(TestStatusReport::DecryptionResult{ data, verify: message.to_vec() }); - }, - Err(e) => { - handler(TestStatusReport::DecryptionFailure{ error: e }); - } - } - } - - fn extract( - identity: Identity, - derive_bad_sk: bool, - ) -> (E::Scalar, IBESecret) { - let msk = ::Scalar::rand(&mut test_rng()); - if derive_bad_sk { - return (msk, IBESecret(E::SignatureGroup::generator())) - } - - let sk = identity.extract::(msk); - (msk, sk) - } - - #[test] - pub fn fullident_identity_construction_works() { - let id_string = b"example@test.com"; - let identity = Identity::new(b"", vec![id_string.to_vec()]); - - let expected_message = Message::new(b"", id_string); - assert_eq!(identity.0[0], expected_message); - } - - #[test] - pub fn fullident_encrypt_and_decrypt() { - let id_string = b"example@test.com"; - let identity = Identity::new(b"", vec![id_string.to_vec()]); - let message: [u8;32] = [2;32]; - - run_test::( - identity, message, false, false, - &|status: TestStatusReport| { - match status { - TestStatusReport::DecryptionResult{ data, verify } => { - assert_eq!(data, verify); - }, - _ => - panic!("Decryption should work"), - } - }); - } - - #[test] - pub fn fullident_decryption_fails_with_bad_ciphertext() { - let id_string = b"example@test.com"; - let identity = Identity::new(b"", vec![id_string.to_vec()]); - let message: [u8;32] = [2;32]; - - run_test::( - identity, - message, - false, - true, - &|status: TestStatusReport| { - match status { - TestStatusReport::DecryptionFailure{ error } => { - assert_eq!(error, IbeError::DecryptionFailed); - }, - _ => panic!("all other conditions invalid"), - } - }); - } - - #[test] - pub fn fullident_decryption_fails_with_bad_key() { - let id_string = b"example@test.com"; - let identity = Identity::new(b"", vec![id_string.to_vec()]); - let message: [u8;32] = [2;32]; - - run_test::( - identity, message, true, false, - &|status: TestStatusReport| { - match status { - TestStatusReport::DecryptionFailure{ error } => { - assert_eq!(error, IbeError::DecryptionFailed); - }, - _ => panic!("all other conditions invalid"), - } - }); - } -} \ No newline at end of file diff --git a/src/tlock.rs b/src/tlock.rs deleted file mode 100644 index 260d39c..0000000 --- a/src/tlock.rs +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright 2024 by Ideal Labs, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -use crate::{ - ibe::fullident::{IBECiphertext, IBESecret, Identity}, - aes, aes::AESOutput, -}; - -use ark_serialize::CanonicalDeserialize; -use ark_serialize::CanonicalSerialize; -use serde::{Deserialize, Serialize}; - -use ark_std::{ - rand::{CryptoRng, Rng}, - vec::Vec, -}; - -use w3f_bls::EngineBLS; - -/// a secret key used for encryption/decryption -pub type OpaqueSecretKey = [u8; 32]; - -// use crate::tiny_bls_381; - -/// the result of successful decryption of a timelocked ciphertext -#[derive(Serialize, Deserialize, Debug)] -pub struct DecryptionResult { - /// the recovered plaintext - pub message: Vec, - /// the recovered secret key - pub secret: OpaqueSecretKey, -} - -// #[derive(Serialize, Deserialize, Debug)] -#[derive(CanonicalDeserialize, CanonicalSerialize, Debug)] -// #[derive(Debug)] -pub struct TLECiphertext { - pub aes_ct: AESOutput, - pub etf_ct: IBECiphertext, -} - -#[derive(Debug, PartialEq)] -pub enum ClientError { - AesEncryptError, - DeserializationError, - DeserializationErrorG1, - DeserializationErrorG2, - DeserializationErrorFr, - DecryptionError, - VectorDimensionMismatch, - InvalidSignature, - Other, -} - -/// encrypt a message for an identity -/// -/// * `p_pub`: the public key commitment for the IBE system (i.e. the setup phase) -/// * `message`: The message to encrypt -/// * `id`: the identity to encrypt for -/// * `rng`: a CSPRNG -/// -pub fn tle( - p_pub: E::PublicKeyGroup, - secret_key: OpaqueSecretKey, - message: &[u8], - id: Identity, - mut rng: R, -) -> Result, ClientError> -where - E: EngineBLS, -{ - let ct_aes = - aes::encrypt(message, secret_key, &mut rng) - .map_err(|_| ClientError::AesEncryptError)?; // not sure how to test this line... - let ct: IBECiphertext = id.encrypt(&secret_key, p_pub, &mut rng); - Ok(TLECiphertext { - aes_ct: ct_aes, - etf_ct: ct, - }) -} - -impl TLECiphertext { - /// decrypt a ciphertext created as a result of timelock encryption - /// the signature should be equivalent to the output of IBE.Extract(ID) - /// where ID is the identity for which the message was created - pub fn tld(&self, sig: E::SignatureGroup) -> Result { - let secret_bytes = IBESecret(sig) - .decrypt(&self.etf_ct) - .map_err(|_| ClientError::InvalidSignature)?; - - return Self::aes_decrypt(&self, secret_bytes); - } - - /// TODO: make t his take secret_bytes: [u8;32] instead - /// decrypt a ciphertext created as a result of timelock encryption. - /// requires user to know the secret key beforehand - pub fn aes_decrypt(&self, secret_bytes: Vec) -> Result { - let secret_array: [u8; 32] = secret_bytes.clone().try_into().unwrap_or([0u8; 32]); - - if let Ok(plaintext) = aes::decrypt(AESOutput { - ciphertext: self.aes_ct.ciphertext.clone(), - nonce: self.aes_ct.nonce.clone(), - key: secret_bytes, - }) { - return Ok(DecryptionResult { - message: plaintext, - secret: secret_array, - }); - } - Err(ClientError::DecryptionError) - } -} - -#[cfg(test)] -mod test { - - use super::*; - use alloc::vec; - use ark_ec::Group; - use ark_ff::UniformRand; - use rand_chacha::ChaCha20Rng; - use rand_core::{OsRng, SeedableRng}; - use sha2::Digest; - use w3f_bls::TinyBLS377; - use crate::curves::drand::TinyBLS381; - - // specific conditions that we want to test/verify - enum TestStatusReport { - DecryptSuccess { actual: Vec, expected: Vec }, - DecryptionFailed { error: ClientError }, - } - - fn tlock_test( - inject_bad_ct: bool, - inject_bad_nonce: bool, - handler: &dyn Fn(TestStatusReport) -> (), - ) { - let message = b"this is a test message".to_vec(); - let id = Identity::new(b"", vec![b"id".to_vec()]); - let sk = E::Scalar::rand(&mut OsRng); - let p_pub = E::PublicKeyGroup::generator() * sk; - - // key used for aes encryption - let msk = [1; 32]; - - let sig: E::SignatureGroup = id.extract::(sk).0; - - match tle::(p_pub, msk, &message, id, OsRng) { - Ok(mut ct) => { - // create error scenarios here - if inject_bad_ct { - ct.aes_ct.ciphertext = vec![]; - } - - if inject_bad_nonce { - ct.aes_ct.nonce = vec![]; - } - - match ct.tld(sig) { - Ok(output) => { - handler(TestStatusReport::DecryptSuccess { - actual: output.message, - expected: message, - }); - } - Err(e) => { - handler(TestStatusReport::DecryptionFailed { error: e }); - } - } - } - Err(_) => { - panic!("The test should pass but failed to run tlock encrypt"); - } - } - } - - #[test] - pub fn tlock_can_encrypt_decrypt_with_single_sig() { - tlock_test::(false, false, &|status: TestStatusReport| match status { - TestStatusReport::DecryptSuccess { actual, expected } => { - assert_eq!(actual, expected); - } - _ => panic!("all other conditions invalid"), - }); - } - - #[test] - pub fn tlock_can_encrypt_decrypt_with_full_sigs_present() { - tlock_test::(false, false, &|status: TestStatusReport| match status { - TestStatusReport::DecryptSuccess { actual, expected } => { - assert_eq!(actual, expected); - } - _ => panic!("all other conditions invalid"), - }); - } - - #[test] - pub fn tlock_can_encrypt_decrypt_with_many_identities_at_threshold() { - tlock_test::(false, false, &|status: TestStatusReport| match status { - TestStatusReport::DecryptSuccess { actual, expected } => { - assert_eq!(actual, expected); - } - _ => panic!("all other conditions invalid"), - }); - } - - #[test] - pub fn tlock_decryption_fails_with_bad_ciphertext() { - tlock_test::(true, false, &|status: TestStatusReport| match status { - TestStatusReport::DecryptionFailed { error } => { - assert_eq!(error, ClientError::DecryptionError); - } - _ => panic!("all other conditions invalid"), - }); - } - - #[test] - pub fn tlock_decryption_fails_with_bad_nonce() { - tlock_test::(false, true, &|status: TestStatusReport| match status { - TestStatusReport::DecryptionFailed { error } => { - assert_eq!(error, ClientError::DecryptionError); - } - _ => panic!("all other conditions invalid"), - }); - } - - #[test] - pub fn tlock_encrypt_decrypt_drand_quicknet_works() { - // using a pulse from drand's QuickNet - // https://api.drand.sh/52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971/public/1000 - // the beacon public key - let pk_bytes = b"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a"; - // a round number that we know a signature for - let round: u64 = 1000; - // the signature produced in that round - let signature = b"b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39"; - - // Convert hex string to bytes - let pub_key_bytes = hex::decode(pk_bytes).expect("Decoding failed"); - // Deserialize to G1Affine - let pub_key = ::PublicKeyGroup::deserialize_compressed( - &*pub_key_bytes, - ) - .unwrap(); - - // then we tlock a message for the pubkey - let plaintext = b"this is a test".as_slice(); - let esk = [2; 32]; - - let sig_bytes = hex::decode(signature).expect("The signature should be well formatted"); - let sig = - ::SignatureGroup::deserialize_compressed(&*sig_bytes) - .unwrap(); - - let message = { - let mut hasher = sha2::Sha256::new(); - hasher.update(round.to_be_bytes()); - hasher.finalize().to_vec() - }; - - let identity = Identity::new(b"", vec![message]); - - let rng = ChaCha20Rng::seed_from_u64(0); - let ct = tle::( - pub_key, - esk, - plaintext, - identity, - rng, - ).unwrap(); - - // then we can decrypt the ciphertext using the signature - let result: DecryptionResult = ct.tld(sig).unwrap(); - assert!(result.message == plaintext); - } -} diff --git a/timelock/Cargo.toml b/timelock/Cargo.toml new file mode 100644 index 0000000..0edf5b1 --- /dev/null +++ b/timelock/Cargo.toml @@ -0,0 +1,70 @@ +[package] +name = "timelock" +version = "0.0.1" +edition = "2021" +description = "timelock encryption imlementation using BF-IBE" +license = "Apache-2.0" +repository = "https://github.com/ideal-lab5/tle" +authors = ["Tony Riemer "] +rust-version = "1.80" +homepage = "https://idealabs.network" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive", "max-encoded-len"] } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +serde = { version = "1.0.204", default-features = false, features = ["derive", "alloc"] } +aes-gcm = { version = "0.10.2", default-features = false, features = ["alloc", "aes", "rand_core"] } +array-bytes = "6.1.0" +generic-array = "0.14.7" +sha2 = { version = "0.10.2", default-features = false } +sha3 = { version = "0.10.0", default-features = false } +# arkworks dependencies +ark-std = { version = "0.4.0", default-features = false } +ark-ff = { version = "0.4.0", default-features = false } +ark-poly = { version = "0.4.0", default-features = false } +ark-ec = { version = "0.4.0", default-features = false } + +ark-serialize = { version = "0.4.0", default-features = false } +ark-bls12-381 = { version = "0.4.0", features = ["curve"], default-features = false } +ark-bls12-377 = { version = "0.4.0", features = ["curve"], default-features = false } + +serde_json = { version = "1.0.108", default-features = false, features = ["alloc"] } +serde_cbor = {version = "0.11.2", default-features = false } +chacha20poly1305 = { version = "0.10.1", default-features = false} + +rand_core = "0.6.4" +rand_chacha = { version = "0.3.1", default-features = false } +w3f-bls = { version = "=0.1.4", default-features = false } + +[dev-dependencies] +hex = "0.4.3" +ark-ed-on-bls12-381 = { version = "^0.4.0", default-features = false, features = [ "r1cs" ] } +simulacrum = "0.3.0" +criterion = { version = "0.4", features = ["html_reports"] } + +[[bench]] +name = "tlock" +harness = false + +[features] +default = ["std"] +std = [ + "codec/std", + "scale-info/std", + "sha2/std", + "sha3/std", + "ark-std/std", + "ark-ff/std", + "ark-poly/std", + "ark-ec/std", + "ark-serialize/std", + "ark-bls12-381/std", + "serde_json/std", + "serde_cbor/std", + "rand_chacha/std", + "chacha20poly1305/std", + "w3f-bls/std", +] diff --git a/timelock/README.md b/timelock/README.md new file mode 100644 index 0000000..bf97026 --- /dev/null +++ b/timelock/README.md @@ -0,0 +1,69 @@ +# Timelock Encryption + +This library enables timelock encryption using the Boneh-Franklin IBE scheme. Specifically, it allows timelock encryption to be instantiated on top of a verifiable randomness beacon, such as the [Ideal Network](https://docs.idealabs.network) or [drand](https://drand.love). The library is implemented with [arkworks](https://github.com/arkworks-rs) + +Currently the scheme supports several flavors of beacons, including the Drand 'quicknet', which uses BLS381 keys, and the Ideal Network beacon, which uses BLS377 keys. Both beacons use a BLS variant with tiny 48 byte signatures and 96 byte public keys, with signatures being elements of $\mathbb{G}_1$ and public keys in $\mathbb{G}_2$. + +This flavor of timelock encryption is a hybrid encryption scheme, using `AES_GCM` to efficiently encrypt and decrypt and size ciphertexts, while secret keys are encrypted for identities of future beacon pulses. + +## Usage + +The library is flexible and can support various flavors of encryption schemes. Officially, only AES_GCM is supported at the moment, but we will support AGE encryption within the library in the near future. You can implement your own by implementing the `StreamCipherProvider` trait. + +### Encrypt a Message + +This is an example of using the Ideal Network beacon to encrypt message. This same can be accomplished against Drand's quicknet. See the tlock tests [here](./src/tlock.rs) for more examples. + +``` rust +// gather public parameters for the randomenss beacon +let pk = hex::decode("471ba929a4e2ef2790fb5f2a65ebe86598a28cbb8a58e49c6cc7292cf40cecbdf10152394ba938367ded5355ae373e01a99567467bc816864774e84b984fc16e2ae2232be6481cd4db0e378e1d6b0c2265d2aa8e0fa4e2c76958ce9f12df8e0134c431c181308a68b94b9cfba5176c3a8dd22ead9a68a077ecce7facfe4adb9e0e0a71c94a0c436d8049b03fa5352301").expect("decoding failure"); +let p_pub = ::deserialize_compressed(&*pk).unwrap(); +// construct an identity +// choose a future round number of the randomness beacon +let round_number: u64 = 10; +let identity = Identity::new(b"", vec![round_number.to_be_bytes()]); +// generate an ephemeral secret key 32-byte secret key +let esk = [2;32]; +// encrypt using the identity +let ct = tle::::(p_pub, msk, &message, id, OsRng).unwrap(); +``` + +### Decrypt a Message + +#### Early decryption +Message can be encrypted at any time using the ephemeral secret key used to encrypt it: +``` rust +// use the same esk as in `encrypt` +let early_result = ct.aes_decrypt(esk).unwrap(); +``` + +#### Timelock Decryption +Messages can also be decrypted with a signature produced by a beacon on top of the 'identity' used to construct it: +``` rust +// first get a valid siganture from the beacon +let signature = hex::decode(b"f8178b1c3c9477f7b0e37cd3e63ff3a184e1d05df3117438cd05e109b5731a52a96ae344e461bc6cb8e04f5efed34701").expect("decoding failure"); +let result: DecryptionResult = ct.tld(sig).unwrap(); +``` + +## Build + +From the root, run `cargo build` + +## Test + + +### Unit tests +From the root, run `cargo test` + +### Coverage +We use [tarpaulin](https://github.com/xd009642/tarpaulin) for test coverage. From the root, run: + +``` +cargo tarpaulin --rustflags="-C opt-level=0" +``` + +### Benchmarks + +``` shell +cargo benchmark +``` diff --git a/benches/benches.md b/timelock/benches/benches.md similarity index 71% rename from benches/benches.md rename to timelock/benches/benches.md index 05038aa..6dd0861 100644 --- a/benches/benches.md +++ b/timelock/benches/benches.md @@ -11,8 +11,8 @@ The output can be found in `/target/criterion/your_bench_target`. It constructs ## Adding new Benches To add a new bench: -1. create a new file under etf-crypto-primitives/benches for example `my_new_bench.rs` -2. register your benchmark in the etf-crypto-primitives Cargo.toml by adding: +1. create a new file under `tle/benches` for example `my_new_bench.rs` +2. register your benchmark in the tle Cargo.toml by adding: ``` toml [[bench]] name = "my_new_bench" diff --git a/timelock/benches/tlock.rs b/timelock/benches/tlock.rs new file mode 100644 index 0000000..46be7c7 --- /dev/null +++ b/timelock/benches/tlock.rs @@ -0,0 +1,62 @@ +use ark_ec::Group; +use ark_ff::UniformRand; +use criterion::{ + black_box, criterion_group, criterion_main, BenchmarkId, Criterion, + Throughput, +}; +use rand_core::OsRng; +use tle::{ibe::fullident::*, stream_ciphers::AESGCMStreamCipherProvider, tlock::*}; +use w3f_bls::{EngineBLS, SecretKey, TinyBLS377}; + +/// encrypts a message for the identity and then decrypts it after preparing a +/// bls sig this expects on a single signature but tests many different input +/// data sizes +fn tlock_tinybls377( + msk: [u8;32], + p_pub: E::PublicKeyGroup, + message: Vec, + id: Identity, + sig: IBESecret, +) { + let ct = tle::( + p_pub, msk, &message, id, OsRng, + ) + .uwnrap(); + let _m = tld::(ct, sig).unwrap(); +} + +fn tlock(c: &mut Criterion) { + static KB: usize = 1024; + + let s = ::Scalar::rand(&mut OsRng); + let p_pub = ::PublicKeyGroup::generator() * s; + let id = Identity::new(b"", vec![b"test".to_vec()]); + let msk = ::Scalar::rand(&mut OsRng); + + let mut group = c.benchmark_group("tlock"); + for size in [KB, 2 * KB, 4 * KB, 8 * KB, 16 * KB, 128 * KB, 256 * KB].iter() { + let mut dummy_data = Vec::with_capacity(*size); + (0..*size).for_each(|i| dummy_data.push(i as u8)); + + group.throughput(Throughput::Bytes(KB as u64)); + group.bench_with_input( + BenchmarkId::from_parameter(size), + size, + |b, &size| { + b.iter(|| { + tlock_tinybls377::( + black_box([2;32]), + black_box(p_pub), + black_box(dummy_data.clone()), + black_box(id.clone()), + black_box(id.extract(s)), + ); + }); + }, + ); + } + group.finish(); +} + +criterion_group!(benches, tlock); +criterion_main!(benches); diff --git a/timelock/src/curves/drand.rs b/timelock/src/curves/drand.rs new file mode 100644 index 0000000..e017ad7 --- /dev/null +++ b/timelock/src/curves/drand.rs @@ -0,0 +1,149 @@ +/* + * Copyright 2024 by Ideal Labs, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use alloc::vec::Vec; + +use ark_ec::{ + hashing::{ + curve_maps::wb::{WBConfig, WBMap}, + map_to_curve_hasher::{MapToCurve, MapToCurveBasedHasher}, + HashToCurve, + }, + pairing::{MillerLoopOutput, Pairing}, + AffineRepr, CurveGroup, +}; +use ark_ff::field_hashers::DefaultFieldHasher; + +use sha2::Sha256; //IETF standard asks for SHA256 + +use ark_ec::bls12::Bls12Config; +use core::marker::PhantomData; +use w3f_bls::EngineBLS; + +pub const QUICKNET_CTX: &[u8] = b"BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_"; + +pub type TinyBLS381 = + TinyBLSDrandQuicknet; + +/// Trait to add extra config for a curve which is not in ArkWorks library +pub trait CurveExtraConfig { + const CURVE_NAME: &'static [u8]; +} + +/// Aggregate BLS signature scheme with Signature in G1 for BLS12-381 curve. +impl CurveExtraConfig for ark_bls12_381::Config { + const CURVE_NAME: &'static [u8] = b"BLS12381"; +} + +/// A BLS variant with tiny 48 byte signatures and 96 byte public keys, +/// +/// Specifically, this configuration is used by Drand's QuickNet. +/// +/// Note on performance: verifiers always perform `O(signers)` additions on the +/// `PublicKeyGroup`, or worse 128 bit scalar multiplications with +/// delinearization. Yet, there are specific use cases where this variant +/// performs better. We swapy two group roles relative to zcash here. +#[derive(Default)] +pub struct TinyBLSDrandQuicknet( + pub E, + PhantomData P>, +) +where +

::G1Config: WBConfig, + WBMap<

::G1Config>: MapToCurve<::G1>; + +impl EngineBLS + for TinyBLSDrandQuicknet +where +

::G1Config: WBConfig, + WBMap<

::G1Config>: MapToCurve<::G1>, +{ + type Engine = E; + type Scalar = ::ScalarField; + + type SignatureGroup = E::G1; + type SignatureGroupAffine = E::G1Affine; + type SignaturePrepared = E::G1Prepared; + type SignatureGroupBaseField = + <::G1 as CurveGroup>::BaseField; + + const SIGNATURE_SERIALIZED_SIZE: usize = 48; + + type PublicKeyGroup = E::G2; + type PublicKeyGroupAffine = E::G2Affine; + type PublicKeyPrepared = E::G2Prepared; + type PublicKeyGroupBaseField = + <::G2 as CurveGroup>::BaseField; + + const PUBLICKEY_SERIALIZED_SIZE: usize = 96; + const SECRET_KEY_SIZE: usize = 32; + + const CURVE_NAME: &'static [u8] = P::CURVE_NAME; + const SIG_GROUP_NAME: &'static [u8] = b"G1"; + const CIPHER_SUIT_DOMAIN_SEPARATION: &'static [u8] = + b"_XMD:SHA-256_SSWU_RO_"; + + type HashToSignatureField = DefaultFieldHasher; + type MapToSignatureCurve = WBMap; + + fn miller_loop<'a, I>(i: I) -> MillerLoopOutput + where + I: IntoIterator< + Item = &'a (Self::PublicKeyPrepared, Self::SignaturePrepared), + >, + { + // We require an ugly unecessary allocation here because + // zcash's pairing library cnsumes an iterator of references + // to tuples of references, which always requires + let (i_a, i_b): ( + Vec, + Vec, + ) = i.into_iter().cloned().unzip(); + + E::multi_miller_loop(i_b, i_a) //in Tiny BLS signature is in G1 + } + + fn pairing(p: G2, q: G1) -> E::TargetField + where + G1: Into, + G2: Into, + { + E::pairing(q.into(), p.into()).0 + } + + /// Prepared negative of the generator of the public key curve. + fn minus_generator_of_public_key_group_prepared() -> Self::PublicKeyPrepared + { + let g2_minus_generator = + ::Affine::generator(); + >::into( + -g2_minus_generator.into_group(), + ) + } + + fn hash_to_curve_map() -> MapToCurveBasedHasher< + Self::SignatureGroup, + Self::HashToSignatureField, + Self::MapToSignatureCurve, + > { + MapToCurveBasedHasher::< + Self::SignatureGroup, + DefaultFieldHasher, + WBMap, + >::new(QUICKNET_CTX) + .unwrap() + } +} diff --git a/src/curves/mod.rs b/timelock/src/curves/mod.rs similarity index 95% rename from src/curves/mod.rs rename to timelock/src/curves/mod.rs index 60729bf..6b3d13f 100644 --- a/src/curves/mod.rs +++ b/timelock/src/curves/mod.rs @@ -1,17 +1,17 @@ -/* - * Copyright 2024 by Ideal Labs, LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// custom curves to support drand -pub mod drand; \ No newline at end of file +/* + * Copyright 2024 by Ideal Labs, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// custom curves to support drand +pub mod drand; diff --git a/timelock/src/ibe/README.md b/timelock/src/ibe/README.md new file mode 100644 index 0000000..68251f0 --- /dev/null +++ b/timelock/src/ibe/README.md @@ -0,0 +1,38 @@ +# Identity Based Encryption + +This module contains an impementation of the [Boneh-Franklin Identity Based Encryption](https://crypto.stanford.edu/~dabo/papers/bfibe.pdf) "FullIdent" scheme. The protocol enables secure message encryption and decryption based on identities. It uses elliptic-curve cryptography (BLS signatures) and is implemented with the [arkworks library](https://github.com/arkworks-rs) and [w3f/bls](https://github.com/w3f/bls). + +## Usage + +Below is an example of encrypting a message for an identity and subsequently decrypting a message using a secret key 'extracted' from the identity. + +``` rust +use bf_ibe::{Identity, Ciphertext, IBESecret}; +use w3f_bls::TinyBLS377; +use ark_std::test_rng; + +// Create an identity +let id_string = b"example@test.com"; +let identity = Identity::new(b"", vec![id_string.to_vec()]); + +// Generate a message +let message: [u8; 32] = [1; 32]; + +// Create master secret and public key +let msk = ::Scalar::rand(&mut test_rng()); +let p_pub = <::PublicKeyGroup as Group>::generator() * msk; + +// Encrypt the message +let ciphertext = identity.encrypt(&message, p_pub, &mut test_rng()); + +// "Extract" a secret key +let sk = identity.extract::(msk); +// Decrypt the message +let decrypted_message = sk.decrypt(&ciphertext).expect("Decryption failed"); + +// Verify +assert_eq!(message.to_vec(), decrypted_message); +``` + +## License +Apache-2.0 \ No newline at end of file diff --git a/timelock/src/ibe/fullident.rs b/timelock/src/ibe/fullident.rs new file mode 100644 index 0000000..7d35bf6 --- /dev/null +++ b/timelock/src/ibe/fullident.rs @@ -0,0 +1,286 @@ +/* + * Copyright 2024 by Ideal Labs, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use super::utils::{cross_product_32, h2, h3, h4}; +use ark_ec::Group; +use ark_ff::{UniformRand, Zero}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use ark_std::{ops::Mul, rand::Rng, vec::Vec}; +use serde::{Deserialize, Serialize}; + +use w3f_bls::{EngineBLS, Message}; + +/// Represents a ciphertext in the BF-IBE FullIdent scheme +#[derive( + Debug, + Clone, + PartialEq, + CanonicalDeserialize, + CanonicalSerialize, + Serialize, + Deserialize, +)] +pub struct Ciphertext { + /// U = rP + pub u: E::PublicKeyGroup, + /// V = sigma (+) H_2(g_id^r) + pub v: Vec, + /// W = message (+) H_4(sigma) + pub w: Vec, +} + +#[derive(Debug, Clone, PartialEq)] +pub enum IbeError { + DecryptionFailed, +} + +/// A type to represent an IBE identity (for which we will encrypt message) +#[derive(Debug, Clone)] +pub struct Identity(pub Vec); + +impl Identity { + /// construct a new identity from a string + pub fn new(ctx: &[u8], identities: Vec>) -> Self { + Self( + identities + .iter() + .map(|identity| Message::new(ctx, &identity)) + .collect::>(), + ) + } + + /// The IBE extract function on a given secret key + pub fn extract(&self, sk: E::Scalar) -> IBESecret { + IBESecret(self.public::() * sk) + } + + /// Derive the public key for this identity (hash to G1) + pub fn public(&self) -> E::SignatureGroup { + self.0 + .iter() + .map(|message| message.hash_to_signature_curve::()) + .fold(E::SignatureGroup::zero(), |acc, val| acc + val) + } + + /// BF-IBE encryption + /// + /// For a message with 32-bytes and a public key (in G2), calculates the + /// BF-IBE ciphertext + /// + /// C = = + /// where r is randomly selected from the finite field (Z_p) and g_{ID} = + /// e(Q_ID, P_pub) + pub fn encrypt( + &self, + message: &[u8; 32], + p_pub: E::PublicKeyGroup, + mut rng: R, + ) -> Ciphertext + where + E: EngineBLS, + R: Rng + Sized, + { + let t = E::Scalar::rand(&mut rng); + let mut t_bytes = Vec::new(); + t.serialize_compressed(&mut t_bytes) + .expect("compressed size has been allocated"); + let sigma = h4(&t_bytes); + // r= H3(sigma, message) + let r: E::Scalar = h3::(&sigma, message); + let p = <::PublicKeyGroup as Group>::generator(); + // U = rP \in \mathbb{G}_1 + let u = p * r; + // e(P_pub, Q_id) + let g_id = E::pairing(p_pub.mul(r), self.public::()); + // sigma (+) H2(e(P_pub, Q_id)) + let v_rhs = h2(g_id); + let v_out = cross_product_32(&sigma, &v_rhs); + // message (+) H4(sigma) + let w_rhs = h4(&sigma); + let w_out = cross_product_32(message, &w_rhs); + // (rP, sigma (+) H2(e(Q_id, P_pub)), message (+) H4(sigma)) + Ciphertext:: { u, v: v_out.to_vec(), w: w_out.to_vec() } + } +} + +/// The output of the IBE extract algorithm is a BLS signature +#[derive( + Debug, + Clone, + CanonicalDeserialize, + CanonicalSerialize, + Serialize, + Deserialize, +)] +pub struct IBESecret(pub E::SignatureGroup); + +impl IBESecret { + /// BF-IBE decryption of a ciphertext C = + /// Attempts to decrypt under the given IBESecret (in G1) + pub fn decrypt( + &self, + ciphertext: &Ciphertext, + ) -> Result, IbeError> { + // sigma = V (+) H2(e(d_id, U)) + let sigma_rhs = h2(E::pairing(ciphertext.u, self.0)); + let sigma = cross_product_32(&ciphertext.v, &sigma_rhs); + // m = W (+) H4(sigma) + let m_rhs = h4(&sigma); + let m = cross_product_32(&ciphertext.w, &m_rhs); + // check: U == rP + let p = <::PublicKeyGroup as Group>::generator(); + let r = h3::(&sigma, &m); + let u_check = p * r; + + if !u_check.eq(&ciphertext.u) { + return Err(IbeError::DecryptionFailed); + } + + Ok(m) + } +} + +#[cfg(test)] +mod test { + + use super::*; + use alloc::vec; + use ark_std::{test_rng, UniformRand}; + use w3f_bls::TinyBLS377; + + // this enum represents the conditions or branches that I want to test + enum TestStatusReport { + DecryptionResult { data: Vec, verify: Vec }, + DecryptionFailure { error: IbeError }, + } + + fn run_test( + identity: Identity, + message: [u8; 32], + derive_bad_sk: bool, + insert_bad_ciphertext: bool, + handler: &dyn Fn(TestStatusReport) -> (), + ) { + let (msk, sk) = extract::(identity.clone(), derive_bad_sk); + + let p_pub = + <::PublicKeyGroup as Group>::generator() * msk; + + let mut ct = Ciphertext { + u: EB::PublicKeyGroup::generator(), + v: vec![], + w: vec![], + }; + + if !insert_bad_ciphertext { + ct = identity.encrypt(&message, p_pub, &mut test_rng()); + } + + match sk.decrypt(&ct) { + Ok(data) => { + handler(TestStatusReport::DecryptionResult { + data, + verify: message.to_vec(), + }); + }, + Err(e) => { + handler(TestStatusReport::DecryptionFailure { error: e }); + }, + } + } + + fn extract( + identity: Identity, + derive_bad_sk: bool, + ) -> (E::Scalar, IBESecret) { + let msk = ::Scalar::rand(&mut test_rng()); + if derive_bad_sk { + return (msk, IBESecret(E::SignatureGroup::generator())); + } + + let sk = identity.extract::(msk); + (msk, sk) + } + + #[test] + pub fn fullident_identity_construction_works() { + let id_string = b"example@test.com"; + let identity = Identity::new(b"", vec![id_string.to_vec()]); + + let expected_message = Message::new(b"", id_string); + assert_eq!(identity.0[0], expected_message); + } + + #[test] + pub fn fullident_encrypt_and_decrypt() { + let id_string = b"example@test.com"; + let identity = Identity::new(b"", vec![id_string.to_vec()]); + let message: [u8; 32] = [2; 32]; + + run_test::( + identity, + message, + false, + false, + &|status: TestStatusReport| match status { + TestStatusReport::DecryptionResult { data, verify } => { + assert_eq!(data, verify); + }, + _ => panic!("Decryption should work"), + }, + ); + } + + #[test] + pub fn fullident_decryption_fails_with_bad_ciphertext() { + let id_string = b"example@test.com"; + let identity = Identity::new(b"", vec![id_string.to_vec()]); + let message: [u8; 32] = [2; 32]; + + run_test::( + identity, + message, + false, + true, + &|status: TestStatusReport| match status { + TestStatusReport::DecryptionFailure { error } => { + assert_eq!(error, IbeError::DecryptionFailed); + }, + _ => panic!("all other conditions invalid"), + }, + ); + } + + #[test] + pub fn fullident_decryption_fails_with_bad_key() { + let id_string = b"example@test.com"; + let identity = Identity::new(b"", vec![id_string.to_vec()]); + let message: [u8; 32] = [2; 32]; + + run_test::( + identity, + message, + true, + false, + &|status: TestStatusReport| match status { + TestStatusReport::DecryptionFailure { error } => { + assert_eq!(error, IbeError::DecryptionFailed); + }, + _ => panic!("all other conditions invalid"), + }, + ); + } +} diff --git a/src/lib.rs b/timelock/src/ibe/lib.rs similarity index 97% rename from src/lib.rs rename to timelock/src/ibe/lib.rs index ed132f9..98962b5 100644 --- a/src/lib.rs +++ b/timelock/src/ibe/lib.rs @@ -33,7 +33,7 @@ extern crate alloc; -pub mod aes; +pub mod stream_ciphers; pub mod curves; pub mod ibe; pub mod tlock; diff --git a/src/ibe/mod.rs b/timelock/src/ibe/mod.rs similarity index 97% rename from src/ibe/mod.rs rename to timelock/src/ibe/mod.rs index 3b34a79..778d17e 100644 --- a/src/ibe/mod.rs +++ b/timelock/src/ibe/mod.rs @@ -15,4 +15,4 @@ */ pub mod fullident; -mod utils; \ No newline at end of file +pub mod utils; diff --git a/src/ibe/utils.rs b/timelock/src/ibe/utils.rs similarity index 55% rename from src/ibe/utils.rs rename to timelock/src/ibe/utils.rs index caca68f..60ebea4 100644 --- a/src/ibe/utils.rs +++ b/timelock/src/ibe/utils.rs @@ -23,58 +23,59 @@ use w3f_bls::EngineBLS; /// sha256 hasher pub fn sha256(b: &[u8]) -> Vec { - let mut hasher = sha2::Sha256::new(); - hasher.update(b); - hasher.finalize().to_vec() + let mut hasher = sha2::Sha256::new(); + hasher.update(b); + hasher.finalize().to_vec() } // TODO: can do this in place instead pub fn cross_product_32(a: &[u8], b: &[u8]) -> Vec { - let mut o = a.to_owned(); - for (i, ri) in o.iter_mut().enumerate().take(32) { - *ri ^= b[i]; - } - o.to_vec() + let mut o = a.to_owned(); + for (i, ri) in o.iter_mut().enumerate().take(32) { + *ri ^= b[i]; + } + o.to_vec() } /// a map from G -> {0, 1}^{32} pub fn h2(g: G) -> Vec { - // let mut out = Vec::with_capacity(g.compressed_size()); - let mut out = Vec::new(); - g.serialize_compressed(&mut out) - .expect("Enough space has been allocated in the buffer"); - sha256(&out) + // let mut out = Vec::with_capacity(g.compressed_size()); + let mut out = Vec::new(); + g.serialize_compressed(&mut out) + .expect("Enough space has been allocated in the buffer"); + sha256(&out) } // Should add a const to the signature so I can enforce sized inputs? // right now this works with any size slices /// H_3: {0,1}^n x {0, 1}^m -> Z_p pub fn h3(a: &[u8], b: &[u8]) -> E::Scalar { - let mut input = Vec::new(); - input.extend_from_slice(a); - input.extend_from_slice(b); - let hash = sha256(&input); - E::Scalar::from_be_bytes_mod_order(&hash) + let mut input = Vec::new(); + input.extend_from_slice(a); + input.extend_from_slice(b); + let hash = sha256(&input); + E::Scalar::from_be_bytes_mod_order(&hash) } /// H_4: {0, 1}^n -> {0, 1}^n pub fn h4(a: &[u8]) -> Vec { - let o = sha256(a); - o[..a.len()].to_vec() + let o = sha256(a); + o[..a.len()].to_vec() } #[cfg(test)] mod test { - use alloc::vec; + use alloc::vec; - #[test] - fn utils_can_calc_sha256() { - let actual = crate::ibe::utils::sha256(b"test"); - let expected = vec![ - 159, 134, 208, 129, 136, 76, 125, 101, 154, 47, 234, 160, 197, 90, 208, 21, 163, 191, - 79, 27, 43, 11, 130, 44, 209, 93, 108, 21, 176, 240, 10, 8, - ]; - assert_eq!(actual, expected); - } + #[test] + fn utils_can_calc_sha256() { + let actual = crate::ibe::utils::sha256(b"test"); + let expected = vec![ + 159, 134, 208, 129, 136, 76, 125, 101, 154, 47, 234, 160, 197, 90, + 208, 21, 163, 191, 79, 27, 43, 11, 130, 44, 209, 93, 108, 21, 176, + 240, 10, 8, + ]; + assert_eq!(actual, expected); + } } diff --git a/timelock/src/lib.rs b/timelock/src/lib.rs new file mode 100644 index 0000000..2b7684c --- /dev/null +++ b/timelock/src/lib.rs @@ -0,0 +1,38 @@ +/* + * Copyright 2024 by Ideal Labs, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#![no_std] +#![warn( + unused, + future_incompatible, + nonstandard_style, + rust_2018_idioms, + rust_2021_compatibility +)] +#![allow( + clippy::op_ref, + clippy::suspicious_op_assign_impl, + clippy::type_complexity, + clippy::should_implement_trait +)] +#![deny(unsafe_code)] + +extern crate alloc; + +pub mod curves; +pub mod ibe; +pub mod stream_ciphers; +pub mod tlock; diff --git a/timelock/src/stream_ciphers.rs b/timelock/src/stream_ciphers.rs new file mode 100644 index 0000000..f79ec22 --- /dev/null +++ b/timelock/src/stream_ciphers.rs @@ -0,0 +1,239 @@ +/* + * Copyright 2024 by Ideal Labs, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use aes_gcm::{ + aead::{Aead, AeadCore, AeadInPlace, KeyInit}, + Aes256Gcm, Nonce, +}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use ark_std::rand::Rng; + +use serde::{Deserialize, Serialize}; + +use ark_std::{rand::CryptoRng, vec::Vec}; + +/// The output of AES_GCM Encryption +#[derive( + Clone, + Serialize, + Deserialize, + Debug, + CanonicalSerialize, + CanonicalDeserialize, +)] +pub struct AESOutput { + /// the AES ciphertext + pub ciphertext: Vec, + /// the AES nonce + pub nonce: Vec, +} + +/// The expected length of a nonce used with AES_GCM +const AES_GCM_NONCE_LEN: usize = 12; + +/// Errors that mayb be encountered with using a stream cipher +#[derive(Debug, PartialEq)] +pub enum Error { + /// The ciphertext exceeds the maximum buffer size + CiphertextTooLarge, + /// The provided decryption key is invalid + InvalidKey, + /// The provided nonce is invalid + BadNonce, +} + +/// Something that provides encryption and decryption using a stream cipher +pub trait StreamCipherProvider { + /// Some identifier to indiciate which ciphersuite was used + const CIPHER_SUITE: &'static [u8]; + type Ciphertext: CanonicalDeserialize + CanonicalSerialize; + /// Encrypt the message under the given N-byte key + fn encrypt( + message: &[u8], + key: [u8; N], + rng: R, + ) -> Result; + + /// Decrypt the ciphertext + fn decrypt( + ciphertext: Self::Ciphertext, + key: [u8; N], + ) -> Result, Error>; +} + +/// This provides the AES_GCM stream cipher, allowing message to be encrypted and decrypted under AES_GCM +pub struct AESGCMStreamCipherProvider; +impl StreamCipherProvider<32> for AESGCMStreamCipherProvider { + const CIPHER_SUITE: &'static [u8] = b"AES_GCM_"; + + type Ciphertext = AESOutput; + + /// AES-GCM encryption of the message using an ephemeral keypair + /// basically a wrapper around the AEADs library to handle serialization + /// + /// * `message`: The message to encrypt + /// * `key`: the key used for encryption + /// * `rng`: A CSPRNG + fn encrypt( + message: &[u8], + key: [u8; 32], + mut rng: R, + ) -> Result { + + let cipher = + Aes256Gcm::new(generic_array::GenericArray::from_slice(&key)); + + let nonce = Aes256Gcm::generate_nonce(&mut rng); // 96-bits; unique per message + + let mut buffer: Vec = Vec::new(); // Note: buffer needs 16-bytes overhead for auth tag + buffer.extend_from_slice(message); + // Encrypt `buffer` in-place, replacing the plaintext contents with + // ciphertext will this error ever be thrown here? nonces should + // always be valid as well as buffer + cipher + .encrypt_in_place(&nonce, b"", &mut buffer) + .map_err(|_| Error::CiphertextTooLarge)?; + Ok(Self::Ciphertext { ciphertext: buffer, nonce: nonce.to_vec() }) + } + + /// AES-GCM decryption + /// + /// * `ciphertext`: the ciphertext to decrypt + /// * `nonce`: the nonce used on encryption + fn decrypt(ct: Self::Ciphertext, key: [u8; 32]) -> Result, Error> { + let cipher = + Aes256Gcm::new_from_slice(&key).map_err(|_| Error::InvalidKey)?; + if ct.nonce.len() != AES_GCM_NONCE_LEN { + return Err(Error::BadNonce); + } + let nonce = Nonce::from_slice(&ct.nonce); + let plaintext = cipher + .decrypt(nonce, ct.ciphertext.as_ref()) + .map_err(|_| Error::InvalidKey)?; + Ok(plaintext) + } +} + +#[cfg(test)] +mod test { + use super::*; + use alloc::vec; + use ark_std::rand::SeedableRng; + use rand_chacha::ChaCha20Rng; + + #[test] + pub fn aes_encrypt_decrypt_works() { + let msg = b"test"; + let esk = [2; 32]; + let rng = ChaCha20Rng::from_seed(esk); + match AESGCMStreamCipherProvider::encrypt(msg, esk, rng) { + Ok(aes_out) => { + match AESGCMStreamCipherProvider::decrypt(aes_out, esk) { + Ok(plaintext) => { + assert_eq!(msg.to_vec(), plaintext); + }, + Err(_) => { + panic!("test should pass"); + }, + } + }, + Err(_) => { + panic!("test should pass"); + }, + } + } + + #[test] + pub fn aes_encrypt_decrypt_fails_with_bad_key() { + let msg = b"test"; + let esk = [2; 32]; + let rng = ChaCha20Rng::from_seed(esk); + match AESGCMStreamCipherProvider::encrypt(msg, esk, rng) { + Ok(aes_out) => { + let bad = AESOutput { + ciphertext: aes_out.ciphertext, + nonce: aes_out.nonce, + }; + match AESGCMStreamCipherProvider::decrypt(bad, [4; 32]) { + Ok(_) => { + panic!("should be an error"); + }, + Err(e) => { + assert_eq!(e, Error::InvalidKey); + }, + } + }, + Err(_) => { + panic!("test should pass"); + }, + } + } + + #[test] + pub fn aes_encrypt_decrypt_fails_with_invalid_nonce() { + let msg = b"test"; + let esk = [2; 32]; + let rng = ChaCha20Rng::from_seed(esk); + match AESGCMStreamCipherProvider::encrypt(msg, esk, rng) { + Ok(aes_out) => { + let bad = AESOutput { + ciphertext: aes_out.ciphertext, + nonce: vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + }; + match AESGCMStreamCipherProvider::decrypt(bad, esk) { + Ok(_) => { + panic!("should be an error"); + }, + Err(e) => { + assert_eq!(e, Error::InvalidKey); + }, + } + }, + Err(_) => { + panic!("test should pass"); + }, + } + } + + #[test] + pub fn aes_encrypt_decrypt_fails_with_bad_length_nonce() { + let msg = b"test"; + let esk = [2; 32]; + let rng = ChaCha20Rng::from_seed(esk); + match AESGCMStreamCipherProvider::encrypt(msg, esk, rng) { + Ok(aes_out) => { + let bad = AESOutput { + ciphertext: aes_out.ciphertext, + nonce: vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + ], + }; + match AESGCMStreamCipherProvider::decrypt(bad, esk) { + Ok(_) => { + panic!("should be an error"); + }, + Err(e) => { + assert_eq!(e, Error::BadNonce); + }, + } + }, + Err(_) => { + panic!("test should pass"); + }, + } + } +} diff --git a/timelock/src/tlock.rs b/timelock/src/tlock.rs new file mode 100644 index 0000000..d626f0e --- /dev/null +++ b/timelock/src/tlock.rs @@ -0,0 +1,338 @@ +/* + * Copyright 2024 by Ideal Labs, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +use crate::{ + ibe::fullident::{Ciphertext as IBECiphertext, IBESecret, Identity}, + stream_ciphers::StreamCipherProvider, +}; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; + +use ark_std::{ + rand::{CryptoRng, Rng}, + vec::Vec, +}; + +pub use w3f_bls::EngineBLS; + +/// A secret key used for encryption/decryption +pub type OpaqueSecretKey = [u8; 32]; + +#[derive(CanonicalDeserialize, CanonicalSerialize, Debug)] +pub struct TLECiphertext { + /// The header holds the IBE encrypted key + pub header: IBECiphertext, + /// The body holds the message encrypted with a stream cipher + pub body: Vec, + /// The cipher suite used + pub cipher_suite: Vec, +} + +/// Errors that may occur while execute timelock encryption/decryption +#[derive(Debug, PartialEq)] +pub enum Error { + /// The message could not be encrypted with the provided cipher + MessageEncryptionError, + /// The type could not be deserialized + DeserializationError, + /// The type could not be deserialized to an element of G1 + DeserializationErrorG1, + /// The type could not be deserialized to an element of G2 + DeserializationErrorG2, + /// The type could not be deserialized to a field element + DeserializationErrorFr, + /// The ciphertext could not be decrypted + DecryptionError, + /// The signature is invalid + InvalidSignature, + /// The secret key is not well-formed (must be 32 bytes) + InvalidSecretKey, +} + +/// Encrypt a message for an identity +/// +/// +/// * `p_pub`: the public key commitment for the IBE system (i.e. the setup +/// phase) +/// * `message`: The message to encrypt +/// * `id`: The identity to encrypt for +/// * `rng`: A CSPRNG +/// +pub fn tle( + p_pub: E::PublicKeyGroup, + secret_key: OpaqueSecretKey, + message: &[u8], + id: Identity, + mut rng: R, +) -> Result, Error> +where + E: EngineBLS, + S: StreamCipherProvider<32>, + R: Rng + CryptoRng, +{ + // IBE encryption 'to the future' + let header: IBECiphertext = id.encrypt(&secret_key, p_pub, &mut rng); + // encrypt arbitrary-length messages with a stream cipher + let body = S::encrypt(message, secret_key, &mut rng) + .map_err(|_| Error::MessageEncryptionError)?; + let mut message_bytes = Vec::new(); + body.serialize_compressed(&mut message_bytes) + .expect("Encryption output must be serializable."); + + Ok(TLECiphertext { + header, + body: message_bytes, + cipher_suite: S::CIPHER_SUITE.to_vec(), + }) +} + +/// Decrypt a ciphertext created as a result of timelock encryption +/// the signature should be equivalent to the output of IBE.Extract(ID) +/// where ID is the identity for which the message was created +/// +/// * `ciphertext`: A TLECiphertext encrypted under some supported protocol +/// * `signature`: A BLS signature that allows decryption of the ciphertext +/// +pub fn tld( + ciphertext: TLECiphertext, + signature: E::SignatureGroup, +) -> Result, Error> +where + E: EngineBLS, + S: StreamCipherProvider<32>, +{ + // IBE decrypt the secret key + let secret_bytes = IBESecret(signature) + .decrypt(&ciphertext.header) + .map_err(|_| Error::InvalidSignature)?; + // ensure we recovered a valid sized secret + let secret_array: [u8; 32] = + secret_bytes.clone().try_into().map_err(|_| Error::InvalidSecretKey)?; + + let ct = S::Ciphertext::deserialize_compressed( + &mut &ciphertext.body.clone()[..], + ) + .map_err(|_| Error::DeserializationError)?; + + return S::decrypt(ct, secret_array).map_err(|_| Error::DecryptionError); +} + +#[cfg(test)] +mod test { + + use super::*; + use crate::{ + curves::drand::TinyBLS381, + stream_ciphers::{AESGCMStreamCipherProvider, AESOutput}, + }; + use alloc::vec; + use ark_ec::Group; + use ark_ff::UniformRand; + use rand_chacha::ChaCha20Rng; + use rand_core::{OsRng, SeedableRng}; + use sha2::Digest; + use w3f_bls::TinyBLS377; + + // specific conditions that we want to test/verify + enum TestStatusReport { + DecryptSuccess { actual: Vec, expected: Vec }, + DecryptionFailed { error: Error }, + } + + // tlock test aes_gcm 256 + fn tlock_test( + inject_bad_ct: bool, + inject_bad_nonce: bool, + handler: &dyn Fn(TestStatusReport) -> (), + ) { + let message = b"this is a test message".to_vec(); + let id = Identity::new(b"", vec![b"id".to_vec()]); + let sk = E::Scalar::rand(&mut OsRng); + let p_pub = E::PublicKeyGroup::generator() * sk; + + // key used for aes encryption + let msk = [1; 32]; + + let sig: E::SignatureGroup = id.extract::(sk).0; + + match tle::( + p_pub, msk, &message, id, OsRng, + ) { + Ok(mut ct) => { + // create error scenarios here + if inject_bad_ct { + let mut output = + AESOutput::deserialize_compressed(&mut &ct.body[..]) + .unwrap(); + output.ciphertext = vec![]; + let mut corrupted = Vec::new(); + output.serialize_compressed(&mut corrupted).unwrap(); + ct.body = corrupted; + } + + if inject_bad_nonce { + let mut output = + AESOutput::deserialize_compressed(&mut &ct.body[..]) + .unwrap(); + output.nonce = vec![]; + let mut corrupted = Vec::new(); + output.serialize_compressed(&mut corrupted).unwrap(); + ct.body = corrupted; + } + + match tld::(ct, sig) { + Ok(output) => { + handler(TestStatusReport::DecryptSuccess { + actual: output, + expected: message, + }); + }, + Err(e) => { + handler(TestStatusReport::DecryptionFailed { + error: e, + }); + }, + } + }, + Err(_) => { + panic!("The test should pass but failed to run tlock encrypt"); + }, + } + } + + #[test] + pub fn tlock_can_encrypt_decrypt_with_single_sig() { + tlock_test::( + false, + false, + &|status: TestStatusReport| match status { + TestStatusReport::DecryptSuccess { actual, expected } => { + assert_eq!(actual, expected); + }, + _ => panic!("all other conditions invalid"), + }, + ); + } + + #[test] + pub fn tlock_can_encrypt_decrypt_with_full_sigs_present() { + tlock_test::( + false, + false, + &|status: TestStatusReport| match status { + TestStatusReport::DecryptSuccess { actual, expected } => { + assert_eq!(actual, expected); + }, + _ => panic!("all other conditions invalid"), + }, + ); + } + + #[test] + pub fn tlock_can_encrypt_decrypt_with_many_identities_at_threshold() { + tlock_test::( + false, + false, + &|status: TestStatusReport| match status { + TestStatusReport::DecryptSuccess { actual, expected } => { + assert_eq!(actual, expected); + }, + _ => panic!("all other conditions invalid"), + }, + ); + } + + #[test] + pub fn tlock_decryption_fails_with_bad_ciphertext() { + tlock_test::( + true, + false, + &|status: TestStatusReport| match status { + TestStatusReport::DecryptionFailed { error } => { + assert_eq!(error, Error::DecryptionError); + }, + _ => panic!("all other conditions invalid"), + }, + ); + } + + #[test] + pub fn tlock_decryption_fails_with_bad_nonce() { + tlock_test::( + false, + true, + &|status: TestStatusReport| match status { + TestStatusReport::DecryptionFailed { error } => { + assert_eq!(error, Error::DecryptionError); + }, + _ => panic!("all other conditions invalid"), + }, + ); + } + + #[test] + pub fn tlock_encrypt_decrypt_drand_quicknet_works() { + // using a pulse from drand's QuickNet + // https://api.drand.sh/52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971/public/1000 + // the beacon public key + let pk_bytes = + b"83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a" + ; // a round number that we know a signature for + let round: u64 = 1000; + // the signature produced in that round + let signature = + b"b44679b9a59af2ec876b1a6b1ad52ea9b1615fc3982b19576350f93447cb1125e342b73a8dd2bacbe47e4b6b63ed5e39" + ; + + // Convert hex string to bytes + let pub_key_bytes = hex::decode(pk_bytes).expect("Decoding failed"); + // Deserialize to G1Affine + let pub_key = + ::PublicKeyGroup::deserialize_compressed( + &*pub_key_bytes, + ) + .unwrap(); + + // then we tlock a message for the pubkey + let plaintext = b"this is a test".as_slice(); + let esk = [2; 32]; + + let sig_bytes = hex::decode(signature) + .expect("The signature should be well formatted"); + let sig = + ::SignatureGroup::deserialize_compressed( + &*sig_bytes, + ) + .unwrap(); + + let message = { + let mut hasher = sha2::Sha256::new(); + hasher.update(round.to_be_bytes()); + hasher.finalize().to_vec() + }; + + let identity = Identity::new(b"", vec![message]); + + let rng = ChaCha20Rng::seed_from_u64(0); + let ct = tle::( + pub_key, esk, plaintext, identity, rng, + ) + .unwrap(); + + // then we can decrypt the ciphertext using the signature + let result = + tld::(ct, sig).unwrap(); + assert!(result == plaintext); + } +} diff --git a/ts/.eslintrc.js b/ts/.eslintrc.js new file mode 100644 index 0000000..d2be887 --- /dev/null +++ b/ts/.eslintrc.js @@ -0,0 +1,49 @@ +module.exports = { + parser: '@typescript-eslint/parser', + parserOptions: { + project: 'tsconfig.json', + tsconfigRootDir: __dirname, + sourceType: 'module', + }, + plugins: ['@typescript-eslint/eslint-plugin'], + extends: [ + 'plugin:@typescript-eslint/recommended', + 'plugin:prettier/recommended', + ], + root: true, + env: { + node: true, + jest: true, + }, + ignorePatterns: ['.eslintrc.js'], + rules: { + 'semi': 'off', + 'indent': 'off', + 'quotes': ['error', 'single'], + 'no-console': ['error', { allow: ['warn', 'error'] }], + 'no-var': 'error', + 'no-undef': 'error', + 'no-empty-pattern': 'off', + 'object-curly-spacing': ['error', 'always'], + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/explicit-member-accessibility': 'off', + '@typescript-eslint/member-delimiter-style': 'off', + '@typescript-eslint/no-var-requires': 'off', + '@typescript-eslint/no-use-before-define': 'off', + '@typescript-eslint/ban-ts-ignore': 'off', + '@typescript-eslint/no-unescaped-entities': 'off', + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + '@typescript-eslint/semi': 'off', + '@typescript-eslint/interface-name-prefix': 'off', + '@typescript-eslint/no-explicit-any': 'error', + }, + overrides: [ + { + files: ['.ts'], + rules: { + 'no-undef': 'off', + }, + }, + ], +} diff --git a/ts/.gitignore b/ts/.gitignore new file mode 100644 index 0000000..8851439 --- /dev/null +++ b/ts/.gitignore @@ -0,0 +1,42 @@ +.DS_STORE +node_modules +scripts/flow/*/.flowconfig +.flowconfig +*~ +*.pyc +.grunt +_SpecRunner.html +__benchmarks__ +build/ +remote-repo/ +coverage/ +.module-cache +fixtures/dom/public/react-dom.js +fixtures/dom/public/react.js +test/the-files-to-test.generated.js +*.log* +chrome-user-data +*.sublime-project +*.sublime-workspace +.idea +*.iml +.vscode +*.swp +*.swo +dist/ +**/package-lock.json +**/yarn.lock +**/pnpm-lock.yaml + +packages/react-devtools-core/dist +packages/react-devtools-extensions/chrome/build +packages/react-devtools-extensions/chrome/*.crx +packages/react-devtools-extensions/chrome/*.pem +packages/react-devtools-extensions/firefox/build +packages/react-devtools-extensions/firefox/*.xpi +packages/react-devtools-extensions/firefox/*.pem +packages/react-devtools-extensions/shared/build +packages/react-devtools-extensions/.tempUserDataDir +packages/react-devtools-inline/dist +packages/react-devtools-shell/dist +packages/react-devtools-timeline/dist diff --git a/ts/.prettierignore b/ts/.prettierignore new file mode 100644 index 0000000..f5e36fe --- /dev/null +++ b/ts/.prettierignore @@ -0,0 +1,7 @@ +.vscode/ +out/ +dist/ +node_modules/ +coverage/ +public/ +.env \ No newline at end of file diff --git a/ts/.prettierrc b/ts/.prettierrc new file mode 100644 index 0000000..009151d --- /dev/null +++ b/ts/.prettierrc @@ -0,0 +1,12 @@ +{ + "printWidth": 80, + "trailingComma": "es5", + "useTabs": false, + "tabWidth": 2, + "semi": false, + "singleQuote": true, + "arrowParens": "always", + "quoteProps": "consistent", + "bracketSpacing": true, + "endOfLine": "auto" +} diff --git a/ts/README.md b/ts/README.md new file mode 100644 index 0000000..e69de29 diff --git a/ts/babel.config.js b/ts/babel.config.js new file mode 100644 index 0000000..3041d12 --- /dev/null +++ b/ts/babel.config.js @@ -0,0 +1,21 @@ +/* + * Copyright 2024 by Ideal Labs, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +module.exports = { + presets: [ + ['@babel/preset-env', { targets: { node: 'current' } }], + '@babel/preset-typescript', + ], +} \ No newline at end of file diff --git a/ts/package.json b/ts/package.json new file mode 100644 index 0000000..61af59a --- /dev/null +++ b/ts/package.json @@ -0,0 +1,33 @@ + +{ + "name": "@ideallabs/timelock.js", + "version": "0.0.1", + "description": "A typescript interface for timelock encryption", + "license": "Apache-2.0", + "repository": "https://github.com/ideal-lab5/tle", + "main": "dist/index.js", + "type": "module", + "dependencies": { + "js-crypto-hkdf": "^1.0.7", + "node-fetch": "^3.3.2", + "timelock-wasm-wrapper": "file:../wasm/pkg/", + "vite": "^5.4.11" + }, + "scripts": { + "build:wasm": "cd ../wasm && ./wasm_build.sh", + "build": "npm run build:wasm && npm i && tsc", + "test": "vitest", + "lint": "prettier --write ." + }, + "devDependencies": { + "@babel/preset-typescript": "^7.22.11", + "@jest/globals": "^29.6.4", + "@types/jest": "^29.5.4", + "jest": "^29.6.2", + "prettier": "^3.0.3", + "ts-jest": "^29.1.1", + "ts-jest-resolver": "^2.0.1", + "typescript": "^5.2.2", + "vitest": "^2.1.5" + } +} diff --git a/ts/src/index.ts b/ts/src/index.ts new file mode 100644 index 0000000..068c5d4 --- /dev/null +++ b/ts/src/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2024 by Ideal Labs, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './timelock' diff --git a/ts/src/test/__mocks__/timelock-wasm-wrapper.ts b/ts/src/test/__mocks__/timelock-wasm-wrapper.ts new file mode 100644 index 0000000..ee7dd9f --- /dev/null +++ b/ts/src/test/__mocks__/timelock-wasm-wrapper.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2024 by Ideal Labs, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module.exports = { + init: jest.fn().mockResolvedValue(undefined), + build_encoded_commitment: jest.fn((bn, id) => `commitment-${bn}-${id}`), + tle: jest.fn((id, message, key, pubKey) => `ciphertext-${id}-${message}`), + tld: jest.fn((ciphertext, signature) => `plaintext-${ciphertext}-${signature}`), + decrypt: jest.fn((ciphertext, key) => `plaintext-${ciphertext}-${key}`), + }; + \ No newline at end of file diff --git a/ts/src/timelock.test.spec.ts b/ts/src/timelock.test.spec.ts new file mode 100644 index 0000000..ffe29a9 --- /dev/null +++ b/ts/src/timelock.test.spec.ts @@ -0,0 +1,56 @@ +/* + * Copyright 2024 by Ideal Labs, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { expect, test, vi } from 'vitest' +import { + timelockEncrypt, + timelockDecrypt, + forceDecrypt, + IdealNetworkIdentityHandler, +} from './timelock' + +test('it should timelock encrypt a message for an IDN style network when params are valid', async () => { + const seed = 'seed' + const roundNumber = 123 + const message = 'Hello, world!' + let idnBeaconPK = + '471ba929a4e2ef2790fb5f2a65ebe86598a28cbb8a58e49c6cc7292cf40cecbdf10152394ba938367ded5355ae373e01a99567467bc816864774e84b984fc16e2ae2232be6481cd4db0e378e1d6b0c2265d2aa8e0fa4e2c76958ce9f12df8e0134c431c181308a68b94b9cfba5176c3a8dd22ead9a68a077ecce7facfe4adb9e0e0a71c94a0c436d8049b03fa5352301' + const publicKey = Uint8Array.from(Buffer.from(idnBeaconPK, 'hex')) + + await timelockEncrypt( + new TextEncoder().encode(message), + roundNumber, + IdealNetworkIdentityHandler, + publicKey, + seed + ).then((result) => { + expect(result).toEqual('tle-ciphertext') + }) +}) + +test('it should timelock decrypt a message', async () => { + const ciphertext = new Uint8Array(1); + const signature = new Uint8Array(2); + const result = await timelockDecrypt(ciphertext, signature); + expect(result).toEqual('tld-plaintext') +}) + +test('it should decrypt a message on demand if the user knows the secret', async () => { + const plaintext = 'plaintext' + const secret = "shhh, it's a secret" + const ciphertext = new Uint8Array(1) + const result = await forceDecrypt(ciphertext, secret) + expect(result).toEqual(plaintext) +}) diff --git a/ts/src/timelock.ts b/ts/src/timelock.ts new file mode 100644 index 0000000..f97680e --- /dev/null +++ b/ts/src/timelock.ts @@ -0,0 +1,113 @@ +/* + * Copyright 2024 by Ideal Labs, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/// Timelock Encryption TS Wrapper +/// This lib provides a typescript wrapper around the wasm-pack output of the timelock encryption library +import init, { + build_encoded_commitment, + tle, + tld, + decrypt, +} from 'timelock-wasm-wrapper' +import hkdf from 'js-crypto-hkdf' // for npm + +const HASH = 'SHA-256' +const HASH_LENGTH = 32 + +/** + * The IdentityBuilder is used to build identities for IBE + * In relation to the verifiable randomness beacon used, the implementation + * should correspond to however that beacon constructs messages for signing. + */ +interface IdentityBuilder { + /** + * Build an identity based on the input 'x' + * @param x : The identity data + * @returns : The constructed identity + */ + build: (x: X) => any +} + +/** + * An IdentityBuilder for the Ideal Network + */ +export const IdealNetworkIdentityHandler: IdentityBuilder = { + build: (bn) => build_encoded_commitment(bn, 0), +} + +/** + * Timelock Encryption: Encrypt the message for the given block + * The HKDF used satisfies RFC5869 + * + * @param encodedMessage: The message to encrypt, encoded as a Uint8Array + * @param roundNumber: The round of the protocol + * @param identityBuilder: Something that imlement IdentityBuilder (e.g. idealNetworkIdentityHandler) + * @param beaconPublicKey: The public key of the randomness beacon used + * @param seed: A seed to derive crypto keys + * @returns the ciphertext + */ +export async function timelockEncrypt( + encodedMessage: Uint8Array, + roundNumber: number, + identityBuilder: IdentityBuilder, + beaconPublicKey: Uint8Array, + seed: string +): Promise { + await init() + let t = new TextEncoder() + let masterSecret = t.encode(seed) + return hkdf + .compute(masterSecret, HASH, HASH_LENGTH, '') + .then((derivedKey) => { + let id = identityBuilder.build(roundNumber) + let ct = tle(id, encodedMessage, derivedKey.key, beaconPublicKey) + return ct + }) +} + +/** + * Timelock decryption: Decrypt the ciphertext using a pulse from the beacon produced at the given block + * @param ciphertext: Ciphertext to be decrypted + * @param blockNumber: Block number that has the signature for decryption + * @returns: Plaintext of encrypted message + */ +export async function timelockDecrypt( + ciphertext: Uint8Array, + signature: Uint8Array +): Promise { + await init() + return tld(ciphertext, signature) +} + +/** + * Decrypt a ciphertext early if you know the seed + * @param ciphertext The ciphertext to decrypt + * @param seed The ciphertext seed + * @returns The plaintext + */ +export async function forceDecrypt( + ciphertext: Uint8Array, + seed: string +): Promise { + await init() + let t = new TextEncoder() + let masterSecret = t.encode(seed) + return hkdf + .compute(masterSecret, HASH, HASH_LENGTH, '') + .then((derivedKey) => { + let pt = decrypt(ciphertext, derivedKey) + return pt + }) +} diff --git a/ts/testSetup.ts b/ts/testSetup.ts new file mode 100644 index 0000000..9bc44d6 --- /dev/null +++ b/ts/testSetup.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2024 by Ideal Labs, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { vi } from 'vitest' + +vi.mock('timelock-wasm-wrapper', () => ({ + default: vi.fn(), + build_encoded_commitment: vi.fn().mockReturnValue('commitment'), + tle: vi.fn().mockReturnValue('tle-ciphertext'), + tld: vi.fn().mockReturnValue('tld-plaintext'), + decrypt: vi.fn().mockReturnValue('plaintext'), + })) + \ No newline at end of file diff --git a/ts/tsconfig.json b/ts/tsconfig.json new file mode 100644 index 0000000..356ddb3 --- /dev/null +++ b/ts/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "es6", + "moduleResolution": "node", + "esModuleInterop": true, + "outDir": "./dist", + "declaration": true, + "resolveJsonModule": true, + }, + "include": ["./src/**/*"], + "exclude": ["node_modules"] +} \ No newline at end of file diff --git a/ts/vitest.config.js b/ts/vitest.config.js new file mode 100644 index 0000000..fef1bb7 --- /dev/null +++ b/ts/vitest.config.js @@ -0,0 +1,23 @@ +/* + * Copyright 2024 by Ideal Labs, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// vite.config.ts +import { defineConfig } from 'vite'; + +export default defineConfig({ + test: { + setupFiles: './testSetup.ts', // Path to the setup file + }, +}); diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml new file mode 100644 index 0000000..63827db --- /dev/null +++ b/wasm/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "timelock-wasm-wrapper" +version = "0.0.1-dev" +edition = "2021" +license = "GPL-3.0-only" +description = "Wasm bidings for the timelock encryption crate" +repository = "https://github.com/ideal-lab5/tle" +authors = [ + "Tony Riemer ", + "Coleman Irby " +] +homepage = "https://idealabs.network" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[lib] +crate-type = [ + "cdylib", + "rlib", +] + +[package.metadata.wasm-pack.profile.release] +wasm-opt = false + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = ["derive"] } +rand_core = "0.6.4" +timelock = { path = "../timelock", default-features = false } +serde = { version = "1.0.208", features = ["derive", "alloc"] } +serde-big-array = { version = "0.5.1", default-features = false } +serde-wasm-bindgen = "0.6.5" +wasm-bindgen = "0.2.92" +ark-serialize = { version = "0.4.0", default-features = false } +ark-std = { version = "0.4.0", default-features = false } +ark-bls12-381 = { version = "0.4.0", features = ["curve"], default-features = false } +ark-ec = { version = "0.4.0", default-features = false } +getrandom = { version = "0.2", features = ["js"] } +rand_chacha = { version = "0.3.1", default-features = false } +w3f-bls = { version = "0.1.3", default-features = false } +sp-consensus-beefy-etf = { git = "https://github.com/ideal-lab5/pallets.git", features = ["bls-experimental"]} +sha2 = { version = "0.10.2", default-features = false } + +[dev-dependencies] +wasm-bindgen-test = "0.3.0" diff --git a/wasm/README.md b/wasm/README.md new file mode 100644 index 0000000..1284d44 --- /dev/null +++ b/wasm/README.md @@ -0,0 +1,12 @@ +# WASM compat + +This crate provides wasm compatibility for the tle crate. + +## Build + +To compile to wasm, first build the project and them run wasm-pack + +``` shell +cargo build +wasm-pack build --target web --out-dir pkg +``` \ No newline at end of file diff --git a/wasm/src/lib.rs b/wasm/src/lib.rs new file mode 100644 index 0000000..53f4fcd --- /dev/null +++ b/wasm/src/lib.rs @@ -0,0 +1,463 @@ +/* + * Copyright 2024 by Ideal Labs, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use codec::Encode; +use rand_chacha::ChaCha20Rng; +use rand_core::{OsRng, SeedableRng}; +use serde::{Deserialize, Serialize}; +use serde_big_array::BigArray; +use sha2::Digest; +use sp_consensus_beefy_etf::{known_payloads, Commitment, Payload}; + +use timelock::{ + ibe::fullident::Identity, + stream_ciphers::{ + AESGCMStreamCipherProvider, AESOutput, StreamCipherProvider, + }, + tlock::{tld as timelock_decrypt, tle as timelock_encrypt, TLECiphertext}, +}; + +use w3f_bls::{DoublePublicKey, DoublePublicKeyScheme, EngineBLS, TinyBLS377}; +use wasm_bindgen::prelude::*; + +/// a helper function to deserialize arkworks elements from bytes +fn convert_from_bytes( + bytes: &[u8; N], +) -> Option { + E::deserialize_compressed(&bytes[..]).ok() +} + +/// The encrypt wrapper used by the WASM blob to call tlock.rs encrypt function +/// * 'id_js': ID string for which the message will be encrypted +/// * 'message_js': Message which will be encrypted +/// * 'sk_js': secret key passed in from UI. This should be obtained elsewhere +/// later on. +/// * 'p_pub_js': the public key commitment for the IBE system +#[wasm_bindgen] +pub fn tle( + id_js: JsValue, + message_js: JsValue, + sk_js: JsValue, + p_pub_js: JsValue, +) -> Result { + let msk_bytes: [u8; 32] = serde_wasm_bindgen::from_value(sk_js.clone()) + .map_err(|_| JsError::new("could not decode secret key"))?; + let pp_conversion: Vec = + serde_wasm_bindgen::from_value(p_pub_js.clone()) + .map_err(|_| JsError::new("could not decode p_pub"))?; + let pp_bytes: [u8; 144] = pp_conversion + .try_into() + .map_err(|_| JsError::new("could not convert public params"))?; + let double_pub_key = + convert_from_bytes::, 144>( + &pp_bytes.clone(), + ) + .ok_or(JsError::new("Could not convert secret key"))?; + let pp = double_pub_key.1; + + let id_bytes: Vec = serde_wasm_bindgen::from_value(id_js.clone()) + .map_err(|_| JsError::new("could not decode id"))?; + let identity = Identity::new(b"", vec![id_bytes]); + let message_bytes: Vec = + serde_wasm_bindgen::from_value(message_js.clone()) + .map_err(|_| JsError::new("could not decode message"))?; + + let mut ciphertext_bytes: Vec<_> = Vec::new(); + let ciphertext: TLECiphertext = + timelock_encrypt::( + pp, + msk_bytes, + &message_bytes, + identity, + OsRng, + ) + .map_err(|_| JsError::new("encryption failed"))?; + + ciphertext + .serialize_compressed(&mut ciphertext_bytes) + .map_err(|_| JsError::new("ciphertext serialization has failed"))?; + + serde_wasm_bindgen::to_value(&ciphertext_bytes) + .map_err(|_| JsError::new("could not convert ciphertext to JsValue")) +} + +/// The decrypt wrapper used by the WASM blob to call tlock.rs encrypt function +/// * 'ciphertext_js': The string to be decrypted +/// * 'sig_vec_js': The array of BLS signatures required to rebuild the secret +/// key and decrypt the message +#[wasm_bindgen] +pub fn tld( + ciphertext_js: JsValue, + sig_vec_js: JsValue, +) -> Result { + let sig_conversion: Vec = + serde_wasm_bindgen::from_value(sig_vec_js.clone()) + .map_err(|_| JsError::new("could not decode secret key"))?; + let sig_bytes = sig_conversion.as_slice(); + let sig_point = + ::SignatureGroup::deserialize_compressed( + sig_bytes, + ) + .map_err(|_| JsError::new("could not deserialize sig_vec"))?; + let ciphertext_vec: Vec = + serde_wasm_bindgen::from_value(ciphertext_js.clone()) + .map_err(|_| JsError::new("could not decode ciphertext"))?; + let ciphertext_bytes: &[u8] = ciphertext_vec.as_slice(); + + let ciphertext: TLECiphertext = + TLECiphertext::deserialize_compressed(ciphertext_bytes) + .map_err(|_| JsError::new("Could not deserialize ciphertext"))?; + let result = timelock_decrypt::( + ciphertext, sig_point, + ) + .map_err(|e| JsError::new(&format!("decryption has failed {:?}", e)))?; + let plaintext: String = String::from_utf8(result).map_err(|_| { + JsError::new("Plaintext could not be converted to a string") + })?; + + serde_wasm_bindgen::to_value(&plaintext) + .map_err(|_| JsError::new("plaintext conversion has failed")) +} + +/// Bypass Tlock by attempting to decrypt the ciphertext with some secret key +/// under the stream cipher only +#[wasm_bindgen] +pub fn decrypt( + ciphertext_js: JsValue, + sk_vec_js: JsValue, +) -> Result { + let sk_bytes: Vec = + serde_wasm_bindgen::from_value(sk_vec_js.clone()) + .map_err(|_| JsError::new("could not decode secret key"))?; + let secret_key: [u8; 32] = sk_bytes.try_into().unwrap(); + + let ciphertext_vec: Vec = + serde_wasm_bindgen::from_value(ciphertext_js.clone()) + .map_err(|_| JsError::new("could not decode ciphertext"))?; + let ciphertext_bytes: &[u8] = ciphertext_vec.as_slice(); + let ciphertext: TLECiphertext = + TLECiphertext::deserialize_compressed(ciphertext_bytes) + .map_err(|_| JsError::new("Could not deserialize ciphertext"))?; + + let aes_ciphertext: AESOutput = AESOutput::deserialize_compressed( + &mut &ciphertext.body[..], + ) + .unwrap(); + + let result = + AESGCMStreamCipherProvider::decrypt(aes_ciphertext, secret_key) + .map_err(|_| JsError::new("Message decryption failed"))?; + + let plaintext: String = String::from_utf8(result).map_err(|_| { + JsError::new("Plaintext could not be converted to a string") + })?; + + serde_wasm_bindgen::to_value(&plaintext) + .map_err(|_| JsError::new("plaintext conversion has failed")) +} + +/// Logging struct, useful for testing and debugging +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(js_namespace = console)] + fn log(s: &str); +} + +/// Struct for testing that allows for the serialization of the double public +/// key type +#[derive( + Serialize, CanonicalSerialize, CanonicalDeserialize, Deserialize, Debug, +)] +pub struct KeyChain { + #[serde(with = "BigArray")] + pub double_public: [u8; 144], + + pub sk: [u8; 32], +} + +/// build an encoded commitment for use in timelock encryption and sig +/// verification +#[wasm_bindgen] +pub fn build_encoded_commitment( + block_number_js: JsValue, + validator_set_id_js: JsValue, +) -> Result { + let block_number: u32 = serde_wasm_bindgen::from_value( + block_number_js.clone(), + ) + .map_err(|_| JsError::new("could not decode a u32 from the input"))?; + let validator_set_id: u64 = serde_wasm_bindgen::from_value( + validator_set_id_js.clone(), + ) + .map_err(|_| JsError::new("could not decode a u32 from the input"))?; + let payload = + Payload::from_single_entry(known_payloads::ETF_SIGNATURE, Vec::new()); + let commitment = Commitment { payload, block_number, validator_set_id }; + let encoded = commitment.encode(); + serde_wasm_bindgen::to_value(&encoded).map_err(|_| { + JsError::new("could not convert the encoded commitment to json") + }) +} + +/// This function is used purely for testing purposes. +/// It takes in a seed and generates a secret key and public params. +#[wasm_bindgen] +pub fn generate_keys(seed: JsValue) -> Result { + let seed_vec: Vec = serde_wasm_bindgen::from_value(seed) + .map_err(|_| JsError::new("Could not convert seed to string"))?; + let seed_vec = seed_vec.as_slice(); + + let mut hasher = sha2::Sha256::default(); + hasher.update(&seed_vec); + let hash = hasher.finalize(); + let seed_hash: [u8; 32] = hash.try_into().unwrap(); + let mut rng: ChaCha20Rng = ChaCha20Rng::from_seed(seed_hash); + let keypair = w3f_bls::KeypairVT::::generate(&mut rng); + let sk_gen: ::Scalar = keypair.secret.0; + let double_public: DoublePublicKey = DoublePublicKey( + keypair.into_public_key_in_signature_group().0, + keypair.public.0, + ); + let mut sk_bytes = Vec::new(); + sk_gen.serialize_compressed(&mut sk_bytes).unwrap(); + let mut double_public_bytes = Vec::new(); + double_public + .serialize_compressed(&mut double_public_bytes) + .unwrap(); + let kc = KeyChain { + double_public: double_public_bytes.try_into().unwrap(), + sk: sk_bytes.try_into().unwrap(), + }; + serde_wasm_bindgen::to_value(&kc) + .map_err(|_| JsError::new("could not convert secret key to JsValue")) +} + +#[cfg(test)] +mod test { + use super::*; + + use std::any::Any; + use w3f_bls::{EngineBLS, TinyBLS377}; + use wasm_bindgen_test::*; + + enum TestStatusReport { + EncryptSuccess { ciphertext: JsValue }, + DecryptSuccess { plaintext: JsValue }, + EncryptFailure { _error: JsError }, + DecryptFailure { error: JsError }, + } + + fn setup_test( + identity_vec: Vec, + message: Vec, + succesful_decrypt: bool, + standard_tle: bool, + handler: &dyn Fn(TestStatusReport) -> (), + ) { + let seed_bytes = "seeeeeeed".as_bytes(); + let seed = serde_wasm_bindgen::to_value(seed_bytes).unwrap(); + + let keys_js = generate_keys(seed).ok().unwrap(); + let key_chain: KeyChain = + serde_wasm_bindgen::from_value(keys_js).unwrap(); + let sk: [u8; 32] = key_chain.sk; + let mut sk_bytes: Vec = Vec::new(); + sk.serialize_compressed(&mut sk_bytes).unwrap(); + let sk_js: JsValue = serde_wasm_bindgen::to_value(&sk_bytes).unwrap(); + + let p_pub: [u8; 144] = key_chain.double_public; + let mut p_pub_bytes: Vec = Vec::new(); + p_pub.serialize_compressed(&mut p_pub_bytes).unwrap(); + let p_pub_js: JsValue = + serde_wasm_bindgen::to_value(&p_pub_bytes).unwrap(); + + let identity_js: JsValue = + serde_wasm_bindgen::to_value(&identity_vec).unwrap(); + let message_js: JsValue = + serde_wasm_bindgen::to_value(&message).unwrap(); + + let msk: ::Scalar = + convert_from_bytes::<::Scalar, 32>(&sk.clone()) + .unwrap(); + let identity = Identity::new(b"", vec![identity_vec]); + + let sig: E::SignatureGroup = identity.extract::(msk).0; + let mut sig_bytes: Vec<_> = Vec::new(); + + if succesful_decrypt { + sig.serialize_compressed(&mut sig_bytes).unwrap(); + } else { + let bad_ident_vec = b"bad_ident".to_vec(); + let bad_ident = Identity::new(b"", vec![bad_ident_vec]); + let bad_sig: E::SignatureGroup = bad_ident.extract::(msk).0; + let bad_sig_vec = vec![bad_sig]; + bad_sig_vec.serialize_compressed(&mut sig_bytes).unwrap(); + + //this portion (intentionally) messes up the decryption result for + // early decryption + let bad_seed_bytes = "bad".as_bytes(); + let bad_seed = + serde_wasm_bindgen::to_value(bad_seed_bytes).unwrap(); + let bad_keys_js: JsValue = generate_keys(bad_seed).ok().unwrap(); + let bad_key_chain: KeyChain = + serde_wasm_bindgen::from_value(bad_keys_js).unwrap(); + let bad_sk: [u8; 32] = bad_key_chain.sk; + bad_sk.serialize_compressed(&mut sk_bytes).unwrap(); + } + + let sig_vec_js: JsValue = + serde_wasm_bindgen::to_value(&sig_bytes).unwrap(); + + if standard_tle { + match tle(identity_js, message_js, sk_js, p_pub_js) { + Ok(ciphertext) => { + let ciphertext_clone = ciphertext.clone(); + handler(TestStatusReport::EncryptSuccess { ciphertext }); + match tld(ciphertext_clone, sig_vec_js) { + Ok(plaintext) => + handler(TestStatusReport::DecryptSuccess { + plaintext, + }), + Err(error) => + handler(TestStatusReport::DecryptFailure { error }), + } + }, + Err(error) => + handler(TestStatusReport::EncryptFailure { _error: error }), + Err(_error) => + handler(TestStatusReport::EncryptFailure { _error }), + } + } else { + match tle(identity_js, message_js, sk_js, p_pub_js) { + Ok(ciphertext) => { + let sk_js_early: JsValue = + serde_wasm_bindgen::to_value(&sk_bytes).unwrap(); + let ciphertext_clone = ciphertext.clone(); + handler(TestStatusReport::EncryptSuccess { ciphertext }); + match decrypt(ciphertext_clone, sk_js_early) { + Ok(plaintext) => + handler(TestStatusReport::DecryptSuccess { + plaintext, + }), + Err(error) => + handler(TestStatusReport::DecryptFailure { error }), + } + }, + Err(error) => + handler(TestStatusReport::EncryptFailure { _error: error }), + } + } + } + + #[wasm_bindgen_test] + pub fn can_encrypt_decrypt() { + let message: Vec = b"this is a test message".to_vec(); + let id: Vec = b"testing purposes".to_vec(); + setup_test::( + id, + message.clone(), + true, + true, + &|status: TestStatusReport| match status { + TestStatusReport::EncryptSuccess { ciphertext } => { + let ciphertext_convert: Vec = + serde_wasm_bindgen::from_value(ciphertext.clone()) + .unwrap(); + assert!(ciphertext.is_truthy()); + assert_ne!(ciphertext_convert, message); + }, + TestStatusReport::DecryptSuccess { plaintext } => { + let plaintext_convert: String = + serde_wasm_bindgen::from_value(plaintext.clone()) + .unwrap(); + let plaintext_compare = + plaintext_convert.as_bytes().to_vec(); + assert_eq!(plaintext_compare, message); + }, + _ => panic!("The ciphertext is falsy"), + }, + ) + } + + #[wasm_bindgen_test] + pub fn can_encrypt_decrypt_early() { + let message: Vec = b"this is a test message".to_vec(); + let id: Vec = b"testing purposes".to_vec(); + setup_test::( + id, + message.clone(), + true, + false, + &|status: TestStatusReport| match status { + TestStatusReport::EncryptSuccess { ciphertext } => { + let ciphertext_convert: Vec = + serde_wasm_bindgen::from_value(ciphertext.clone()) + .unwrap(); + assert!(ciphertext.is_truthy()); + assert_ne!(ciphertext_convert, message); + }, + TestStatusReport::DecryptSuccess { plaintext } => { + let plaintext_convert: String = + serde_wasm_bindgen::from_value(plaintext.clone()) + .unwrap(); + let plaintext_compare = + plaintext_convert.as_bytes().to_vec(); + assert_eq!(plaintext_compare, message); + }, + _ => panic!("The ciphertext is falsy"), + }, + ) + } + + #[wasm_bindgen_test] + pub fn decrypt_failure_early() { + let message: Vec = b"this is a test message".to_vec(); + let id: Vec = b"testing purposes".to_vec(); + setup_test::( + id, + message.clone(), + false, + false, + &|status: TestStatusReport| { + match status { + TestStatusReport::EncryptSuccess { ciphertext } => { + let ciphertext_convert: Vec = + serde_wasm_bindgen::from_value(ciphertext.clone()) + .unwrap(); + assert!(ciphertext.is_truthy()); + assert_ne!(ciphertext_convert, message); + }, + TestStatusReport::DecryptFailure { error } => { + // This test needs to be updated. As of right now, there + // doesn't seem to be a way to reliably compare errors + // however the test will fail if no error is thrown from + // decrypt. We just won't know if it was the decrypt + // function failing. NOTE: TypeId comes from the + // std library. A `TypeId` represents a globally + // unique identifier for a type. + let error_compare = JsError::new("this is irrelevant. We only check that it's a JsError (which it always is)"); + let type_id_compare = error_compare.type_id(); + let type_id = error.type_id(); + + assert_eq!(type_id, type_id_compare); + }, + _ => panic!("decrypt was successful"), + } + }, + ) + } +} diff --git a/wasm/wasm_build.sh b/wasm/wasm_build.sh new file mode 100755 index 0000000..4fcaa5e --- /dev/null +++ b/wasm/wasm_build.sh @@ -0,0 +1,2 @@ +cargo build +wasm-pack build --target web --out-dir pkg \ No newline at end of file