diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..67dda906 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,36 @@ +name: basics + +on: + pull_request: + push: + branches: + - main + +env: + CARGO_TERM_COLOR: always + +jobs: + cargo: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + checks: [ + fmt --all --check, + check --all-targets --all-features, + clippy --all-targets --all-features -- -D warnings, + test --all-targets --all-features + ] + steps: + - uses: actions/checkout@v4 + - uses: arduino/setup-protoc@v2 + - uses: Swatinem/rust-cache@v2 + - name: Default on nightly Rust + run: rustup default nightly + - name: Install additional components + run: | + rustup component add rustfmt + rustup component add clippy + - name: ${{ matrix.checks }} + run: cargo ${{ matrix.checks }} + diff --git a/.gitignore b/.gitignore index 9b62d3b3..00b3872a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ /target -Cargo.lock *.txt .DS_Store +.idea +crates/tests/e2e-tests/files +crates/tests/e2e-tests/prover +crates/tests/e2e-tests/verifier diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000..02da8e80 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,4426 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "ahash" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "anstream" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 0.2.9", + "http-body 0.4.5", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" +dependencies = [ + "serde", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "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 = "blake3" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "memmap2", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "borsh" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf617fabf5cdbdc92f774bfe5062d870f228b80056d41180797abf48bed4056e" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f404657a7ea7b5249e36808dff544bc88a28f26e0ac40009f674b7a009d14be3" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.39", + "syn_derive", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "bytecheck" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "clap" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + +[[package]] +name = "console-api" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd326812b3fd01da5bb1af7d340d0d555fd3d4b641e7f1dfcf5962a902952787" +dependencies = [ + "futures-core", + "prost 0.12.3", + "prost-types 0.12.3", + "tonic 0.10.2", + "tracing-core", +] + +[[package]] +name = "console-subscriber" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7481d4c57092cd1c19dd541b92bdce883de840df30aa5d03fd48a3935c01842e" +dependencies = [ + "console-api", + "crossbeam-channel", + "crossbeam-utils", + "futures-task", + "hdrhistogram", + "humantime", + "prost-types 0.12.3", + "serde", + "serde_json", + "thread_local", + "tokio", + "tokio-stream", + "tonic 0.10.2", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "fiat-crypto", + "platforms", + "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.39", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "ecies" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53f43496fc04523aa716c5dd76133cb6d7c81eb213375684d06a8b1683f8bc1e" +dependencies = [ + "aes-gcm", + "getrandom", + "hkdf", + "libsecp256k1", + "once_cell", + "parking_lot", + "rand_core", + "sha2 0.10.8", + "typenum", + "wasm-bindgen", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +dependencies = [ + "serde", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fiat-crypto" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" + +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.8", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-executor" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +dependencies = [ + "gloo-timers", + "send_wrapper", +] + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gevulot-cli" +version = "0.1.0" +dependencies = [ + "anyhow", + "blake3", + "clap", + "futures-util", + "gevulot-node", + "hex", + "http-body-util", + "hyper 1.1.0", + "hyper-util", + "indicatif", + "libsecp256k1", + "log", + "rand", + "serde", + "serde_json", + "sha3", + "tokio", + "tokio-util", + "tracing-subscriber", + "url", +] + +[[package]] +name = "gevulot-e2e-test-programs" +version = "0.1.0" +dependencies = [ + "gevulot-shim", +] + +[[package]] +name = "gevulot-e2e-tests" +version = "0.1.0" +dependencies = [ + "anyhow", + "blake3", + "clap", + "futures-util", + "gevulot-node", + "hex", + "http-body-util", + "hyper 1.1.0", + "hyper-util", + "libsecp256k1", + "rand", + "sha3", + "tokio", + "tokio-util", +] + +[[package]] +name = "gevulot-node" +version = "0.1.0" +dependencies = [ + "async-trait", + "bincode", + "blake3", + "bytes", + "clap", + "console-subscriber", + "ecies", + "eyre", + "futures-util", + "hex", + "home", + "jsonrpsee", + "libsecp256k1", + "num-bigint", + "num-traits", + "parking_lot", + "pea2pea", + "prost 0.11.9", + "qapi", + "rand", + "reqwest", + "serde", + "serde_json", + "sha3", + "snow", + "sqlx", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tokio-vsock", + "tonic 0.8.3", + "tonic-build", + "tower", + "tracing", + "tracing-subscriber", + "uuid", + "vsock", +] + +[[package]] +name = "gevulot-shim" +version = "0.1.0" +dependencies = [ + "anyhow", + "prost 0.11.9", + "tokio", + "tokio-stream", + "tokio-vsock", + "tonic 0.8.3", + "tonic-build", + "tower", + "uuid", + "vsock", +] + +[[package]] +name = "gevulot-shim-ffi" +version = "0.1.0" +dependencies = [ + "gevulot-shim", +] + +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "gloo-net" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ac9e8288ae2c632fa9f8657ac70bfe38a1530f345282d7ba66a1f70b72b7dc4" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "http 0.2.9", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-utils" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "h2" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.9", + "indexmap 1.9.3", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d308f63daf4181410c242d34c11f928dcb3aa105852019e043c9d1f4e4368a" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 1.0.0", + "indexmap 2.1.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.7", +] + +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +dependencies = [ + "ahash 0.8.6", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.2", +] + +[[package]] +name = "hdrhistogram" +version = "7.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" +dependencies = [ + "base64 0.21.5", + "byteorder", + "flate2", + "nom", + "num-traits", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http 0.2.9", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.0.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +dependencies = [ + "bytes", + "futures-util", + "http 1.0.0", + "http-body 1.0.0", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.21", + "http 0.2.9", + "http-body 0.4.5", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.0", + "http 1.0.0", + "http-body 1.0.0", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.9", + "hyper 0.14.27", + "log", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper 0.14.27", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper 0.14.27", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "hyper-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdea9aac0dbe5a9240d68cfd9501e2db94222c6dc06843e06640b9e07f0fdc67" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.0.0", + "http-body 1.0.0", + "hyper 1.1.0", + "pin-project-lite", + "socket2 0.5.5", + "tokio", + "tower", + "tower-service", + "tracing", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[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.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.2", +] + +[[package]] +name = "indicatif" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonrpsee" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "affdc52f7596ccb2d7645231fc6163bb314630c989b64998f3699a28b4d5d4dc" +dependencies = [ + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-http-client", + "jsonrpsee-server", + "jsonrpsee-types", + "jsonrpsee-wasm-client", + "jsonrpsee-ws-client", + "tokio", +] + +[[package]] +name = "jsonrpsee-client-transport" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b005c793122d03217da09af68ba9383363caa950b90d3436106df8cabce935" +dependencies = [ + "futures-channel", + "futures-util", + "gloo-net", + "http 0.2.9", + "jsonrpsee-core", + "pin-project", + "rustls-native-certs", + "soketto", + "thiserror", + "tokio", + "tokio-rustls", + "tokio-util", + "tracing", + "url", + "webpki-roots 0.25.3", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2327ba8df2fdbd5e897e2b5ed25ce7f299d345b9736b6828814c3dbd1fd47b" +dependencies = [ + "anyhow", + "async-lock", + "async-trait", + "beef", + "futures-timer", + "futures-util", + "hyper 0.14.27", + "jsonrpsee-types", + "parking_lot", + "rand", + "rustc-hash", + "serde", + "serde_json", + "soketto", + "thiserror", + "tokio", + "tracing", + "wasm-bindgen-futures", +] + +[[package]] +name = "jsonrpsee-http-client" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f80c17f62c7653ce767e3d7288b793dfec920f97067ceb189ebdd3570f2bc20" +dependencies = [ + "async-trait", + "hyper 0.14.27", + "hyper-rustls", + "jsonrpsee-core", + "jsonrpsee-types", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-server" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82c39a00449c9ef3f50b84fc00fc4acba20ef8f559f07902244abf4c15c5ab9c" +dependencies = [ + "futures-util", + "http 0.2.9", + "hyper 0.14.27", + "jsonrpsee-core", + "jsonrpsee-types", + "route-recognizer", + "serde", + "serde_json", + "soketto", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tracing", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be0be325642e850ed0bdff426674d2e66b2b7117c9be23a7caef68a2902b7d9" +dependencies = [ + "anyhow", + "beef", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "jsonrpsee-wasm-client" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c7cbb3447cf14fd4d2f407c3cc96e6c9634d5440aa1fbed868a31f3c02b27f0" +dependencies = [ + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", +] + +[[package]] +name = "jsonrpsee-ws-client" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bca9cb3933ccae417eb6b08c3448eb1cb46e39834e5b503e395e5e5bd08546c0" +dependencies = [ + "http 0.2.9", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", + "url", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libsecp256k1" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" +dependencies = [ + "arrayref", + "base64 0.13.1", + "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 = "libsqlite3-sys" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[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 = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "memmap2" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl" +version = "0.10.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pea2pea" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffa4e14ee283108ef3cb55fe216cb89e3bc894423d38b8434952dfce0751fd7" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "parking_lot", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.1.0", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "platforms" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + +[[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.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive 0.11.9", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive 0.12.3", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck", + "itertools 0.10.5", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost 0.11.9", + "prost-types 0.11.9", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost 0.11.9", +] + +[[package]] +name = "prost-types" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +dependencies = [ + "prost 0.12.3", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "qapi" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6412bdd014ebee03ddbbe79ac03a0b622cce4d80ba45254f6357c847f06fa38" +dependencies = [ + "bytes", + "futures", + "log", + "memchr", + "qapi-qmp", + "qapi-spec", + "serde", + "serde_json", + "tokio", + "tokio-util", +] + +[[package]] +name = "qapi-codegen" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba4de731473de4c8bd508ddb38a9049e999b8a7429f3c052ba8735a178ff68c" +dependencies = [ + "qapi-parser", +] + +[[package]] +name = "qapi-parser" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80044db145aa2953ef5803d0376dcbca50f2763242547e856b7f37507adca677" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "qapi-qmp" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8b944db7e544d2fa97595e9a000a6ba5c62c426fa185e7e00aabe4b5640b538" +dependencies = [ + "qapi-codegen", + "qapi-spec", + "serde", +] + +[[package]] +name = "qapi-spec" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b360919a24ea5fc02fa762cb01bd8f43b643fee51c585f763257773b4dc5a9e8" +dependencies = [ + "base64 0.13.1", + "serde", + "serde_json", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +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 = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", +] + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.2", +] + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "rend" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64 0.21.5", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.21", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "winreg", +] + +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted", + "windows-sys 0.48.0", +] + +[[package]] +name = "rkyv" +version = "0.7.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" +dependencies = [ + "bitvec", + "bytecheck", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "route-recognizer" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" + +[[package]] +name = "rsa" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ef35bf3e7fe15a53c4ab08a998e42271eab13eb0db224126bc7bc4c4bad96d" +dependencies = [ + "const-oid", + "digest 0.10.7", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rust_decimal" +version = "1.33.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06676aec5ccb8fc1da723cc8c0f9a46549f21ebb8753d3915c6c41db1e7f1dc4" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits", + "rand", + "rkyv", + "serde", + "serde_json", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustls" +version = "0.21.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.5", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" + +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + +[[package]] +name = "serde" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[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 = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" + +[[package]] +name = "snow" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58021967fd0a5eeeb23b08df6cc244a4d4a5b4aec1d27c9e02fad1a58b4cd74e" +dependencies = [ + "aes-gcm", + "blake2", + "chacha20poly1305", + "curve25519-dalek", + "rand_core", + "rustc_version", + "sha2 0.10.8", + "subtle", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.1", + "bytes", + "futures", + "http 0.2.9", + "httparse", + "log", + "rand", + "sha-1", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85" +dependencies = [ + "itertools 0.11.0", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e50c216e3624ec8e7ecd14c6a6a6370aad6ee5d8cfc3ab30b5162eeeef2ed33" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d6753e460c998bbd4cd8c6f0ed9a64346fcca0723d6e75e52fdc351c5d2169d" +dependencies = [ + "ahash 0.8.6", + "atoi", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashlink", + "hex", + "indexmap 2.1.0", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rust_decimal", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "sha2 0.10.8", + "smallvec", + "sqlformat", + "thiserror", + "time", + "tokio", + "tokio-stream", + "tracing", + "url", + "uuid", + "webpki-roots 0.24.0", +] + +[[package]] +name = "sqlx-macros" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a793bb3ba331ec8359c1853bd39eed32cdd7baaf22c35ccf5c92a7e8d1189ec" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4ee1e104e00dedb6aa5ffdd1343107b0a4702e862a84320ee7cc74782d96fc" +dependencies = [ + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2 0.10.8", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 1.0.109", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864b869fdf56263f4c95c45483191ea0af340f9f3e3e7b4d57a61c7c87a970db" +dependencies = [ + "atoi", + "base64 0.21.5", + "bitflags 2.4.1", + "byteorder", + "bytes", + "crc", + "digest 0.10.7", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac 0.12.1", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand", + "rsa", + "rust_decimal", + "serde", + "sha1", + "sha2 0.10.8", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb7ae0e6a97fb3ba33b23ac2671a5ce6e3cabe003f451abd5a56e7951d975624" +dependencies = [ + "atoi", + "base64 0.21.5", + "bitflags 2.4.1", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac 0.12.1", + "home", + "itoa", + "log", + "md-5", + "memchr", + "num-bigint", + "once_cell", + "rand", + "rust_decimal", + "serde", + "serde_json", + "sha1", + "sha2 0.10.8", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59dc83cf45d89c555a577694534fcd1b55c545a816c816ce51f20bbe56a4f3f" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "time", + "tracing", + "url", + "uuid", +] + +[[package]] +name = "stringprep" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +dependencies = [ + "finl_unicode", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +dependencies = [ + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +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 = "tokio" +version = "1.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.5", + "tokio-macros", + "tracing", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tokio-vsock" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52a15c15b1bc91f90902347eff163b5b682643aff0c8e972912cca79bd9208dd" +dependencies = [ + "bytes", + "futures", + "libc", + "tokio", + "tonic 0.8.3", + "vsock", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.1.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tonic" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.13.1", + "bytes", + "futures-core", + "futures-util", + "h2 0.3.21", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost 0.11.9", + "prost-derive 0.11.9", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "tracing-futures", +] + +[[package]] +name = "tonic" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.21.5", + "bytes", + "h2 0.3.21", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost 0.12.3", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +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-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[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", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[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-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +dependencies = [ + "getrandom", + "rand", + "serde", + "uuid-macro-internal", +] + +[[package]] +name = "uuid-macro-internal" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d8c6bba9b149ee82950daefc9623b32bb1dacbfb1890e352f6b887bd582adaf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vsock" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8e1df0bf1e1b28095c24564d1b90acae64ca69b097ed73896e342fa6649c57" +dependencies = [ + "libc", + "nix", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.39", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" + +[[package]] +name = "wasm-streams" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" +dependencies = [ + "rustls-webpki", +] + +[[package]] +name = "webpki-roots" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "whoami" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winnow" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.7.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd369a67c0edfef15010f980c3cbe45d7f651deac2cd67ce097cd801de16557" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2f140bda219a26ccc0cdb03dba58af72590c53b22642577d88a927bc5c87d6b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000..44bcdc67 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[workspace] +exclude = [ + "prover" +] +members = [ + "crates/node", + "crates/cli", + "crates/shim", + "crates/shim-ffi", + "crates/tests/test-programs", + "crates/tests/e2e-tests", +] +resolver = "2" diff --git a/Containerfile b/Containerfile new file mode 100644 index 00000000..ba87f2af --- /dev/null +++ b/Containerfile @@ -0,0 +1,32 @@ +FROM rust:1-bookworm + +COPY ./Cargo.* ./ +COPY ./crates ./crates + +RUN apt-get update && apt-get install -y \ + libssl-dev \ + protobuf-compiler + +RUN cargo build --release + +FROM debian:bookworm + +# Copy Gevulot node bin from earlier build step. +COPY --from=0 target/release/gevulot /gevulot + +# Install QEMU. +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + qemu-system + +# Install Ops. +RUN /bin/curl -Lo /bin/ops https://storage.googleapis.com/cli/linux/ops && chmod 755 /bin/ops && /bin/ops update + +COPY ./crates/node/migrations /migrations + +RUN mkdir -p /var/lib/gevulot +RUN /gevulot generate node-key + +CMD ["run"] +ENTRYPOINT ["/gevulot"] diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 00000000..12f269d7 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,189 @@ +# Gevulot node installation guide + +## Hardware system requirements + +Gevulot node itself runs on modest resources. The real system HW requirements are dictated by the provers run on this platform. + +Many ZK provers require modern multi-core processor and a lot of RAM. Some also need plenty of fast disk space. + +Currently Gevulot supports nVidia 3090 and 4090 GPUs. + +### Minimum requirements for devnet + +- CPU: 64+ cores +- RAM: 512GB +- Disk: 1 TB NVMe + +These requirements are formed by best estimate based on earlier documentation of production requirements for Polygon Hermez and Aztec provers, and empirical experience from working with Taiko prover. + +## Software system requirements + +Gevulot node requires modern Linux distribution with systemd, quadlet and necessary KVM components (on Fedora this is provider by `qemu-kvm` package) installed. + +Development & testing has been done on Fedora 39. + +For GPU support the PCI passthrough must be appropriately configured. + +## PCI passthrough for GPU + +### Blacklist nVidia drivers from loading during boot + +When passing GPU to VM running unikernel, the device cannot be in use by the host operating system. Therefore the GPU drivers must be blacklisted. + +**/etc/modprobe.d/nvidia.conf** +``` +blacklist nvidia +blacklist nvidia-drm +``` + +### Load VFIO & VSOCK modules + +[VFIO](https://docs.kernel.org/driver-api/vfio.html) provides framework for virtual machines to utilize host machine hardware directly, allowing high performance device access. + +In Gevulot this is needed for direct access to GPU. + +**/etc/modules-load.d/vfio.conf** +``` +kvmgt +vfio-pci +vfio-iommu-type1 +vfio-mdev +``` + +[VSOCK](https://nanovms.com/dev/tutorials/what-is-vsock-why-use-with-unikernels) provides high speed communication channel between Gevulot node and program running in VM. + +**/etc/modules-load.d/vsock.conf** +``` +vsock_vhost +``` + +### Configure GPU's PCI bus devices to be bound with VFIO + +Depending on specific construction of the GPU device card, there can be multiple PCI device entries on the bus. + +In order to make PCI passthrough work with virtual machines, all devices present in PCI bus must be bound with VFIO driver. + +Find out the device IDs of the GPU: +``` +lspci -nnD | grep -i nvidia +``` + +**Example output:** +``` +0000:01:00.0 VGA compatible controller [0300]: NVIDIA Corporation AD102 [GeForce RTX 4090] [10de:2684] (rev a1) +0000:01:00.1 Audio device [0403]: NVIDIA Corporation AD102 High Definition Audio Controller [10de:22ba] (rev a1) +``` + +In the above example output the first entry on the line is the PCI slot name. The second last column is the PCI ID. + +Configure all PCI device IDs to VFIO: +**/etc/modprobe.d/vfio.conf** +``` +options vfio-pci ids=10de:2684,10de:22ba +``` + + +### Adjust VFIO device permissions with udev rule + +By default, the VFIO group devices are only accessible by root. In order to allow Gevulot node be run as non-root, the VFIO group devices' permissions must be adjusted: + +**/etc/udev/rules.d/99-vfio.rules** +``` +SUBSYSTEM=="vfio", OWNER="root", GROUP="kvm" +``` + +That will allow VFIO device access to all users who belong to `kvm` group. + +### Further device driver adjustments + +In some cases the GPU board might have devices which have drivers directly built into kernel and which cannot be blacklisted due to critical nature. + +One such example is a USB controller embedded on GPU board. + +Individual PCI device's driver attachment can be fixed in a following way: +``` +echo "0000:01:00.2" | sudo tee /sys/bus/pci/drivers/xhci_hcd/unbind +echo "0000:01:00.2" | sudo tee /sys/bus/pci/drivers/vfio-pci/bind +``` + +The device specific string above is the PCI slot name (first record of `lspci -nnD`). + +For persistent effect, create a systemd unit for this. + +## Postgres + +Gevulot node uses Postgres database for its operation. It has been tested to work with Postgres releases 15 and 16. + +### Database migration + +In order to create initial tables or perform latest migrations, run: +``` +podman run -it --network=host quay.io/gevulot/node:latest migrate [--db-url=] +``` + +## Gevulot user + +Gevulot node runs as a normal user. For privilege separation purposes, create a user for Gevulot. + +In order to allow access to virtualization functionalities, add the user into `kvm` group. + +## Gevulot node storage + +Gevulot node requires plenty of storage for program images and their output data. + +Create a directory on a volume with enough space. + +This guide uses `/var/lib/gevulot`, which is also the default, but it is configurable. + +## Gevulot node key + +Each Gevulot node requires a keypair for operation. It can be generated with Gevulot node container: +``` +podman run -it -v /var/lib/gevulot:/var/lib/gevulot:z quay.io/gevulot/node:latest generate node-key +``` + +## Gevulot node systemd unit + +Gevulot node is packaged as a container for best possible platform compatibility and it is recommended to run it with Podman Quadlet. + +Use following systemd unit as basis for running Gevulot node: +**/etc/containers/systemd/gevulot-node.container** +``` +[Install] +WantedBy=default.target + +[Unit] +Requires=gevulot-postgres.service +After=gevulot-postgres.service + +[Container] +ContainerName=gevulot-node + +Image=quay.io/gevulot/node:latest +AutoUpdate=registry + +Environment=RUST_LOG=warn,gevulot=debug,sqlx=error +Environment=GEVULOT_DB_URL=postgres://:@/gevulot +Environment=GEVULOT_GPU_DEVICES=0000:01:00.0 + +Network=host + +# Expose JSON-RPC. +ExposeHostPort=9944 + +# Bind VSOCK & GPU into container. +AddDevice=/dev/vsock:rw +AddDevice=/dev/vfio/59:rw + +# Disable SELinux labelling to allow access to VFIO devices. +SecurityLabelDisable=true + +# Run as gevulot user. +User=gevulot + +# Maintain existing groups. +UserNS=keep-id + +# Mount host directory for Gevulot files. +Volume=/var/lib/gevulot:/var/lib/gevulot:z +``` diff --git a/README.md b/README.md index 837f535f..d3c5f253 100644 --- a/README.md +++ b/README.md @@ -6,362 +6,66 @@ For a more in-depth look at the network design see our [docs](https://gevulot.gi The current status of the project is pre-alpha. -## Unikernel Setup +## Gevulot Node -Gevulot provers run in a [Nanos unikernel](https://nanovms.com/). Each prover must be a single binary that performs the proof computation. The binary is packaged with an execution manifest and required dynamic libraries into an image file that is then run to produce a proof. +Gevulot node is written in Rust and packaged into a container. It uses QEMU-KVM as its hypervisor to run unikernel programs. -### Tooling +### Building container -[Ops](https://ops.city/) provides functionality to prepare unikernel images, disk volumes and execute instances. It supports local execution under QEMU/KVM hypervisors and various cloud providers. +To build Gevulot node container image: -### Running a Prover in a Unikernel - -Running a prover in a unikernel is quite simple: - -- [Ensure that Ops is installed](https://docs.ops.city/ops/getting_started#installing-ops) -- Build Linux x86_64 binary. -- If the application loads dynamic libraries during runtime (not listed in ELF headers), then bundle these under `lib64` directory in unikernel image. -- [Prepare execution manifest](https://docs.ops.city/ops/configuration) -- [Google Cloud: Build the unikernel image](https://docs.ops.city/ops/google_cloud#create-image) -- [Build auxiliary disk volume, if needed](https://docs.ops.city/ops/volumes) -- Locally: `ops run -c config.json [--mounts volume:/directory]` -- [GCP: Create instance from the image](https://docs.ops.city/ops/google_cloud#create-instance) - -#### Debugging - -When there are problems with the unikernel execution, for example if the cloud instance stops almost immediately after start, the most common problem comes from dynamic libraries that are loaded during the runtime via `dlopen(3)`. -Finding those files can be done using `strace` when running the program natively on Linux: -``` -$ strace -o strace.log -f -e trace=file -``` - -...and then looking at `openat(2)` calls for libraries that **are not** present in `ldd ` output. - -Another way of debugging unikernel execution is to export [trace log](https://docs.ops.city/ops/debugging#tracing) from `ops run`: -``` -$ ops run [-c myconfig.json] [--mounts myvolume:/mnt] --trace &> trace.log -``` - -That will produce Nanos' trace log into `trace.log` for further analysis. - - -## Running Gevulot multi-prover in a Unikernel - -### Compile `prover` - -``` -$ cd prover -$ cargo build --release -``` - -### Generate ED25519 Groth16 Proof & Verify it - -First, due to large size of R1CS constraints & witnesses, the proof input data must be uncompressed: -``` -$ unzip -d test-data test-data/ed25519.zip -``` - -Then, create working volume: -``` -$ ops volume create deployments -n -s 2g -d deployments -``` - -...and finally generate the proof & verify it: -``` -$ # First the proof: -$ ops run target/release/prover -n -c scripts/ed25519-groth-proof.json --mounts deployments:/deployments -$ -$ # Then verification: -$ ops run target/release/prover -n -c scripts/ed25519-groth-verify.json --mounts deployments:/deployments -``` - -To cleanup: -``` -$ ops volume delete deployments -``` - -### Generate Sudoku Marlin Proof & Verify it - -First, [setup Circom & generate test circuit.](prover/circom/README.md) - -Then, create working volume: -``` -$ ops volume create deployments -n -s 2g -d deployments -``` - -...and finally generate the proof & verify it: -``` -$ # First the proof: -$ ops run target/release/prover -n -c scripts/sudoku-marlin-proof.json --mounts deployments:/deployments -$ -$ # Then verification: -$ ops run target/release/prover -n -c scripts/sudoku-marlin-verify.json --mounts deployments:/deployments -``` - -To cleanup: -``` -$ ops volume delete deployments -``` - - -## Running the Starkware Stone prover in a Unikernel - -### Build - -1. After forking the [stone-prover repository](https://github.com/starkware-libs/stone-prover), you will have to comment out six lines of code in one file. That particular code uses syscalls unsupported by Nanos (`schded_getscheduler` and `sched_setscheduler`) -These lines should be commented out: https://github.com/starkware-libs/stone-prover/blob/00b274b55c82077184be4c0758f7bed18950eaba/src/starkware/utils/task_manager.cc#L67-#L72 - -``` - struct sched_param params {}; - int ret = sched_setscheduler(0, SCHED_BATCH, ¶ms); - ASSERT_RELEASE(ret == 0, "Filed to set scheduling policy."); - - int policy = sched_getscheduler(0); - ASSERT_RELEASE(policy == SCHED_BATCH, "the scheduling policy was not set properly.") -``` -2. Build the docker image, along with the standalone prover and verifier. While the repository's readme explains everything thoroughly, here is a summary: - -``` -docker build --tag prover . -container_id=$(docker create prover) -docker cp -L ${container_id}:/bin/cpu_air_prover . -docker cp -L ${container_id}:/bin/cpu_air_verifier . -``` - -### Running the prover and verifier locally - -1. Copy the two executables -- `cpu_air_prover` and `cpu_air_prover` -- from the root level of `stone-prover` into the gevulot `/prover` folder. -2. In the terminal, go to the `gevulot/prover` folder. -3. Create an ops volume, pointing to the `deployments` folder. -``` -ops volume create deployments -n -s 2g -d deployments ``` -4. Run the Starkware prover with 8 CPU threads +podman build -t gevulot-node . ``` -ops run cpu_air_prover -n -c starkware/fibo-prover.json --mounts deployments:/deployments --smp 8 -``` - -You'll see some verbose output similar to this: - -``` -running local instance -booting /home/ader/.ops/images/cpu_air_prover ... -en1: assigned 10.0.2.15 -I1025 10:02:59.046082 2 profiling.cc:58] Prover started -I1025 10:02:59.061094 2 memory_cell.inl:121] Filled 766 vacant slots in memory: 0 holes and 766 spares. -I1025 10:02:59.220237 2 stark.cc:423] Trace cells count: -Log number of rows: 13 -Number of first trace columns: 23 -Number of interaction columns: 2 -Total trace cells: 204800 -en1: assigned FE80::4CFB:E9FF:FE89:7145 -I1025 10:03:02.006559 2 prover_main_helper_impl.cc:147] Byte count: 63016 -Hash count: 843 -Commitment count: 5 -Field element count: 1126 -Data count: 1 -I1025 10:03:02.009160 2 profiling.cc:85] Prover finished in 2.96277 sec -``` -5. Run the Starkware verifier -``` -ops run cpu_air_verifier -n -c gevulot/fibo-verify.json --mounts deployments:/deployments - -``` -response: -``` -running local instance -booting /home/ader/.ops/images/cpu_air_verifier ... -en1: assigned 10.0.2.15 -I1025 10:08:09.364480 2 task_manager.cc:33] TaskManager::TaskManager : n_threads 1. -I1025 10:08:09.370080 2 cpu_air_verifier_main.cc:39] Proof verified successfully. -``` - -## Wrapping a generic prover in a unikernel - -### rust-fil-proofs / benchy - -Filecoin Proving Subsystem provides a convenient benchmarking tool to compute various proofs. -This is a good test prover for the platform. - -#### Prepare Unikernel Image -**NOTE:** Following scripts use `2KiB` sector-size for proof construction. Also `8MiB`, `512MiB`, `32GiB` and `64GiB` are supported, when volume sizes are adjusted accordingly. +### Running the node -*Clone the repo & build benchy:* -``` -$ git clone git@github.com:filecoin-project/rust-fil-proofs.git -$ cd rust-fil-proofs -$ cargo build --release - -# Create separate directory for the deployment -$ mkdir deployment -$ cp target/release/benchy deployment -$ cp rust-fil-proofs.config.toml.sample deployment/rust-fil-proofs.config.toml -$ cd deployment -``` +In order to run the node, refer [installation guide](INSTALL.md). -*Edit `rust-fil-proofs.config.toml` file locations to use base path `/tmp` instead of `/var/tmp`. It should look like following:* -``` -# To use this configuration, copy this file to './rust-fil-proofs.config.toml'. +### Development -# The location to store downloaded parameter files required for proofs. -parameter_cache = "/tmp/filecoin-proofs-parameters/" +For development you need following dependencies (package names for Fedora): -# The location to store the on-disk parents cache. -parent_cache = "/tmp/filecoin-parents" -# The max number of parent cache elements to have mapped in RAM at a time. -sdr_parents_cache_size = 2_048 +- `openssl-devel` +- `protobuf` +- `protobuf-c` +- `protobuf-compiler` +- `protobuf-devel` -# This enables the use of the GPU for column tree building. -use_gpu_column_builder = false -# If the GPU is used for column building, this is the batch size to send to the GPU at a time. -max_gpu_column_batch_size = 400_000 -# This is the batch size for writing out the column tree elements to disk after it's generated. -column_write_batch_size = 262_144 +#### Database -# This enables the use of the GPU for tree r last building. -use_gpu_tree_builder = false -# If the GPU is used for tree r last building, this is the batch size to send to the GPU at a time. -max_gpu_tree_batch_size = 700_000 +##### Local postgres container under systemd -# This setting affects tree_r_last (MerkleTree) generation and access -# and determines the size of the on disk tree caches. This value MUST -# NOT be changed after tree_r_last caches have been generated on your -# system, as any remaining will no longer be accessible. A tool -# exists called 'update_tree_r_last' that can rebuild cache files if -# it's required, but updating this setting is NOT recommended. -rows_to_discard = 2 - -# This value is defaulted to the number of cores available on your system. -#window_post_synthesis_num_cpus = 8 - -# This enables multicore SDR replication -use_multicore_sdr = false -``` +Local development postgres can be run e.g. as a user's quadlet systemd unit: -*Download param files (adjust sector-size accordingly!):* -``` -$ mkdir -p tmp/filecoin-proofs-parameters -$ jq -r 'map_values(select(.sector_size == 2048))| keys[]' ../parameters.json | xargs -I{} curl -L -o tmp/filecoin-proofs-parameters/{} https://proofs.filecoin.io/{} +**~/.config/containers/systemd/gevulot-postgres.container** ``` +[Install] +WantedBy=default.target -*Create Nanos manifest* +[Container] +ContainerName=gevulot-postgres -Following one is for local QEMU/KVM use. Save it to `local.json`: -``` -{ - "RebootOnExit": true, - "Files":["rust-fil-proofs.config.toml"], - "Env":{ - "BELLMAN_NO_GPU": "1", - "RUST_BACKTRACE": "1", - "RUST_LOG": "trace" - }, - "Args":["winning-post", "--size", "2KiB", "--fake"], - "Program":"benchy" -} -``` +Image=docker.io/library/postgres:16-alpine -*Build the volume with parameter files & space for working files:* -``` -$ ops volume create tmp -n -s 40g -d tmp -``` - -#### Run the unikernel locally +Environment=POSTGRES_USER=gevulot +Environment=POSTGRES_PASSWORD=gevulot +Environment=POSTGRES_DB=gevulot -*When running single instances of the unikernel locally, one can omit the image building phase and directly run it:* -``` -$ ops run benchy -n -c local.json --mounts tmp:/tmp +Network=host +ExposeHostPort=5432 ``` -#### Run the unikernel in Google Cloud +##### Initialization -When running unikernels in Google Cloud, the images must be built ahead of time, instances scheduled separately for running them and volumes mounted once the instance is running. - -*Prepare `gcloud.json` configuration:* -``` -{ - "CloudConfig" :{ - "ProjectID": "", - "Zone": "europe-west1-b", - "BucketName":"", - "Flavor":"n1-standard-8" - }, - "Klibs":["gcp", "tls"], - "RebootOnExit": true, - "RunConfig": { - "CPUs":8 - }, - "Files":["rust-fil-proofs.config.toml"], - "Env":{ - "BELLMAN_NO_GPU": "1", - "RUST_BACKTRACE": "1", - "RUST_LOG": "trace" - }, - "Args":["winning-post", "--size", "2KiB", "--fake"], - "Program":"benchy" -} -``` - -*Create volume in GCP:* -``` -$ ops volume create tmp -s 40g -n -t gcp -c gcloud.json -d tmp -``` - -*Create unikernel image to GCP:* -``` -$ ops image create benchy -n -t gcp -c gcloud.json --mounts tmp:/tmp -``` - -*Start an instance in GCP:* -``` -$ ops instance create benchy -t gcp -c gcloud.json - -``` - -Capture the created `instance ID` from the output of previous command. It's `benchy-`, like: `benchy-1693468118`. - -*Attach `tmp` volume to running instance:* -``` -$ ops volume attach tmp -t gcp -c gcloud.json -``` - -*Inspect console logs from a running instance:* -``` -$ ops instance logs -t gcp -c gcloud.json -``` - -*Finally, to delete the instance & volume:* -``` -$ ops instance delete -t gcp -c gcloud.json -$ ops volume delete tmp -t gcp -c gcloud.json -``` - - -Please note that by default the instance will stop immediately after program completion, so when running in cloud you may want to put some sleep in the end of execution to keep the console logs available: -``` -diff --git a/fil-proofs-tooling/src/bin/benchy/main.rs b/fil-proofs-tooling/src/bin/benchy/main.rs -index a3c03b7d..25385b31 100644 ---- a/fil-proofs-tooling/src/bin/benchy/main.rs -+++ b/fil-proofs-tooling/src/bin/benchy/main.rs -@@ -3,6 +3,7 @@ - - use std::io::{stdin, stdout}; - use std::str::FromStr; -+use std::{thread, time}; - - use anyhow::Result; - use byte_unit::Byte; -@@ -322,5 +323,7 @@ fn main() -> Result<()> { - _ => unreachable!(), - } - -+ thread::sleep(time::Duration::from_secs(240)); -+ - Ok(()) - } -``` +`sqlx-cli` can be run from `crates/node` directory as follows: +- **Create database**: + - `cargo sqlx database create --database-url postgres://gevulot:gevulot@localhost/gevulot` +- **Run DB migrations**: + - `cargo sqlx migrate run --database-url postgres://gevulot:gevulot@localhost/gevulot` +##### Refresh SQLX cache +- `cargo sqlx prepare --database-url postgres://gevulot:gevulot@localhost/gevulot` ## License diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml new file mode 100644 index 00000000..f21e94f4 --- /dev/null +++ b/crates/cli/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "gevulot-cli" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" + +[dependencies] +anyhow = "1.0.71" +blake3 = { version = "1.5", features = [ "mmap" ] } +clap = { version = "4.0.29", features = ["derive"] } +futures-util = { version = "0.3", default-features = false } +gevulot-node = { path = "../node" } +hex = "0.4" +http-body-util = "0.1" +hyper = { version = "1", features = ["full"] } +hyper-util = { version = "0.1", features = ["full"] } +indicatif = "0.17.7" +libsecp256k1 = "0.7" +log = "0.4.20" +rand = { version = "0.8", features = [ "std_rng" ] } +serde = { version = "1.0", features = ["derive"] } +serde_json = { version = "1.0"} +sha3 = "0.10" +tracing-subscriber = "0.3.18" +tokio = { version = "1", features = [ "full" ] } +tokio-util = "0.7" +url = "2.5.0" diff --git a/crates/cli/README.md b/crates/cli/README.md new file mode 100644 index 00000000..f2a37ae0 --- /dev/null +++ b/crates/cli/README.md @@ -0,0 +1,72 @@ +# Gevulot cli tool + +Gevulot cli tool allows to send commands / transactions to a Gevulot node. + +## Available commands + +The commands provided by gevulot-cli are: + * **generate-key** : Generate a secret key in the specified file. The secret key is used to sign the Tx sent to the node. + * **deploy**: Send a deploy Tx to the node to deploy the specified prover / verifier. + * **exec** : Send a run Tx to be executed by the node. + * **calculate-hash**: Calculate the Hash of the specified file. + + For detailed information use : gevulot-cli --help + +### Common parameters + + * -j, --jsonurl: URL of the node JSON-RPC access point. Default: http://localhost:9944 + * -k, --keyfile: Path to a secret key file. Default: localkey.pki + +### Deploy command + +This command allows to deploy a compiled prover / verified image to the node specified with the --jsonurl parameter. + +The deployment can be done using file installed on the same host as the gevulot-cli tool. In this case the --prover and / or --verifier contains the path to the image to deploy. The Gevulot node try to open an http connection to the gevulot-cli host. Use `--listen-addr` to specify the http bind address used by gevulot-cli (default 127.0.0.1:8080). +If the host that executes gevulot-cli cannot be reached by the node using http, the image can be installed on an http host that is visible to the node and the url can be specified. In this case the --prover and / or --verifier parameters contains the hash of the image. Use the **calculate-hash** command to get the Hash of an image file. To specify the distant image http url use the --proverimgurl and / or --verifierimgurl + +For more information use: `gevulot-cli deploy --help` + +#### Examples: + +To deploy local images: +``` +gevulot-cli -- deploy --name test --prover ./prover --verifier ./verifier +``` + +To deploy a local prover and a distant verifier: +``` +gevulot-cli -- deploy --name test --prover ../../target/debug/prover --verifier 491907d04032869088ef9b81004639ed1bb185f0413a261f74faaa0aa943d3f3 --verifierimgurl http://... +``` + +### Exec command + +This command allows to execute a workflow of task on the nodes. A task is an execution of a program on the node. Deployed prover or verifier are programs. + +The tasks are defined using a json format. Use `--tasks` parameter to specify a list of execution tasks or steps. + +#### Example of steps: + +To execute the program with the specified hash with arguments `--nonce=42`: +``` +{"program":"9616d42b0d82c1ed06eab8eaa26680261ad831012bbf3ad8303738a53bf85c7c","cmd_args":[{"name":"--nonce","value":"42"}],"inputs":[]} +``` + +To execute a program with input of type output for the program data: +``` +{"program":"37ef718f473a96e2dd56ac27fc175bfa08f4a30e34bdff5802e2f5071265a942", "cmd_args":[],"inputs":[{"Output":{"source_program":"9616d42b0d82c1ed06eab8eaa26680261ad831012bbf3ad8303738a53bf85c7c","file_name":"/workspace/proof.dat"}}]} +``` + +A command using these steps: +``` +gelulot-cli -- exec --tasks '[{"program":"9616d42b0d82c1ed06eab8eaa26680261ad831012bbf3ad8303738a53bf85c7c","cmd_args":[{"name":"--nonce","value":"42"}],"inputs":[]},{"program":"37ef718f473a96e2dd56ac27fc175bfa08f4a30e34bdff5802e2f5071265a942","cmd_args":[],"inputs":[{"Output":{"source_program":"9616d42b0d82c1ed06eab8eaa26680261ad831012bbf3ad8303738a53bf85c7c","file_name":"/workspace/proof.dat"}}]}]' +``` + +## License + +This library is licensed under either of the following licenses, at your discretion. + +[Apache License Version 2.0](LICENSE-APACHE) + +[MIT License](LICENSE-MIT) + +Any contribution that you submit to this library shall be dual licensed as above (as defined in the Apache v2 License), without any additional terms or conditions. diff --git a/crates/cli/src/keyfile.rs b/crates/cli/src/keyfile.rs new file mode 100644 index 00000000..7d7fa494 --- /dev/null +++ b/crates/cli/src/keyfile.rs @@ -0,0 +1,23 @@ +use libsecp256k1::SecretKey; +use rand::rngs::StdRng; +use rand::SeedableRng; +use std::fs; +use std::path::PathBuf; + +pub fn create_key_file(file_path: &PathBuf) -> crate::BoxResult<()> { + let key = SecretKey::random(&mut StdRng::from_entropy()); + let key_array = key.serialize(); + if !file_path.as_path().exists() { + Ok(fs::write(file_path, &key_array[..])?) + } else { + Err(Box::new(std::io::Error::new( + std::io::ErrorKind::Other, + "Key file already exist. Can't erase it.", + ))) + } +} + +pub fn read_key_file(file_path: &PathBuf) -> crate::BoxResult { + let key_array = fs::read(file_path)?; + Ok(SecretKey::parse_slice(&key_array)?) +} diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs new file mode 100644 index 00000000..89b7b279 --- /dev/null +++ b/crates/cli/src/lib.rs @@ -0,0 +1,330 @@ +use gevulot_node::{ + rpc_client::RpcClient, + types::{ + transaction::{Payload, ProgramData, ProgramMetadata, Workflow, WorkflowStep}, + Hash, Transaction, + }, +}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::net::SocketAddr; +use std::path::PathBuf; + +pub mod keyfile; +mod server; + +type BoxResult = std::result::Result>; + +pub async fn calculate_hash_command(file_path: &PathBuf) -> BoxResult { + Ok(extract_hash_from_file_content(file_path) + .ok_or_else(|| format!("File not found:{:?}", file_path))?) +} + +// { +// program: "Program Hash", +// cmd_args: [ {name: "args name", value:"args value"}, ...], +// inputs: vec![], +// } +#[derive(Serialize, Deserialize, Debug, Clone)] +struct JsonCmdArgs { + name: String, + value: String, +} + +impl From for [String; 2] { + fn from(args: JsonCmdArgs) -> Self { + [args.name, args.value] + } +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +struct JsonExecArgs { + program: String, + cmd_args: Vec, + inputs: Vec, +} + +impl TryFrom for WorkflowStep { + type Error = String; + + fn try_from(data: JsonExecArgs) -> Result { + Ok(WorkflowStep { + program: (&(hex::decode(data.program) + .map_err(|err| format!("program decoding hash error:{err}"))?)[..]) + .into(), + args: data + .cmd_args + .into_iter() + .flat_map(<[String; 2]>::from) + .collect(), + inputs: data + .inputs + .into_iter() + .map(|i| i.try_into()) + .collect::, _>>() + .map_err(|err| format!("Source program decoding hash error:{err}"))?, + }) + } +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +pub enum JsonProgramData { + Input { + file_name: String, + file_url: String, + checksum: String, + }, + Output { + source_program: String, + file_name: String, + }, +} + +impl TryFrom for ProgramData { + type Error = hex::FromHexError; + + fn try_from(data: JsonProgramData) -> Result { + match data { + JsonProgramData::Input { + file_name, + file_url, + checksum, + } => Ok(ProgramData::Input { + file_name, + file_url, + checksum, + }), + JsonProgramData::Output { + source_program, + file_name, + } => Ok(ProgramData::Output { + source_program: (&(hex::decode(source_program)?)[..]).into(), + file_name, + }), + } + } +} + +pub async fn run_exec_command( + client: RpcClient, + keyfile: PathBuf, + json_tasks: String, +) -> BoxResult { + let key = keyfile::read_key_file(&keyfile).map_err(|err| { + format!( + "Error during key file:{} reading:{err}", + keyfile.to_str().unwrap_or("") + ) + })?; + + let steps = serde_json::from_str::>(&json_tasks) + .map_err(|err| format!("Json decoding error :{err} with :{json_tasks}"))? + .into_iter() + .map(|t| t.try_into()) + .collect::, _>>()?; + + let tx = Transaction::new( + Payload::Run { + workflow: Workflow { steps }, + }, + &key, + ); + + client.send_transaction(&tx).await?; + Ok(tx.hash.to_string()) +} + +#[allow(clippy::too_many_arguments)] +pub async fn run_deploy_command( + client: RpcClient, + keyfile: PathBuf, + name: String, + prover: String, + verifier: String, + prover_img_url: Option, + verifier_img_url: Option, + listen_addr: SocketAddr, +) -> BoxResult<(String, String, String)> { + let key = keyfile::read_key_file(&keyfile).map_err(|err| { + format!( + "Error during key file:{} reading:{err}", + keyfile.to_str().unwrap_or("") + ) + })?; + let exist_prover_path = verify_file_path(&prover); + let exist_verifier_path = verify_file_path(&verifier); + + // Start the local server if needed. Local file provided. + let server_files_path: Vec = exist_prover_path + .iter() + .chain(exist_verifier_path.iter()) + .cloned() + .collect(); + let (served_file_map, server_jh) = if !server_files_path.is_empty() { + //some local files start the server. + server::serve_file(listen_addr, &server_files_path) + .await + .map(|(map, jh)| (map, Some(jh))) + .map_err(|err| { + format!( + "Couldn't bind to specified bind address:{} because {err}", + listen_addr + ) + })? + } else { + (HashMap::new(), None) + }; + + //create tx data + let Ok(prover_data) = + create_tx_data(exist_prover_path, prover, prover_img_url, &served_file_map) + else { + return Err( + "Wrong specified prover image file path. File can't be read." + .to_string() + .into(), + ); + }; + let Ok(verifier_data) = create_tx_data( + exist_verifier_path, + verifier, + verifier_img_url, + &served_file_map, + ) else { + return Err( + "Wrong specified verifier image file path. File can't be read." + .to_string() + .into(), + ); + }; + + let prover_hash = prover_data.hash.to_string(); + let verifier_hash = verifier_data.hash.to_string(); + + let tx = Transaction::new( + Payload::Deploy { + name, + prover: prover_data, + verifier: verifier_data, + }, + &key, + ); + + client + .send_transaction(&tx) + .await + .map_err(|err| format!("Error during send transaction to the node:{err}"))?; + + let read_tx = client + .get_transaction(&tx.hash) + .await + .map_err(|err| format!("Error during send get_transaction from the node:{err}"))?; + + let tx_hash = read_tx + .as_ref() + .and_then(|read| (tx.hash == read.hash).then_some(read.hash)) + .ok_or_else(|| { + format!( + "Error get_transaction doesn't return the right tx send tx:{} read tx:{:?}", + tx.hash, read_tx + ) + })?; + + if let Some(server_jh) = server_jh { + let _ = server_jh.await; + } + + Ok((tx_hash.to_string(), prover_hash, verifier_hash)) +} + +fn create_tx_data( + verified_file: Option, + tx_input_args: String, + file_url_args: Option, + served_file_map: &HashMap<&PathBuf, String>, +) -> std::result::Result { + let (image_file_name, image_file_url, image_file_checksum) = + generate_tx_data(verified_file, tx_input_args, file_url_args, served_file_map)?; + let mut data = ProgramMetadata { + name: image_file_name.clone(), + hash: Hash::default(), + image_file_name, + image_file_url: image_file_url.to_string(), + image_file_checksum, + }; + //TODO use a new to be sure the update is done during creation. + data.update_hash(); + Ok(data) +} + +fn generate_tx_data( + verified_file: Option, + tx_input_args: String, + file_url_args: Option, + served_file_map: &HashMap<&PathBuf, String>, +) -> std::result::Result<(String, String, String), String> { + verified_file + .and_then(|path| { + //case 1 prover is a file name + extract_hash_from_file_content(&path) + .and_then(|file_hash| { + path.file_name() + .and_then(|file_name| file_name.to_str()) + .map(|file_name| (file_name.to_string(), file_hash)) + }) + .and_then(|(file_name, file_hash)| { + served_file_map + .get(&path) + .map(|url| Ok((file_name, url.to_string(), file_hash))) + }) + }) + .or_else(|| { + //case 2 prover is a hash + //try to detect if the parameters is a hash + let res = hex::decode(&tx_input_args) + .map_err(|err| format!("error during Hash decoding:{err}")) + .and_then(|val| { + <[u8; 32]>::try_from(val) + .map_err(|err| format!("error Hash binary vec into array conv:{err:?}"))?; + Ok(()) + }) + .and_then(|_| { + //Get file name from url or define as file hash + let filename = file_url_args + .as_ref() + .and_then(|url| get_last_segment_from_url(url)) + .unwrap_or(tx_input_args.to_string()); + file_url_args + .map(|img_url| (filename, img_url, tx_input_args)) + .ok_or("Image url not provided with Hash".to_string()) + }); + Some(res) + }) + //never None + .unwrap() +} + +fn get_last_segment_from_url(url: &str) -> Option { + url::Url::parse(url).ok().and_then(|s| { + s.path_segments() + .and_then(|iter| iter.last().map(String::from)) + }) +} + +// Verify that the path exists and is a file. +fn verify_file_path(file_path: &str) -> Option { + let path: PathBuf = file_path.into(); + path.try_exists() + .map(|res| res && path.is_file()) + .ok() + .and_then(|present| present.then_some(path)) +} + +// TODO: Add utility function to Hash. +fn extract_hash_from_file_content(path: &PathBuf) -> Option { + let mut hasher = blake3::Hasher::new(); + let fd = std::fs::File::open(path).ok()?; + hasher.update_reader(fd).ok()?; + let checksum = hasher.finalize(); + Some(checksum.to_string()) +} diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs new file mode 100644 index 00000000..1e4449cf --- /dev/null +++ b/crates/cli/src/main.rs @@ -0,0 +1,150 @@ +use clap::Parser; +use clap::Subcommand; +use gevulot_node::rpc_client::RpcClient; +use std::net::SocketAddr; +use std::path::PathBuf; + +#[derive(Parser, Debug)] +#[clap(author = "Gevulot Team", version, about, long_about = None)] +pub struct ArgConfiguration { + /// RPC url of the Gevulot node + #[clap( + short, + long = "jsonurl", + default_value = "http://localhost:9944", + value_name = "URL" + )] + json_url: String, + /// Private key file path to sign Tx. + #[clap( + short, + long, + default_value = "localkey.pki", + value_name = "KEY FILE PATH" + )] + keyfile: PathBuf, + #[command(subcommand)] + command: ConfCommands, +} + +#[derive(Subcommand, Debug)] +enum ConfCommands { + /// Generate a private key file using --keyfile option. + GenerateKey, + + /// Deploy prover and verifier. + #[command(arg_required_else_help = true)] + Deploy { + /// name of the deployment. + #[clap(short, long, value_name = "DEPLOYMENT NAME")] + name: String, + /// file path containing the program image of the prover to deploy or the hash of the prover image file (--prover-img-url is mandatory in this case). If the file doesn't exist, the parameter is used as a hash. + #[clap(short, long, value_name = "PROVER FILE or HASH")] + prover: String, + /// file path containing the program image of the verifier to deploy or the hash of the verifier image file (--verifier-img-url is mandatory in this case). If the file doesn't exist, the parameter is used as a hash. + #[clap(short, long, value_name = "VERIFIER FILE or HASH")] + verifier: String, + /// url to get the prover image. If provided the prover will use this URL to get the prover image file. If not the cli tool starts a local HTTP server to serve the file to the node. + #[clap(long = "proverimgurl", value_name = "PROVER URL")] + prover_img_url: Option, + /// url to get the verifier image. If provided the verifier will use this URL to get the verifier image. If not the cli tool starts a local HTTP server to serve the file to the node. + #[clap(long = "verifierimgurl", value_name = "VERIFIER URL")] + verifier_img_url: Option, + /// Address the local http server use to listen for node file download request. + #[clap( + short, + long, + default_value = "127.0.0.1:8080", + value_name = "LOCAL SERVER BIND ADDR" + )] + listen_addr: SocketAddr, + }, + + /// Execute the list of task in the order one after the other. + #[command(arg_required_else_help = true)] + Exec { + /// array of Json task definition. + /// Json format of the task data: + /// [{ + /// program: "Program Hash", + /// cmd_args: [ {name: "args name", value:"args value"}, ...], + /// inputs: [{"Output":{"source_program":"Program Hash","file_name":"filename"}}], + /// , ... + /// }] + /// Example for proving and verification: + /// --tasks '[ + /// {"program":"9616d42b0d82c1ed06eab8eaa26680261ad831012bbf3ad8303738a53bf85c7c","cmd_args":[{"name":"--nonce","value":"42"}],"inputs":[]} + ///, + ///{ + /// "program":"37ef718f473a96e2dd56ac27fc175bfa08f4a30e34bdff5802e2f5071265a942", + /// "cmd_args":[{"name":"--nonce2","value":"45"},{"name":"--nonce3","value":"46"}] + ///,"inputs":[{"Output":{"source_program":"9616d42b0d82c1ed06eab8eaa26680261ad831012bbf3ad8303738a53bf85c7c","file_name":"/workspace/proof.dat"}}] + /// } + ///]' + #[clap(short, long, value_name = "TASK ARRAY")] + tasks: String, + }, + /// Calculate the Hash of the specified file. + #[command(arg_required_else_help = true)] + CalculateHash { + /// Path to the file to hash. + #[clap(short, long, value_name = "FILE PATH")] + file: PathBuf, + }, +} + +#[tokio::main] +async fn main() { + tracing_subscriber::fmt::init(); + + let args = ArgConfiguration::parse(); + + let client = RpcClient::new(args.json_url); + + match args.command { + ConfCommands::GenerateKey => match gevulot_cli::keyfile::create_key_file(&args.keyfile) { + Ok(()) => println!( + "Key generated and saved in file:{}", + args.keyfile.to_str().unwrap_or("") + ), + Err(err) => println!("Error during key file creation:{err}"), + }, + ConfCommands::Deploy { + name, + prover, + verifier, + prover_img_url, + verifier_img_url, + listen_addr, + } => { + println!("Start prover / verifier deployement"); + match gevulot_cli::run_deploy_command( + client, + args.keyfile, + name, + prover, + verifier, + prover_img_url, + verifier_img_url, + listen_addr, + ) + .await + { + Ok((tx_hash, prover_hash, verifier_hash)) => println!("Prover / Verifier deployed correctly. Prover hash:{prover_hash} Verifier hash:{verifier_hash}. Tx Hash:{tx_hash}"), + Err(err) => println!("An error occurs during Prover / Verifier deployement :{err}"), + } + } + ConfCommands::Exec { tasks } => { + match gevulot_cli::run_exec_command(client, args.keyfile, tasks).await { + Ok(tx_hash) => println!("Programs send to execution correctly. Tx hash:{tx_hash}"), + Err(err) => println!("An error occurs during send execution Tx :{err}"), + } + } + ConfCommands::CalculateHash { file } => { + match gevulot_cli::calculate_hash_command(&file).await { + Ok(tx_hash) => println!("The hash of the file is: {tx_hash}"), + Err(err) => println!("An error hash calculus Tx :{err}"), + } + } + } +} diff --git a/crates/cli/src/server.rs b/crates/cli/src/server.rs new file mode 100644 index 00000000..7be0bdea --- /dev/null +++ b/crates/cli/src/server.rs @@ -0,0 +1,208 @@ +use futures_util::StreamExt; +use futures_util::TryStreamExt; +use http_body_util::combinators::BoxBody; +use http_body_util::{BodyExt, Full, StreamBody}; +use hyper::body::{self, Bytes, Frame}; +use hyper::server::conn::http1; +use hyper::service::service_fn; +use hyper::{Request, Response, StatusCode}; +use hyper_util::rt::TokioIo; +use indicatif::{MultiProgress, ProgressBar, ProgressState, ProgressStyle}; +use sha3::{Digest, Sha3_256}; +use std::collections::HashMap; +use std::fmt::Write; +use std::net::SocketAddr; +use std::path::Path; +use std::path::PathBuf; +use std::sync::Arc; +use tokio::fs::File; +use tokio::net::TcpListener; +use tokio::task::JoinHandle; +use tokio::time::{self, Duration}; +use tokio_util::io::ReaderStream; + +//start the local server and serve the specified file path. +//Return the file_names and associated Url to get the file from the server. +pub async fn serve_file( + bind_addr: SocketAddr, + files: &[PathBuf], +) -> crate::BoxResult<(HashMap<&PathBuf, String>, JoinHandle<()>)> { + let listener = TcpListener::bind(bind_addr).await?; + + // Re-read the listen address in case random port was used. + let listener_addr = listener.local_addr()?; + + let files_data: Vec<(&PathBuf, (String, String))> = files + .iter() + .map(|path| (path, calculate_file_url_digest(path, listener_addr))) + .collect(); + //create the list of file to be served. + let mut served_files: HashMap = files_data + .iter() + .map(|(path, (_url, hash))| (hash.to_string(), path.to_path_buf())) + .collect(); + + //build progress bar + let multi_pg = MultiProgress::new(); + let pg_map: HashMap = served_files + .iter() + .map::, _>(|(digest, path)| { + let metadata = std::fs::metadata(path)?; + let filename = path + .file_name() + .and_then(|file_name| file_name.to_str()) + .unwrap_or("img_file"); + let pg = multi_pg.add(build_file_progress_bar( + filename.to_string(), + metadata.len(), + )); + Ok((digest.to_string(), pg)) + }) + .filter_map(Result::ok) + .collect(); + + let jh = tokio::spawn({ + async move { + let local_file_list = Arc::new(served_files.clone()); + let (counter_tx, mut counter_rx) = tokio::sync::mpsc::unbounded_channel(); + + //timer that detect if the download has been started before it trigger. + //node download should start before 10 second. + let mut download_started = false; + let mut download_started_interval = time::interval(Duration::from_millis(10000)); + download_started_interval.tick().await; + + loop { + tokio::select! { + listen = listener.accept() => match listen { + Ok((stream, _)) => { + let io = TokioIo::new(stream); + tokio::task::spawn({ + let local_file_list = local_file_list.clone(); + let conn_counter_tx = counter_tx.clone(); + async move { + if let Err(err) = http1::Builder::new() + .serve_connection( + io, + service_fn(|req| server_process_file(req, &local_file_list, conn_counter_tx.clone())), + ) + .await + { + log::error!("Error serving node connection: {err}. Wait for a new node connection."); + } + } + }); + } + Err(err) => { + log::error!( + "Error during node connection to local server:{err} \ + The img file hasn't been delivered. Wait for a new node connection" + ); + } + }, + //manage file download tracking. + Some((file_digest, byte_len)) = counter_rx.recv() => { + download_started = true; + if let Some(pg) = pg_map.get(&file_digest) { + pg.inc(byte_len as u64); + if pg.length().unwrap() <= pg.position() { //unwrap because always present, inited in the pg constructor. + pg.finish_with_message("Uploaded"); + served_files.remove(&file_digest); + } + + } + if served_files.is_empty() { + //end of the download + //wait that the http download buffer flush. + tokio::time::sleep(tokio::time::Duration::from_millis(250)).await; + break; + } + } + _ = download_started_interval.tick() => { + if !download_started { + log::error!("Node download didn't started in time. Local host can be unreachable from node."); + break; + } + } + } + } + } + }); + + //return served file url. + let ret = files_data + .into_iter() + .map(|(path, (url, _hash))| (path, url)) + .collect(); + Ok((ret, jh)) +} + +async fn server_process_file( + req: Request, + files: &HashMap, + counter_sender: tokio::sync::mpsc::UnboundedSender<(String, usize)>, +) -> std::result::Result>, hyper::Error> { + let file_digest = &req.uri().path()[1..]; + let file_path = match files.get(file_digest) { + Some(file_path) => file_path, + None => { + return Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body( + Full::new("Not found.".into()) + .map_err(|e| match e {}) + .boxed(), + ) + .unwrap()) + } + }; + let file = match File::open(file_path).await { + Ok(file) => file, + Err(_) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body( + Full::new("Internal server error".into()) + .map_err(|e| match e {}) + .boxed(), + ) + .unwrap()) + } + }; + + let file_hash = file_digest.to_string(); + let reader = ReaderStream::new(file).map(move |bytes| { + let nb_bytes = bytes.as_ref().map(|b| b.len()).unwrap_or(0); + if let Err(err) = counter_sender.send((file_hash.clone(), nb_bytes)) { + log::error!("An error occurs during file download. NOtofication channel close:{err}"); + } + bytes + }); + let stream_body = StreamBody::new(reader.map_ok(Frame::data)); + + Ok(Response::builder() + .status(StatusCode::OK) + .body(BodyExt::boxed(stream_body)) + .unwrap()) +} + +//calculate the file name digest and the local server url. +//return the file path, file_url and file digest +fn calculate_file_url_digest(file_path: &Path, listen_addr: SocketAddr) -> (String, String) { + //use to_string_lossy because path verification should have been done before. + let file_name = file_path.to_string_lossy(); + let mut hasher = Sha3_256::new(); + hasher.update(file_name.as_bytes()); + let digest = hex::encode(hasher.finalize()); + let file_url = format!("http://{}/{}", listen_addr, digest); + (file_url, digest) +} + +fn build_file_progress_bar(file_name: String, total_size: u64) -> ProgressBar { + let pb = ProgressBar::new(total_size); + pb.set_style(ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})") + .unwrap() + .with_key("eta", move |state: &ProgressState, w: &mut dyn Write| write!(w, "{}-{:.1}s", file_name, state.eta().as_secs_f64()).unwrap()) + .progress_chars("#>-")); + pb +} diff --git a/crates/node/.sqlx/query-151f420a22124e7c5f7d6a868f06c71e6f6805787aae1dea47cb248d07689498.json b/crates/node/.sqlx/query-151f420a22124e7c5f7d6a868f06c71e6f6805787aae1dea47cb248d07689498.json new file mode 100644 index 00000000..758221cf --- /dev/null +++ b/crates/node/.sqlx/query-151f420a22124e7c5f7d6a868f06c71e6f6805787aae1dea47cb248d07689498.json @@ -0,0 +1,34 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO assets ( tx ) VALUES ( $1 ) RETURNING *", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "tx", + "type_info": "Varchar" + }, + { + "ordinal": 1, + "name": "created", + "type_info": "Timestamp" + }, + { + "ordinal": 2, + "name": "completed", + "type_info": "Timestamp" + } + ], + "parameters": { + "Left": [ + "Varchar" + ] + }, + "nullable": [ + false, + false, + true + ] + }, + "hash": "151f420a22124e7c5f7d6a868f06c71e6f6805787aae1dea47cb248d07689498" +} diff --git a/crates/node/Cargo.lock b/crates/node/Cargo.lock new file mode 100644 index 00000000..4f6a2cbb --- /dev/null +++ b/crates/node/Cargo.lock @@ -0,0 +1,3152 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "actix-codec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" +dependencies = [ + "bitflags 1.3.2", + "bytes", + "futures-core", + "futures-sink", + "memchr", + "pin-project-lite", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "actix-http" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92ef85799cba03f76e4f7c10f533e66d87c9a7e7055f3391f09000ad8351bc9" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "ahash", + "base64 0.21.4", + "bitflags 2.4.0", + "brotli", + "bytes", + "bytestring", + "derive_more", + "encoding_rs", + "flate2", + "futures-core", + "h2", + "http", + "httparse", + "httpdate", + "itoa", + "language-tags", + "local-channel", + "mime", + "percent-encoding", + "pin-project-lite", + "rand", + "sha1", + "smallvec", + "tokio", + "tokio-util", + "tracing", + "zstd", +] + +[[package]] +name = "actix-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" +dependencies = [ + "quote", + "syn 2.0.37", +] + +[[package]] +name = "actix-router" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" +dependencies = [ + "bytestring", + "http", + "regex", + "serde", + "tracing", +] + +[[package]] +name = "actix-rt" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" +dependencies = [ + "futures-core", + "tokio", +] + +[[package]] +name = "actix-server" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" +dependencies = [ + "actix-rt", + "actix-service", + "actix-utils", + "futures-core", + "futures-util", + "mio", + "socket2 0.5.4", + "tokio", + "tracing", +] + +[[package]] +name = "actix-service" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" +dependencies = [ + "futures-core", + "paste", + "pin-project-lite", +] + +[[package]] +name = "actix-utils" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" +dependencies = [ + "local-waker", + "pin-project-lite", +] + +[[package]] +name = "actix-web" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4a5b5e29603ca8c94a77c65cf874718ceb60292c5a5c3e5f4ace041af462b9" +dependencies = [ + "actix-codec", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-utils", + "actix-web-codegen", + "ahash", + "bytes", + "bytestring", + "cfg-if", + "cookie", + "derive_more", + "encoding_rs", + "futures-core", + "futures-util", + "itoa", + "language-tags", + "log", + "mime", + "once_cell", + "pin-project-lite", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "smallvec", + "socket2 0.5.4", + "time", + "url", +] + +[[package]] +name = "actix-web-codegen" +version = "4.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" +dependencies = [ + "actix-router", + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "anstream" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +dependencies = [ + "serde", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brotli" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da74e2b81409b1b743f8f0c62cc6254afefb8b8e50bbfe3735550f7aeefa3448" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "bytestring" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "238e4886760d98c4f899360c834fa93e62cf7f721ac3c2da375cbdf4b8679aae" +dependencies = [ + "bytes", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "clap_lex" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cookie" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +dependencies = [ + "serde", +] + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "eyre" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.8", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "h2" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 1.9.3", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.1", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.9", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[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.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +dependencies = [ + "equivalent", + "hashbrown 0.14.1", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "language-tags" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "libc" +version = "0.2.148" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" + +[[package]] +name = "libm" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" + +[[package]] +name = "libsqlite3-sys" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" + +[[package]] +name = "local-channel" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a493488de5f18c8ffcba89eebb8532ffc562dc400490eb65b84893fae0b178" +dependencies = [ + "futures-core", + "futures-sink", + "local-waker", +] + +[[package]] +name = "local-waker" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[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 = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "node" +version = "0.1.0" +dependencies = [ + "actix-web", + "async-trait", + "clap", + "eyre", + "prost", + "rand", + "reqwest", + "serde", + "sqlx", + "thiserror", + "tokio", + "tokio-stream", + "tokio-vsock", + "tonic", + "tonic-build", + "tower", + "tracing", + "tracing-subscriber", + "uuid", + "vsock", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[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-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "openssl" +version = "0.10.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9dfc0783362704e97ef3bd24261995a699468440099ef95d869b4d9732f829a" +dependencies = [ + "bitflags 2.4.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f55da20b29f956fb01f0add8683eb26ee13ebe3ebd935e49898717c6b4b2830" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.0.2", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[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.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro2" +version = "1.0.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck", + "itertools 0.10.5", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[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 = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", +] + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.2", +] + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64 0.21.4", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "winreg", +] + +[[package]] +name = "rsa" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" +dependencies = [ + "byteorder", + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f9da0cbd88f9f09e7814e388301c8414c51c62aa6ce1e4b5c551d49d96e531" +dependencies = [ + "bitflags 2.4.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "serde_json" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[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 = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85" +dependencies = [ + "itertools 0.11.0", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e50c216e3624ec8e7ecd14c6a6a6370aad6ee5d8cfc3ab30b5162eeeef2ed33" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d6753e460c998bbd4cd8c6f0ed9a64346fcca0723d6e75e52fdc351c5d2169d" +dependencies = [ + "ahash", + "atoi", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashlink", + "hex", + "indexmap 2.0.2", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlformat", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "url", + "uuid", +] + +[[package]] +name = "sqlx-macros" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a793bb3ba331ec8359c1853bd39eed32cdd7baaf22c35ccf5c92a7e8d1189ec" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4ee1e104e00dedb6aa5ffdd1343107b0a4702e862a84320ee7cc74782d96fc" +dependencies = [ + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 1.0.109", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864b869fdf56263f4c95c45483191ea0af340f9f3e3e7b4d57a61c7c87a970db" +dependencies = [ + "atoi", + "base64 0.21.4", + "bitflags 2.4.0", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb7ae0e6a97fb3ba33b23ac2671a5ce6e3cabe003f451abd5a56e7951d975624" +dependencies = [ + "atoi", + "base64 0.21.4", + "bitflags 2.4.0", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand", + "serde", + "serde_json", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59dc83cf45d89c555a577694534fcd1b55c545a816c816ce51f20bbe56a4f3f" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "tracing", + "url", + "uuid", +] + +[[package]] +name = "stringprep" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +dependencies = [ + "finl_unicode", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys", +] + +[[package]] +name = "thiserror" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +dependencies = [ + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +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 = "tokio" +version = "1.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.4", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tokio-vsock" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52a15c15b1bc91f90902347eff163b5b682643aff0c8e972912cca79bd9208dd" +dependencies = [ + "bytes", + "futures", + "libc", + "tokio", + "tonic", + "vsock", +] + +[[package]] +name = "tonic" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.13.1", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "prost-derive", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "tracing-futures", +] + +[[package]] +name = "tonic-build" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "tracing-core" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[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-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +dependencies = [ + "getrandom", + "rand", + "serde", + "uuid-macro-internal", +] + +[[package]] +name = "uuid-macro-internal" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7e1ba1f333bd65ce3c9f27de592fcbc256dafe3af2717f56d7c87761fbaccf4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vsock" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8e1df0bf1e1b28095c24564d1b90acae64ca69b097ed73896e342fa6649c57" +dependencies = [ + "libc", + "nix", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.37", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" + +[[package]] +name = "wasm-streams" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "whoami" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys", +] + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" + +[[package]] +name = "zstd" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "6.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.9+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml new file mode 100644 index 00000000..f69a635e --- /dev/null +++ b/crates/node/Cargo.toml @@ -0,0 +1,51 @@ +[package] +name = "gevulot-node" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" + +[[bin]] +name = "gevulot" +path = "src/main.rs" + +[dependencies] +async-trait = "0.1.74" +bincode = "1.3" +blake3 = "1.5" +bytes = "1.5" +clap = { version = "4", features = ["derive", "env", "string"] } +console-subscriber = "0.2" +ecies = {version = "0.2", default-features = false, features = ["pure"]} +eyre = "0.6.8" +futures-util = "0.3" +hex = "0.4" +home = "0.5" +jsonrpsee = { version = "0.20", features = [ "client", "server" ] } +libsecp256k1 = "0.7" +num-bigint = { version = "0.4", features = [ "serde" ] } +num-traits = "0.2" +parking_lot = "0.12" +pea2pea = "0.48" +prost = "0.11" +qapi = { version = "0.14", features = [ "qmp", "async-tokio-net" ]} +rand = { version = "0.8", features = [ "std_rng" ] } +reqwest = { version = "0.11", features = [ "stream" ] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "^1.0.9" +sha3 = "0.10" +snow = "0.9" +sqlx = { version = "0.7", features = ["postgres", "migrate", "runtime-tokio", "rust_decimal", "time", "tls-rustls", "uuid"] } +thiserror = "1" +tokio = { version = "1", features = ["full", "tracing"] } +tokio-stream = "0.1" +tokio-util = "0.7" +tokio-vsock = { version = "0.4.0", features = ["tonic-conn"] } +tonic = "0.8.3" +tower = "0.4.0" +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +vsock = "0.3.0" +uuid = { version = "1", features = [ "v4", "fast-rng", "macro-diagnostics", "serde" ] } + +[build-dependencies] +tonic-build = "0.8" diff --git a/crates/node/README.md b/crates/node/README.md new file mode 100644 index 00000000..13d411b7 --- /dev/null +++ b/crates/node/README.md @@ -0,0 +1,93 @@ +# Gevulot Node + +**Work in Progress** + +## Initial setup + +Preliminary assumptions: +- Linux operating system +- x86_64 processor +- Rust installed + +### Dependencies + +- `cuda-opencl-` +- `cuda-opencl-devel-` +- `hwlock-devel` +- `ocl-icd-devel` +- `protobuf` +- `protobuf-c` +- `protobuf-compiler` +- `protobuf-devel` + +- `cargo install sqlx-cli` + +### Gevulot working directory + +`mkdir -p /var/lib/gevulot` + +Also ensure appropriate rights for that directory. + +### Database + +#### Initialization +- `podman-compose up` +- `cargo sqlx database create --database-url postgres://gevulot:gevulot@localhost/gevulot` +- `cargo sqlx migrate run --database-url postgres://gevulot:gevulot@localhost/gevulot` + +#### Refresh SQLX cache +- `cargo sqlx prepare --database-url postgres://gevulot:gevulot@localhost/gevulot` + +### GPU Passthrough + +#### nVidia driver adjustments for Gevulot + +##### Blacklist nVidia modules +**/etc/modprobe.d/nvidia.conf** +``` +blacklist nvidia +blacklist nvidia-drm +``` + +##### Load the VFIO modules +**/etc/modules-load.d/vfio.conf +``` +kvmgt +vfio-pci +vfio-iommu-type1 +vfio-mdev +``` + +##### Configure vfio-pci passthrough devices + +First find out PCI IDs: +``` +$ lspci -nn | grep -i nvidia +01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU104 [GeForce RTX 2070 SUPER] [10de:1e84] (rev a1) +01:00.1 Audio device [0403]: NVIDIA Corporation TU104 HD Audio Controller [10de:10f8] (rev a1) +01:00.2 USB controller [0c03]: NVIDIA Corporation TU104 USB 3.1 Host Controller [10de:1ad8] (rev a1) +01:00.3 Serial bus controller [0c80]: NVIDIA Corporation TU104 USB Type-C UCSI Controller [10de:1ad9] (rev a1) +``` + +Then add all the GPU PCI IDs into module config: +**/etc/modprobe.d/vfio.conf** +``` +options vfio-pci ids=10de:1e84,10de:10f8,10de:1ad8,10de:1ad9 +``` + +##### Adjust vfio device permissions with udev rule + +**/etc/udev/rules.d/99-vfio.rules** +``` +SUBSYSTEM=="vfio", OWNER="root", GROUP="kvm" +``` + +#### Fix GPU USB-controller binding: + +It is possible that `xhci_hcd` driver is built into kernel and it's impossible +to prevent it from binding GPU's USB controller, so it must be fixed after boot. + +``` +echo "0000:01:00.2" | sudo tee /sys/bus/pci/drivers/xhci_hcd/unbind +echo "0000:01:00.2" | sudo tee /sys/bus/pci/drivers/vfio-pci/bind +``` diff --git a/crates/node/build.rs b/crates/node/build.rs new file mode 100644 index 00000000..a2f49078 --- /dev/null +++ b/crates/node/build.rs @@ -0,0 +1,4 @@ +fn main() -> Result<(), Box> { + tonic_build::compile_protos("../shim/proto/vm_service.proto")?; + Ok(()) +} diff --git a/crates/node/migrations/20231009111859_programs-table.sql b/crates/node/migrations/20231009111859_programs-table.sql new file mode 100644 index 00000000..d221bda7 --- /dev/null +++ b/crates/node/migrations/20231009111859_programs-table.sql @@ -0,0 +1,10 @@ + +DROP TABLE IF EXISTS program; + +CREATE TABLE program ( + hash VARCHAR(64) PRIMARY KEY, + name VARCHAR(128) NOT NULL, + image_file_name VARCHAR(256) NOT NULL, + image_file_url VARCHAR(1024) NOT NULL, + image_file_checksum VARCHAR(128) NOT NULL +); diff --git a/crates/node/migrations/20231009111925_tasks-table.sql b/crates/node/migrations/20231009111925_tasks-table.sql new file mode 100644 index 00000000..1c2ce845 --- /dev/null +++ b/crates/node/migrations/20231009111925_tasks-table.sql @@ -0,0 +1,30 @@ + +DROP TABLE IF EXISTS file; +DROP TABLE IF EXISTS task; +DROP TYPE IF EXISTS task_state; +DROP TYPE IF EXISTS task_kind; + +CREATE TYPE task_state AS ENUM ('new', 'pending', 'running', 'ready', 'failed'); +CREATE TYPE task_kind AS ENUM ('proof', 'verification', 'pow', 'nop'); + +CREATE TABLE task ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + name VARCHAR(128) NOT NULL, + args VARCHAR(512)[], + kind task_kind NOT NULL DEFAULT 'nop', + program_id VARCHAR(64) NOT NULL, + serial SERIAL, + state task_state, + CONSTRAINT fk_program + FOREIGN KEY (program_id) + REFERENCES program (hash) ON DELETE CASCADE +); + +CREATE TABLE file ( + task_id uuid NOT NULL, + name VARCHAR(256) NOT NULL, + url VARCHAR(2048) NOT NULL, + CONSTRAINT fk_task + FOREIGN KEY (task_id) + REFERENCES task (id) ON DELETE CASCADE +); diff --git a/crates/node/migrations/20231128120351_transactions-table.sql b/crates/node/migrations/20231128120351_transactions-table.sql new file mode 100644 index 00000000..8ce61ec2 --- /dev/null +++ b/crates/node/migrations/20231128120351_transactions-table.sql @@ -0,0 +1,119 @@ + +DROP TABLE IF EXISTS verification; +DROP TABLE IF EXISTS proof_key; +DROP TABLE IF EXISTS proof; +DROP TABLE IF EXISTS program_output_data; +DROP TABLE IF EXISTS program_input_data; +DROP TABLE IF EXISTS workflow_step; +DROP TABLE IF EXISTS deploy; +DROP TABLE IF EXISTS transaction; +DROP TYPE IF EXISTS transaction_kind; + +CREATE TYPE transaction_kind AS ENUM ('empty','transfer', 'stake', 'unstake', 'deploy', 'run', 'proof', 'proofkey', 'verification', 'cancel'); + +CREATE TABLE transaction ( + author VARCHAR(130) NOT NULL, + hash VARCHAR(64) PRIMARY KEY NOT NULL, + kind transaction_kind NOT NULL, + nonce NUMERIC NOT NULL, + signature VARCHAR(128) NOT NULL, + propagated BOOLEAN, + executed BOOLEAN +); + +CREATE TABLE deploy ( + tx VARCHAR(64) PRIMARY KEY NOT NULL, + name VARCHAR(256), + prover VARCHAR(64), + verifier VARCHAR(64), + CONSTRAINT fk_transaction + FOREIGN KEY (tx) + REFERENCES transaction (hash) ON DELETE CASCADE, + CONSTRAINT fk_prover + FOREIGN KEY (prover) + REFERENCES program (hash) ON DELETE CASCADE, + CONSTRAINT fk_verifier + FOREIGN KEY (verifier) + REFERENCES program (hash) ON DELETE CASCADE +); + +CREATE TABLE workflow_step ( + id BIGSERIAL UNIQUE, + tx VARCHAR(64) NOT NULL, + sequence INTEGER NOT NULL, + program VARCHAR(64) NOT NULL, + args VARCHAR(512)[], + PRIMARY KEY (tx, sequence), + CONSTRAINT fk_transaction + FOREIGN KEY (tx) + REFERENCES transaction (hash) ON DELETE CASCADE, + CONSTRAINT fk_program + FOREIGN KEY (program) + REFERENCES program (hash) ON DELETE CASCADE +); + +CREATE TABLE program_input_data ( + workflow_step_id BIGINT NOT NULL, + file_name VARCHAR(1024) NOT NULL, + file_url VARCHAR(4096) NOT NULL, + checksum VARCHAR(512) NOT NULL, + PRIMARY KEY (workflow_step_id, file_name), + CONSTRAINT fk_workflow_step + FOREIGN KEY (workflow_step_id) + REFERENCES workflow_step (id) ON DELETE CASCADE +); + +CREATE TABLE program_output_data ( + workflow_step_id BIGINT NOT NULL, + file_name VARCHAR(1024) NOT NULL, + source_program VARCHAR(64) NOT NULL, + PRIMARY KEY (workflow_step_id, file_name), + CONSTRAINT fk_workflow_step + FOREIGN KEY (workflow_step_id) + REFERENCES workflow_step (id) ON DELETE CASCADE, + CONSTRAINT fk_source_program + FOREIGN KEY (source_program) + REFERENCES program (hash) ON DELETE CASCADE +); + +CREATE TABLE proof ( + tx VARCHAR(64) PRIMARY KEY NOT NULL, + parent VARCHAR(64) NOT NULL, + prover VARCHAR(64), + proof BYTEA NOT NULL, + UNIQUE(parent, prover), + CONSTRAINT fk_transaction1 + FOREIGN KEY (tx) + REFERENCES transaction (hash) ON DELETE CASCADE, + CONSTRAINT fk_transaction2 + FOREIGN KEY (parent) + REFERENCES transaction (hash) ON DELETE CASCADE, + CONSTRAINT fk_prover + FOREIGN KEY (prover) + REFERENCES program (hash) ON DELETE CASCADE +); + +CREATE TABLE verification ( + tx VARCHAR(64) PRIMARY KEY NOT NULL, + parent VARCHAR(64) NOT NULL, + verifier VARCHAR(64), + verification BYTEA NOT NULL, + CONSTRAINT fk_transaction1 + FOREIGN KEY (tx) + REFERENCES transaction (hash) ON DELETE CASCADE, + CONSTRAINT fk_transaction2 + FOREIGN KEY (parent) + REFERENCES transaction (hash) ON DELETE CASCADE, + CONSTRAINT fk_verifier + FOREIGN KEY (verifier) + REFERENCES program (hash) ON DELETE CASCADE +); + +CREATE TABLE proof_key ( + tx VARCHAR(64) PRIMARY KEY NOT NULL, + parent VARCHAR(64) NOT NULL, + key BYTEA NOT NULL, + CONSTRAINT fk_transaction + FOREIGN KEY (tx) + REFERENCES transaction (hash) ON DELETE CASCADE +); diff --git a/crates/node/migrations/20231128120829_assets-table.sql b/crates/node/migrations/20231128120829_assets-table.sql new file mode 100644 index 00000000..94b547c5 --- /dev/null +++ b/crates/node/migrations/20231128120829_assets-table.sql @@ -0,0 +1,11 @@ + +DROP TABLE IF EXISTS assets; + +CREATE TABLE assets ( + tx VARCHAR(64) PRIMARY KEY NOT NULL, + created TIMESTAMP NOT NULL DEFAULT NOW(), + completed TIMESTAMP, + CONSTRAINT fk_transaction + FOREIGN KEY (tx) + REFERENCES transaction (hash) ON DELETE CASCADE +); diff --git a/crates/node/migrations/20240121151959_acl_whitelist.sql b/crates/node/migrations/20240121151959_acl_whitelist.sql new file mode 100644 index 00000000..c4ac4867 --- /dev/null +++ b/crates/node/migrations/20240121151959_acl_whitelist.sql @@ -0,0 +1,6 @@ + +DROP TABLE IF EXISTS acl_whitelist; + +CREATE TABLE acl_whitelist ( + key VARCHAR(130) PRIMARY KEY NOT NULL +); diff --git a/crates/node/podman-compose.yml b/crates/node/podman-compose.yml new file mode 100644 index 00000000..cc792d38 --- /dev/null +++ b/crates/node/podman-compose.yml @@ -0,0 +1,14 @@ +version: 3.7 + +services: + database: + image: docker.io/library/postgres:16-alpine + restart: always + volumes: + - /tmp/gevulot/database:/var/lib/postgresql/data:Z + environment: + - POSTGRES_USER=gevulot + - POSTGRES_PASSWORD=gevulot + - POSTGRES_DB=gevulot + network_mode: host + hostname: 127.0.0.1 diff --git a/crates/node/src/asset_manager/mod.rs b/crates/node/src/asset_manager/mod.rs new file mode 100644 index 00000000..7c001dd4 --- /dev/null +++ b/crates/node/src/asset_manager/mod.rs @@ -0,0 +1,188 @@ +use std::{path::PathBuf, sync::Arc, time::Duration}; + +use eyre::Result; +use gevulot_node::types::{ + self, + transaction::{Payload, ProgramData}, +}; +use thiserror::Error; +use tokio::{io::AsyncWriteExt, time::sleep}; + +use crate::{ + cli::Config, + storage::{self, Database}, + types::{ + transaction::{self, Transaction}, + Hash, Program, + }, +}; + +#[allow(clippy::enum_variant_names)] +#[derive(Error, Debug)] +enum AssetManagerError { + #[error("program image download")] + ProgramImageDownload, + + #[error("incompatible transaction payload")] + IncompatibleTxPayload(Hash), +} + +/// AssetManager is reponsible for coordinating asset management for a new +/// transaction. New deployment of prover & verifier requires downloading of +/// VM images for those programs. Similarly, Run transaction has associated +/// input data which must be downloaded, but also built into workspace volume +/// for execution. +pub struct AssetManager { + config: Arc, + database: Arc, + http_client: reqwest::Client, +} + +impl AssetManager { + pub fn new(config: Arc, database: Arc) -> Self { + AssetManager { + config, + database, + http_client: reqwest::Client::new(), + } + } + + pub async fn run(&self) -> Result<()> { + // Main processing loop. + loop { + for tx_hash in self.database.get_incomplete_assets().await? { + if let Some(tx) = self.database.find_transaction(&tx_hash).await? { + if let Err(err) = self.process_transaction(&tx).await { + tracing::error!( + "failed to process transaction (hash: {}) assets: {}", + tx.hash, + err + ); + continue; + } + + self.database.mark_asset_complete(&tx_hash).await?; + } else { + tracing::warn!("asset entry for missing transaction; hash: {}", &tx_hash); + } + } + + // TODO: Define specific period for Asset processing refresh and + // compute remaining sleep time from that. If asset processing + // takes longer than anticipated, then there's no sleep. Otherwise + // next iteration starts from same periodic cycle as normally. + sleep(Duration::from_millis(500)).await; + } + } + + /// handle_transaction admits transaction into `AssetManager` for further + /// processing. + pub async fn handle_transaction(&self, tx: &Transaction) -> Result<()> { + self.database.add_asset(&tx.hash).await + } + + async fn process_transaction(&self, tx: &Transaction) -> Result<()> { + match tx.payload { + transaction::Payload::Deploy { .. } => self.process_deployment(tx).await, + transaction::Payload::Run { .. } => self.process_run(tx).await, + // Other transaction types don't have external assets that would + // need processing. + _ => Ok(()), + } + } + + async fn process_deployment(&self, tx: &Transaction) -> Result<()> { + let (prover, verifier) = match tx.payload.clone() { + Payload::Deploy { + name: _, + prover, + verifier, + } => (Program::from(prover), Program::from(verifier)), + _ => return Err(AssetManagerError::IncompatibleTxPayload(tx.hash).into()), + }; + + self.process_program(&prover).await?; + self.process_program(&verifier).await?; + + Ok(()) + } + + async fn process_program(&self, program: &Program) -> Result<()> { + // TODO: Process and program files are now downloaded in different ways. Combine these. + let file_path = PathBuf::new() + .join(self.config.data_directory.clone()) + .join("images") + .join(program.hash.to_string()) + .join(program.image_file_name.clone()); + + let url = reqwest::Url::parse(&program.image_file_url)?; + self.download(&url, &file_path).await + } + + async fn process_run(&self, tx: &Transaction) -> Result<()> { + // TODO: Process and program files are now downloaded in different ways. Combine these. + let file_storage = storage::File::new(&self.config.data_directory); + + let workflow = match tx.payload.clone() { + Payload::Run { workflow } => workflow, + _ => return Err(AssetManagerError::IncompatibleTxPayload(tx.hash).into()), + }; + + // TODO: Ideally the following would happen concurrently for each file... + for step in workflow.steps { + for input in step.inputs { + match input { + ProgramData::Input { + file_name, + file_url, + checksum, + } => { + let f = types::File { + tx: tx.hash, + name: file_name, + url: file_url, + }; + file_storage.download(&f).await?; + } + ProgramData::Output { .. } => { + /* ProgramData::Output asinput means it comes from another + program execution -> skip this branch. */ + } + } + } + } + + Ok(()) + } + + /// download downloads file from the given `url` and saves it to file in `file_path`. + async fn download(&self, url: &reqwest::Url, file_path: &PathBuf) -> Result<()> { + // TODO: Blocking operation. + std::fs::create_dir_all(file_path.parent().unwrap())?; + + let mut resp = self.http_client.get(url.clone()).send().await?; + + if resp.status() == reqwest::StatusCode::OK { + let fd = tokio::fs::File::create(&file_path).await?; + let mut fd = tokio::io::BufWriter::new(fd); + + while let Some(chunk) = resp.chunk().await? { + fd.write_all(&chunk).await?; + } + + fd.flush().await?; + tracing::info!( + "downloaded file to {}", + file_path.as_path().to_str().unwrap().to_string() + ); + } else { + tracing::error!( + "failed to download file from {}: response status: {}", + url, + resp.status() + ); + } + + Ok(()) + } +} diff --git a/crates/node/src/cli.rs b/crates/node/src/cli.rs new file mode 100644 index 00000000..065a7fe7 --- /dev/null +++ b/crates/node/src/cli.rs @@ -0,0 +1,205 @@ +use std::{net::SocketAddr, path::PathBuf}; + +use clap::{Args, Parser, Subcommand}; + +#[derive(Debug, Args)] +pub struct Config { + #[arg( + long, + long_help = "Directory where the node should store its data", + env = "GEVULOT_DATA_DIRECTORY", + default_value_os_t = PathBuf::from("/var/lib/gevulot"), + )] + pub data_directory: PathBuf, + + #[arg( + long, + long_help = "Database URL", + env = "GEVULOT_DB_URL", + default_value = "postgres://gevulot:gevulot@localhost/gevulot" + )] + pub db_url: String, + + #[arg( + long, + long_help = "JSON-RPC listen address", + env = "GEVULOT_JSON_RPC_LISTEN_ADDR", + default_value = "127.0.0.1:9944" + )] + pub json_rpc_listen_addr: SocketAddr, + + #[arg( + long, + long_help = "Directory where the node should store logs", + env = "GEVULOT_LOG_DIRECTORY", + default_value_os_t = PathBuf::from("/var/lib/gevulot/log"), + )] + pub log_directory: PathBuf, + + #[arg( + long, + long_help = "File where the node key is persisted", + env = "GEVULOT_NODE_KEY_FILE", + default_value_os_t = PathBuf::from("/var/lib/gevulot/node.key"), + )] + pub node_key_file: PathBuf, + + #[arg( + long, + long_help = "", + env = "GEVULOT_P2P_DISCOVERY_ADDR", + default_value = "bootstrap.p2p.devnet.gevulot.com" + )] + pub p2p_discovery_addrs: Vec, + + #[arg( + long, + long_help = "P2P listen address", + env = "GEVULOT_P2P_LISTEN_ADDR", + default_value = "127.0.0.1:9999" + )] + pub p2p_listen_addr: SocketAddr, + + #[arg( + long, + long_help = "P2P PSK passphrase", + env = "GEVULOT_PSK_PASSPHRASE", + default_value = "Pack my box with five dozen liquor jugs." + )] + pub p2p_psk_passphrase: String, + + #[arg( + long, + long_help = "Provider backend to run tasks", + env = "GEVULOT_PROVIDER", + default_value = "qemu" + )] + pub provider: String, + + #[arg( + long, + long_help = "Listen port for VSOCK gRPC service", + env = "GEVULOT_VSOCK_LISTEN_PORT", + default_value_t = 8080 + )] + pub vsock_listen_port: u32, + + #[arg( + long, + long_help = "Number of CPUs available", + env = "GEVULOT_CPUS", + default_value_t = 8 + )] + pub num_cpus: u64, + + #[arg( + long, + long_help = "Amount of memory available (in GBs)", + env = "GEVULOT_MEM_GB", + default_value_t = 8 + )] + pub mem_gb: u64, + + #[arg(long, long_help = "GPU PCI devices", env = "GEVULOT_GPU_DEVICES")] + pub gpu_devices: Option, +} + +#[derive(Debug, Args)] +pub struct NodeKeyOptions { + #[arg( + long, + long_help = "Node key filename", + default_value_os_t = PathBuf::from("/var/lib/gevulot/node.key"), + )] + pub node_key_file: PathBuf, +} + +#[derive(Debug, Subcommand)] +pub enum PeerCommand { + Whitelist { + #[arg( + long, + long_help = "Database URL", + env = "GEVULOT_DB_URL", + default_value = "postgres://gevulot:gevulot@localhost/gevulot" + )] + db_url: String, + }, + Deny { + #[arg( + long, + long_help = "Database URL", + env = "GEVULOT_DB_URL", + default_value = "postgres://gevulot:gevulot@localhost/gevulot" + )] + db_url: String, + }, +} + +#[derive(Debug, Subcommand)] +pub enum GenerateCommand { + NodeKey { + #[command(flatten)] + options: NodeKeyOptions, + }, +} + +#[derive(Debug, Subcommand)] +pub enum ShowCommand { + PublicKey { + #[arg( + long, + long_help = "Key filename", + default_value_os_t = PathBuf::from("/var/lib/gevulot/node.key"), + )] + key_file: PathBuf, + }, +} + +#[allow(clippy::large_enum_variant)] +#[derive(Debug, Subcommand)] +pub enum Command { + /// Generate objects. + Generate { + #[command(subcommand)] + target: GenerateCommand, + }, + + /// Migrate DB. + Migrate { + #[arg( + long, + long_help = "Database URL", + env = "GEVULOT_DB_URL", + default_value = "postgres://gevulot:gevulot@localhost/gevulot" + )] + db_url: String, + }, + + /// Peer related commands. + Peer { + peer: String, + + #[command(subcommand)] + op: PeerCommand, + }, + + /// Run the node. + Run { + #[command(flatten)] + config: Config, + }, + + /// Show information. + Show { + #[command(subcommand)] + op: ShowCommand, + }, +} + +#[derive(Debug, Parser)] +#[command(author, version, about = "Gevulot node")] +pub struct Cli { + #[command(subcommand)] + pub subcommand: Command, +} diff --git a/crates/node/src/lib.rs b/crates/node/src/lib.rs new file mode 100644 index 00000000..be6e68d6 --- /dev/null +++ b/crates/node/src/lib.rs @@ -0,0 +1,2 @@ +pub mod rpc_client; +pub mod types; diff --git a/crates/node/src/main.rs b/crates/node/src/main.rs new file mode 100644 index 00000000..be59caab --- /dev/null +++ b/crates/node/src/main.rs @@ -0,0 +1,316 @@ +#![allow(dead_code)] +#![allow(unused_variables)] + +use std::{ + io::{ErrorKind, Write}, + net::ToSocketAddrs, + path::PathBuf, + sync::{Arc, Mutex}, + thread::sleep, + time::Duration, +}; + +use asset_manager::AssetManager; +use async_trait::async_trait; +use clap::Parser; +use cli::{Cli, Command, Config, GenerateCommand, NodeKeyOptions, PeerCommand, ShowCommand}; +use eyre::Result; +use gevulot_node::types; +use libsecp256k1::{PublicKey, SecretKey}; +use pea2pea::Pea2Pea; +use rand::{rngs::StdRng, SeedableRng}; +use sqlx::postgres::PgPoolOptions; +use tokio::sync::{Mutex as TMutex, RwLock}; +use tonic::transport::Server; +use tracing_subscriber::{filter::LevelFilter, fmt::format::FmtSpan, EnvFilter}; +use types::{Hash, Transaction}; +use workflow::WorkflowEngine; + +mod asset_manager; +mod cli; +mod mempool; +mod nanos; +mod networking; +mod rpc_server; +mod scheduler; +mod storage; +mod vmm; +mod workflow; + +use mempool::Mempool; +use storage::{database::entity, Database}; + +fn start_logger(default_level: LevelFilter) { + let filter = match EnvFilter::try_from_default_env() { + Ok(filter) => filter, + _ => EnvFilter::default().add_directive(default_level.into()), + }; + + tracing_subscriber::fmt() + .with_env_filter(filter) + .with_span_events(FmtSpan::CLOSE) + .with_target(false) + .init(); + + // Comment above & uncomment below for tokio-console. + //console_subscriber::init(); +} + +#[tokio::main] +async fn main() -> Result<()> { + start_logger(LevelFilter::INFO); + + let cli = Cli::parse(); + + match cli.subcommand { + Command::Generate { target } => match target { + GenerateCommand::NodeKey { options } => generate_node_key(options), + }, + Command::Migrate { db_url } => { + let pool = PgPoolOptions::new() + .max_connections(5) + .acquire_timeout(Duration::from_millis(500)) + .connect(&db_url) + .await?; + // This will pick them up from `./migrations`. + sqlx::migrate!().run(&pool).await.map_err(|e| e.into()) + } + Command::Peer { peer, op } => match op { + PeerCommand::Whitelist { db_url } => { + let db = storage::Database::new(&db_url).await?; + let key = entity::PublicKey::try_from(peer.as_str())?; + db.acl_whitelist(&key).await + } + PeerCommand::Deny { db_url } => { + let db = storage::Database::new(&db_url).await?; + let key = entity::PublicKey::try_from(peer.as_str())?; + db.acl_deny(&key).await + } + }, + Command::Run { config } => run(Arc::new(config)).await, + Command::Show { op } => match op { + ShowCommand::PublicKey { key_file } => { + let bs = std::fs::read(key_file)?; + let key = SecretKey::parse(bs.as_slice().try_into()?)?; + let public_key = PublicKey::from_secret_key(&key); + println!("{}", hex::encode(public_key.serialize())); + Ok(()) + } + }, + } +} + +fn generate_node_key(opts: NodeKeyOptions) -> Result<()> { + let key = SecretKey::random(&mut StdRng::from_entropy()); + let mut fd = match std::fs::OpenOptions::new() + .read(true) + .write(true) + .create_new(true) + .open(&opts.node_key_file) + { + Ok(fd) => fd, + Err(err) => match err.kind() { + ErrorKind::NotFound => { + eprintln!("directory for {:#?} doesn't exist", &opts.node_key_file); + std::process::exit(1); + } + ErrorKind::AlreadyExists => { + eprintln!("file {:#?} already exists", &opts.node_key_file); + std::process::exit(1); + } + _ => return Err(err.into()), + }, + }; + + fd.write_all(&key.serialize()[..])?; + fd.flush()?; + Ok(()) +} + +#[async_trait] +impl mempool::Storage for storage::Database { + async fn get(&self, hash: &Hash) -> Result> { + self.find_transaction(hash).await + } + + async fn set(&self, tx: &Transaction) -> Result<()> { + self.add_transaction(tx).await + } + + async fn fill_deque(&self, deque: &mut std::collections::VecDeque) -> Result<()> { + for t in self.get_unexecuted_transactions().await? { + deque.push_back(t); + } + + Ok(()) + } +} + +#[async_trait] +impl workflow::TransactionStore for storage::Database { + async fn find_transaction(&self, tx_hash: &Hash) -> Result> { + self.find_transaction(tx_hash).await + } +} + +struct P2PTxHandler { + mempool: Arc>, + database: Arc, +} + +impl P2PTxHandler { + pub fn new(mempool: Arc>, database: Arc) -> Self { + Self { mempool, database } + } +} + +#[async_trait::async_trait] +impl networking::p2p::TxHandler for P2PTxHandler { + async fn recv_tx(&self, tx: Transaction) -> Result<()> { + // The transaction was received from P2P network so we can consider it + // propagated at this point. + let mut tx = tx; + tx.propagated = true; + + // Submit the tx to mempool. + self.mempool.write().await.add(tx).await + } +} + +#[async_trait::async_trait] +impl mempool::AclWhitelist for Database { + async fn contains(&self, key: &PublicKey) -> Result { + let key = entity::PublicKey(*key); + self.acl_whitelist_has(&key).await + } +} + +async fn run(config: Arc) -> Result<()> { + let database = Arc::new(Database::new(&config.db_url).await?); + let file_storage = Arc::new(storage::File::new(&config.data_directory)); + + let p2p = Arc::new( + networking::P2P::new( + "mempool-pubsub", + config.p2p_listen_addr, + &config.p2p_psk_passphrase, + ) + .await, + ); + + let mempool = Arc::new(RwLock::new( + Mempool::new(database.clone(), database.clone(), Some(p2p.clone())).await?, + )); + + p2p.register_tx_handler(Arc::new(P2PTxHandler::new( + mempool.clone(), + database.clone(), + ))) + .await; + + // TODO(tuommaki): read total available resources from config / acquire system stats. + let num_gpus = if config.gpu_devices.is_some() { 1 } else { 0 }; + let resource_manager = Arc::new(Mutex::new(scheduler::ResourceManager::new( + config.mem_gb * 1024 * 1024 * 1024, + config.num_cpus, + num_gpus, + ))); + + // TODO(tuommaki): Handle provider from config. + let qemu_provider = vmm::qemu::Qemu::new(config.clone()); + let vsock_stream = qemu_provider.vm_server_listener().expect("vsock bind"); + + let provider = Arc::new(TMutex::new(qemu_provider)); + let program_manager = scheduler::ProgramManager::new( + database.clone(), + provider.clone(), + resource_manager.clone(), + ); + + let asset_mgr = Arc::new(AssetManager::new(config.clone(), database.clone())); + + let node_key = read_node_key(&config.node_key_file)?; + + // Launch AssetManager's background processing. + tokio::spawn({ + let asset_mgr = asset_mgr.clone(); + async move { asset_mgr.run().await } + }); + + let workflow_engine = Arc::new(WorkflowEngine::new(database.clone(), file_storage.clone())); + + let scheduler = Arc::new(scheduler::Scheduler::new( + mempool.clone(), + database.clone(), + program_manager, + workflow_engine, + node_key, + )); + + let vm_server = + vmm::vm_server::VMServer::new(scheduler.clone(), provider, file_storage.clone()); + + // Start gRPC VSOCK server. + tokio::spawn(async move { + Server::builder() + .add_service(vm_server.grpc_server()) + .serve_with_incoming(vsock_stream) + .await + }); + + // Start Scheduler. + tokio::spawn({ + let scheduler = scheduler.clone(); + async move { scheduler.run().await } + }); + + let p2p_addr = p2p.node().start_listening().await?; + tracing::info!("listening for p2p at {}", p2p_addr); + + for addr in config.p2p_discovery_addrs.clone() { + tracing::info!("connecting to p2p peer {}", addr); + match addr.to_socket_addrs() { + Ok(mut socket_iter) => { + if let Some(peer) = socket_iter.next() { + p2p.node().connect(peer).await?; + break; + } + } + Err(err) => { + tracing::error!("failed to resolve {}: {}", addr, err); + } + } + } + + // Start JSON-RPC server. + let rpc_server = rpc_server::RpcServer::run( + config.clone(), + database.clone(), + mempool.clone(), + asset_mgr.clone(), + ) + .await?; + + tracing::info!("gevulot node started"); + loop { + sleep(Duration::from_secs(1)); + } +} + +fn read_node_key(node_key_file: &PathBuf) -> Result { + let bs = match std::fs::read(node_key_file) { + Ok(key_data) => key_data, + Err(err) => match err.kind() { + std::io::ErrorKind::NotFound => { + eprintln!( + "\nerror: node key not found.\n\nplease create node-key with:\n\t{} generate node-key\n", + std::env::current_exe().unwrap().to_str().unwrap() + ); + std::process::exit(1); + } + _ => return Err(err.into()), + }, + }; + + SecretKey::parse(bs.as_slice().try_into().expect("invalid node key")).map_err(|e| e.into()) +} diff --git a/crates/node/src/mempool/mod.rs b/crates/node/src/mempool/mod.rs new file mode 100644 index 00000000..e8ff0e41 --- /dev/null +++ b/crates/node/src/mempool/mod.rs @@ -0,0 +1,117 @@ +use async_trait::async_trait; +use bytes::Bytes; +use eyre::Result; +use libsecp256k1::PublicKey; +use pea2pea::protocols::Writing; +use std::collections::VecDeque; +use std::sync::Arc; +use thiserror::Error; +use tokio::sync::RwLock; + +use crate::{ + networking, + types::{Hash, Transaction}, +}; + +#[async_trait] +pub trait Storage: Send + Sync { + async fn get(&self, hash: &Hash) -> Result>; + async fn set(&self, tx: &Transaction) -> Result<()>; + async fn fill_deque(&self, deque: &mut VecDeque) -> Result<()>; +} + +#[async_trait] +pub trait AclWhitelist: Send + Sync { + async fn contains(&self, key: &PublicKey) -> Result; +} + +#[allow(clippy::enum_variant_names)] +#[derive(Error, Debug)] +pub enum MempoolError { + #[error("permission denied")] + PermissionDenied, +} + +#[derive(Clone)] +pub struct Mempool { + storage: Arc, + acl_whitelist: Arc, + // TODO: This should be refactored to PubSub channel abstraction later on. + tx_chan: Option>, + deque: VecDeque, +} + +impl Mempool { + pub async fn new( + storage: Arc, + acl_whitelist: Arc, + tx_chan: Option>, + ) -> Result { + let mut deque = VecDeque::new(); + storage.fill_deque(&mut deque).await?; + + Ok(Self { + storage, + acl_whitelist, + tx_chan, + deque, + }) + } + + pub fn next(&mut self) -> Option { + // TODO(tuommaki): Should storage reflect the POP in state? + self.deque.pop_front() + } + + pub fn peek(&self) -> Option<&Transaction> { + self.deque.front() + } + + pub async fn add(&mut self, tx: Transaction) -> Result<()> { + // First validate transaction. + tx.validate()?; + + // Secondly verify that author is whitelisted. + if !self.acl_whitelist.contains(&tx.author).await? { + return Err(MempoolError::PermissionDenied.into()); + } + + let mut tx = tx; + self.storage.set(&tx).await?; + + // Broadcast new transaction to P2P network if it's configured. + if let Some(ref tx_chan) = self.tx_chan { + if tx_chan.send_tx(&tx).await.is_ok() { + tx.propagated = true; + self.storage.set(&tx).await?; + } else { + // TODO: Implement retry? + } + } + + self.deque.push_back(tx); + Ok(()) + } + + pub fn size(&self) -> usize { + self.deque.len() + } +} + +pub struct P2PTxHandler(Arc>); + +#[async_trait::async_trait] +impl networking::p2p::TxHandler for P2PTxHandler { + async fn recv_tx(&self, tx: Transaction) -> Result<()> { + self.0.write().await.add(tx).await + } +} + +#[async_trait::async_trait] +impl networking::p2p::TxChannel for networking::p2p::P2P { + async fn send_tx(&self, tx: &Transaction) -> Result<()> { + let bs = Bytes::from(bincode::serialize(tx)?); + self.broadcast(bs)?; + Ok(()) + } +} diff --git a/crates/node/src/nanos/mod.rs b/crates/node/src/nanos/mod.rs new file mode 100644 index 00000000..f3ae1ada --- /dev/null +++ b/crates/node/src/nanos/mod.rs @@ -0,0 +1 @@ +pub mod volume; diff --git a/crates/node/src/nanos/volume.rs b/crates/node/src/nanos/volume.rs new file mode 100644 index 00000000..8c1c1082 --- /dev/null +++ b/crates/node/src/nanos/volume.rs @@ -0,0 +1,152 @@ +use std::{path::PathBuf, process::Command}; + +use eyre::Result; +use thiserror::Error; + +#[allow(clippy::enum_variant_names)] +#[derive(Error, Debug)] +pub enum NanosVolumeError { + #[error("ops error: {0}")] + OpsError(String), + + #[error("parse error: {0}")] + ParseError(String), +} + +pub fn create(label: &str, size: &str) -> Result { + let output = Command::new("ops") + .arg("volume") + .arg("create") + .arg(label) + .arg("-s") + .arg(size) + .output()?; + + if !output.status.success() { + return Err( + NanosVolumeError::OpsError(String::from("failed to run 'ops volume create'")).into(), + ); + } + + let volume_file = parse_output(&String::from_utf8(output.stderr)?)?; + Ok(PathBuf::new() + .join(home::home_dir().expect("missing $HOME")) + .join(".ops") + .join("volumes") + .join(volume_file)) +} + +pub fn delete(label: &str) -> Result<()> { + let output = Command::new("ops") + .arg("volume") + .arg("delete") + .arg(label) + .output()?; + + if !output.status.success() { + return Err( + NanosVolumeError::OpsError(String::from("failed to run 'ops volume delete'")).into(), + ); + } + + Ok(()) +} + +fn parse_output(output: &str) -> Result { + let tokens: Vec = output + .split_whitespace() + .map(|t| t.to_lowercase()) + .collect(); + + if tokens.is_empty() { + return Err(NanosVolumeError::ParseError(String::from("empty string")).into()); + } + + let mut uuid: Option = None; + let mut label: Option = None; + + let mut i = 0; + while i < (tokens.len() - 1) { + match tokens[i].as_str() { + "uuid" => { + i += 1; + uuid = Some(tokens[i].clone()); + } + "label" => { + i += 1; + label = Some(tokens[i].clone()); + } + _ => (), + } + + i += 1 + } + + if uuid.is_some() && label.is_some() { + return Ok(format!("{}:{}.raw", label.unwrap(), uuid.unwrap())); + } + + Err(NanosVolumeError::ParseError( + "couldn't find all required components from 'ops volume create' output".to_string(), + ) + .into()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_parse_output() { + let output = "2023/12/22 14:58:10 volume: abcdefghijklmn created with UUID 3d30257d-650b-4b22-b68d-f85b312a0956 and label abcdefghijklmn"; + let res = parse_output(output); + assert!(res.is_ok()); + assert_eq!( + res.unwrap(), + "abcdefghijklmn:3d30257d-650b-4b22-b68d-f85b312a0956.raw" + ); + } + + #[test] + fn test_parse_output_no_uuid() { + let output = "2023/12/22 14:58:10 volume: abcdefghijklmn created with 3d30257d-650b-4b22-b68d-f85b312a0956 and label abcdefghijklmn"; + let res = parse_output(output); + assert!(res.is_err()); + } + + #[test] + fn test_parse_output_no_label() { + let output = "2023/12/22 14:58:10 volume: abcdefghijklmn created with UUID 3d30257d-650b-4b22-b68d-f85b312a0956 and abcdefghijklmn"; + let res = parse_output(output); + assert!(res.is_err()); + } + + #[test] + fn test_parse_output_unexpected_end_of_str() { + let output = "2023/12/22 14:58:10 volume: abcdefghijklmn created with UUID 3d30257d-650b-4b22-b68d-f85b312a0956 and label"; + let res = parse_output(output); + assert!(res.is_err()); + } + + #[test] + fn test_parse_output_unexpected_order() { + let output = "2023/12/22 14:58:10 volume: abcdefghijklmn created and label abcdefghijklmn with UUID 3d30257d-650b-4b22-b68d-f85b312a0956"; + let res = parse_output(output); + assert!(res.is_ok()); + assert_eq!( + res.unwrap(), + "abcdefghijklmn:3d30257d-650b-4b22-b68d-f85b312a0956.raw" + ); + } + + #[test] + fn test_parse_output_unexpected_content() { + let output = " created and label abcdefghijklmn with very unusual and obscure <>|! UUID 3d30257d-650b-4b22-b68d-f85b312a0956 "; + let res = parse_output(output); + assert!(res.is_ok()); + assert_eq!( + res.unwrap(), + "abcdefghijklmn:3d30257d-650b-4b22-b68d-f85b312a0956.raw" + ); + } +} diff --git a/crates/node/src/networking/download_manager.rs b/crates/node/src/networking/download_manager.rs new file mode 100644 index 00000000..581d7b00 --- /dev/null +++ b/crates/node/src/networking/download_manager.rs @@ -0,0 +1,21 @@ +use std::sync::Arc; + +use crate::{cli::Config, storage}; + +pub struct DownloadManager { + database: Arc, + file_storage: Arc, +} + +impl DownloadManager { + pub fn new( + _config: Arc, + database: Arc, + file_storage: Arc, + ) -> Self { + DownloadManager { + database, + file_storage, + } + } +} diff --git a/crates/node/src/networking/mod.rs b/crates/node/src/networking/mod.rs new file mode 100644 index 00000000..e34f90c2 --- /dev/null +++ b/crates/node/src/networking/mod.rs @@ -0,0 +1,8 @@ +mod download_manager; +mod noise; +pub mod p2p; + +#[allow(unused_imports)] +pub use download_manager::DownloadManager; + +pub use p2p::P2P; diff --git a/crates/node/src/networking/noise.rs b/crates/node/src/networking/noise.rs new file mode 100644 index 00000000..5aab44d7 --- /dev/null +++ b/crates/node/src/networking/noise.rs @@ -0,0 +1,274 @@ +//! A `snow`-powered implementation of the noise XX handshake for `pea2pea`. +// +// Original source: https://github.com/ljedrz/pea2pea/blob/master/examples/common/noise.rs + +use std::{io, sync::Arc}; + +use bytes::{Bytes, BytesMut}; +use futures_util::{sink::SinkExt, TryStreamExt}; +use pea2pea::{protocols::Handshake, Connection, ConnectionSide}; +use tokio_util::codec::{Decoder, Encoder, Framed, FramedParts, LengthDelimitedCodec}; +use tracing::*; + +// maximum noise message size, as specified by its protocol +pub const MAX_MESSAGE_LEN: usize = 65535; + +// noise state during the handshake +pub struct HandshakeState(Box); + +// noise state after the handshake +#[derive(Clone)] +pub struct PostHandshakeState { + // stateless state can be used immutably + state: Arc, + // any leftover bytes from the handshake + rx_carryover: Option, + // only used in Reading + rx_nonce: u64, + // only used in Writing + tx_nonce: u64, +} + +// an object representing the state of noise +pub enum State { + Handshake(HandshakeState), + PostHandshake(PostHandshakeState), +} + +// only post-handshake state is cloned (in the Reading impl) +impl Clone for State { + fn clone(&self) -> Self { + match self { + Self::Handshake(..) => panic!("unsupported"), + Self::PostHandshake(ph) => Self::PostHandshake(ph.clone()), + } + } +} + +impl State { + // obtain the handshake noise state + fn handshake(&mut self) -> Option<&mut snow::HandshakeState> { + if let Self::Handshake(state) = self { + Some(&mut state.0) + } else { + None + } + } + + // transform the noise state into post-handshake + pub fn into_post_handshake(self) -> Self { + if let Self::Handshake(state) = self { + let state = state.0.into_stateless_transport_mode().unwrap(); + Self::PostHandshake(PostHandshakeState { + state: Arc::new(state), + rx_carryover: Default::default(), + rx_nonce: 0, + tx_nonce: 0, + }) + } else { + panic!(); + } + } + + // obtain the post-handshake noise state + fn post_handshake(&mut self) -> Option<&mut PostHandshakeState> { + if let Self::PostHandshake(ph) = self { + Some(ph) + } else { + None + } + } + + pub fn save_buffer(&mut self, buf: BytesMut) { + self.post_handshake().unwrap().rx_carryover = Some(buf); + } +} + +// a codec used to (en/de)crypt messages using noise +pub struct Codec { + codec: LengthDelimitedCodec, + pub noise: State, + buffer: Box<[u8]>, + span: Span, +} + +impl Codec { + pub fn new(prefix_len: usize, max_frame_len: usize, noise: State, span: Span) -> Self { + Codec { + codec: LengthDelimitedCodec::builder() + .length_field_length(prefix_len) + .max_frame_length(max_frame_len) + .new_codec(), + noise, + buffer: vec![0u8; MAX_MESSAGE_LEN].into(), + span, + } + } +} + +impl Decoder for Codec { + type Item = BytesMut; + type Error = io::Error; + + fn decode(&mut self, src: &mut BytesMut) -> Result, Self::Error> { + // if any bytes were carried over from the handshake, prepend them to src + if let Some(mut carryover) = self + .noise + .post_handshake() + .and_then(|ph| ph.rx_carryover.take()) + { + carryover.unsplit(src.split()); + *src = carryover; + } + + // obtain the whole encrypted message first, using the length-delimited codec + let bytes = if let Some(bytes) = self.codec.decode(src)? { + bytes + } else { + return Ok(None); + }; + + // decrypt the noise message + match self.noise { + State::Handshake(ref mut noise) => { + let msg_len = noise + .0 + .read_message(&bytes, &mut self.buffer) + .map_err(|e| { + error!(parent: &self.span, "noise: {}; raw bytes: {:?}", e, bytes); + io::ErrorKind::InvalidData + })?; + + Ok(Some(self.buffer[..msg_len].into())) + } + State::PostHandshake(ref mut noise) => { + let mut decrypted_msg = BytesMut::new(); + + for encrypted_chunk in bytes.chunks(MAX_MESSAGE_LEN) { + let msg_len = noise + .state + .read_message(noise.rx_nonce, encrypted_chunk, &mut self.buffer) + .map_err(|e| { + let span = self.span.clone(); + error!( + parent: &span, + "noise error: {}; raw chunk: {:?}", e, encrypted_chunk + ); + io::ErrorKind::InvalidData + })?; + noise.rx_nonce += 1; + + decrypted_msg.extend_from_slice(&self.buffer[..msg_len]); + } + + Ok(Some(decrypted_msg)) + } + } + } +} + +impl Encoder for Codec { + type Error = io::Error; + + fn encode(&mut self, msg: Bytes, dst: &mut BytesMut) -> Result<(), Self::Error> { + match self.noise { + State::Handshake(ref mut noise) => { + let msg_len = noise.0.write_message(&msg, &mut self.buffer).unwrap(); + + self.codec + .encode(Bytes::from(self.buffer[..msg_len].to_vec()), dst) + } + State::PostHandshake(ref mut noise) => { + let mut encrypted_msg = BytesMut::new(); + + for msg_chunk in msg.chunks(MAX_MESSAGE_LEN - 16) { + let msg_len = noise + .state + .write_message(noise.tx_nonce, msg_chunk, &mut self.buffer) + .unwrap(); + noise.tx_nonce += 1; + + encrypted_msg.extend_from_slice(&self.buffer[..msg_len]); + } + + self.codec.encode(encrypted_msg.freeze(), dst) + } + } + } +} + +// perform the noise XX handshake +pub async fn handshake_xx<'a, T: Handshake>( + node: &T, + conn: &mut Connection, + noise_builder: snow::Builder<'a>, + payload: Bytes, +) -> io::Result<(State, Bytes)> { + let node_conn_side = !conn.side(); + let stream = node.borrow_stream(conn); + + let (noise_state, secure_payload) = match node_conn_side { + ConnectionSide::Initiator => { + let noise = Box::new(noise_builder.build_initiator().unwrap()); + let mut framed = Framed::new( + stream, + Codec::new( + 2, + u16::MAX as usize, + State::Handshake(HandshakeState(noise)), + node.node().span().clone(), + ), + ); + + // -> e + framed.send("".into()).await?; + debug!(parent: node.node().span(), "sent e (XX handshake part 1/3)"); + + // <- e, ee, s, es + let secure_payload = framed.try_next().await?.unwrap_or_default(); + debug!(parent: node.node().span(), "received e, ee, s, es (XX handshake part 2/3)"); + + // -> s, se, psk + framed.send(payload).await?; + debug!(parent: node.node().span(), "sent s, se, psk (XX handshake part 3/3)"); + + let FramedParts { codec, .. } = framed.into_parts(); + let Codec { noise, .. } = codec; + + (noise.into_post_handshake(), secure_payload) + } + ConnectionSide::Responder => { + let noise = Box::new(noise_builder.build_responder().unwrap()); + let mut framed = Framed::new( + stream, + Codec::new( + 2, + u16::MAX as usize, + State::Handshake(HandshakeState(noise)), + node.node().span().clone(), + ), + ); + + // <- e + framed.try_next().await?; + debug!(parent: node.node().span(), "received e (XX handshake part 1/3)"); + + // -> e, ee, s, es + framed.send(payload).await?; + debug!(parent: node.node().span(), "sent e, ee, s, es (XX handshake part 2/3)"); + + // <- s, se, psk + let secure_payload = framed.try_next().await?.unwrap_or_default(); + debug!(parent: node.node().span(), "received s, se, psk (XX handshake part 3/3)"); + + let FramedParts { codec, .. } = framed.into_parts(); + let Codec { noise, .. } = codec; + + (noise.into_post_handshake(), secure_payload) + } + }; + + debug!(parent: node.node().span(), "XX handshake complete"); + + Ok((noise_state, secure_payload.freeze())) +} diff --git a/crates/node/src/networking/p2p.rs b/crates/node/src/networking/p2p.rs new file mode 100644 index 00000000..cc41c95f --- /dev/null +++ b/crates/node/src/networking/p2p.rs @@ -0,0 +1,505 @@ +use std::{ + collections::{BTreeSet, HashMap}, + io, + net::SocketAddr, + str, + sync::Arc, +}; +use tokio::io::AsyncReadExt; +use tokio::io::AsyncWriteExt; + +use super::noise; +use bytes::{Bytes, BytesMut}; +use eyre::Result; +use gevulot_node::types::Transaction; +use parking_lot::RwLock; +use pea2pea::{ + protocols::{Handshake, OnDisconnect, Reading, Writing}, + Config, Connection, ConnectionSide, Node, Pea2Pea, +}; +use sha3::{Digest, Sha3_256}; + +#[async_trait::async_trait] +pub trait TxHandler: Send + Sync { + async fn recv_tx(&self, tx: Transaction) -> Result<()>; +} + +#[async_trait::async_trait] +pub trait TxChannel: Send + Sync { + async fn send_tx(&self, tx: &Transaction) -> Result<()>; +} + +struct BlackholeTxHandler; +#[async_trait::async_trait] +impl TxHandler for BlackholeTxHandler { + async fn recv_tx(&self, tx: Transaction) -> Result<()> { + tracing::debug!("submitting received tx to black hole"); + Ok(()) + } +} + +// NOTE: This P2P implementation is originally from `pea2pea` Noise handshake example. +#[derive(Clone)] +pub struct P2P { + node: Node, + noise_states: Arc>>, + tx_handler: Arc>>, + psk: Vec, + peer_list: Arc>>, + //Map to connection local addr notified on_disconnect and the peer connection addr (peer_list). + peer_addr_mapping: Arc>>, +} + +impl Pea2Pea for P2P { + fn node(&self) -> &Node { + &self.node + } +} + +impl P2P { + pub async fn new(name: &str, listen_addr: SocketAddr, psk_passphrase: &str) -> Self { + let config = Config { + name: Some(name.into()), + listener_ip: Some(listen_addr.ip()), + desired_listening_port: Some(listen_addr.port()), + ..Default::default() + }; + let node = Node::new(config); + + // Main purpose of hashing here is to convert any passphrase string + // into a 32 bytes long "string". + let mut hasher = Sha3_256::new(); + hasher.update(psk_passphrase); + let psk = hasher.finalize(); + + let instance = Self { + node, + noise_states: Default::default(), + tx_handler: Arc::new(tokio::sync::RwLock::new(Arc::new(BlackholeTxHandler {}))), + psk: psk.to_vec(), + peer_list: Default::default(), + peer_addr_mapping: Default::default(), + }; + + // Enable node functionalities. + instance.enable_handshake().await; + instance.enable_reading().await; + instance.enable_writing().await; + instance.enable_disconnect().await; + + instance + } + + pub async fn register_tx_handler(&self, tx_handler: Arc) { + let mut old_handler = self.tx_handler.write().await; + *old_handler = tx_handler; + tracing::debug!("new tx handler registered"); + } + + async fn recv_tx(&self, tx: Transaction) { + tracing::debug!("submitting received tx to tx_handler"); + let tx_handler = self.tx_handler.read().await; + if let Err(err) = tx_handler.recv_tx(tx).await { + tracing::error!("failed to handle incoming transaction: {}", err); + } else { + tracing::debug!("submitted received tx to tx_handler"); + } + } +} + +#[async_trait::async_trait] +impl Handshake for P2P { + async fn perform_handshake(&self, mut conn: Connection) -> io::Result { + // create the noise objects + let noise_builder = + snow::Builder::new("Noise_XXpsk3_25519_ChaChaPoly_BLAKE2s".parse().unwrap()); + let noise_keypair = noise_builder.generate_keypair().unwrap(); + let noise_builder = noise_builder.local_private_key(&noise_keypair.private); + let noise_builder = noise_builder.psk(3, self.psk.as_slice()); + + // perform the noise handshake + let (noise_state, _) = + noise::handshake_xx(self, &mut conn, noise_builder, Bytes::new()).await?; + + // save the noise state to be reused by Reading and Writing + self.noise_states.write().insert(conn.addr(), noise_state); + + //exchange peer list + + let node_conn_side = !conn.side(); + let stream = self.borrow_stream(&mut conn); + + let local_bind_addr = self.node.listening_addr().unwrap(); + let peer_list_bytes: Vec = { + let peer_list: &mut BTreeSet = &mut self.peer_list.write(); + peer_list.insert(local_bind_addr); //add it if not present. + bincode::serialize(peer_list).map_err(|err| { + std::io::Error::new(std::io::ErrorKind::Other, format!("serialize error:{err}")) + })? + }; + + let (distant_peer_list, distant_listening_addr) = match node_conn_side { + ConnectionSide::Initiator => { + //on_disconnect doesn't notify with the bind port but the connect port. + //can't be use to open a connection. + //So the connecting node notify it's bind address. + let bind_addr_bytes = bincode::serialize(&self.node.listening_addr().unwrap()) + .map_err(|err| { + std::io::Error::new( + std::io::ErrorKind::Other, + format!("serialize error:{err}"), + ) + })?; + stream.write_u32(bind_addr_bytes.len() as u32).await?; + stream.write_all(&bind_addr_bytes).await?; + + //send peer list + stream.write_u32(peer_list_bytes.len() as u32).await?; + stream.write_all(&peer_list_bytes).await?; + + // receive the peer list + let buffer_len = stream.read_u32().await? as usize; + //TODO validate buffer lengh + let mut buffer = vec![0; buffer_len]; + stream.read_exact(&mut buffer).await?; + let distant_peer_list: BTreeSet = bincode::deserialize(&buffer) + .map_err(|err| { + std::io::Error::new( + std::io::ErrorKind::Other, + format!("deserialize error:{err}"), + ) + })?; + + self.peer_addr_mapping + .write() + .insert(stream.peer_addr().unwrap(), stream.peer_addr().unwrap()); + + (distant_peer_list, stream.peer_addr().unwrap()) + } + ConnectionSide::Responder => { + //receive the connecting node addr + let buffer_len = stream.read_u32().await? as usize; + let mut buffer = vec![0; buffer_len]; + stream.read_exact(&mut buffer).await?; + let distant_listening_addr: SocketAddr = + bincode::deserialize(&buffer).map_err(|err| { + std::io::Error::new( + std::io::ErrorKind::Other, + format!("deserialize error:{err}"), + ) + })?; + { + self.peer_list.write().insert(distant_listening_addr); + self.peer_addr_mapping + .write() + .insert(stream.peer_addr().unwrap(), distant_listening_addr); + } + + // receive the peer list + let buffer_len = stream.read_u32().await? as usize; + let mut buffer = vec![0; buffer_len]; + stream.read_exact(&mut buffer).await?; + let distant_peer_list: BTreeSet = bincode::deserialize(&buffer) + .map_err(|err| { + std::io::Error::new( + std::io::ErrorKind::Other, + format!("deserialize error:{err}"), + ) + })?; + + //send peer list + stream.write_u32(peer_list_bytes.len() as u32).await?; + stream.write_all(&peer_list_bytes).await?; + + (distant_peer_list, distant_listening_addr) + } + }; + + //do peer comparition + let mut local_diff = { + let local_peer_list: &mut BTreeSet = &mut self.peer_list.write(); + let local_diff: BTreeSet = distant_peer_list + .difference(local_peer_list) + .cloned() + .collect(); + + local_peer_list.append(&mut local_diff.iter().cloned().collect()); + local_diff + }; + local_diff.remove(&local_bind_addr); + local_diff.remove(&distant_listening_addr); + + let node = self.node(); + for addr in local_diff { + //the return error is not use because: + //already logged and mostly because there's double connection between 2 peers. + let _ = node.connect(addr).await; + } + + Ok(conn) + } +} + +#[async_trait::async_trait] +impl Reading for P2P { + type Message = BytesMut; + type Codec = noise::Codec; + + fn codec(&self, addr: SocketAddr, _side: ConnectionSide) -> Self::Codec { + let state = self.noise_states.read().get(&addr).cloned().unwrap(); + noise::Codec::new(2, u16::MAX as usize, state, self.node().span().clone()) + } + + async fn process_message(&self, source: SocketAddr, message: Self::Message) -> io::Result<()> { + tracing::debug!(parent: self.node().span(), "decrypted a message from {}", source); + + match bincode::deserialize(message.as_ref()) { + Ok(tx) => self.recv_tx(tx).await, + Err(err) => tracing::error!("failed to decode incoming transaction: {}", err), + } + + Ok(()) + } +} + +impl Writing for P2P { + type Message = Bytes; + type Codec = noise::Codec; + + fn codec(&self, addr: SocketAddr, _side: ConnectionSide) -> Self::Codec { + let state = self.noise_states.write().remove(&addr).unwrap(); + noise::Codec::new(2, u16::MAX as usize, state, self.node().span().clone()) + } +} + +#[async_trait::async_trait] +impl OnDisconnect for P2P { + async fn on_disconnect(&self, addr: SocketAddr) { + if let Some(peer_conn_addr) = self.peer_addr_mapping.write().remove(&addr) { + self.peer_list.write().remove(&peer_conn_addr); + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use eyre::Result; + use gevulot_node::types::{transaction::Payload, Transaction}; + use libsecp256k1::SecretKey; + use rand::{rngs::StdRng, SeedableRng}; + use tokio::sync::mpsc::{self, Sender}; + use tracing::level_filters::LevelFilter; + use tracing_subscriber::EnvFilter; + + struct Sink(Arc>); + impl Sink { + fn new(tx: Arc>) -> Self { + Self(tx) + } + } + + #[async_trait::async_trait] + impl TxHandler for Sink { + async fn recv_tx(&self, tx: Transaction) -> Result<()> { + tracing::debug!("sink received new transaction"); + self.0.send(tx).await.expect("sink send"); + tracing::debug!("sink submitted tx to channel"); + Ok(()) + } + } + + #[tokio::test] + async fn test_peer_list_inter_connection() { + //start_logger(LevelFilter::ERROR); + + let (tx1, mut rx1) = mpsc::channel(1); + let (tx2, mut rx2) = mpsc::channel(1); + let (tx3, mut rx3) = mpsc::channel(1); + let (sink1, sink2, sink3) = ( + Arc::new(Sink::new(Arc::new(tx1))), + Arc::new(Sink::new(Arc::new(tx2))), + Arc::new(Sink::new(Arc::new(tx3))), + ); + let (peer1, peer2, peer3) = ( + P2P::new("peer1", "127.0.0.1:0".parse().unwrap(), "secret passphrase").await, + P2P::new("peer2", "127.0.0.1:0".parse().unwrap(), "secret passphrase").await, + P2P::new("peer3", "127.0.0.1:0".parse().unwrap(), "secret passphrase").await, + ); + + tracing::debug!("start listening"); + let bind_add = peer1.node().start_listening().await.expect("peer1 listen"); + let bind_add = peer2.node().start_listening().await.expect("peer2 listen"); + let bind_add = peer3.node().start_listening().await.expect("peer3 listen"); + + tracing::debug!("register tx handlers"); + peer1.register_tx_handler(sink1.clone()).await; + peer2.register_tx_handler(sink2.clone()).await; + peer3.register_tx_handler(sink3.clone()).await; + + tracing::debug!("connect peer2 to peer1"); + peer2 + .node() + .connect(peer1.node().listening_addr().unwrap()) + .await + .unwrap(); + + tracing::debug!("connect peer3 to peer1"); + peer3 + .node() + .connect(peer1.node().listening_addr().unwrap()) + .await + .unwrap(); + + tokio::time::sleep(tokio::time::Duration::from_millis(500)).await; + + tracing::debug!("send tx from peer2 to peer1 and peer3"); + let tx = new_tx(); + peer2.send_tx(&tx).await.unwrap(); + tracing::debug!("recv tx on peer1 from peer2"); + let recv_tx = rx1.recv().await.expect("sink recv"); + assert_eq!(tx, recv_tx); + tracing::debug!("recv tx on peer3 from peer2"); + let recv_tx = rx3.recv().await.expect("sink recv"); + assert_eq!(tx, recv_tx); + + let tx = new_tx(); + tracing::debug!("send tx from peer3 to peer1 and peer2"); + peer3.send_tx(&tx).await.unwrap(); + tracing::debug!("recv tx on peer1 from peer3"); + let recv_tx = rx1.recv().await.expect("sink recv"); + assert_eq!(tx, recv_tx); + tracing::debug!("recv tx on peer2 from peer3"); + let recv_tx = rx2.recv().await.expect("sink recv"); + assert_eq!(tx, recv_tx); + } + + #[tokio::test] + async fn test_two_peers_disconnect() { + //start_logger(LevelFilter::ERROR); + + let (tx1, mut rx1) = mpsc::channel(1); + let (tx2, mut rx2) = mpsc::channel(1); + let (sink1, sink2) = ( + Arc::new(Sink::new(Arc::new(tx1))), + Arc::new(Sink::new(Arc::new(tx2))), + ); + + let peer1 = P2P::new("peer1", "127.0.0.1:0".parse().unwrap(), "secret passphrase").await; + peer1.node().start_listening().await.expect("peer1 listen"); + peer1.register_tx_handler(sink1.clone()).await; + + { + let peer2 = + P2P::new("peer2", "127.0.0.1:0".parse().unwrap(), "secret passphrase").await; + peer2.node().start_listening().await.expect("peer2 listen"); + + peer2.register_tx_handler(sink2.clone()).await; + tracing::debug!("Nodes init Done"); + + peer1 + .node() + .connect(peer2.node().listening_addr().unwrap()) + .await + .unwrap(); + + tracing::debug!("Nodes Connected"); + tracing::debug!("send tx from peer1 to peer2"); + let tx = new_tx(); + peer1.send_tx(&tx).await.unwrap(); + tracing::debug!("recv tx on peer2 from peer1"); + let recv_tx = rx2.recv().await.expect("sink recv"); + assert_eq!(tx, recv_tx); + + let tx = new_tx(); + tracing::debug!("send tx from peer2 to peer1"); + peer2.send_tx(&tx).await.unwrap(); + tracing::debug!("recv tx on peer1 from peer2"); + let recv_tx = rx1.recv().await.expect("sink recv"); + assert_eq!(tx, recv_tx); + + let peers = peer2.node().connected_addrs(); + for addr in peers { + peer2.node().disconnect(addr).await; + } + } + + tokio::time::sleep(tokio::time::Duration::from_millis(500)).await; + + //simulate the silent node de-connection by dropping the node. + tracing::debug!("send tx from peer1 to disconnected peer2"); + let tx = new_tx(); + peer1.send_tx(&tx).await.unwrap(); + + tokio::time::sleep(tokio::time::Duration::from_millis(500)).await; + + assert_eq!(peer1.peer_list.read().len(), 1); + assert!(peer1.peer_addr_mapping.read().is_empty()); + } + + #[tokio::test] + async fn test_two_peers() { + //start_logger(LevelFilter::ERROR); + + let (tx1, mut rx1) = mpsc::channel(1); + let (tx2, mut rx2) = mpsc::channel(1); + let (sink1, sink2) = ( + Arc::new(Sink::new(Arc::new(tx1))), + Arc::new(Sink::new(Arc::new(tx2))), + ); + let (peer1, peer2) = ( + P2P::new("peer1", "127.0.0.1:0".parse().unwrap(), "secret passphrase").await, + P2P::new("peer2", "127.0.0.1:0".parse().unwrap(), "secret passphrase").await, + ); + + tracing::debug!("start listening"); + peer1.node().start_listening().await.expect("peer1 listen"); + peer2.node().start_listening().await.expect("peer2 listen"); + + tracing::debug!("register tx handlers"); + peer1.register_tx_handler(sink1.clone()).await; + peer2.register_tx_handler(sink2.clone()).await; + + tracing::debug!("connect peer2 to peer1"); + peer2 + .node() + .connect(peer1.node().listening_addr().unwrap()) + .await + .unwrap(); + + tracing::debug!("send tx from peer1 to peer2"); + let tx = new_tx(); + peer1.send_tx(&tx).await.unwrap(); + tracing::debug!("recv tx on peer2 from peer1"); + let recv_tx = rx2.recv().await.expect("sink recv"); + assert_eq!(tx, recv_tx); + + let tx = new_tx(); + tracing::debug!("send tx from peer2 to peer1"); + peer2.send_tx(&tx).await.unwrap(); + tracing::debug!("recv tx on peer1 from peer2"); + let recv_tx = rx1.recv().await.expect("sink recv"); + assert_eq!(tx, recv_tx); + } + + fn new_tx() -> Transaction { + let rng = &mut StdRng::from_entropy(); + let key = SecretKey::random(rng); + Transaction::new(Payload::Empty, &key) + } + + fn start_logger(default_level: LevelFilter) { + let filter = match EnvFilter::try_from_default_env() { + Ok(filter) => filter.add_directive("tokio_util=off".parse().unwrap()), + _ => EnvFilter::default() + .add_directive(default_level.into()) + .add_directive("tokio_util=off".parse().unwrap()), + }; + + tracing_subscriber::fmt() + .with_env_filter(filter) + .without_time() + .with_target(false) + .init(); + } +} diff --git a/crates/node/src/rpc_client/mod.rs b/crates/node/src/rpc_client/mod.rs new file mode 100644 index 00000000..eaffb24b --- /dev/null +++ b/crates/node/src/rpc_client/mod.rs @@ -0,0 +1,70 @@ +use std::error::Error; + +use jsonrpsee::{ + core::{client::ClientT, params::ArrayParams}, + http_client::{HttpClient, HttpClientBuilder}, +}; + +use crate::types::{rpc::RpcResponse, transaction::TransactionTree, Hash, Transaction}; + +pub struct RpcClient { + client: HttpClient, +} + +impl RpcClient { + pub fn new(url: impl AsRef) -> Self { + let client = HttpClientBuilder::default() + .build(url) + .expect("http client"); + RpcClient { client } + } + + pub async fn get_transaction( + &self, + tx_hash: &Hash, + ) -> Result, Box> { + let mut params = ArrayParams::new(); + params.insert(tx_hash).expect("rpc params"); + + let resp = self + .client + .request::, ArrayParams>("getTransaction", params) + .await + .expect("rpc request"); + + match resp { + RpcResponse::Ok(tx) => Ok(Some(tx)), + _ => Ok(None), + } + } + + pub async fn send_transaction(&self, tx: &Transaction) -> Result<(), Box> { + let mut params = ArrayParams::new(); + params.insert(tx).expect("rpc params"); + + let resp = self + .client + .request::, ArrayParams>("sendTransaction", params) + .await + .expect("rpc request"); + + if let RpcResponse::Err(e) = resp { + return Err(Box::new(e)); + } + + Ok(()) + } + + pub async fn get_tx_tree(&self, tx_hash: &Hash) -> Result> { + let mut params = ArrayParams::new(); + params.insert(tx_hash).expect("rpc params"); + + let resp = self + .client + .request::, ArrayParams>("getTransactionTree", params) + .await + .expect("rpc request"); + + Ok(resp.unwrap()) + } +} diff --git a/crates/node/src/rpc_server/mod.rs b/crates/node/src/rpc_server/mod.rs new file mode 100644 index 00000000..6cbc8c53 --- /dev/null +++ b/crates/node/src/rpc_server/mod.rs @@ -0,0 +1,222 @@ +use std::{net::SocketAddr, sync::Arc}; + +use eyre::Result; +use gevulot_node::types::{ + rpc::{RpcError, RpcResponse}, + Hash, TransactionTree, +}; +use jsonrpsee::{ + server::{RpcModule, Server, ServerHandle}, + types::Params, +}; +use tokio::sync::RwLock; + +use crate::{ + asset_manager::AssetManager, cli::Config, mempool::Mempool, storage::Database, + types::Transaction, +}; + +struct Context { + database: Arc, + mempool: Arc>, + asset_manager: Arc, +} + +impl std::fmt::Debug for Context { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "RPC Context") + } +} + +pub struct RpcServer { + local_addr: SocketAddr, + server_handle: ServerHandle, +} + +impl RpcServer { + pub async fn run( + cfg: Arc, + database: Arc, + mempool: Arc>, + asset_manager: Arc, + ) -> Result { + let server = Server::builder().build(cfg.json_rpc_listen_addr).await?; + let mut module = RpcModule::new(Context { + database, + mempool, + asset_manager, + }); + + module.register_async_method("sendTransaction", send_transaction)?; + module.register_async_method("getTransaction", get_transaction)?; + module.register_async_method("getTransactionTree", get_tx_tree)?; + + let local_addr = server.local_addr().unwrap(); + let server_handle = server.start(module); + tracing::info!("listening for json-rpc at {}", local_addr); + Ok(RpcServer { + local_addr, + server_handle, + }) + } + + pub fn addr(&self) -> SocketAddr { + self.local_addr + } + + pub async fn stop(&self) -> Result<()> { + self.server_handle.stop().map_err(|e| e.into()) + } +} + +#[tracing::instrument(level = "info")] +async fn send_transaction(params: Params<'static>, ctx: Arc) -> RpcResponse<()> { + tracing::info!("JSON-RPC: send_transaction()"); + + // Real logic + let tx: Transaction = match params.one() { + Ok(tx) => tx, + Err(e) => { + tracing::error!("failed to parse transaction: {}", e); + return RpcResponse::Err(RpcError::InvalidRequest(e.to_string())); + } + }; + + if let Err(err) = ctx.mempool.write().await.add(tx.clone()).await { + tracing::error!("failed to persist transaction: {}", err); + return RpcResponse::Err(RpcError::InvalidRequest( + "failed to persist transaction".to_string(), + )); + } + + if let Err(err) = ctx.asset_manager.handle_transaction(&tx).await { + tracing::error!( + "failed to enqueue transaction for asset processing: {}", + err + ); + return RpcResponse::Err(RpcError::InvalidRequest( + "failed to enqueue transaction for asset processing".to_string(), + )); + } + + RpcResponse::Ok(()) +} + +#[tracing::instrument(level = "info")] +async fn get_transaction(params: Params<'static>, ctx: Arc) -> RpcResponse { + let tx_hash: Hash = match params.one() { + Ok(tx_hash) => tx_hash, + Err(e) => { + tracing::error!("failed to parse transaction: {}", e); + return RpcResponse::Err(RpcError::InvalidRequest(e.to_string())); + } + }; + + tracing::info!("JSON-RPC: get_transaction()"); + + match ctx.database.find_transaction(&tx_hash).await { + Ok(Some(tx)) => RpcResponse::Ok(tx), + Ok(None) => RpcResponse::Err(RpcError::NotFound(tx_hash.to_string())), + Err(e) => RpcResponse::Err(RpcError::NotFound(tx_hash.to_string())), + } +} + +#[tracing::instrument(level = "info")] +async fn get_tx_tree(params: Params<'static>, ctx: Arc) -> RpcResponse { + tracing::info!("JSON-RPC: get_tx_tree()"); + RpcResponse::Err(RpcError::NotFound("TODO".to_string())) +} + +#[cfg(test)] +mod tests { + + use std::{env::temp_dir, path::PathBuf}; + + use jsonrpsee::{ + core::{client::ClientT, params::ArrayParams}, + http_client::HttpClientBuilder, + }; + use libsecp256k1::{PublicKey, SecretKey}; + use tracing_subscriber::{filter::LevelFilter, fmt::format::FmtSpan, EnvFilter}; + + use crate::mempool; + + use super::*; + + struct AlwaysGrantAclWhitelist; + #[async_trait::async_trait] + impl mempool::AclWhitelist for AlwaysGrantAclWhitelist { + async fn contains(&self, key: &PublicKey) -> Result { + Ok(true) + } + } + + #[ignore] + #[tokio::test] + async fn test_send_transaction() { + start_logger(LevelFilter::INFO); + let rpc_server = new_rpc_server().await; + + let url = format!("http://{}", rpc_server.addr()); + let rpc_client = HttpClientBuilder::default() + .build(url) + .expect("http client"); + + let key = SecretKey::default(); + let mut tx = Transaction::default(); + tx.sign(&key); + + let mut params = ArrayParams::new(); + params.insert(&tx).expect("rpc params"); + + let resp = rpc_client + .request::, ArrayParams>("sendTransaction", params) + .await + .expect("rpc request"); + + dbg!(resp); + } + + fn start_logger(default_level: LevelFilter) { + let filter = match EnvFilter::try_from_default_env() { + Ok(filter) => filter, + _ => EnvFilter::default().add_directive(default_level.into()), + }; + + tracing_subscriber::fmt() + .with_env_filter(filter) + .with_span_events(FmtSpan::CLOSE) + .with_target(false) + .init(); + } + + async fn new_rpc_server() -> RpcServer { + let cfg = Arc::new(Config { + data_directory: temp_dir(), + db_url: "postgres://gevulot:gevulot@localhost/gevulot".to_string(), + json_rpc_listen_addr: "127.0.0.1:0".parse().unwrap(), + log_directory: temp_dir(), + node_key_file: PathBuf::new().join("node.key"), + p2p_discovery_addrs: vec![], + p2p_listen_addr: "127.0.0.1:9999".parse().unwrap(), + p2p_psk_passphrase: "secret.".to_string(), + provider: "qemu".to_string(), + vsock_listen_port: 8080, + num_cpus: 8, + mem_gb: 8, + gpu_devices: None, + }); + + let db = Arc::new(Database::new(&cfg.db_url).await.unwrap()); + let mempool = Arc::new(RwLock::new( + Mempool::new(db.clone(), Arc::new(AlwaysGrantAclWhitelist {}), None) + .await + .unwrap(), + )); + let asset_manager = Arc::new(AssetManager::new(cfg.clone(), db.clone())); + + RpcServer::run(cfg.clone(), db.clone(), mempool, asset_manager) + .await + .expect("rpc_server.run") + } +} diff --git a/crates/node/src/scheduler/mod.rs b/crates/node/src/scheduler/mod.rs new file mode 100644 index 00000000..952d86ca --- /dev/null +++ b/crates/node/src/scheduler/mod.rs @@ -0,0 +1,360 @@ +mod program_manager; +mod resource_manager; + +use crate::storage::Database; +use crate::types::TaskState; +use crate::vmm::vm_server::grpc; +use crate::vmm::{vm_server::TaskManager, VMId}; +use crate::workflow::{WorkflowEngine, WorkflowError}; +use async_trait::async_trait; +use gevulot_node::types::transaction::Payload; +use gevulot_node::types::{TaskKind, Transaction}; +use libsecp256k1::SecretKey; +pub use program_manager::ProgramManager; +use rand::RngCore; +pub use resource_manager::ResourceManager; + +use std::time::Instant; +use std::{ + collections::{HashMap, VecDeque}, + sync::Arc, + time::Duration, +}; + +use eyre::Result; +use tokio::{ + sync::{Mutex, RwLock}, + time::sleep, +}; + +use crate::{ + mempool::Mempool, + types::{Hash, Task}, +}; + +use self::program_manager::{ProgramError, ProgramHandle}; +use self::resource_manager::ResourceError; + +struct RunningTask { + task: Task, + vm_id: Arc, + task_scheduled: Instant, + task_started: Instant, +} + +// TODO: I believe `Scheduler` should be rather named `Node` at some point. It +// has started to become as a kind of central place for node logic +// coordination. +// +// It could use some re-structuring in order to not be so convoluted, but +// otherwise it seems to be okayish. +pub struct Scheduler { + mempool: Arc>, + database: Arc, + program_manager: Mutex, + workflow_engine: Arc, + node_key: SecretKey, + + pending_programs: Arc>>, + running_tasks: Arc>>, + running_vms: Arc>>, + #[allow(clippy::type_complexity)] + task_queue: Arc>>>, +} + +impl Scheduler { + pub fn new( + mempool: Arc>, + database: Arc, + program_manager: ProgramManager, + workflow_engine: Arc, + node_key: SecretKey, + ) -> Self { + Self { + mempool, + database, + program_manager: Mutex::new(program_manager), + workflow_engine, + node_key, + + pending_programs: Arc::new(Mutex::new(VecDeque::new())), + running_tasks: Arc::new(Mutex::new(vec![])), + running_vms: Arc::new(Mutex::new(vec![])), + task_queue: Arc::new(Mutex::new(HashMap::new())), + } + } + + pub async fn run(&self) -> Result<()> { + 'SCHEDULING_LOOP: loop { + // Before scheduling new workload, try to start pending programs first. + { + let mut pending_programs = self.pending_programs.lock().await; + while let Some(program_id) = pending_programs.pop_front() { + match self + .program_manager + .lock() + .await + .start_program(program_id, None) + .await + { + Ok(p) => self.running_vms.lock().await.push(p), + Err(e) if e.is::() => { + let err = e.downcast_ref::().unwrap(); + tracing::info!("resources unavailable: {}", err); + sleep(Duration::from_millis(500)).await; + continue 'SCHEDULING_LOOP; + } + Err(e) => panic!("failed to start program: {e}"), + } + } + } + + let mut task = match self.pick_task().await { + Some(t) => { + tracing::debug!("task {}/{} scheduled for running", t.id, t.tx); + t + } + None => { + sleep(Duration::from_millis(100)).await; + continue; + } + }; + + // Push the task into program's work queue. + { + let mut task_queue_map = self.task_queue.lock().await; + if let Some(task_queue) = task_queue_map.get_mut(&task.program_id) { + task_queue.push_back((task.clone(), Instant::now())); + } else { + let mut queue = VecDeque::new(); + queue.push_back((task.clone(), Instant::now())); + task_queue_map.insert(task.program_id, queue); + } + } + + // Start the program. + match self + .program_manager + .lock() + .await + .start_program(task.program_id, None) + .await + { + Ok(p) => self.running_vms.lock().await.push(p), + Err(ref err) => { + if let Some(err) = err.downcast_ref::() { + let ResourceError::NotEnoughResources(msg) = err; + self.reschedule(&task).await?; + tracing::warn!("task {} rescheduled: {}", task.id.to_string(), msg); + continue; + } + + if let Some(err) = err.downcast_ref::() { + let ProgramError::ProgramNotFound(msg) = err; + tracing::error!("failed to schedule task {}: {}", task.id.to_string(), msg); + + // TODO: Persist failed task state. + task.state = TaskState::Failed; + + // Drop the program's task queue. The program's not + // there so no need to have queue for it either. + let program_id = &task.program_id.clone(); + self.task_queue.lock().await.remove(program_id); + } + } + } + } + } + + async fn pick_task(&self) -> Option { + // Acquire write lock. + let mut mempool = self.mempool.write().await; + + // Check if next tx is ready for processing? + let tx = match mempool.peek() { + Some(tx) => { + if let Payload::Run { .. } = tx.payload { + if self.database.has_assets_loaded(&tx.hash).await.unwrap() { + mempool.next().unwrap() + } else { + // Assets are still downloading. + // TODO: This can stall the whole processing pipeline!! + // XXX: ....^.........^........^......^.......^........ + tracing::info!("assets for tx {} still loading", tx.hash); + return None; + } + } else { + tracing::debug!("scheduling new task from tx {}", tx.hash); + mempool.next().unwrap() + } + } + None => return None, + }; + + match self.workflow_engine.next_task(&tx).await { + Ok(res) => res, + Err(e) if e.is::() => { + let err = e.downcast_ref::(); + match err { + Some(WorkflowError::IncompatibleTransaction(_)) => { + tracing::debug!("{}", e); + None + } + _ => { + tracing::error!("failed to compute next task for tx:{}: {}", tx.hash, e); + None + } + } + } + Err(e) => { + tracing::error!("failed to compute next task for tx:{}: {}", tx.hash, e); + None + } + } + } + + async fn reschedule(&self, task: &Task) -> Result<()> { + // The task is already pending in program's work queue. Push program ID + // to pending programs queue to wait available resources. + self.pending_programs + .lock() + .await + .push_back(task.program_id); + Ok(()) + } + + async fn terminate_vm(&self, program: Hash, vm_id: Arc) {} +} + +#[async_trait] +impl TaskManager for Scheduler { + async fn get_task(&self, program: Hash, vm_id: Arc) -> Option { + tracing::debug!( + "program {} running in vm_id {} requests for new task", + program, + vm_id + ); + + if let Some(task_queue) = self.task_queue.lock().await.get(&program) { + if let Some((task, scheduled)) = task_queue.front() { + tracing::debug!( + "task {} found for program {} running in vm_id {}", + task.id, + program, + vm_id + ); + tracing::info!( + "task {} started in {}ms", + task.id, + scheduled.elapsed().as_millis() + ); + + self.running_tasks.lock().await.push(RunningTask { + task: task.clone(), + vm_id: vm_id.clone(), + task_scheduled: *scheduled, + task_started: Instant::now(), + }); + + return Some(grpc::Task { + id: task.tx.to_string(), + name: task.name.clone(), + args: task.args.clone(), + files: task.files.iter().map(|x| x.name.clone()).collect(), + }); + } + } + + None + } + + async fn submit_result( + &self, + program: Hash, + vm_id: Arc, + result: grpc::task_result_request::Result, + ) -> bool { + dbg!(&result); + + let grpc::task_result_request::Result::Task(result) = result else { + todo!("task failed; handle it correctly") + }; + + let task_id = &result.id; + let mut running_tasks = self.running_tasks.lock().await; + if let Some(idx) = running_tasks + .iter() + .position(|e| &e.task.tx.to_string() == task_id) + { + let running_task = running_tasks.swap_remove(idx); + tracing::info!( + "task {} finished in {}sec", + task_id, + running_task.task_started.elapsed().as_secs() + ); + + if let Err(err) = self.database.mark_tx_executed(&running_task.task.tx).await { + tracing::error!( + "failed to update transaction.executed => true - tx.hash: {}", + &running_task.task.tx + ); + } + + let nonce = rand::thread_rng().next_u64(); + let tx = match running_task.task.kind { + TaskKind::Proof => Transaction::new( + Payload::Proof { + parent: running_task.task.tx, + prover: program, + proof: result.data, + }, + &self.node_key, + ), + TaskKind::Verification => Transaction::new( + Payload::Verification { + parent: running_task.task.tx, + verifier: program, + verification: result.data, + }, + &self.node_key, + ), + TaskKind::PoW => { + todo!("proof of work tasks not implemented yet"); + } + TaskKind::Nop => { + panic!( + "impossible to receive result from a task ({}/{}) with task.kind == Nop", + running_task.task.id, running_task.task.tx + ); + } + }; + + let mut mempool = self.mempool.write().await; + if let Err(err) = mempool.add(tx.clone()).await { + tracing::error!("failed to add transaction to mempool: {}", err); + } else { + dbg!(tx); + tracing::info!("successfully added new tx to mempool from task result"); + } + + tracing::debug!("terminating VM {} running program {}", vm_id, program); + + let mut running_vms = self.running_vms.lock().await; + let idx = running_vms.iter().position(|e| e.vm_id().eq(vm_id.clone())); + if idx.is_some() { + let program_handle = running_vms.remove(idx.unwrap()); + if let Err(err) = self + .program_manager + .lock() + .await + .stop_program(program_handle) + .await + { + tracing::error!("failed to stop program {}: {}", program, err); + } + } + } + + return false; + } +} diff --git a/crates/node/src/scheduler/program_manager.rs b/crates/node/src/scheduler/program_manager.rs new file mode 100644 index 00000000..57a8500b --- /dev/null +++ b/crates/node/src/scheduler/program_manager.rs @@ -0,0 +1,73 @@ +use eyre::Result; +use std::sync::{Arc, Mutex}; +use thiserror::Error; +use tokio::sync::Mutex as TMutex; + +use crate::scheduler::resource_manager::{ResourceAllocation, ResourceManager}; +use crate::storage::Database; +use crate::types::program::ResourceRequest; +use crate::types::Hash; +use crate::vmm::{Provider, VMHandle, VMId}; + +#[allow(clippy::enum_variant_names)] +#[derive(Error, Debug)] +pub enum ProgramError { + #[error("program not found: {0}")] + ProgramNotFound(String), +} + +pub struct ProgramHandle { + resource_allocation: ResourceAllocation, + vm_handle: VMHandle, +} + +impl ProgramHandle { + pub fn vm_id(&self) -> Arc { + self.vm_handle.vm_id() + } +} + +pub struct ProgramManager { + storage: Arc, + resource_manager: Arc>, + vm_provider: Arc>, +} + +impl ProgramManager { + pub fn new( + storage: Arc, + vm_provider: Arc>, + resource_manager: Arc>, + ) -> Self { + Self { + storage, + resource_manager, + vm_provider, + } + } + + pub async fn start_program( + &mut self, + id: Hash, + limits: Option, + ) -> Result { + let program = match self.storage.find_program(&id).await? { + Some(program) => program, + None => return Err(ProgramError::ProgramNotFound(id.to_string()).into()), + }; + + let req = limits.unwrap_or(program.limits.clone()); + let resource_allocation = + ResourceManager::try_allocate(self.resource_manager.clone(), &req)?; + let vm_handle = self.vm_provider.lock().await.start_vm(program, req).await?; + + Ok(ProgramHandle { + resource_allocation, + vm_handle, + }) + } + + pub async fn stop_program(&mut self, prg_handle: ProgramHandle) -> Result<()> { + self.vm_provider.lock().await.stop_vm(prg_handle.vm_handle) + } +} diff --git a/crates/node/src/scheduler/resource_manager.rs b/crates/node/src/scheduler/resource_manager.rs new file mode 100644 index 00000000..5e02d79e --- /dev/null +++ b/crates/node/src/scheduler/resource_manager.rs @@ -0,0 +1,163 @@ +use crate::types::program::ResourceRequest; +use eyre::Result; +use std::sync::{Arc, Mutex}; +use thiserror::Error; + +pub struct ResourceAllocation { + pub(self) resource_manager: Arc>, + pub(self) mem: u64, + pub(self) cpus: u64, + pub(self) gpus: u64, +} + +impl Drop for ResourceAllocation { + fn drop(&mut self) { + self.resource_manager + .clone() + .lock() + .expect("acquire resource manager instance lock") + .free(self); + } +} + +#[allow(clippy::enum_variant_names)] +#[derive(Error, Debug)] +pub enum ResourceError { + #[error("not enough resources: {0}")] + NotEnoughResources(String), +} + +#[derive(Debug)] +pub struct ResourceManager { + available_mem: u64, + available_cpus: u64, + available_gpus: u64, +} + +impl ResourceManager { + pub fn new(total_mem: u64, total_cpus: u64, total_gpus: u64) -> Self { + ResourceManager { + available_mem: total_mem, + available_cpus: total_cpus, + available_gpus: total_gpus, + } + } + + pub fn try_allocate( + resource_manager: Arc>, + request: &ResourceRequest, + ) -> Result { + let rm = resource_manager.clone(); + let mut rm = rm.lock().expect("acquire resource manager instance lock"); + + if rm.available_mem < request.mem { + return Err(ResourceError::NotEnoughResources("memory".to_string()).into()); + } + + if rm.available_cpus < request.cpus { + return Err(ResourceError::NotEnoughResources("cpus".to_string()).into()); + } + + if rm.available_gpus < request.gpus { + return Err(ResourceError::NotEnoughResources("gpus".to_string()).into()); + } + + rm.available_mem -= request.mem; + rm.available_cpus -= request.cpus; + rm.available_gpus -= request.gpus; + + Ok(ResourceAllocation { + resource_manager: resource_manager.clone(), + mem: request.mem, + cpus: request.cpus, + gpus: request.gpus, + }) + } + + pub(self) fn free(&mut self, allocation: &ResourceAllocation) { + self.available_mem += allocation.mem; + self.available_cpus += allocation.cpus; + self.available_gpus += allocation.gpus; + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_try_allocate_succeeds() { + let rm = Arc::new(Mutex::new(ResourceManager::new(2048, 4, 0))); + + let req = &ResourceRequest { + mem: 1024, + cpus: 1, + gpus: 0, + }; + + ResourceManager::try_allocate(rm.clone(), req).unwrap(); + ResourceManager::try_allocate(rm.clone(), req).unwrap(); + } + + #[test] + fn test_free_succeeds() { + let rm = Arc::new(Mutex::new(ResourceManager::new(2048, 4, 0))); + + let req = &ResourceRequest { + mem: 2048, + cpus: 4, + gpus: 0, + }; + + // Allocate all available resources. + let ra = ResourceManager::try_allocate(rm.clone(), req).unwrap(); + + // Assert that we are out of resources. + let ra2 = ResourceManager::try_allocate(rm.clone(), req); + assert!(ra2.is_err()); + + drop(ra); + + // Allocate again all available resources. + ResourceManager::try_allocate(rm.clone(), req).unwrap(); + } + + #[test] + fn test_try_allocate_fails_on_mem() { + let rm = Arc::new(Mutex::new(ResourceManager::new(2048, 4, 0))); + let req = &ResourceRequest { + mem: 4096, + cpus: 2, + gpus: 0, + }; + + let ra = ResourceManager::try_allocate(rm, req); + assert!(ra.is_err()); + } + + #[test] + fn test_try_allocate_fails_on_cpus() { + let rm = Arc::new(Mutex::new(ResourceManager::new(2048, 4, 0))); + let req = &ResourceRequest { + mem: 1024, + cpus: 8, + gpus: 0, + }; + + let ra = ResourceManager::try_allocate(rm, req); + assert!(ra.is_err()); + } + + #[test] + fn test_try_allocate_fails_on_gpus() { + let rm = Arc::new(Mutex::new(ResourceManager::new(2048, 4, 0))); + let req = &ResourceRequest { + mem: 1024, + cpus: 1, + gpus: 1, + }; + + let ra = ResourceManager::try_allocate(rm, req); + assert!(ra.is_err()); + } +} diff --git a/crates/node/src/scheduler/task_picker.rs b/crates/node/src/scheduler/task_picker.rs new file mode 100644 index 00000000..e69de29b diff --git a/crates/node/src/scheduler/work_distributor.rs b/crates/node/src/scheduler/work_distributor.rs new file mode 100644 index 00000000..e69de29b diff --git a/crates/node/src/storage/database/entity/mod.rs b/crates/node/src/storage/database/entity/mod.rs new file mode 100644 index 00000000..2a14e19a --- /dev/null +++ b/crates/node/src/storage/database/entity/mod.rs @@ -0,0 +1,6 @@ +pub mod payload; +pub mod public_key; +pub mod transaction; + +pub use public_key::PublicKey; +pub use transaction::Transaction; diff --git a/crates/node/src/storage/database/entity/payload.rs b/crates/node/src/storage/database/entity/payload.rs new file mode 100644 index 00000000..d914c6b9 --- /dev/null +++ b/crates/node/src/storage/database/entity/payload.rs @@ -0,0 +1,62 @@ +use crate::types::Hash; +use libsecp256k1::{PublicKey, SecretKey}; +use num_bigint::BigInt; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, Deserialize, Serialize, sqlx::FromRow)] +pub struct Transfer { + pub to: PublicKey, + pub value: BigInt, +} + +impl Default for Transfer { + fn default() -> Self { + Transfer { + to: PublicKey::from_secret_key(&SecretKey::default()), + value: BigInt::default(), + } + } +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize, sqlx::FromRow)] +pub struct Stake { + pub value: BigInt, +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize, sqlx::FromRow)] +pub struct Unstake { + pub value: BigInt, +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize, sqlx::FromRow)] +pub struct Deploy { + pub name: String, + /// prover field is the hash of the corresponding prover program. + pub prover: Hash, + /// verifier field is the hash of the corresponding verifyier program. + pub verifier: Hash, +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize, sqlx::FromRow)] +pub struct WorkflowStep { + pub id: Option, + pub tx: Hash, + pub sequence: i32, + pub program: Hash, + pub args: Vec, +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize, sqlx::FromRow)] +pub struct ProgramInputData { + pub workflow_step_id: i64, + pub file_name: String, + pub file_url: String, + pub checksum: String, +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize, sqlx::FromRow)] +pub struct ProgramOutputData { + pub workflow_step_id: i64, + pub source_program: Hash, + pub file_name: String, +} diff --git a/crates/node/src/storage/database/entity/public_key.rs b/crates/node/src/storage/database/entity/public_key.rs new file mode 100644 index 00000000..4f0fc6c0 --- /dev/null +++ b/crates/node/src/storage/database/entity/public_key.rs @@ -0,0 +1,89 @@ +use std::fmt; + +use serde::{Deserialize, Serialize}; +use sqlx::{Decode, Encode, Postgres, Type}; +use thiserror::Error; + +#[allow(clippy::enum_variant_names)] +#[derive(Error, Debug)] +pub enum PublicKeyError { + #[error("public key parse error: {0}")] + ParseError(String), +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct PublicKey(pub libsecp256k1::PublicKey); + +impl Default for PublicKey { + fn default() -> Self { + PublicKey(libsecp256k1::PublicKey::from_secret_key( + &libsecp256k1::SecretKey::default(), + )) + } +} + +impl fmt::Display for PublicKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", hex::encode(self.0.serialize())) + } +} +impl From for libsecp256k1::PublicKey { + fn from(value: PublicKey) -> Self { + value.0 + } +} + +impl From for PublicKey { + fn from(value: String) -> Self { + Self::try_from(value.as_str()).expect("from string") + } +} + +impl TryFrom<&str> for PublicKey { + type Error = PublicKeyError; + + fn try_from(value: &str) -> Result { + let bs = hex::decode(value).map_err(|e| PublicKeyError::ParseError(e.to_string()))?; + let bs: [u8; 65] = bs + .try_into() + .map_err(|_| PublicKeyError::ParseError("byte array length".to_string()))?; + let pub_key = libsecp256k1::PublicKey::parse(&bs) + .map_err(|e| PublicKeyError::ParseError(e.to_string()))?; + Ok(PublicKey(pub_key)) + } +} + +impl PublicKey { + pub fn from_secret_key(secret_key: &libsecp256k1::SecretKey) -> PublicKey { + PublicKey(libsecp256k1::PublicKey::from_secret_key(secret_key)) + } +} + +impl<'q> Decode<'q, Postgres> for PublicKey { + fn decode( + value: >::ValueRef, + ) -> Result { + let str_value = >::decode(value)?; + Ok(PublicKey::from(str_value)) + } +} + +impl<'q> Encode<'q, Postgres> for PublicKey { + fn encode_by_ref( + &self, + buf: &mut >::ArgumentBuffer, + ) -> sqlx::encode::IsNull { + let str_value = self.to_string(); + >::encode(str_value, buf) + } +} + +impl Type for PublicKey { + fn type_info() -> ::TypeInfo { + >::type_info() + } + + fn compatible(ty: &::TypeInfo) -> bool { + >::compatible(ty) + } +} diff --git a/crates/node/src/storage/database/entity/transaction.rs b/crates/node/src/storage/database/entity/transaction.rs new file mode 100644 index 00000000..eeb4b6b5 --- /dev/null +++ b/crates/node/src/storage/database/entity/transaction.rs @@ -0,0 +1,73 @@ +use crate::storage::database::entity; +use crate::types::{self, transaction, Hash, Signature}; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, Debug, Default, Deserialize, Serialize, sqlx::Type)] +#[sqlx(type_name = "transaction_kind", rename_all = "lowercase")] +pub enum Kind { + #[default] + Empty, + Transfer, + Stake, + Unstake, + Deploy, + Run, + Proof, + ProofKey, + Verification, + Cancel, +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize, sqlx::FromRow)] +pub struct Transaction { + pub author: entity::PublicKey, + pub hash: Hash, + pub kind: Kind, + pub nonce: sqlx::types::Decimal, + pub signature: Signature, + pub propagated: bool, + pub executed: bool, +} + +impl From<&types::Transaction> for Transaction { + fn from(value: &types::Transaction) -> Self { + let kind = match value.payload { + transaction::Payload::Empty => Kind::Empty, + transaction::Payload::Transfer { .. } => Kind::Transfer, + transaction::Payload::Stake { .. } => Kind::Stake, + transaction::Payload::Unstake { .. } => Kind::Unstake, + transaction::Payload::Deploy { .. } => Kind::Deploy, + transaction::Payload::Run { .. } => Kind::Run, + transaction::Payload::Proof { .. } => Kind::Proof, + transaction::Payload::ProofKey { .. } => Kind::ProofKey, + transaction::Payload::Verification { .. } => Kind::Verification, + transaction::Payload::Cancel { .. } => Kind::Cancel, + }; + + Transaction { + author: entity::PublicKey(value.author), + hash: value.hash, + kind, + nonce: value.nonce.into(), + signature: value.signature, + propagated: value.propagated, + executed: value.executed, + } + } +} + +impl From for types::Transaction { + fn from(value: Transaction) -> types::Transaction { + types::Transaction { + author: value.author.into(), + hash: value.hash, + // This field is complemented separately. + payload: transaction::Payload::Empty, + nonce: TryFrom::::try_from(value.nonce) + .expect("invalid nonce in db"), + signature: value.signature, + propagated: value.propagated, + executed: value.executed, + } + } +} diff --git a/crates/node/src/storage/database/mod.rs b/crates/node/src/storage/database/mod.rs new file mode 100644 index 00000000..c9f215f4 --- /dev/null +++ b/crates/node/src/storage/database/mod.rs @@ -0,0 +1,2 @@ +pub mod entity; +pub mod postgres; diff --git a/crates/node/src/storage/database/postgres.rs b/crates/node/src/storage/database/postgres.rs new file mode 100644 index 00000000..417170a6 --- /dev/null +++ b/crates/node/src/storage/database/postgres.rs @@ -0,0 +1,646 @@ +use std::time::Duration; + +use eyre::Result; +use sqlx::{self, postgres::PgPoolOptions, Row}; +use uuid::Uuid; + +use super::entity::{self}; +use crate::types::{self, transaction::ProgramData, File, Hash, Program, Task}; + +const MAX_DB_CONNS: u32 = 64; +const DB_CONNECT_TIMEOUT: Duration = Duration::from_millis(750); + +#[derive(Clone)] +pub struct Database { + pool: sqlx::PgPool, +} + +// TODO: Split this into domain specific components. +impl Database { + pub async fn new(db_url: &str) -> Result { + let pool = PgPoolOptions::new() + .max_connections(MAX_DB_CONNS) + .acquire_timeout(DB_CONNECT_TIMEOUT) + .connect(db_url) + .await?; + Ok(Database { pool }) + } + + pub async fn add_program(&self, db_conn: &mut sqlx::PgConnection, p: &Program) -> Result<()> { + sqlx::query( + "INSERT INTO program ( hash, name, image_file_name, image_file_url, image_file_checksum ) VALUES ( $1, $2, $3, $4, $5 ) ON CONFLICT (hash) DO NOTHING RETURNING *") + .bind(p.hash) + .bind(&p.name) + .bind(&p.image_file_name) + .bind(&p.image_file_url) + .bind(&p.image_file_checksum) + .execute(db_conn) + .await?; + Ok(()) + } + + pub async fn find_program(&self, hash: impl AsRef) -> Result> { + // non-macro query_as used because of sqlx limitations with enums. + let program = sqlx::query_as::<_, Program>("SELECT * FROM program WHERE hash = $1") + .bind(hash.as_ref()) + .fetch_optional(&self.pool) + .await?; + + Ok(program) + } + + pub async fn get_program( + &self, + db_conn: &mut sqlx::PgConnection, + hash: impl AsRef, + ) -> Result { + // non-macro query_as used because of sqlx limitations with enums. + let program = sqlx::query_as::<_, Program>("SELECT * FROM program WHERE hash = $1") + .bind(hash.as_ref()) + .fetch_one(db_conn) + .await?; + + Ok(program) + } + + pub async fn get_programs(&self) -> Result> { + let programs = sqlx::query_as::<_, Program>("SELECT * FROM program") + .fetch_all(&self.pool) + .await?; + Ok(programs) + } + + pub async fn add_task(&self, t: &Task) -> Result<()> { + let mut tx = self.pool.begin().await?; + + if let Err(err) = sqlx::query( + "INSERT INTO task ( id, name, args, state, program_id ) VALUES ( $1, $2, $3, $4, $5 )", + ) + .bind(t.id) + .bind(&t.name) + .bind(&t.args) + .bind(&t.state) + .bind(t.program_id) + .execute(&self.pool) + .await + { + tx.rollback().await?; + return Err(err.into()); + } + + { + let mut query_builder = + sqlx::QueryBuilder::new("INSERT INTO file ( task_id, name, url )"); + query_builder.push_values(&t.files, |mut b, new_file| { + b.push_bind(t.id) + .push_bind(&new_file.name) + .push_bind(&new_file.url); + }); + + let query = query_builder.build(); + if let Err(err) = query.execute(&mut *tx).await { + tx.rollback().await?; + return Err(err.into()); + } + } + + tx.commit().await.map_err(|e| e.into()) + } + + pub async fn find_task(&self, id: Uuid) -> Result> { + let mut tx = self.pool.begin().await?; + + // non-macro query_as used because of sqlx limitations with enums. + let task = sqlx::query_as::<_, Task>("SELECT * FROM task WHERE id = $1") + .bind(id) + .fetch_optional(&mut *tx) + .await?; + + // Fetch accompanied Files for the Task. + match task { + Some(mut task) => { + let mut files = sqlx::query_as::<_, File>("SELECT * FROM file WHERE task_id = $1") + .bind(id) + .fetch_all(&mut *tx) + .await?; + task.files.append(&mut files); + Ok(Some(task)) + } + None => Ok(None), + } + } + + pub async fn get_tasks(&self) -> Result> { + let mut tx = self.pool.begin().await?; + + // non-macro query_as used because of sqlx limitations with enums. + let mut tasks = sqlx::query_as::<_, Task>("SELECT * FROM task") + .fetch_all(&mut *tx) + .await?; + + for task in &mut tasks { + let mut files = sqlx::query_as::<_, File>("SELECT * FROM file WHERE task_id = $1") + .bind(task.id) + .fetch_all(&mut *tx) + .await?; + + task.files.append(&mut files); + } + + Ok(tasks) + } + + pub async fn update_task_state(&self, t: &Task) -> Result<()> { + sqlx::query("UPDATE task SET state = $1 WHERE id = $2") + .bind(&t.state) + .bind(t.id) + .execute(&self.pool) + .await?; + Ok(()) + } + + pub async fn add_asset(&self, tx_hash: &Hash) -> Result<()> { + sqlx::query!( + "INSERT INTO assets ( tx ) VALUES ( $1 ) RETURNING *", + tx_hash.to_string(), + ) + .fetch_one(&self.pool) + .await?; + Ok(()) + } + + pub async fn has_assets_loaded(&self, tx_hash: &Hash) -> Result { + let res: Option = + sqlx::query("SELECT 1 FROM assets WHERE completed IS NOT NULL AND tx = $1") + .bind(tx_hash) + .map(|row: sqlx::postgres::PgRow| row.get(0)) + .fetch_optional(&self.pool) + .await?; + + Ok(res.is_some()) + } + + pub async fn get_incomplete_assets(&self) -> Result> { + let assets = + sqlx::query("SELECT tx FROM assets WHERE completed IS NULL ORDER BY created ASC") + .map(|row: sqlx::postgres::PgRow| row.get(0)) + .fetch_all(&self.pool) + .await?; + + Ok(assets) + } + + pub async fn mark_asset_complete(&self, tx_hash: &Hash) -> Result<()> { + sqlx::query("UPDATE assets SET completed = NOW() WHERE tx = $1") + .bind(&tx_hash.to_string()) + .execute(&self.pool) + .await?; + Ok(()) + } + + // NOTE: There are plenty of opportunities for optimizations in following + // transaction related operations. They are implemented naively on purpose + // for now to maintain initial flexibility in development. Later on, these + // queries here are easy low hanging fruits for optimizations. + pub async fn find_transaction(&self, tx_hash: &Hash) -> Result> { + let mut db_tx = self.pool.begin().await?; + + let entity = + sqlx::query_as::<_, entity::Transaction>("SELECT * FROM transaction WHERE hash = $1") + .bind(tx_hash) + .fetch_optional(&mut *db_tx) + .await?; + + if entity.is_some() { + let entity = entity.unwrap(); + let payload = match entity.kind { + entity::transaction::Kind::Deploy => { + let deploy = sqlx::query_as::<_, entity::payload::Deploy>( + "SELECT * FROM deploy WHERE tx = $1", + ) + .bind(tx_hash) + .fetch_one(&mut *db_tx) + .await?; + + let prover = self.get_program(&mut db_tx, deploy.prover).await?; + let verifier = self.get_program(&mut db_tx, deploy.verifier).await?; + + types::transaction::Payload::Deploy { + name: deploy.name, + prover: prover.into(), + verifier: verifier.into(), + } + } + entity::transaction::Kind::Run => { + let steps = sqlx::query_as::<_, entity::payload::WorkflowStep>( + "SELECT * FROM workflow_step WHERE tx = $1", + ) + .bind(tx_hash) + .fetch_all(&mut *db_tx) + .await?; + + let program_inputs = sqlx::query_as::<_, entity::payload::ProgramInputData>( + "SELECT * FROM program_input_data AS pid JOIN workflow_step AS ws ON pid.workflow_step_id = ws.id WHERE ws.tx = $1", + ) + .bind(tx_hash) + .fetch_all(&mut *db_tx) + .await?; + + let program_outputs = sqlx::query_as::<_, entity::payload::ProgramOutputData>( + "SELECT * FROM program_output_data AS pod JOIN workflow_step AS ws ON pod.workflow_step_id = ws.id WHERE ws.tx = $1", + ) + .bind(tx_hash) + .fetch_all(&mut *db_tx) + .await?; + + let steps = steps + .iter() + .map(|step| { + let step_id = step.id.unwrap(); + let program_inputs: Vec<&entity::payload::ProgramInputData> = + program_inputs + .iter() + .filter(|e| e.workflow_step_id == step_id) + .collect(); + let program_outputs: Vec<&entity::payload::ProgramOutputData> = + program_outputs + .iter() + .filter(|e| e.workflow_step_id == step_id) + .collect(); + + let mut program_data: Vec = + program_inputs + .iter() + .map(|e| types::transaction::ProgramData::Input { + file_name: e.file_name.clone(), + file_url: e.file_url.clone(), + checksum: e.checksum.clone(), + }) + .collect(); + + let mut program_outputs: Vec = + program_outputs + .iter() + .map(|e| types::transaction::ProgramData::Output { + file_name: e.file_name.clone(), + source_program: e.source_program, + }) + .collect(); + program_data.append(&mut program_outputs); + + types::transaction::WorkflowStep { + program: step.program, + args: step.args.clone(), + inputs: program_data, + } + }) + .collect(); + + types::transaction::Payload::Run { + workflow: types::transaction::Workflow { steps }, + } + } + entity::transaction::Kind::Proof => { + sqlx::query("SELECT parent, prover, proof FROM proof WHERE tx = $1") + .bind(tx_hash) + .map( + |row: sqlx::postgres::PgRow| types::transaction::Payload::Proof { + parent: row.get(0), + prover: row.get(1), + proof: row.get(2), + }, + ) + .fetch_one(&mut *db_tx) + .await? + } + entity::transaction::Kind::ProofKey => { + sqlx::query("SELECT parent, key FROM proof_key WHERE tx = $1") + .bind(tx_hash) + .map( + |row: sqlx::postgres::PgRow| types::transaction::Payload::ProofKey { + parent: row.get(0), + key: row.get(1), + }, + ) + .fetch_one(&mut *db_tx) + .await? + } + entity::transaction::Kind::Verification => { + sqlx::query( + "SELECT parent, verifier, verification FROM verification WHERE tx = $1", + ) + .bind(tx_hash) + .map( + |row: sqlx::postgres::PgRow| types::transaction::Payload::Verification { + parent: row.get(0), + verifier: row.get(1), + verification: row.get(2), + }, + ) + .fetch_one(&mut *db_tx) + .await? + } + _ => types::transaction::Payload::Empty, + }; + + let mut tx: types::transaction::Transaction = entity.into(); + tx.payload = payload; + Ok(Some(tx)) + } else { + Ok(None) + } + } + + pub async fn get_transactions(&self) -> Result> { + let mut db_tx = self.pool.begin().await?; + let refs: Vec = sqlx::query("SELECT hash FROM transaction") + .map(|row: sqlx::postgres::PgRow| row.get(0)) + .fetch_all(&mut *db_tx) + .await?; + + let mut txs = Vec::with_capacity(refs.len()); + for tx_hash in refs { + let tx = self.find_transaction(&tx_hash).await?; + if let Some(tx) = tx { + txs.push(tx); + } + } + + Ok(txs) + } + + pub async fn get_unexecuted_transactions(&self) -> Result> { + let mut db_tx = self.pool.begin().await?; + let refs: Vec = sqlx::query("SELECT hash FROM transaction WHERE executed IS false") + .map(|row: sqlx::postgres::PgRow| row.get(0)) + .fetch_all(&mut *db_tx) + .await?; + + let mut txs = Vec::with_capacity(refs.len()); + for tx_hash in refs { + let tx = self.find_transaction(&tx_hash).await?; + if let Some(tx) = tx { + txs.push(tx); + } + } + + Ok(txs) + } + + pub async fn add_transaction(&self, tx: &types::Transaction) -> Result<()> { + let entity = entity::Transaction::from(tx); + + let mut db_tx = self.pool.begin().await?; + + sqlx::query( + "INSERT INTO transaction ( author, hash, kind, nonce, signature, propagated, executed ) VALUES ( $1, $2, $3, $4, $5, $6, $7 ) ON CONFLICT (hash) DO UPDATE SET propagated = $6, executed = $7") + .bind(entity.author) + .bind(entity.hash) + .bind(entity.kind) + .bind(entity.nonce) + .bind(entity.signature) + .bind(entity.propagated) + .bind(entity.executed) + .execute(&mut *db_tx) + .await?; + + match &tx.payload { + types::transaction::Payload::Deploy { + ref name, + ref prover, + ref verifier, + } => { + self.add_program(&mut db_tx, &Program::from(prover.clone())) + .await?; + self.add_program(&mut db_tx, &Program::from(verifier.clone())) + .await?; + + sqlx::query( + "INSERT INTO deploy ( tx, name, prover, verifier ) VALUES ( $1, $2, $3, $4 ) ON CONFLICT (tx) DO NOTHING") + .bind(tx.hash) + .bind(name) + .bind(prover.hash) + .bind(verifier.hash) + .execute(&mut *db_tx) + .await?; + } + types::transaction::Payload::Run { ref workflow } => { + let mut step_sequence = 1; + for step in &workflow.steps { + let result = sqlx::query( + "WITH ws AS (INSERT INTO workflow_step ( tx, sequence, program, args ) VALUES ( $1, $2, $3, $4 ) ON CONFLICT (tx, sequence) DO NOTHING RETURNING id) SELECT * FROM ws UNION SELECT id FROM workflow_step WHERE tx = $1 AND sequence = $2") + .bind(tx.hash) + .bind(step_sequence) + .bind(step.program) + .bind(&step.args) + .fetch_one(&mut *db_tx) + .await?; + + let step_id: i64 = result.get(0); + + for input in &step.inputs { + match input { + ProgramData::Input { + file_name, + file_url, + checksum, + } => { + sqlx::query( + "INSERT INTO program_input_data ( workflow_step_id, file_name, file_url, checksum ) VALUES ( $1, $2, $3, $4 ) ON CONFLICT (workflow_step_id) DO NOTHING") + .bind(step_id) + .bind(file_name) + .bind(file_url) + .bind(checksum) + .execute(&mut *db_tx) + .await?; + } + ProgramData::Output { + file_name, + source_program, + } => { + sqlx::query( + "INSERT INTO program_output_data ( workflow_step_id, file_name, source_program ) VALUES ( $1, $2, $3 ) ON CONFLICT (workflow_step_id, file_name) DO NOTHING") + .bind(step_id) + .bind(file_name) + .bind(source_program) + .execute(&mut *db_tx) + .await?; + } + } + } + + step_sequence += 1; + } + } + types::transaction::Payload::Proof { + parent, + prover, + proof, + } => { + sqlx::query( + "INSERT INTO proof ( tx, parent, prover, proof ) VALUES ( $1, $2, $3, $4 ) ON CONFLICT (tx) DO NOTHING", + ) + .bind(tx.hash) + .bind(parent) + .bind(prover) + .bind(proof) + .execute(&mut *db_tx) + .await?; + } + + types::transaction::Payload::ProofKey { parent, key } => { + sqlx::query("INSERT INTO proof_key ( tx, parent, key ) VALUES ( $1, $2, $3 ) ON CONFLICT (tx) DO NOTHING") + .bind(tx.hash) + .bind(parent) + .bind(key) + .execute(&mut *db_tx) + .await?; + } + + types::transaction::Payload::Verification { + parent, + verifier, + verification, + } => { + sqlx::query( + "INSERT INTO verification ( tx, parent, verifier, verification ) VALUES ( $1, $2, $3, $4 ) ON CONFLICT (tx) DO NOTHING", + ) + .bind(tx.hash) + .bind(parent) + .bind(verifier) + .bind(verification) + .execute(&mut *db_tx) + .await?; + } + _ => { /* ignore for now */ } + } + + db_tx.commit().await.map_err(|e| e.into()) + } + + pub async fn mark_tx_executed(&self, tx_hash: &Hash) -> Result<()> { + sqlx::query("UPDATE transaction SET executed = true WHERE id = $1") + .bind(tx_hash) + .execute(&self.pool) + .await?; + Ok(()) + } + + pub async fn acl_whitelist_has(&self, key: &entity::PublicKey) -> Result { + let res: Option = sqlx::query("SELECT 1 FROM acl_whitelist WHERE key = $1") + .bind(key) + .map(|row: sqlx::postgres::PgRow| row.get(0)) + .fetch_optional(&self.pool) + .await?; + + Ok(res.is_some()) + } + + pub async fn acl_whitelist(&self, key: &entity::PublicKey) -> Result<()> { + sqlx::query("INSERT INTO acl_whitelist ( key ) VALUES ( $1 ) ON CONFLICT (key) DO NOTHING") + .bind(key) + .execute(&self.pool) + .await?; + Ok(()) + } + + pub async fn acl_deny(&self, key: &entity::PublicKey) -> Result<()> { + sqlx::query("DELETE FROM acl_whitelist WHERE key = $1") + .bind(key) + .execute(&self.pool) + .await?; + Ok(()) + } + + // Delete is mainly for test cases. + async fn delete_transaction(&self, tx_hash: &Hash) -> Result<()> { + let mut db_tx = self.pool.begin().await?; + + sqlx::query("DELETE FROM program USING deploy WHERE (program.hash = deploy.prover OR program.hash = deploy.verifier) AND deploy.tx = $1") + .bind(tx_hash) + .execute(&mut *db_tx) + .await?; + sqlx::query("DELETE FROM transaction WHERE hash = $1") + .bind(tx_hash) + .execute(&mut *db_tx) + .await?; + + db_tx.commit().await.map_err(|e| e.into()) + } +} + +#[cfg(test)] +mod tests { + use libsecp256k1::{PublicKey, SecretKey}; + + use crate::types::{ + transaction::{Payload, ProgramMetadata}, + Signature, Transaction, + }; + + use super::*; + + #[ignore] + #[tokio::test] + async fn test_add_and_find_deploy_transaction() { + let database = Database::new("postgres://gevulot:gevulot@localhost/gevulot") + .await + .expect("failed to connect to db"); + + let tx = Transaction { + author: PublicKey::from_secret_key(&SecretKey::default()), + hash: Hash::default(), + payload: Payload::Deploy { + name: "test deployment".to_string(), + prover: ProgramMetadata { + name: "test prover".to_string(), + hash: Hash::from( + "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", + ), + image_file_name: "test_prover.img".to_string(), + image_file_url: "http://example.localhost:8080/foobar/test_prover.img" + .to_string(), + image_file_checksum: + "ebc81c06a5ae263d0d4e4efcb06e668b3b786ccc83cb738de5aabb9b966668db" + .to_string(), + }, + verifier: ProgramMetadata { + name: "test verifier".to_string(), + hash: Hash::from( + "fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210", + ), + image_file_name: "test_verifier.img".to_string(), + image_file_url: "http://example.localhost:8080/foobar/test_verifier.img" + .to_string(), + image_file_checksum: + "ebc81c06a5ae263d0d4e4efcb06e668b3b786ccc83cb738de5aabb9b966668aa" + .to_string(), + }, + }, + nonce: 64, + signature: Signature::default(), + propagated: false, + executed: false, + }; + + database + .add_transaction(&tx) + .await + .expect("add transaction to db"); + + let read_tx = database.find_transaction(&tx.hash).await; + + // Cleanup + database + .delete_transaction(&tx.hash) + .await + .expect("delete transaction"); + + // Assertions + assert!(read_tx.is_ok()); + let read_tx = read_tx.unwrap(); + + assert!(read_tx.is_some()); + assert_eq!(tx, read_tx.unwrap()); + } +} diff --git a/crates/node/src/storage/file.rs b/crates/node/src/storage/file.rs new file mode 100644 index 00000000..81ad0111 --- /dev/null +++ b/crates/node/src/storage/file.rs @@ -0,0 +1,145 @@ +use std::path::{Path, PathBuf}; + +use crate::types; +use eyre::Result; +use tokio::io::AsyncWriteExt; + +pub struct File { + client: reqwest::Client, + data_dir: String, +} + +impl File { + pub fn new(data_dir: &Path) -> Self { + File { + client: reqwest::Client::new(), + data_dir: data_dir.as_os_str().to_str().expect("filename").to_string(), + } + } + + pub async fn get_task_file( + &self, + task_id: &str, + path: &str, + ) -> Result> { + let mut path = Path::new(path); + if path.is_absolute() { + path = path.strip_prefix("/")?; + } + let path = PathBuf::new().join(&self.data_dir).join(task_id).join(path); + let fd = tokio::fs::File::open(path).await?; + Ok(tokio::io::BufReader::new(fd)) + } + + pub async fn move_task_file( + &self, + task_id_src: &str, + task_id_dst: &str, + path: &str, + ) -> Result<()> { + let mut path = Path::new(path); + if path.is_absolute() { + path = path.strip_prefix("/")?; + } + + let src_file_path = PathBuf::new() + .join(&self.data_dir) + .join(task_id_src) + .join(path); + let dst_file_path = PathBuf::new() + .join(&self.data_dir) + .join(task_id_dst) + .join(path); + + tracing::debug!( + "moving file from {:#?} to {:#?}", + src_file_path, + dst_file_path + ); + + // Ensure any necessary subdirectories exists. + if let Some(parent) = dst_file_path.parent() { + tokio::fs::create_dir_all(parent) + .await + .expect("task file mkdir"); + } + + tokio::fs::rename(src_file_path, dst_file_path) + .await + .map_err(|e| e.into()) + } + + pub async fn save_task_file(&self, task_id: &str, path: &str, data: Vec) -> Result<()> { + let mut path = Path::new(path); + if path.is_absolute() { + path = path.strip_prefix("/")?; + } + + let file_path = PathBuf::new().join(&self.data_dir).join(task_id).join(path); + + tracing::debug!( + "saving task {} file {:#?} to {:#?}", + task_id, + path, + file_path + ); + + // Ensure any necessary subdirectories exists. + if let Some(parent) = file_path.parent() { + tokio::fs::create_dir_all(parent) + .await + .expect("task file mkdir"); + } + + let fd = tokio::fs::File::create(&file_path).await?; + let mut fd = tokio::io::BufWriter::new(fd); + + fd.write_all(data.as_slice()).await?; + fd.flush().await?; + + tracing::debug!("file {:#?} successfully written", file_path); + + Ok(()) + } + + pub async fn download(&self, file: &types::File) -> Result<()> { + let file_name = Path::new(&file.name).file_name().unwrap(); + let file_path = PathBuf::new() + .join(&self.data_dir) + .join(file.tx.to_string()) + .join(file_name); + + // Ensure any necessary subdirectories exists. + if let Some(parent) = file_path.parent() { + tokio::fs::create_dir_all(parent) + .await + .expect("download file mkdir"); + } + + let url = reqwest::Url::parse(&file.url)?; + let mut resp = self.client.get(url.clone()).send().await?; + + if resp.status() == reqwest::StatusCode::OK { + let fd = tokio::fs::File::create(&file_path).await?; + let mut fd = tokio::io::BufWriter::new(fd); + + while let Some(chunk) = resp.chunk().await? { + fd.write_all(&chunk).await?; + } + + fd.flush().await?; + tracing::info!( + "downloaded file to {}", + file_path.into_os_string().to_str().unwrap().to_string() + ); + } else { + tracing::error!( + "failed to download file from {}: response status: {}", + url, + resp.status() + ); + } + + Ok(()) + } +} diff --git a/crates/node/src/storage/mod.rs b/crates/node/src/storage/mod.rs new file mode 100644 index 00000000..af53df79 --- /dev/null +++ b/crates/node/src/storage/mod.rs @@ -0,0 +1,5 @@ +pub(crate) mod database; +mod file; + +pub use database::postgres::Database; +pub use file::File; diff --git a/crates/node/src/types/account.rs b/crates/node/src/types/account.rs new file mode 100644 index 00000000..3c58d6fb --- /dev/null +++ b/crates/node/src/types/account.rs @@ -0,0 +1,9 @@ +use libsecp256k1::PublicKey; +use num_bigint::BigInt; + +#[allow(dead_code)] +#[derive(Debug, Clone)] +pub struct Account { + public_key: PublicKey, + balance: BigInt, +} diff --git a/crates/node/src/types/deployment.rs b/crates/node/src/types/deployment.rs new file mode 100644 index 00000000..18ac08b2 --- /dev/null +++ b/crates/node/src/types/deployment.rs @@ -0,0 +1,10 @@ +use serde::{Deserialize, Serialize}; + +use super::Program; + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct Deployment { + pub prover: Program, + pub verifier: Program, + pub signature: String, +} diff --git a/crates/node/src/types/hash.rs b/crates/node/src/types/hash.rs new file mode 100644 index 00000000..a0d78922 --- /dev/null +++ b/crates/node/src/types/hash.rs @@ -0,0 +1,141 @@ +use libsecp256k1::Message; +use rand::Rng; +use serde::{de, Deserialize, Serialize}; +use sqlx::{self, Decode, Encode, Postgres, Type}; +use std::fmt; + +const HASH_SIZE: usize = 32; + +#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq, Serialize, Deserialize)] +pub struct Hash([u8; HASH_SIZE]); + +impl Hash { + pub fn to_vec(&self) -> Vec { + self.0.to_vec() + } + + pub fn random(rng: &mut R) -> Hash { + let mut bs = [0u8; HASH_SIZE]; + rng.fill_bytes(&mut bs); + Hash(bs) + } +} + +impl AsRef for Hash { + fn as_ref(&self) -> &Hash { + self + } +} + +impl fmt::Display for Hash { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", hex::encode(self)) + } +} + +impl From<&blake3::Hash> for Hash { + fn from(value: &blake3::Hash) -> Self { + Hash(*value.as_bytes()) + } +} + +impl From<&str> for Hash { + fn from(value: &str) -> Self { + Hash( + hex::decode(value) + .expect("invalid value") + .try_into() + .unwrap(), + ) + } +} + +impl From for Hash { + fn from(value: String) -> Self { + Self::from(value.as_str()) + } +} + +impl From<&[u8]> for Hash { + fn from(value: &[u8]) -> Self { + Self(value.try_into().expect("copy")) + } +} + +impl From for Message { + fn from(value: Hash) -> Self { + // This function requires changes if HASH_SIZE changes. Add guard for it. + const _: [(); 0 - { HASH_SIZE != 32 } as usize] = []; + + let x = &value.0; + Message(libsecp256k1::curve::Scalar([ + u32::from_be_bytes([x[0], x[1], x[2], x[3]]), + u32::from_be_bytes([x[4], x[5], x[6], x[7]]), + u32::from_be_bytes([x[8], x[9], x[10], x[11]]), + u32::from_be_bytes([x[12], x[13], x[14], x[15]]), + u32::from_be_bytes([x[16], x[17], x[18], x[19]]), + u32::from_be_bytes([x[20], x[21], x[22], x[23]]), + u32::from_be_bytes([x[24], x[25], x[26], x[27]]), + u32::from_be_bytes([x[28], x[29], x[30], x[31]]), + ])) + } +} + +impl AsRef<[u8]> for Hash { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +impl<'q> Decode<'q, Postgres> for Hash { + fn decode( + value: >::ValueRef, + ) -> Result { + let str_value = >::decode(value)?; + Ok(Hash::from(str_value)) + } +} + +impl<'q> Encode<'q, Postgres> for Hash { + fn encode_by_ref( + &self, + buf: &mut >::ArgumentBuffer, + ) -> sqlx::encode::IsNull { + let str_value = self.to_string(); + >::encode(str_value, buf) + } +} + +impl Type for Hash { + fn type_info() -> ::TypeInfo { + >::type_info() + } + + fn compatible(ty: &::TypeInfo) -> bool { + >::compatible(ty) + } +} + +pub fn deserialize_hash_from_json<'de, D>(deserializer: D) -> Result +where + D: de::Deserializer<'de>, +{ + struct JsonStringVisitor; + + impl<'de> de::Visitor<'de> for JsonStringVisitor { + type Value = Hash; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a hex encoded Hash") + } + + fn visit_str(self, v: &str) -> Result + where + E: de::Error, + { + Ok(Hash::from(v)) + } + } + + deserializer.deserialize_any(JsonStringVisitor) +} diff --git a/crates/node/src/types/key_capsule.rs b/crates/node/src/types/key_capsule.rs new file mode 100644 index 00000000..aeefb3aa --- /dev/null +++ b/crates/node/src/types/key_capsule.rs @@ -0,0 +1,135 @@ +use std::error::Error; + +use libsecp256k1::{PublicKey, SecretKey}; +use serde::{Deserialize, Serialize}; + +#[derive(Default, Serialize, Deserialize)] +pub struct KeyCapsule { + pub msg: Vec, + pub keys: Vec<(Vec, Vec)>, +} + +impl KeyCapsule { + pub fn new(msg: &[u8], recipients: &[PublicKey]) -> Self { + // Generate fresh keypair for new capsule. + let (sk, pk) = ecies::utils::generate_keypair(); + let (sk, pk) = (&sk.serialize(), &pk.serialize()); + + // Encrypt the ephemeral key for each recipient. + let mut keys: Vec<(Vec, Vec)> = vec![]; + for recipient in recipients { + let key = ecies::encrypt(recipient.serialize().as_slice(), sk).unwrap(); + keys.push((recipient.serialize().to_vec(), key)); + } + + KeyCapsule { + // Encrypt the message for ephemeral key. + msg: ecies::encrypt(pk, msg).unwrap(), + keys, + } + } + + pub fn decrypt(&self, secret_key: &SecretKey) -> Result, Box> { + let pk = &PublicKey::from_secret_key(secret_key).serialize(); + let sk = &secret_key.serialize(); + + match self.keys.iter().find(|(recipient, _)| recipient == pk) { + Some((_, key)) => { + let key = ecies::decrypt(sk, key)?; + let msg = ecies::decrypt(&key, self.msg.as_slice())?; + Ok(msg.to_vec()) + } + None => Err(String::from("recipient not present").into()), + } + } + + pub fn as_bytes(&self) -> Vec { + bincode::serialize(self).unwrap() + } +} + +impl From> for KeyCapsule { + fn from(value: Vec) -> Self { + KeyCapsule::from(value.as_slice()) + } +} + +impl From<&[u8]> for KeyCapsule { + fn from(value: &[u8]) -> Self { + bincode::deserialize(value).unwrap() + } +} + +#[cfg(test)] +mod tests { + + use rand::{rngs::StdRng, SeedableRng}; + + use super::*; + + #[test] + fn test_no_recipient() { + let msg = "Hello, World!".as_bytes(); + let capsule = KeyCapsule::new(msg, &[]); + + assert_ne!(msg, capsule.msg); + assert!(capsule.decrypt(&SecretKey::default()).is_err()); + } + + #[test] + fn test_one_recipient() { + let sk = SecretKey::random(&mut StdRng::from_entropy()); + let pk = PublicKey::from_secret_key(&sk); + let msg = "Hello, World!".as_bytes(); + let capsule = KeyCapsule::new(msg, &[pk]); + + assert_ne!(msg, capsule.msg); + assert_eq!(msg, capsule.decrypt(&sk).unwrap()); + } + + #[test] + fn test_two_recipients() { + let sk1 = SecretKey::random(&mut StdRng::from_entropy()); + let pk1 = PublicKey::from_secret_key(&sk1); + let sk2 = SecretKey::random(&mut StdRng::from_entropy()); + let pk2 = PublicKey::from_secret_key(&sk2); + + let msg = "Hello, World!".as_bytes(); + let capsule = KeyCapsule::new(msg, &[pk1, pk2]); + + assert_ne!(msg, capsule.msg); + assert_eq!(msg, capsule.decrypt(&sk1).unwrap()); + assert_eq!(msg, capsule.decrypt(&sk2).unwrap()); + } + + #[test] + fn test_not_in_recipients() { + let sk1 = SecretKey::random(&mut StdRng::from_entropy()); + let pk1 = PublicKey::from_secret_key(&sk1); + let sk2 = SecretKey::random(&mut StdRng::from_entropy()); + + let msg = "Hello, World!".as_bytes(); + let capsule = KeyCapsule::new(msg, &[pk1]); + + assert_ne!(msg, capsule.msg); + assert_eq!(msg, capsule.decrypt(&sk1).unwrap()); + assert!(capsule.decrypt(&sk2).is_err()); + } + + #[test] + fn test_serialization() { + let sk1 = SecretKey::random(&mut StdRng::from_entropy()); + let pk1 = PublicKey::from_secret_key(&sk1); + let sk2 = SecretKey::random(&mut StdRng::from_entropy()); + let pk2 = PublicKey::from_secret_key(&sk2); + + let msg = "Hello, World!".as_bytes(); + let capsule = KeyCapsule::new(msg, &[pk1, pk2]); + + let bs = capsule.as_bytes(); + let kc = KeyCapsule::from(bs); + + assert_eq!(capsule.msg, kc.msg); + assert_eq!(capsule.keys, kc.keys); + } +} diff --git a/crates/node/src/types/mod.rs b/crates/node/src/types/mod.rs new file mode 100644 index 00000000..ba477a5b --- /dev/null +++ b/crates/node/src/types/mod.rs @@ -0,0 +1,19 @@ +mod account; +mod deployment; +mod hash; +mod key_capsule; +pub mod program; +pub mod rpc; +mod signature; +mod task; +pub mod transaction; + +#[allow(unused_imports)] +pub use deployment::Deployment; +pub use hash::Hash; +pub use key_capsule::KeyCapsule; +pub use program::Program; +pub use signature::Signature; +#[allow(unused_imports)] +pub use task::{File, Task, TaskId, TaskKind, TaskResult, TaskState}; +pub use transaction::{Transaction, TransactionTree}; diff --git a/crates/node/src/types/program.rs b/crates/node/src/types/program.rs new file mode 100644 index 00000000..3cb7fc04 --- /dev/null +++ b/crates/node/src/types/program.rs @@ -0,0 +1,60 @@ +use serde::{Deserialize, Serialize}; + +use super::{ + hash::{deserialize_hash_from_json, Hash}, + transaction, +}; + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct ResourceRequest { + pub mem: u64, + pub cpus: u64, + pub gpus: u64, +} + +impl Default for ResourceRequest { + fn default() -> Self { + Self { + mem: 2048, + cpus: 2, + gpus: 0, + } + } +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize, sqlx::FromRow)] +pub struct Program { + #[serde(deserialize_with = "deserialize_hash_from_json")] + pub hash: Hash, + pub name: String, + pub image_file_name: String, + pub image_file_url: String, + pub image_file_checksum: String, + #[sqlx(skip)] + pub limits: ResourceRequest, +} + +impl From for Program { + fn from(value: transaction::ProgramMetadata) -> Self { + Program { + hash: value.hash, + name: value.name, + image_file_name: value.image_file_name, + image_file_url: value.image_file_url, + image_file_checksum: value.image_file_checksum, + limits: Default::default(), + } + } +} + +impl From for transaction::ProgramMetadata { + fn from(value: Program) -> Self { + transaction::ProgramMetadata { + name: value.name, + hash: value.hash, + image_file_name: value.image_file_name, + image_file_url: value.image_file_url, + image_file_checksum: value.image_file_checksum, + } + } +} diff --git a/crates/node/src/types/rpc.rs b/crates/node/src/types/rpc.rs new file mode 100644 index 00000000..6f2295da --- /dev/null +++ b/crates/node/src/types/rpc.rs @@ -0,0 +1,40 @@ +use std::borrow::Cow; + +use jsonrpsee::IntoResponse; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +#[allow(clippy::enum_variant_names)] +#[derive(Clone, Error, Debug, Serialize, Deserialize)] +pub enum RpcError { + #[error("not found: {0}")] + NotFound(String), + + #[error("invalid request: {0}")] + InvalidRequest(String), +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum RpcResponse { + Ok(T), + Err(RpcError), +} + +impl RpcResponse { + pub fn unwrap(&self) -> T { + if let RpcResponse::Ok(v) = self { + v.clone() + } else { + // TODO: Consider better debug print here? + panic!("unwrap"); + } + } +} + +impl IntoResponse for RpcResponse { + type Output = RpcResponse; + + fn into_response(self) -> jsonrpsee::types::ResponsePayload<'static, Self::Output> { + jsonrpsee::types::ResponsePayload::Result(Cow::Owned(self)) + } +} diff --git a/crates/node/src/types/signature.rs b/crates/node/src/types/signature.rs new file mode 100644 index 00000000..df597d5f --- /dev/null +++ b/crates/node/src/types/signature.rs @@ -0,0 +1,136 @@ +use serde::{de, Deserialize, Serialize}; +use sqlx::{self, Decode, Encode, Postgres, Type}; +use std::fmt; +use thiserror::Error; + +#[allow(clippy::enum_variant_names)] +#[derive(Error, Debug)] +pub enum SignatureError { + #[error("signature parse error: {0}")] + ParseError(String), +} + +/// Scalar is mirror of libsecp256k1::curve::Scalar; replicated for control +/// over its interface. +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct Scalar(pub [u32; 8]); + +impl From for Scalar { + fn from(value: libsecp256k1::curve::Scalar) -> Self { + Self(value.0) + } +} + +impl From for libsecp256k1::curve::Scalar { + fn from(value: Scalar) -> Self { + libsecp256k1::curve::Scalar(value.0) + } +} + +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] +pub struct Signature { + pub r: Scalar, + pub s: Scalar, +} + +impl fmt::Display for Signature { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + hex::encode(Into::::into(*self).serialize()) + ) + } +} + +impl From for Signature { + fn from(value: String) -> Self { + Self::try_from(value.as_str()).expect("from string") + } +} + +impl TryFrom<&str> for Signature { + type Error = SignatureError; + + fn try_from(value: &str) -> Result { + let bs = hex::decode(value).map_err(|e| SignatureError::ParseError(e.to_string()))?; + let bs: [u8; 64] = bs + .try_into() + .map_err(|_| SignatureError::ParseError("byte array length".to_string()))?; + let sig = libsecp256k1::Signature::parse_standard(&bs) + .map_err(|e| SignatureError::ParseError(e.to_string()))?; + Ok(From::::from(sig)) + } +} + +impl From for Signature { + fn from(value: libsecp256k1::Signature) -> Self { + Signature { + r: value.r.into(), + s: value.s.into(), + } + } +} + +impl From for libsecp256k1::Signature { + fn from(value: Signature) -> Self { + libsecp256k1::Signature { + r: value.r.into(), + s: value.s.into(), + } + } +} + +impl<'q> Decode<'q, Postgres> for Signature { + fn decode( + value: >::ValueRef, + ) -> Result { + let str_value = >::decode(value)?; + Ok(Signature::from(str_value)) + } +} + +impl<'q> Encode<'q, Postgres> for Signature { + fn encode_by_ref( + &self, + buf: &mut >::ArgumentBuffer, + ) -> sqlx::encode::IsNull { + let str_value = self.to_string(); + >::encode(str_value, buf) + } +} + +impl Type for Signature { + fn type_info() -> ::TypeInfo { + >::type_info() + } + + fn compatible(ty: &::TypeInfo) -> bool { + >::compatible(ty) + } +} + +#[allow(dead_code)] +pub fn deserialize_hash_from_json<'de, D>(deserializer: D) -> Result +where + D: de::Deserializer<'de>, +{ + struct JsonStringVisitor; + + impl<'de> de::Visitor<'de> for JsonStringVisitor { + type Value = Signature; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a hex encoded Signature") + } + + fn visit_str(self, v: &str) -> Result + where + E: de::Error, + { + Signature::try_from(v).map_err(E::custom) + } + } + + deserializer.deserialize_any(JsonStringVisitor) +} diff --git a/crates/node/src/types/task.rs b/crates/node/src/types/task.rs new file mode 100644 index 00000000..8b06d93e --- /dev/null +++ b/crates/node/src/types/task.rs @@ -0,0 +1,54 @@ +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +use super::hash::{deserialize_hash_from_json, Hash}; + +pub type TaskId = Uuid; + +#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize, sqlx::Type)] +#[sqlx(type_name = "task_state", rename_all = "lowercase")] +pub enum TaskState { + #[default] + New, + Pending, + Running, + Ready, + Failed, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize, sqlx::Type)] +#[sqlx(type_name = "task_kind", rename_all = "lowercase")] +pub enum TaskKind { + Proof, + Verification, + PoW, + #[default] + Nop, +} + +#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize, sqlx::FromRow)] +pub struct File { + #[serde(skip_serializing, skip_deserializing)] + pub tx: Hash, + pub name: String, + pub url: String, +} + +#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize, sqlx::FromRow)] +pub struct Task { + pub id: TaskId, + pub tx: Hash, + pub name: String, + pub kind: TaskKind, + #[serde(deserialize_with = "deserialize_hash_from_json")] + pub program_id: Hash, + pub args: Vec, + #[sqlx(skip)] + pub files: Vec, + #[serde(skip_deserializing)] + pub serial: i32, + #[serde(skip_deserializing)] + pub state: TaskState, +} + +pub struct TaskResult {} diff --git a/crates/node/src/types/transaction.rs b/crates/node/src/types/transaction.rs new file mode 100644 index 00000000..52e55b61 --- /dev/null +++ b/crates/node/src/types/transaction.rs @@ -0,0 +1,395 @@ +use std::{collections::HashSet, sync::Arc}; + +use super::hash::Hash; +use super::signature::Signature; +use eyre::Result; +use libsecp256k1::{sign, verify, Message, PublicKey, SecretKey}; +use num_bigint::BigInt; +use serde::{Deserialize, Serialize}; +use sha3::{Digest, Sha3_256}; +use thiserror::Error; + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +pub enum TransactionTree { + Root { + children: Vec>, + hash: Hash, + }, + Node { + parent: Arc, + children: Vec>, + hash: Hash, + }, + Leaf { + parent: Arc, + hash: Hash, + }, +} + +impl Default for TransactionTree { + fn default() -> Self { + TransactionTree::Root { + children: vec![], + hash: Hash::default(), + } + } +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)] +pub struct ProgramMetadata { + pub name: String, + /// Program hash. Used to identify `Program`. + pub hash: Hash, + pub image_file_name: String, + pub image_file_url: String, + // Image file checksum is BLAKE3 hash of the file. + pub image_file_checksum: String, +} + +impl ProgramMetadata { + pub fn update_hash(&mut self) { + let mut hasher = Sha3_256::new(); + hasher.update(self.name.as_bytes()); + hasher.update(self.image_file_name.as_bytes()); + hasher.update(self.image_file_url.as_bytes()); + hasher.update(self.image_file_checksum.as_bytes()); + self.hash = hasher.finalize()[0..32].into(); + } + + pub fn serialize_into(&self, buf: &mut Vec) { + buf.append(&mut self.name.as_bytes().to_vec()); + buf.append(&mut self.hash.to_vec()); + buf.append(&mut self.image_file_name.as_bytes().to_vec()); + buf.append(&mut self.image_file_url.as_bytes().to_vec()); + buf.append(&mut self.image_file_checksum.as_bytes().to_vec()); + } +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +pub enum ProgramData { + Input { + file_name: String, + file_url: String, + checksum: String, + }, + Output { + source_program: Hash, + file_name: String, + }, +} + +impl ProgramData { + fn serialize_into(&self, buf: &mut Vec) { + match self { + ProgramData::Input { + file_name, + file_url, + checksum, + } => { + buf.append(&mut file_name.as_bytes().to_vec()); + buf.append(&mut file_url.as_bytes().to_vec()); + buf.append(&mut checksum.as_bytes().to_vec()); + } + ProgramData::Output { + source_program, + file_name, + } => { + buf.append(&mut source_program.to_vec()); + buf.append(&mut file_name.as_bytes().to_vec()); + } + } + } +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)] +pub struct WorkflowStep { + pub program: Hash, + pub args: Vec, + pub inputs: Vec, +} + +impl WorkflowStep { + fn serialize_into(&self, buf: &mut Vec) { + buf.append(&mut self.program.to_vec()); + self.args + .iter() + .for_each(|e| buf.append(&mut e.as_bytes().to_vec())); + self.inputs.iter().for_each(|e| e.serialize_into(buf)); + } +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)] +pub struct Workflow { + pub steps: Vec, +} + +impl Workflow { + fn serialize_into(&self, buf: &mut Vec) { + self.steps.iter().for_each(|e| e.serialize_into(buf)); + } +} + +#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)] +pub enum Payload { + #[default] + Empty, + Transfer { + to: PublicKey, + value: BigInt, + }, + Stake { + value: BigInt, + }, + Unstake { + value: BigInt, + }, + Deploy { + name: String, + prover: ProgramMetadata, + verifier: ProgramMetadata, + }, + Run { + workflow: Workflow, + }, + Proof { + parent: Hash, + prover: Hash, + proof: Vec, + }, + ProofKey { + parent: Hash, + key: Vec, + }, + Verification { + parent: Hash, + verifier: Hash, + verification: Vec, + }, + Cancel { + parent: Hash, + }, +} + +impl Payload { + fn serialize_into(&self, buf: &mut Vec) { + match self { + Payload::Empty => {} + Payload::Transfer { to, value } => { + buf.append(&mut to.serialize().to_vec()); + buf.append(&mut value.to_signed_bytes_be()); + } + Payload::Stake { value } => { + buf.append(&mut value.to_signed_bytes_be()); + } + Payload::Unstake { value } => { + buf.append(&mut value.to_signed_bytes_be()); + } + Payload::Deploy { + name, + prover, + verifier, + } => { + buf.append(&mut name.as_bytes().to_vec()); + prover.serialize_into(buf); + verifier.serialize_into(buf); + } + Payload::Run { workflow } => { + workflow.serialize_into(buf); + } + Payload::Proof { + parent, + prover, + proof, + } => { + buf.append(&mut parent.to_vec()); + buf.append(&mut prover.to_vec()); + buf.append(proof.clone().as_mut()); + } + Payload::ProofKey { parent, key } => { + buf.append(&mut parent.to_vec()); + buf.append(key.clone().as_mut()); + } + Payload::Verification { + parent, + verifier, + verification, + } => { + buf.append(&mut parent.to_vec()); + buf.append(&mut verifier.to_vec()); + buf.append(verification.clone().as_mut()); + } + Payload::Cancel { parent } => { + buf.append(&mut parent.to_vec()); + } + } + } +} + +#[allow(clippy::enum_variant_names)] +#[derive(Error, Debug)] +pub enum TransactionError { + #[error("validation: {0}")] + Validation(String), +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +pub struct Transaction { + pub author: PublicKey, + pub hash: Hash, + pub payload: Payload, + pub nonce: u64, + pub signature: Signature, + #[serde(skip_serializing, skip_deserializing)] + pub propagated: bool, + #[serde(skip_serializing, skip_deserializing)] + pub executed: bool, +} + +impl Default for Transaction { + fn default() -> Self { + Self { + author: PublicKey::from_secret_key(&SecretKey::default()), + hash: Hash::default(), + payload: Payload::default(), + nonce: 0, + signature: Signature::default(), + propagated: false, + executed: false, + } + } +} + +impl Transaction { + pub fn new(payload: Payload, signing_key: &SecretKey) -> Self { + let author = PublicKey::from_secret_key(signing_key); + + let mut tx = Self { + author, + hash: Hash::default(), + payload, + nonce: 0, + signature: Signature::default(), + propagated: false, + executed: false, + }; + + tx.sign(signing_key); + + tx + } + + pub fn sign(&mut self, key: &SecretKey) { + // Refresh transaction hash before signing. + self.hash = self.compute_hash(); + let msg: Message = self.hash.into(); + let (sig, _) = sign(&msg, key); + self.signature = sig.into(); + } + + pub fn verify(&self) -> bool { + let hash = self.compute_hash(); + let msg: Message = hash.into(); + verify(&msg, &self.signature.into(), &self.author) + } + + pub fn compute_hash(&self) -> Hash { + let mut hasher = Sha3_256::new(); + let mut buf = vec![]; + self.payload.serialize_into(&mut buf); + hasher.update(buf); + hasher.update(self.nonce.to_be_bytes()); + (&hasher.finalize()[0..32]).into() + } + + pub fn validate(&self) -> Result<()> { + if let Payload::Run { ref workflow } = self.payload { + let mut programs = HashSet::new(); + for step in &workflow.steps { + if !programs.insert(step.program) { + return Err(TransactionError::Validation(format!( + "multiple programs in workflow: {}", + &step.program + )) + .into()); + } + } + } + + if !self.verify() { + return Err(TransactionError::Validation(String::from( + "signature verification failed", + )) + .into()); + } + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + + use rand::{rngs::StdRng, SeedableRng}; + + use super::*; + + #[test] + fn test_sign_and_verify_tx() { + let sk = SecretKey::random(&mut StdRng::from_entropy()); + + let tx = Transaction::new(Payload::Empty, &sk); + assert!(tx.verify()); + } + + #[test] + fn test_verify_fails_on_tamper() { + let sk = SecretKey::random(&mut StdRng::from_entropy()); + + let mut tx = Transaction::new(Payload::Empty, &sk); + + // Change nonce after signing. + tx.nonce += 1; + + // Verify must return false. + assert!(!tx.verify()); + } + + #[test] + fn test_tx_validate_ensures_unique_programs() { + let prover = WorkflowStep::default(); + let verifier = WorkflowStep::default(); + + let workflow = Workflow { + // Both steps are `Default::default()` -> same program hash -> invalid. + steps: vec![prover, verifier], + }; + + let sk = SecretKey::random(&mut StdRng::from_entropy()); + let tx = Transaction { + author: PublicKey::from_secret_key(&sk), + hash: Hash::default(), + payload: Payload::Run { workflow }, + nonce: 0, + signature: Signature::default(), + propagated: false, + executed: false, + }; + + assert!(tx.validate().is_err()); + } + + #[test] + fn test_tx_validations_verifies_signature() { + let tx = Transaction { + author: PublicKey::from_secret_key(&SecretKey::default()), + hash: Hash::default(), + payload: Payload::Empty, + nonce: 0, + signature: Signature::default(), + propagated: false, + executed: false, + }; + + assert!(tx.validate().is_err()); + } +} diff --git a/crates/node/src/vmm/mod.rs b/crates/node/src/vmm/mod.rs new file mode 100644 index 00000000..a76a4da8 --- /dev/null +++ b/crates/node/src/vmm/mod.rs @@ -0,0 +1,33 @@ +use std::any::Any; +use std::path::Path; +use std::sync::Arc; + +use crate::types::{program::ResourceRequest, Program}; +use async_trait::async_trait; +use eyre::Result; + +pub mod qemu; +pub mod vm_server; + +pub trait VMId: Send + Sync + std::fmt::Display { + fn as_any(&self) -> &dyn Any; + fn eq(&self, x: Arc) -> bool; +} + +pub struct VMHandle { + vm_id: Arc, +} + +impl VMHandle { + pub fn vm_id(&self) -> Arc { + self.vm_id.clone() + } +} + +#[async_trait] +pub trait Provider: Send + Sync { + async fn start_vm(&mut self, program: Program, req: ResourceRequest) -> Result; + fn stop_vm(&mut self, vm: VMHandle) -> Result<()>; + + fn prepare_image(&mut self, program: Program, image: &Path) -> Result<()>; +} diff --git a/crates/node/src/vmm/qemu.rs b/crates/node/src/vmm/qemu.rs new file mode 100644 index 00000000..3a81100f --- /dev/null +++ b/crates/node/src/vmm/qemu.rs @@ -0,0 +1,510 @@ +use std::{ + any::Any, + collections::HashMap, + fs::File, + io::Read, + path::Path, + process::{Child, Command, Stdio}, + sync::Arc, + time::Duration, +}; + +use async_trait::async_trait; +use eyre::Result; +use qapi::{ + futures::{QapiStream, QmpStreamTokio}, + qmp, + qmp::StatusInfo, +}; +use rand::{self, distributions::Alphanumeric, Rng}; +use serde_json::json; +use tokio::{ + io::{ReadHalf, WriteHalf}, + net::{TcpStream, ToSocketAddrs}, + time::sleep, +}; +use tokio_vsock::{Incoming, VsockConnectInfo, VsockListener}; +use tonic::Extensions; +use vsock::get_local_cid; + +use super::{vm_server::ProgramRegistry, Provider, VMHandle, VMId}; +use crate::{ + cli::Config, + nanos, + types::{Hash, Program}, + vmm::ResourceRequest, +}; + +const IMAGES_DIR: &str = "images"; + +impl VMId for u32 { + fn as_any(&self) -> &dyn Any { + self + } + + fn eq(&self, x: Arc) -> bool { + *self == u32_from_any(x.as_any()) + } +} + +fn u32_from_any(x: &dyn Any) -> u32 { + match x.downcast_ref::() { + Some(cid) => *cid, + None => panic!("incompatible VMId type"), + } +} + +pub struct QEMUVMHandle { + child: Option, + cid: u32, + program_id: Hash, + workspace_volume_label: String, + //qmp: Arc>, +} + +pub struct Qemu { + config: Arc, + cid_allocations: Vec, + vm_registry: HashMap, +} + +impl Qemu { + pub fn new(config: Arc) -> Self { + Qemu { + config, + cid_allocations: vec![], + vm_registry: HashMap::new(), + } + } + + fn allocate_cid(&mut self) -> u32 { + loop { + let cid = rand::random::(); + + if cid < 3 { + // CIDs 0, 1 and 2 are reserved. + continue; + } + + if self.cid_allocations.iter().any(|&x| x == cid) { + // Generated CID found from existing allocations. + continue; + }; + + self.cid_allocations.push(cid); + return cid; + } + } + + fn release_cid(&mut self, cid: u32) { + if let Some(idx) = self.cid_allocations.iter().position(|&x| x == cid) { + self.cid_allocations.remove(idx); + self.vm_registry.remove(&cid); + } + } + + pub fn vm_server_listener(&self) -> Result { + let cid = match get_local_cid() { + Ok(cid) => cid, + Err(ref e) if e.kind() == std::io::ErrorKind::NotFound => { + eprintln!( + "error: /dev/vsock not found; ensure 'vhost_vsock' kernel module is loaded" + ); + std::process::exit(-1); + } + Err(e) => panic!("can't get local VSOCK CID: {}", e), + }; + let listener = VsockListener::bind(cid, self.config.vsock_listen_port).expect("bind"); + Ok(listener.incoming()) + } +} + +impl ProgramRegistry for Qemu { + fn find_by_req(&mut self, extensions: &Extensions) -> Option<(Hash, Arc)> { + let conn_info = extensions.get::().unwrap(); + match conn_info.peer_addr() { + Some(addr) => { + self.vm_registry + .get(&addr.cid()) + .map(|handle| -> (Hash, Arc) { + (handle.program_id, Arc::new(addr.cid())) + }) + } + None => None, + } + } +} + +#[async_trait] +impl Provider for Qemu { + async fn start_vm(&mut self, program: Program, req: ResourceRequest) -> Result { + // TODO: + // - Builder to construct QEMU flags + // - Handle GPUs + + let img_file = Path::new(&self.config.data_directory) + .join(IMAGES_DIR) + .join(program.hash.to_string()) + .join(program.image_file_name); + + let workspace_volume_label: String = rand::thread_rng() + .sample_iter(&Alphanumeric) + .take(16) + .map(char::from) + .collect::() + .to_lowercase(); + + // XXX: This isn't async and will call out to `ops` for now. + let workspace_file = nanos::volume::create(&workspace_volume_label, "2g")?.into_os_string(); + let workspace_file = workspace_file.to_str().expect("workspace volume path"); + + let cpus = req.cpus; + let mem_req = req.mem; + let cid = self.allocate_cid(); + + // Random unprivileged port computed from allocated CID. + // If there is collision with the port, QEMU startup will fail and + // watchdog will reap it. + let qmp_port = (cid % 64512) + 1024; + + let program_id = program.hash; + let qemu_vm_handle = QEMUVMHandle { + child: None, + cid, + program_id, + workspace_volume_label, + //qmp: Arc::new(Mutex::new(qmp)), + }; + + // Must VM must be registered before start, because when the VM starts, + // the program in it starts immediately and queries for task, which + // requires the VM to be registered for identification. + self.vm_registry.insert(cid, qemu_vm_handle); + + // Update the child process field. + let qemu_vm_handle = &mut self.vm_registry.get_mut(&cid).unwrap(); + let mut cmd = Command::new("/usr/bin/qemu-system-x86_64"); + + cmd.args(["-machine", "q35"]) + .args([ + "-device", + "pcie-root-port,port=0x10,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x3", + ]) + .args([ + "-device", + "pcie-root-port,port=0x11,chassis=2,id=pci.2,bus=pcie.0,addr=0x3.0x1", + ]) + .args([ + "-device", + "pcie-root-port,port=0x12,chassis=3,id=pci.3,bus=pcie.0,addr=0x3.0x2", + ]) + // Register 2 hard drives via SCSI + .args(["-device", "virtio-scsi-pci,bus=pci.2,addr=0x0,id=scsi0"]) + .args(["-device", "scsi-hd,bus=scsi0.0,drive=hd0"]) + //.args(["-device", "scsi-hd,bus=scsi0.0,drive=hd1"]) + .args(["-vga", "none"]) + // CPUS + .args(["-smp", &cpus.to_string()]) + .args(["-device", "isa-debug-exit"]) + // MEMORY + .args(["-m", &format!("{mem_req}M")]) + .args(["-device", "virtio-rng-pci"]) + .args(["-machine", "accel=kvm:tcg"]) + .args(["-cpu", "host"]) + //.arg("-no-reboot") + .arg("-no-shutdown") + .args(["-cpu", "max"]) + // IMAGE FILE + .args([ + "-drive", + &format!( + "file={},format=raw,if=none,id=hd0,readonly=on", + &img_file.into_os_string().into_string().unwrap(), + ), + ]) + // WORKSPACE FILE + /* + .args([ + "-drive", + &format!("file={},format=raw,if=none,id=hd1", &workspace_file), + ])*/ + // NETWORKING + .args([ + "-device", + "virtio-net,bus=pci.3,addr=0x0,netdev=n0,mac=8e:97:45:7c:fb:3d", + ]) + .args(["-netdev", "user,id=n0"]) + .args(["-display", "none"]) + .args(["-serial", "stdio"]) + // VSOCK + .args(["-device", &format!("vhost-vsock-pci,guest-cid={cid}")]) + // QMP + .args(["-qmp", &format!("tcp:localhost:{qmp_port},server")]); + + // TODO: When GPU argument handling is refactored, this should be fixed as well. + if self.config.gpu_devices.is_some() { + cmd.args(parse_gpu_devices_into_qemu_params( + self.config.gpu_devices.as_ref().unwrap(), + )); + } + + // Setup stdout & stderr log to VM execution. + { + let log_dir_path = Path::new(&self.config.log_directory).join(program.hash.to_string()); + std::fs::create_dir_all(&log_dir_path)?; + let stdout = File::options() + .create(true) + .append(true) + .open(Path::new(&log_dir_path).join("stdout.log"))?; + let stderr = File::options() + .create(true) + .append(true) + .open(Path::new(&log_dir_path).join("stderr.log"))?; + cmd.stdout(Stdio::from(stdout)); + cmd.stderr(Stdio::from(stderr)); + } + + tracing::info!("starting QEMU. args:\n{:#?}\n", cmd.get_args()); + + qemu_vm_handle.child = Some(cmd.spawn().expect("failed to start VM")); + + sleep(Duration::from_millis(300)).await; + let mut qmp_client = Qmp::new(format!("localhost:{qmp_port}")).await?; + + // Attach the workspace volume. + let err_add = qmp_client.blockdev_add("workspace", workspace_file).await; + if err_add.is_err() { + tracing::error!("blockdev_add failed: {:?}", err_add); + } + //sleep(Duration::from_millis(100)).await; + let err_add = qmp_client.device_add("workspace", 1).await; + if err_add.is_err() { + tracing::error!("device_add failed: {:?}", err_add); + } + //sleep(Duration::from_millis(100)).await; + qmp_client.system_reset().await?; + //sleep(Duration::from_millis(100)).await; + + /* + tokio::spawn({ + let mut qemu_vm_handle = qemu_vm_handle.clone(); + async move { + watchdog(&mut qemu_vm_handle).await; + } + }); + */ + + //watchdog(&mut qemu_vm_handle); + + /* + for _ in 1..5 { + if let Ok(status) = qmp_client.query_status().await { + tracing::debug!("VCPU status: {:#?}", status); + let stdout = qemu_vm_handle.child.as_mut().unwrap().stdout.as_mut(); + if stdout.is_some() { + dump_read(&mut stdout.unwrap()); + } + /* + dump_read( + &mut qemu_vm_handle + .child + .as_mut() + .unwrap() + .stderr + .as_mut() + .unwrap(), + ); + */ + } else { + tracing::error!("VM died"); + let stdout = qemu_vm_handle.child.as_mut().unwrap().stdout.as_mut(); + if stdout.is_some() { + dump_read(&mut stdout.unwrap()); + } + + let stderr = qemu_vm_handle.child.as_mut().unwrap().stderr.as_mut(); + if stderr.is_some() { + dump_read(&mut stderr.unwrap()); + } + + qemu_vm_handle.child.as_mut().unwrap().wait().unwrap(); + } + + sleep(Duration::from_secs(3)).await; + } + */ + + Ok(VMHandle { + vm_id: Arc::new(cid), + }) + } + + fn stop_vm(&mut self, vm: VMHandle) -> Result<()> { + if let Some(qemu_vm_handle) = self.vm_registry.get_mut(&u32_from_any(vm.vm_id.as_any())) { + drop(vm); + qemu_vm_handle + .child + .as_mut() + .unwrap() + .kill() + .expect("failed to kill VM"); + + // GC ephemeral workspace volume. + // XXX: This isn't async and will call out to `ops`. + nanos::volume::delete(&qemu_vm_handle.workspace_volume_label)?; + + let cid = qemu_vm_handle.cid; + self.release_cid(cid); + + Ok(()) + } else { + todo!("create error type for VM NOT FOUND"); + } + } + + fn prepare_image(&mut self, _program: Program, _image: &std::path::Path) -> Result<()> { + // QEMU provider doesn't need to do anything for the image. + // It uses the local file as-is. + Ok(()) + } +} + +struct Qmp { + stream: QapiStream>, QmpStreamTokio>>, +} + +impl Qmp { + async fn new(addr: impl ToSocketAddrs) -> Result { + let stream = QmpStreamTokio::open_tcp(addr).await?; + tracing::debug!("QMP: {:#?}", stream.capabilities); + let stream = stream.negotiate().await?; + + Ok(Qmp { stream }) + } + + async fn query_status(&mut self) -> Result { + self.stream + .execute(qmp::query_status {}) + .await + .map_err(|e| e.into()) + } + + async fn blockdev_add(&mut self, node_name: &str, device_file: &str) -> Result<()> { + self.stream + .execute(qmp::blockdev_add(qmp::BlockdevOptions::raw { + base: qmp::BlockdevOptionsBase { + detect_zeroes: None, + cache: None, + discard: None, + force_share: None, + auto_read_only: None, + node_name: Some(node_name.to_string()), + read_only: None, + }, + raw: qmp::BlockdevOptionsRaw { + base: qmp::BlockdevOptionsGenericFormat { + file: qmp::BlockdevRef::definition(Box::new(qmp::BlockdevOptions::file { + base: qmp::BlockdevOptionsBase { + auto_read_only: None, + cache: None, + detect_zeroes: None, + discard: None, + force_share: None, + node_name: None, //Some(format!("{node_name}")), + read_only: Some(false), + }, + file: qmp::BlockdevOptionsFile { + aio: None, + filename: device_file.to_string(), + aio_max_batch: None, + drop_cache: None, + locking: None, + pr_manager: None, + x_check_cache_dropped: None, + }, + })), + }, + offset: None, + size: None, + }, + })) + .await + .map_err(|e| e.into()) + .map(|_| ()) + } + + async fn device_add(&mut self, node_name: &str, disk_id: u8) -> Result<()> { + let mut args = serde_json::map::Map::new(); + args.insert(String::from("drive"), json!(node_name)); + args.insert( + String::from("device_id"), + json!(format!("persistent-disk-{disk_id}")), + ); + self.stream + .execute(qmp::device_add { + bus: Some("scsi0.0".to_string()), + id: Some(node_name.to_string()), + driver: "scsi-hd".to_string(), + arguments: args, + }) + .await + .map_err(|e| e.into()) + .map(|_| ()) + } + + async fn system_reset(&mut self) -> Result<()> { + self.stream + .execute(qmp::system_reset {}) + .await + .map_err(|e| e.into()) + .map(|_| ()) + } +} + +/* +async fn watchdog(vm_handle: &QEMUVMHandle) { + loop { + if let Ok(status) = vm_handle + .qmp + .lock() + .expect("QEMUVMHandle.qmp.lock()") + .query_status() + .await + { + tracing::debug!("VCPU status: {:#?}", status); + } else { + tracing::error!("VM died"); + let mut child = vm_handle.child.lock().expect("QEMUVMHandle.child.lock()"); + dump_read(child.stdout.as_mut().unwrap()); + dump_read(child.stderr.as_mut().unwrap()); + + child.wait().unwrap(); + } + + sleep(Duration::from_secs(3)).await; + } +} + */ + +fn dump_read(mut read: impl Read) { + let mut buffer = String::new(); + read.read_to_string(&mut buffer).unwrap(); + tracing::info!(buffer); +} + +// +// TODO: This is totally wrong place to put CLI argument parsing, but done +// this way to save some time. +// +// The GPU arguments should be completely refactored. Possibly even removed +// and replaced with automatic detection (by filtering PCI devices that are +// bound with vfio_pci driver). +fn parse_gpu_devices_into_qemu_params(arg: &str) -> Vec { + let devices: Vec<&str> = arg.split(',').collect(); + let mut params = vec![]; + for device in devices { + params.push("-device".to_string()); + params.push(format!("vfio-pci,rombar=0,host={}", device)); + } + params +} diff --git a/crates/node/src/vmm/vm_server.rs b/crates/node/src/vmm/vm_server.rs new file mode 100644 index 00000000..da6cf3b7 --- /dev/null +++ b/crates/node/src/vmm/vm_server.rs @@ -0,0 +1,205 @@ +use std::fmt::Debug; +use std::sync::Arc; + +use async_trait::async_trait; +use eyre::Result; +use tokio::io::AsyncReadExt; +use tokio::sync::{mpsc, Mutex}; +use tokio_stream::wrappers::ReceiverStream; +use tonic::{Extensions, Request, Response, Status}; + +use grpc::vm_service_server::VmService; +use grpc::{FileRequest, Task, TaskRequest, TaskResultResponse}; + +use crate::storage; +use crate::types::Hash; +use crate::vmm::vm_server::grpc::file_response; + +use self::grpc::{task_result_request, FileResponse, TaskResponse, TaskResultRequest}; + +use super::VMId; + +pub mod grpc { + tonic::include_proto!("vm_service"); +} + +/// DATA_STREAM_CHUNK_SIZE controls the chunk size for streaming byte +/// transfers, e.g. when transferring the input parameter file to `Program`. +const DATA_STREAM_CHUNK_SIZE: usize = 4096; + +/// TaskManager defines interface that `VMServer` uses to pull new tasks for VM's +/// requesting for work and submitting results of tasks. +#[async_trait] +pub trait TaskManager: Send + Sync { + async fn get_task(&self, program: Hash, vm_id: Arc) -> Option; + async fn submit_result( + &self, + program: Hash, + vm_id: Arc, + result: grpc::task_result_request::Result, + ) -> bool; +} + +/// ProgramRegistry defines interface that `VMServer` uses to identify which +/// `Program` sent corresponding request. +pub trait ProgramRegistry: Send { + fn find_by_req(&mut self, extensions: &Extensions) -> Option<(Hash, Arc)>; +} + +/// VMServer is the integration point between Gevulot node and individual +/// Nanos VMs. It implements the gRPC interface that program running in VM +/// connects to and communicates with. +pub struct VMServer { + task_source: Arc, + program_registry: Arc>, + file_storage: Arc, +} + +impl Debug for VMServer { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "vmserver") + } +} + +impl VMServer { + pub fn new( + task_source: Arc, + program_registry: Arc>, + file_storage: Arc, + ) -> Self { + VMServer { + task_source, + program_registry, + file_storage, + } + } + + pub fn grpc_server(self) -> grpc::vm_service_server::VmServiceServer { + grpc::vm_service_server::VmServiceServer::new(self) + } +} + +#[tonic::async_trait] +impl VmService for VMServer { + type GetFileStream = ReceiverStream>; + + #[tracing::instrument] + async fn get_task( + &self, + request: Request, + ) -> Result, Status> { + tracing::info!("request for task: {:?}", request); + let mut program_registry = self.program_registry.lock().await; + let (program, vm_id) = program_registry + .find_by_req(request.extensions()) + .unwrap_or_else(|| panic!("unknown VM: {:?}", request.remote_addr())); + + let reply = match self.task_source.get_task(program, vm_id).await { + Some(task) => { + tracing::info!("task has {} files", task.files.len()); + grpc::TaskResponse { + result: Some(grpc::task_response::Result::Task(grpc::Task { + id: task.id.to_string(), + name: task.name.to_string(), + args: task.args, + files: task.files, + })), + } + } + None => grpc::TaskResponse { + result: Some(grpc::task_response::Result::Error( + grpc::TaskError::Unavailable.into(), + )), + }, + }; + + Ok(Response::new(reply)) + } + + #[tracing::instrument] + async fn get_file( + &self, + request: Request, + ) -> Result, Status> { + tracing::info!("request for file: {:?}", request); + + let req = request.into_inner(); + + // TODO(tuommaki): Handle following error in better way! + let mut file = self + .file_storage + .get_task_file(&req.task_id, &req.path) + .await + .expect("failed to read file"); + + let (tx, rx) = mpsc::channel(4); + tokio::spawn({ + async move { + let mut buf: [u8; DATA_STREAM_CHUNK_SIZE] = [0; DATA_STREAM_CHUNK_SIZE]; + + loop { + match file.read(&mut buf).await { + Ok(0) => return Ok(()), + Ok(n) => { + if let Err(e) = tx + .send(Ok(grpc::FileResponse { + result: Some(file_response::Result::Chunk(grpc::FileChunk { + data: buf[..n].to_vec(), + })), + })) + .await + { + tracing::error!("send {} bytes from file {}: {}", n, &req.path, &e); + break; + } + } + Err(e) => return Err(e), + } + } + + Ok(()) + } + }); + + Ok(Response::new(ReceiverStream::new(rx))) + } + + #[tracing::instrument] + async fn submit_result( + &self, + request: Request, + ) -> Result, Status> { + let (program, vm_id) = self + .program_registry + .lock() + .await + .find_by_req(request.extensions()) + .unwrap_or_else(|| panic!("unknown VM: {:?}", request.remote_addr())); + + let result = request.into_inner().result; + + if let Some(result) = result { + if let task_result_request::Result::Task(ref result) = result { + // Save resulting files. + for file in result.files.clone() { + if let Err(err) = self + .file_storage + .save_task_file(&result.id, &file.path, file.data) + .await + { + tracing::error!( + "failed to save task {} result file {}", + result.id, + file.path + ); + } + } + } + + self.task_source.submit_result(program, vm_id, result).await; + } + + let reply = grpc::TaskResultResponse { r#continue: false }; + Ok(Response::new(reply)) + } +} diff --git a/crates/node/src/workflow/mod.rs b/crates/node/src/workflow/mod.rs new file mode 100644 index 00000000..89c0c9ac --- /dev/null +++ b/crates/node/src/workflow/mod.rs @@ -0,0 +1,489 @@ +use std::sync::Arc; + +use async_trait::async_trait; +use eyre::Result; +use gevulot_node::types::{ + transaction::{Payload, ProgramData, Workflow, WorkflowStep}, + File, Hash, Task, TaskKind, Transaction, +}; +use thiserror::Error; +use uuid::Uuid; + +use crate::storage; + +#[allow(clippy::enum_variant_names)] +#[derive(Error, Debug, PartialEq)] +pub enum WorkflowError { + #[error("incompatible transaction: {0}")] + IncompatibleTransaction(String), + + #[error("workflow transaction missing: {0}")] + WorkflowTransactionMissing(String), + + #[error("workflow step missing: {0}")] + WorkflowStepMissing(String), + + #[error("transaction not found: {0}")] + TransactionNotFound(Hash), +} + +#[async_trait] +pub trait TransactionStore: Sync + Send { + async fn find_transaction(&self, tx_hash: &Hash) -> Result>; +} + +pub struct WorkflowEngine { + tx_store: Arc, + file_storage: Arc, +} + +impl WorkflowEngine { + pub fn new(tx_store: Arc, file_storage: Arc) -> Self { + WorkflowEngine { + tx_store, + file_storage, + } + } + + pub async fn next_task(&self, cur_tx: &Transaction) -> Result> { + let workflow = self.workflow_for_transaction(&cur_tx.hash).await?; + + match &cur_tx.payload { + Payload::Run { workflow } => { + tracing::debug!("creating next task from Run tx {}", &cur_tx.hash); + + if workflow.steps.is_empty() { + Ok(None) + } else { + Ok(Some( + self.workflow_step_to_task( + cur_tx.hash, + &workflow.steps[0], + TaskKind::Proof, + ) + .await?, + )) + } + } + Payload::Proof { + parent, + prover, + proof, + } => { + tracing::debug!("creating next task from Proof tx {}", &cur_tx.hash); + + match workflow.steps.iter().position(|s| s.program == *prover) { + Some(proof_step_idx) => { + if workflow.steps.len() <= proof_step_idx { + Err(WorkflowError::WorkflowStepMissing(format!( + "verifier for proof tx {}", + cur_tx.hash.clone(), + )) + .into()) + } else { + Ok(Some( + self.workflow_step_to_task( + cur_tx.hash, + &workflow.steps[proof_step_idx + 1], + TaskKind::Verification, + ) + .await?, + )) + } + } + None => Err(WorkflowError::WorkflowStepMissing(format!( + "verifier for proof tx {}", + cur_tx.hash + )) + .into()), + } + } + Payload::ProofKey { parent, key } => { + tracing::debug!("creating next task from ProofKey tx {}", &cur_tx.hash); + + let proof_tx = match self.tx_store.find_transaction(parent).await { + Ok(None) => { + return Err(WorkflowError::WorkflowTransactionMissing(format!( + "Proof tx, hash {}", + parent + )) + .into()); + } + Ok(Some(tx)) => tx, + Err(err) => return Err(err), + }; + + // TODO: Rewrite this spaghetti! + + if let Payload::Proof { + parent, + prover, + proof, + } = proof_tx.payload + { + match workflow.steps.iter().position(|s| s.program == prover) { + Some(proof_step_idx) => { + if workflow.steps.len() <= proof_step_idx { + Err(WorkflowError::WorkflowStepMissing(format!( + "verifier for proof tx {}", + proof_tx.hash + )) + .into()) + } else { + Ok(Some( + self.workflow_step_to_task( + proof_tx.hash, + &workflow.steps[proof_step_idx + 1], + TaskKind::Verification, + ) + .await?, + )) + } + } + None => Err(WorkflowError::WorkflowStepMissing(format!( + "verifier for proof tx {}", + proof_tx.hash + )) + .into()), + } + } else { + Err(WorkflowError::IncompatibleTransaction(proof_tx.hash.to_string()).into()) + } + } + _ => Err(WorkflowError::IncompatibleTransaction( + "unsupported payload type".to_string(), + ) + .into()), + } + } + + async fn find_parent_tx_for_program(&self, tx_hash: &Hash, program: &Hash) -> Result { + let mut cur_tx = *tx_hash; + + tracing::debug!("finding workflow for transaction {}", tx_hash); + + // Traverse transaction tree up by tracing parent until the right tx is found. + loop { + let tx = self.tx_store.find_transaction(&cur_tx).await?; + + if tx.is_none() { + return Err(WorkflowError::TransactionNotFound(cur_tx).into()); + } + + match tx.unwrap().payload { + Payload::Run { workflow } => { + if workflow.steps.is_empty() { + return Err(WorkflowError::TransactionNotFound(cur_tx).into()); + } + + if workflow.steps.first().unwrap().program == *program { + return Ok(cur_tx); + } else { + return Err(WorkflowError::TransactionNotFound(cur_tx).into()); + } + } + Payload::Proof { parent, prover, .. } => { + if &cur_tx != tx_hash && prover == *program { + return Ok(cur_tx); + } + + cur_tx = parent; + continue; + } + Payload::ProofKey { parent, .. } => { + cur_tx = parent; + continue; + } + Payload::Verification { + parent, verifier, .. + } => { + if &cur_tx != tx_hash && verifier == *program { + return Ok(cur_tx); + } + + cur_tx = parent; + continue; + } + _ => { + tracing::debug!( + "failed to find workflow for transaction {}: incompatible transaction", + cur_tx + ); + return Err(WorkflowError::IncompatibleTransaction(cur_tx.to_string()).into()); + } + } + } + } + + async fn workflow_for_transaction(&self, tx_hash: &Hash) -> Result { + let mut tx_hash = *tx_hash; + + tracing::debug!("finding workflow for transaction {}", tx_hash); + + // Traverse transaction tree up by tracing parent until + // Payload::Run is found. + loop { + let tx = self.tx_store.find_transaction(&tx_hash).await?; + + if tx.is_none() { + return Err(WorkflowError::TransactionNotFound(tx_hash).into()); + } + + match tx.unwrap().payload { + Payload::Run { workflow } => { + tracing::debug!("workflow found for transaction {}", tx_hash); + return Ok(workflow); + } + Payload::Proof { parent, .. } => { + tracing::debug!("finding workflow from parent {} of {}", &parent, tx_hash); + tx_hash = parent; + continue; + } + Payload::ProofKey { parent, .. } => { + tracing::debug!("finding workflow from parent {} of {}", &parent, tx_hash); + tx_hash = parent; + continue; + } + Payload::Verification { parent, .. } => { + tracing::debug!("finding workflow from parent {} of {}", &parent, tx_hash); + tx_hash = parent; + continue; + } + _ => { + tracing::debug!( + "failed to find workflow for transaction {}: incompatible transaction", + &tx_hash + ); + return Err(WorkflowError::IncompatibleTransaction(tx_hash.to_string()).into()); + } + } + } + } + + async fn workflow_step_to_task( + &self, + tx: Hash, + step: &WorkflowStep, + kind: TaskKind, + ) -> Result { + let id = Uuid::new_v4(); + let mut file_transfers = vec![]; + let files = step + .inputs + .iter() + .map(|e| match e { + ProgramData::Input { + file_name, + file_url, + .. + } => File { + tx, + name: file_name.clone(), + url: file_url.clone(), + }, + ProgramData::Output { + source_program, + file_name, + } => { + // Make record of file that needs transfer from source tx to current tx's files. + file_transfers.push((*source_program, file_name.clone())); + + File { + tx, + name: file_name.clone(), + url: "".to_string(), + } + } + }) + .collect(); + + // Process file transfers from source programs. + for (source_program, file_name) in file_transfers { + let source_tx = self + .find_parent_tx_for_program(&tx, &source_program) + .await + .expect("output file dependency missing"); + + self.file_storage + .move_task_file(&source_tx.to_string(), &tx.to_string(), &file_name) + .await?; + } + + Ok(Task { + id, + tx, + name: format!("{}-{}", id, step.program), + kind, + program_id: step.program, + args: step.args.clone(), + files, + ..Default::default() + }) + } +} + +#[cfg(test)] +mod tests { + use std::{collections::HashMap, env::temp_dir}; + + use gevulot_node::types::{ + transaction::{Payload, ProgramData, Workflow, WorkflowStep}, + Hash, TaskKind, Transaction, + }; + use libsecp256k1::SecretKey; + use rand::{rngs::StdRng, SeedableRng}; + + use super::*; + + pub struct TxStore { + pub txs: HashMap, + } + + impl TxStore { + pub fn new(txs: &[Transaction]) -> Self { + let mut store = TxStore { + txs: HashMap::with_capacity(txs.len()), + }; + txs.iter().for_each(|tx| { + store.txs.insert(tx.hash, tx.clone()); + }); + store + } + } + + #[async_trait] + impl TransactionStore for TxStore { + async fn find_transaction(&self, tx_hash: &Hash) -> Result> { + Ok(self.txs.get(tx_hash).cloned()) + } + } + + #[tokio::test] + async fn test_next_task_for_empty_workflow_steps() { + let wfe = WorkflowEngine::new( + Arc::new(TxStore::new(&[])), + Arc::new(storage::File::new(&temp_dir())), + ); + let tx = transaction_for_workflow_steps(vec![]); + if let Payload::Run { workflow } = &tx.payload { + let res = wfe.next_task(&tx).await; + assert!(res.is_err()); + } + } + + #[tokio::test] + async fn test_next_task_for_simple_workflow_steps() { + let rng = &mut StdRng::from_entropy(); + let prover_hash = Hash::random(rng); + + let proving = WorkflowStep { + program: prover_hash, + args: vec![], + inputs: vec![], + }; + + let verifying = WorkflowStep { + program: Hash::random(rng), + args: vec![], + inputs: vec![ProgramData::Output { + source_program: prover_hash, + file_name: "proof.dat".to_string(), + }], + }; + + let tx = transaction_for_workflow_steps(vec![proving.clone(), verifying]); + let wfe = WorkflowEngine::new( + Arc::new(TxStore::new(&[tx.clone()])), + Arc::new(storage::File::new(&temp_dir())), + ); + + if let Payload::Run { workflow } = &tx.payload { + let task = wfe.next_task(&tx).await.expect("next_task").unwrap(); + assert_eq!(task.kind, TaskKind::Proof); + assert_eq!(task.program_id, proving.program); + assert_eq!(task.args, Vec::::new()); + }; + } + + #[tokio::test] + async fn test_next_task_for_verification() { + let rng = &mut StdRng::from_entropy(); + let prover_hash = Hash::random(rng); + let verifier_hash = Hash::random(rng); + + let proving = WorkflowStep { + program: prover_hash, + args: vec![], + inputs: vec![], + }; + + let verifying = WorkflowStep { + program: verifier_hash, + args: vec![], + inputs: vec![], + }; + + let workflow_steps = vec![proving.clone(), verifying]; + let workflow = Workflow { + steps: workflow_steps.clone(), + }; + + let root_tx = transaction_for_workflow_steps(workflow_steps); + let proof_tx = transaction_for_proof(&root_tx.hash, &prover_hash); + let proofkey_tx = transaction_for_proofkey(&proof_tx.hash); + let verification_tx = transaction_for_verification(&proof_tx.hash, &verifier_hash); + let tx_store = TxStore::new(&[root_tx, proof_tx, proofkey_tx.clone(), verification_tx]); + let wfe = WorkflowEngine::new( + Arc::new(tx_store), + Arc::new(storage::File::new(&temp_dir())), + ); + + let task = wfe.next_task(&proofkey_tx).await; + assert!(task.is_ok()); + } + + fn transaction_for_workflow_steps(steps: Vec) -> Transaction { + let key = SecretKey::random(&mut StdRng::from_entropy()); + Transaction::new( + Payload::Run { + workflow: Workflow { steps }, + }, + &key, + ) + } + + fn transaction_for_proof(parent: &Hash, program: &Hash) -> Transaction { + let key = SecretKey::random(&mut StdRng::from_entropy()); + Transaction::new( + Payload::Proof { + parent: *parent, + prover: *program, + proof: "proof.".into(), + }, + &key, + ) + } + + fn transaction_for_proofkey(parent: &Hash) -> Transaction { + let key = SecretKey::random(&mut StdRng::from_entropy()); + Transaction::new( + Payload::ProofKey { + parent: *parent, + key: "key.".into(), + }, + &key, + ) + } + + fn transaction_for_verification(parent: &Hash, program: &Hash) -> Transaction { + let key = SecretKey::random(&mut StdRng::from_entropy()); + Transaction::new( + Payload::Verification { + parent: *parent, + verifier: *program, + verification: b"verification.".to_vec(), + }, + &key, + ) + } +} diff --git a/crates/shim-ffi/Cargo.toml b/crates/shim-ffi/Cargo.toml new file mode 100644 index 00000000..172ecd86 --- /dev/null +++ b/crates/shim-ffi/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "gevulot-shim-ffi" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +gevulot-shim = { path = "../shim" } diff --git a/crates/shim-ffi/shim.h b/crates/shim-ffi/shim.h new file mode 100644 index 00000000..98fabc6c --- /dev/null +++ b/crates/shim-ffi/shim.h @@ -0,0 +1,29 @@ +#ifndef SHIM_H +#define SHIM_H + +#include +#include + + +/* Task type contains necessary parameters for executing the program. */ +typedef struct Task { + const char *id; + const char *const *args; + const char *const *files; +} Task; + +/* new_task_result is a function to construct the task result type. It takes + * result data as a parameter, in case there is some. */ +void *new_task_result(uint8_t *data, size_t len); + +/* add_file_to_result allows adding persisted files to task result for + * returning back to Gevulot node. */ +void add_file_to_result(void *result, const char *file_name); + +/* run function is the entry point for Gevulot. It takes callback function + * pointer as a parameter and invokes it when there is task for execution. + * The callback function is then expected to return task result once it's + * finished. */ +void run(void *(*callback)(const struct Task*)); + +#endif diff --git a/crates/shim-ffi/src/lib.rs b/crates/shim-ffi/src/lib.rs new file mode 100644 index 00000000..19fd5110 --- /dev/null +++ b/crates/shim-ffi/src/lib.rs @@ -0,0 +1,104 @@ +use std::ffi::{c_char, CStr, CString}; + +#[repr(C)] +pub struct Task { + id: *const c_char, + pub args: *const *const c_char, + pub files: *const *const c_char, +} + +impl std::fmt::Debug for Task { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "id: {:#?}", self.id)?; + write!(f, "args: {:#?}", self.args)?; + write!(f, "files: {:#?}", self.files) + } +} + +#[repr(C)] +pub struct TaskResult { + data: Vec, + files: Vec, +} + +/// # Safety +/// This function is safe as long as passed parameters `data` and `len` together +/// are valid ((NULL, 0) are also valid). +#[no_mangle] +pub unsafe extern "C" fn new_task_result(data: *mut u8, len: usize) -> *mut TaskResult { + // SAFETY: 1. This is safe as long as passed `data` and `len` arguments are valid. + unsafe { + let data = if data.is_null() { + vec![] + } else { + let slice = std::slice::from_raw_parts(data, len); + slice.to_vec() + }; + + Box::into_raw(Box::new(TaskResult { + data, + files: vec![], + })) + } +} + +/// # Safety +/// This function is save as long as passed parameters are valid. +#[no_mangle] +pub unsafe extern "C" fn add_file_to_result(result: *mut TaskResult, file_name: *const c_char) { + // SAFETY: Following is only safe if the passed `file_name` is: + // 1. valid pointer + // 2. null terminated. + let c_str = unsafe { CStr::from_ptr(file_name) }; + + // SAFETY: `result` pointer dereferencing is safe because that pointer + // originates from this library (above). + unsafe { + (*result) + .files + .push(c_str.to_string_lossy().into_owned().clone()); + } +} + +#[no_mangle] +pub extern "C" fn run(callback: extern "C" fn(*const Task) -> *mut TaskResult) { + let res = gevulot_shim::run(|task: &gevulot_shim::Task| -> Result> { + let id_cstr = CString::new(task.id.clone()).expect("task.id"); + + // Convert Vec -> *const *const c_char. + let cstr_args: Vec = task.args.iter().map(|s| CString::new(s.as_str()).expect("task.arg")).collect(); + let cstr_files: Vec = task.files.iter().map(|s| CString::new(s.as_str()).expect("task.file")).collect(); + + let mut carr_args: Vec<*const c_char> = cstr_args.iter().map(|s| s.as_ptr()).collect(); + let mut carr_files: Vec<*const c_char> = cstr_files.iter().map(|s| s.as_ptr()).collect(); + + // Terminate the arrays. + carr_args.push(std::ptr::null()); + carr_files.push(std::ptr::null()); + + let c_task = Task{ + id: id_cstr.as_ptr(), + args: carr_args.as_ptr(), + files: carr_files.as_ptr(), + }; + + let result = callback(&c_task); + + let data; + let files; + + // SAFETY: Given that pointer of `result` is valid, the internals of + // TaskResult are handled within this library and are therefore + // expected to be safe. + unsafe { + files = (*result).files.clone(); + data = (*result).data.clone(); + } + + task.result(data, files) + }); + + if res.is_err() { + eprintln!("error: {:#?}", res.unwrap()) + } +} diff --git a/crates/shim/Cargo.lock b/crates/shim/Cargo.lock new file mode 100644 index 00000000..57ba8688 --- /dev/null +++ b/crates/shim/Cargo.lock @@ -0,0 +1,1277 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-executor" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gevulot-shim" +version = "0.1.0" +dependencies = [ + "anyhow", + "prost", + "tokio", + "tokio-vsock", + "tonic", + "tonic-build", + "tower", + "uuid", + "vsock", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "h2" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 1.9.3", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[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.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.2", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" + +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.1.0", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[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 = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.38.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "serde" +version = "1.0.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.190" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys", +] + +[[package]] +name = "tokio" +version = "1.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2 0.5.5", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tokio-vsock" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52a15c15b1bc91f90902347eff163b5b682643aff0c8e972912cca79bd9208dd" +dependencies = [ + "bytes", + "futures", + "libc", + "tokio", + "tonic", + "vsock", +] + +[[package]] +name = "tonic" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "prost-derive", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "tracing-futures", +] + +[[package]] +name = "tonic-build" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "uuid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +dependencies = [ + "getrandom", + "rand", + "uuid-macro-internal", +] + +[[package]] +name = "uuid-macro-internal" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d8c6bba9b149ee82950daefc9623b32bb1dacbfb1890e352f6b887bd582adaf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "vsock" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8e1df0bf1e1b28095c24564d1b90acae64ca69b097ed73896e342fa6649c57" +dependencies = [ + "libc", + "nix", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/crates/shim/Cargo.toml b/crates/shim/Cargo.toml new file mode 100644 index 00000000..66b9f205 --- /dev/null +++ b/crates/shim/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "gevulot-shim" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" + +[dependencies] +anyhow = "1" +prost = "0.11" +tokio = { version = "1.0", features = ["fs", "macros", "rt-multi-thread"] } +tokio-stream = "0.1" +tokio-vsock = { version = "0.4.0", features = ["tonic-conn"] } +tonic = "0.8.3" +tower = "0.4.0" +vsock = "0.3.0" +uuid = { version = "1.4.1", features = [ "v4", "fast-rng", "macro-diagnostics" ] } + +[build-dependencies] +tonic-build = "0.8" diff --git a/crates/shim/build.rs b/crates/shim/build.rs new file mode 100644 index 00000000..46e00d34 --- /dev/null +++ b/crates/shim/build.rs @@ -0,0 +1,4 @@ +fn main() -> Result<(), Box> { + tonic_build::compile_protos("proto/vm_service.proto")?; + Ok(()) +} diff --git a/crates/shim/proto/vm_service.proto b/crates/shim/proto/vm_service.proto new file mode 100644 index 00000000..2462cf6d --- /dev/null +++ b/crates/shim/proto/vm_service.proto @@ -0,0 +1,73 @@ +syntax = "proto3"; + +package vm_service; + +service VMService { + rpc GetTask (TaskRequest) returns (TaskResponse) {} + rpc GetFile (FileRequest) returns (stream FileResponse) {} + + rpc SubmitResult(TaskResultRequest) returns (TaskResultResponse) {} +} + +message TaskRequest {} + +message Task { + string id = 1; + string name = 2; + repeated string args = 3; + repeated string files = 4; +} + +enum TaskError { + Unavailable = 0; + Failed = 1; +} + +message TaskResponse { + oneof result { + Task task = 1; + TaskError error = 2; + } +} + +message FileRequest { + string task_id = 1; + string path = 2; +} + +message File { + string path = 1; + bytes data = 2; +} + +message FileChunk { + bytes data = 1; +} + +enum FileError { + NotFound = 0; +} + +message FileResponse { + oneof result { + FileChunk chunk = 1; + FileError error = 2; + } +} + +message TaskResult { + string id = 1; + bytes data = 2; + repeated File files = 3; +} + +message TaskResultRequest { + oneof result { + TaskResult task = 1; + TaskError error = 2; + } +} + +message TaskResultResponse { + bool continue = 1; +} diff --git a/crates/shim/src/lib.rs b/crates/shim/src/lib.rs new file mode 100644 index 00000000..eae3e684 --- /dev/null +++ b/crates/shim/src/lib.rs @@ -0,0 +1,262 @@ +use std::fs::File; +use std::io::{BufRead, BufReader}; +use std::time::Instant; +use std::{path::Path, thread::sleep, time::Duration}; + +use grpc::vm_service_client::VmServiceClient; +use tokio::runtime::Runtime; +use tokio::{io::AsyncWriteExt, sync::Mutex}; +use tokio_stream::StreamExt; +use tokio_vsock::VsockStream; +use tonic::transport::{Channel, Endpoint, Uri}; +use tower::service_fn; +use vsock::VMADDR_CID_HOST; + +mod grpc { + tonic::include_proto!("vm_service"); +} + +/// MOUNT_TIMEOUT is maximum amount of time to wait for workspace mount to be +/// present in /proc/mounts. +const MOUNT_TIMEOUT: Duration = Duration::from_secs(30); + +type Result = std::result::Result>; +pub type TaskId = String; + +#[derive(Debug)] +pub struct Task { + pub id: TaskId, + pub args: Vec, + pub files: Vec, +} + +#[derive(Debug)] +pub struct TaskResult { + id: TaskId, + data: Vec, + files: Vec, +} + +impl Task { + pub fn result(&self, data: Vec, files: Vec) -> Result { + Ok(TaskResult { + id: self.id.clone(), + data, + files, + }) + } +} + +struct GRPCClient { + /// `workspace` is the file directory used for task specific file downloads. + workspace: String, + + client: Mutex>, + rt: Runtime, +} + +impl GRPCClient { + fn new(port: u32, workspace: &str) -> Result { + let rt = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build()?; + + let client = rt.block_on(GRPCClient::connect(port))?; + + println!("waiting for {workspace} mount to be present"); + let beginning = Instant::now(); + loop { + if beginning.elapsed() > MOUNT_TIMEOUT { + panic!("{} mount timeout", workspace); + } + + if mount_present(workspace)? { + println!("{workspace} mount is now present"); + break; + } + + sleep(Duration::from_secs(1)); + } + + Ok(GRPCClient { + workspace: workspace.to_string(), + client: Mutex::new(client), + rt, + }) + } + + async fn connect(port: u32) -> Result> { + let channel = Endpoint::try_from(format!("http://[::]:{}", port))? + .connect_with_connector(service_fn(move |_: Uri| { + // Connect to a VSOCK server + VsockStream::connect(VMADDR_CID_HOST, port) + })) + .await?; + + Ok(grpc::vm_service_client::VmServiceClient::new(channel)) + } + + fn get_task(&mut self) -> Result> { + let task_response = self + .rt + .block_on(async { + self.client + .lock() + .await + .get_task(grpc::TaskRequest {}) + .await + })? + .into_inner(); + + let mut task = match task_response.result { + Some(grpc::task_response::Result::Task(task)) => Task { + id: task.id, + args: task.args, + files: task.files, + }, + Some(grpc::task_response::Result::Error(_err)) => { + todo!("construct proper error types from TaskError") + } + None => return Ok(None), + }; + + let mut files = vec![]; + for file in task.files { + let path = self + .rt + .block_on(self.download_file(task.id.clone(), file))?; + files.push(path); + } + task.files = files; + + Ok(Some(task)) + } + + fn submit_result(&mut self, result: &TaskResult) -> Result { + // TODO(tuommaki): Implement result file transformation! + let task_result_req = grpc::TaskResultRequest { + result: Some(grpc::task_result_request::Result::Task(grpc::TaskResult { + id: result.id.clone(), + data: result.data.clone(), + files: result + .files + .iter() + .map(|f| grpc::File { + path: f.to_string(), + data: std::fs::read(f).expect("result file read"), + }) + .collect(), + })), + }; + + let response = self + .rt + .block_on(async { + self.client + .lock() + .await + .submit_result(task_result_req) + .await + })? + .into_inner(); + + Ok(response.r#continue) + } + + /// download_file asks gRPC server for file with a `name` and writes it to + /// `workspace`. + async fn download_file(&self, task_id: TaskId, name: String) -> Result { + let file_req = grpc::FileRequest { + task_id: task_id.clone(), + path: name.clone(), + }; + + let path = match Path::new(&self.workspace) + .join(task_id) + .join(name.clone()) + .into_os_string() + .into_string() + { + Ok(path) => path, + Err(e) => panic!("failed to construct path for a file to write: {:?}", e), + }; + + let mut stream = self + .client + .lock() + .await + .get_file(file_req) + .await? + .into_inner(); + let out_file = tokio::fs::File::create(path.clone()).await?; + let mut writer = tokio::io::BufWriter::new(out_file); + + let mut total_bytes = 0; + + while let Some(Ok(grpc::FileResponse { result: resp })) = stream.next().await { + match resp { + Some(grpc::file_response::Result::Chunk(file_chunk)) => { + total_bytes += file_chunk.data.len(); + writer.write_all(file_chunk.data.as_ref()).await?; + } + Some(grpc::file_response::Result::Error(err)) => { + panic!("error while fetching file {}: {}", name, err) + } + None => { + println!("stream broken"); + break; + } + } + } + + writer.flush().await?; + + println!("downloaded {} bytes for {}", &total_bytes, &name); + + Ok(path) + } +} + +fn mount_present(mount_point: &str) -> Result { + let file = File::open("/proc/mounts")?; + let reader = BufReader::new(file); + + for line in reader.lines() { + let line = line.expect("read /proc/mounts"); + if line.contains(mount_point) { + return Ok(true); + } + } + + Ok(false) +} + +/// run function takes `callback` that is invoked with executable `Task` and +/// which is expected to return `TaskResult`. +pub fn run(callback: impl Fn(&Task) -> Result) -> Result<()> { + let mut client = GRPCClient::new(8080, "/workspace")?; + + loop { + let task = match client.get_task() { + Ok(Some(task)) => task, + Ok(None) => { + sleep(Duration::from_secs(1)); + continue; + } + Err(err) => { + println!("get_task(): {}", err); + sleep(Duration::from_secs(5)); + continue; + } + }; + + let result = callback(&task)?; + + let should_continue = client.submit_result(&result)?; + if !should_continue { + break; + } + } + + Ok(()) +} diff --git a/crates/tests/e2e-tests/Cargo.toml b/crates/tests/e2e-tests/Cargo.toml new file mode 100644 index 00000000..0bacbfb7 --- /dev/null +++ b/crates/tests/e2e-tests/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "gevulot-e2e-tests" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.71" +blake3 = { version = "1.5", features = [ "mmap" ] } +clap = { version = "4.0.29", features = ["derive"] } +futures-util = { version = "0.3", default-features = false } +gevulot-node = { path = "../../node" } +hex = "0.4" +http-body-util = "0.1" +hyper = { version = "1", features = ["full"] } +hyper-util = { version = "0.1", features = ["full"] } +libsecp256k1 = "0.7" +rand = { version = "0.8", features = [ "std_rng" ] } +sha3 = "0.10" +tokio = { version = "1", features = [ "full" ] } +tokio-util = "0.7" diff --git a/crates/tests/e2e-tests/manifest/prover.json b/crates/tests/e2e-tests/manifest/prover.json new file mode 100644 index 00000000..118fa238 --- /dev/null +++ b/crates/tests/e2e-tests/manifest/prover.json @@ -0,0 +1,19 @@ +{ + "RebootOnExit": true, + "RunConfig": { + "CPUs": 2, + "Memory": "2g" + }, + "ManifestPassthrough": { + "readonly_rootfs": "true" + }, + "Env":{ + "RUST_BACKTRACE": "1", + "RUST_LOG": "trace" + }, + "Program":"prover", + "Mounts": { + "%1": "/workspace" + } +} + diff --git a/crates/tests/e2e-tests/manifest/verifier.json b/crates/tests/e2e-tests/manifest/verifier.json new file mode 100644 index 00000000..8954ab52 --- /dev/null +++ b/crates/tests/e2e-tests/manifest/verifier.json @@ -0,0 +1,19 @@ +{ + "RebootOnExit": true, + "RunConfig": { + "CPUs": 2, + "Memory": "2g" + }, + "ManifestPassthrough": { + "readonly_rootfs": "true" + }, + "Env":{ + "RUST_BACKTRACE": "1", + "RUST_LOG": "trace" + }, + "Program":"verifier", + "Mounts": { + "%1": "/workspace" + } +} + diff --git a/crates/tests/e2e-tests/src/main.rs b/crates/tests/e2e-tests/src/main.rs new file mode 100644 index 00000000..2f68a000 --- /dev/null +++ b/crates/tests/e2e-tests/src/main.rs @@ -0,0 +1,174 @@ +use std::{ + net::SocketAddr, + path::{Path, PathBuf}, + sync::Arc, + time::Duration, +}; + +use clap::Parser; +use gevulot_node::{ + rpc_client::RpcClient, + types::{ + transaction::{Payload, ProgramData, ProgramMetadata, Workflow, WorkflowStep}, + Hash, Transaction, + }, +}; +use libsecp256k1::SecretKey; +use rand::{rngs::StdRng, SeedableRng}; +use server::FileServer; +use tokio::time::sleep; + +mod server; + +type Result = std::result::Result>; + +#[derive(Parser, Debug)] +#[clap(author = "Gevulot Team", version, about, long_about = None)] +pub struct ArgConfiguration { + #[clap(short, long)] + pub prover_img: PathBuf, + #[clap(short, long)] + pub verifier_img: PathBuf, + #[clap(short, long, default_value = "http://localhost:9944")] + pub json_rpc_url: String, + #[clap(short, long, default_value = "127.0.0.1:0")] + pub listen_addr: SocketAddr, +} + +#[tokio::main] +async fn main() -> Result<()> { + let cfg = ArgConfiguration::parse(); + let client = RpcClient::new(cfg.json_rpc_url); + let file_server = Arc::new(FileServer::new(cfg.listen_addr).await); + + let key = SecretKey::random(&mut StdRng::from_entropy()); + + let (_tx_hash, prover_hash, verifier_hash) = deploy_programs( + &client, + file_server.clone(), + &key, + "e2e-test", + &cfg.prover_img, + &cfg.verifier_img, + ) + .await + .expect("deploy"); + + for nonce in 1..2 { + send_proving_task(&client, &key, nonce, &prover_hash, &verifier_hash) + .await + .expect("send proving task"); + } + + sleep(Duration::from_secs(360)).await; + + Ok(()) +} + +async fn deploy_programs( + client: &RpcClient, + file_server: Arc, + key: &SecretKey, + deployment_name: &str, + prover_img: &Path, + verifier_img: &Path, +) -> Result<(Hash, Hash, Hash)> { + let prover = + from_img_file_to_metadata(prover_img, &file_server.register_file(prover_img).await); + let verifier = + from_img_file_to_metadata(verifier_img, &file_server.register_file(verifier_img).await); + let mut tx = Transaction { + payload: Payload::Deploy { + name: deployment_name.to_string(), + prover: prover.clone(), + verifier: verifier.clone(), + }, + nonce: 42, + ..Default::default() + }; + + // Transaction hash gets computed during this as well. + tx.sign(key); + + client + .send_transaction(&tx) + .await + .expect("send_transaction"); + + let read_tx = client + .get_transaction(&tx.hash) + .await + .expect("get_transaction"); + + assert!(read_tx.is_some()); + assert_eq!(tx, read_tx.unwrap()); + + Ok((tx.hash, prover.hash, verifier.hash)) +} + +async fn send_proving_task( + client: &RpcClient, + key: &SecretKey, + nonce: u64, + prover_hash: &Hash, + verifier_hash: &Hash, +) -> Result { + let proving_step = WorkflowStep { + program: *prover_hash, + args: vec!["--nonce".to_string(), nonce.to_string()], + inputs: vec![], + }; + + let verifying_step = WorkflowStep { + program: *verifier_hash, + args: vec!["--nonce".to_string(), nonce.to_string()], + inputs: vec![ProgramData::Output { + source_program: *prover_hash, + file_name: "/workspace/proof.dat".to_string(), + }], + }; + + let mut tx = Transaction { + payload: Payload::Run { + workflow: Workflow { + steps: vec![proving_step, verifying_step], + }, + }, + nonce, + ..Default::default() + }; + + tx.sign(key); + + client + .send_transaction(&tx) + .await + .expect("send_transaction"); + + Ok(tx.hash) +} + +fn from_img_file_to_metadata(img_file: &Path, img_file_url: &str) -> ProgramMetadata { + let mut hasher = blake3::Hasher::new(); + let fd = std::fs::File::open(img_file).expect("open"); + hasher.update_reader(fd).expect("checksum"); + let checksum = hasher.finalize(); + + let file_name = img_file + .file_name() + .expect("file name") + .to_str() + .unwrap() + .to_string(); + + let mut program = ProgramMetadata { + name: file_name.clone(), + hash: Hash::default(), + image_file_name: file_name, + image_file_url: img_file_url.to_string(), + image_file_checksum: checksum.to_string(), + }; + + program.update_hash(); + program +} diff --git a/crates/tests/e2e-tests/src/server.rs b/crates/tests/e2e-tests/src/server.rs new file mode 100644 index 00000000..67877405 --- /dev/null +++ b/crates/tests/e2e-tests/src/server.rs @@ -0,0 +1,128 @@ +use futures_util::TryStreamExt; +use http_body_util::combinators::BoxBody; +use http_body_util::{BodyExt, Full, StreamBody}; +use hyper::body::{self, Bytes, Frame}; +use hyper::server::conn::http1; +use hyper::service::service_fn; +use hyper::{Request, Response, StatusCode}; +use hyper_util::rt::TokioIo; +use sha3::{Digest, Sha3_256}; +use std::collections::HashMap; +use std::net::SocketAddr; +use std::path::Path; +use std::sync::Arc; +use tokio::fs::File; +use tokio::net::TcpListener; +use tokio::sync::RwLock; +use tokio_util::io::ReaderStream; + +type Result = std::result::Result>; + +#[derive(Clone)] +pub struct FileServer { + file_map: Arc>>, + listen_addr: SocketAddr, +} + +impl FileServer { + pub async fn new(listen_addr: SocketAddr) -> Self { + let mut server = FileServer { + file_map: Arc::new(RwLock::new(HashMap::new())), + listen_addr, + }; + + let addr = server.listen(listen_addr).await; + server.listen_addr = addr.expect("FileServer::listen"); + server + } + + pub async fn register_file(&self, file: &Path) -> String { + let file_name = file.to_string_lossy().to_string(); + let mut file_map = self.file_map.write().await; + let mut hasher = Sha3_256::new(); + hasher.update(file_name.as_bytes()); + let digest = hex::encode(hasher.finalize()); + let url = format!("http://{}/{}", self.listen_addr, digest); + file_map.insert(digest, file_name); + url + } + + async fn listen(&self, listen_addr: SocketAddr) -> Result { + let listener = TcpListener::bind(listen_addr).await?; + + // Re-read the listen address in case random port was used. + let addr = listener.local_addr()?; + + tokio::spawn({ + let server = self.clone(); + async move { + loop { + let (stream, _) = listener.accept().await.expect("accept"); + let io = TokioIo::new(stream); + + tokio::task::spawn({ + let server = server.clone(); + async move { + if let Err(err) = http1::Builder::new() + .serve_connection(io, service_fn(|req| server.serve_file(req))) + .await + { + println!("Error serving connection: {:?}", err); + } + } + }); + } + } + }); + + println!("Listening on http://{}", addr); + Ok(addr) + } + + async fn serve_file( + &self, + req: Request, + ) -> std::result::Result>, hyper::Error> { + let path = &req.uri().path()[1..]; + + // Acquire read lock. + let file_map = self.file_map.read().await; + + println!("request file: {}", path); + + let file_path = match file_map.get(path) { + Some(file_path) => file_path, + None => { + return Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body( + Full::new("Not found.".into()) + .map_err(|e| match e {}) + .boxed(), + ) + .unwrap()) + } + }; + let file = match File::open(file_path).await { + Ok(file) => file, + Err(_) => { + return Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body( + Full::new("Internal server error".into()) + .map_err(|e| match e {}) + .boxed(), + ) + .unwrap()) + } + }; + + let reader = ReaderStream::new(file); + let stream_body = StreamBody::new(reader.map_ok(Frame::data)); + + Ok(Response::builder() + .status(StatusCode::OK) + .body(stream_body.boxed()) + .unwrap()) + } +} diff --git a/crates/tests/test-programs/Cargo.toml b/crates/tests/test-programs/Cargo.toml new file mode 100644 index 00000000..8e88bf50 --- /dev/null +++ b/crates/tests/test-programs/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "gevulot-e2e-test-programs" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" + + +[[bin]] +name = "prover" +path = "src/prover.rs" + +[[bin]] +name = "verifier" +path = "src/verifier.rs" + +[dependencies] +gevulot-shim = { path = "../../shim" } diff --git a/crates/tests/test-programs/src/prover.rs b/crates/tests/test-programs/src/prover.rs new file mode 100644 index 00000000..1078da1c --- /dev/null +++ b/crates/tests/test-programs/src/prover.rs @@ -0,0 +1,15 @@ +use gevulot_shim::{Task, TaskResult}; + +type Result = std::result::Result>; + +fn main() -> Result<()> { + gevulot_shim::run(run_task) +} + +fn run_task(task: &Task) -> Result { + println!("prover: task.args: {:?}", &task.args); + + std::fs::write("/workspace/proof.dat", b"this is a proof.")?; + + task.result(vec![], vec![String::from("/workspace/proof.dat")]) +} diff --git a/crates/tests/test-programs/src/verifier.rs b/crates/tests/test-programs/src/verifier.rs new file mode 100644 index 00000000..fc5ace82 --- /dev/null +++ b/crates/tests/test-programs/src/verifier.rs @@ -0,0 +1,13 @@ +use gevulot_shim::{Task, TaskResult}; + +type Result = std::result::Result>; + +fn main() -> Result<()> { + gevulot_shim::run(run_task) +} + +fn run_task(task: &Task) -> Result { + println!("verifier: task.args: {:?}", &task.args); + + task.result(vec![], vec![]) +} diff --git a/prover/.gitignore b/prover/.gitignore deleted file mode 100644 index 826e32f4..00000000 --- a/prover/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -/target -Cargo.lock -deployments/*.json -!deployments/window-post-inputs.json -!deployments/winning-post-inputs.json -*.txt -.DS_Store -circom/*.r1cs -circom/*.sym -circom/*_js -.vscode -proof.json -rust-fil-proofs/target diff --git a/prover/Cargo.toml b/prover/Cargo.toml deleted file mode 100644 index bd5ae461..00000000 --- a/prover/Cargo.toml +++ /dev/null @@ -1,34 +0,0 @@ -[package] -name = "prover" -version = "0.3.0" -edition = "2021" -license = "MIT or Apache-2.0" - -[dependencies] -anyhow = "1.0.71" -base64 = "0.21.2" -serde_json = "1.0.96" -serde = { version = "1.0", features = ["derive"] } -ark-bls12-381 = { version = "^0.3.0", default-features = false, features = [ - "curve", -] } -ark-serialize = { version = "^0.3.0", default-features = false, features = [ - "derive", -] } -clap = { version = "4.0.29", features = ["derive"] } -gev-core = { path = "gev-core" } -thiserror = "1.0.44" -ark-marlin = { path = "marlin" } -ark-groth16 = { path = "groth16" } -ark-bn254 = { version = "0.4.0", default-features = false, features = [ - "curve", -] } -filecoin-proofs = { path = "rust-fil-proofs/filecoin-proofs" } - -[dependencies.uuid] -version = "1.3.4" -features = [ - "v4", # Lets you generate random UUIDs - "fast-rng", # Use a faster (but still sufficiently random) RNG - "macro-diagnostics", # Enable better diagnostics for compile-time UUIDs -] diff --git a/prover/circom/README.md b/prover/circom/README.md deleted file mode 100644 index 2aef0553..00000000 --- a/prover/circom/README.md +++ /dev/null @@ -1,106 +0,0 @@ -# Test Circom Circuit - -The circom program file used here is from this repository: - -https://github.com/nalinbhardwaj/snarky-sudoku - -The library of circuits found in the `prover/circom/circuits` fold were taken from the circomlib repo. - -https://github.com/iden3/circomlib - -There is a readme file there documentating the various circuits. - - -[CircomLib circuit cibrary readme](circuits/README.md) - -## Install `circom` and `snarkjs` - -You must have `circom` and `snarkjs` installed on your system. - -1. circom: https://docs.circom.io/getting-started/installation/ -``` -git clone https://github.com/iden3/circom.git -cd circom -cargo build --release -cargo install --path circom -``` -2. snarkjs -``` -sudo npm install -g snarkjs -``` - -## The test circuit - -The file is `sudoku.circom`. This program checks a given solution against a sudoku puzzle. - - -### Compilation -To compile the script to `r1cs`, `wasm`, and `sym` files, run this command from the `prover/circom` directory. - -``` -circom sudoku.circom --r1cs --wasm --sym -``` - -You should see output like this: -``` -template instances: 10 -non-linear constraints: 4374 -linear constraints: 0 -public inputs: 81 -public outputs: 0 -private inputs: 81 -private outputs: 0 -wires: 3970 -labels: 19036 -Written successfully: ./sudoku.r1cs -Written successfully: ./sudoku.sym -Written successfully: ./sudoku_js/sudoku.wasm -Everything went okay, circom safe -``` -The `r1cs` file will be used directly by us. -The `sym` file is there as a reference, showing the mapping to named variables in the program. -The `wasm` file will be used to generate the witness. - -You will also see a newly create folder named `sudoku_js`. - -### Input file - -The inputs for this puzzle are in `sudoku.json`. - -``` -{ - "unsolved_grid": [ - [6, 0, 3, 2, 0, 5, 4, 7, 0], - [7, 9, 1, 4, 6, 0, 0, 2, 8], - [5, 2, 4, 9, 0, 0, 1, 6, 0], - [0, 4, 0, 0, 5, 7, 3, 0, 0], - [3, 1, 0, 6, 8, 0, 7, 4, 2], - [0, 7, 0, 3, 4, 2, 0, 0, 0], - [0, 0, 0, 5, 2, 4, 0, 0, 0], - [1, 0, 0, 7, 3, 0, 0, 0, 4], - [0, 3, 0, 0, 9, 1, 0, 0, 7] - ], - "solved_grid": [ - [6, 8, 3, 2, 1, 5, 4, 7, 9], - [7, 9, 1, 4, 6, 3, 5, 2, 8], - [5, 2, 4, 9, 7, 8, 1, 6, 3], - [2, 4, 9, 1, 5, 7, 3, 8, 6], - [3, 1, 5, 6, 8, 9, 7, 4, 2], - [8, 7, 6, 3, 4, 2, 9, 1, 5], - [9, 6, 7, 5, 2, 4, 8, 3, 1], - [1, 5, 8, 7, 3, 6, 2, 9, 4], - [4, 3, 2, 8, 9, 1, 6, 5, 7] - ] -} -``` - -### Witness File - -Generate the witness file with node and snarkjs. - -``` -cd sudoku_js -node generate_witness.js sudoku.wasm ../sudoku.json sudoku.wtns -``` - -If you edit the `sudoku.js` file to make an incorrect solution or unsolved board, the generation of the witness will fail. diff --git a/prover/circom/circuits/README.md b/prover/circom/circuits/README.md deleted file mode 100644 index 40a833e7..00000000 --- a/prover/circom/circuits/README.md +++ /dev/null @@ -1,830 +0,0 @@ -# CircomLib/Circuits - -## Description - -- This folder contains circuit templates for standard operations and many cryptographic primitives. -- Below you can find specifications of each function. In the representation of elements, there are three tyes: - - Binary - - String - - Field element (the field is specified in each case. We consider 2 possible fields: Fp and Fr, where p... and r... .) - -## Table of Contents - -[TOC] - -## Jordi - -* compconstant - Returns 1 if `in` (expanded to binary array) > `ct` -* aliascheck - check if `in` (expanded to binary array) oveflowed its 254 bits (<= -1) -* babyjub - twisted Edwards curve 168700.x^2 + y^2 = 1 + 168696.x^2.y^2 - * BabyAdd - (`xout`,`yout`) = (`x1`,`y1`) + (`x2`,`y2`) - * BabyDbl - (`xout`,`yout`) = 2*(`x`,`y`) - * BabyCheck - check that (`x`,`y`) is on the curve -* binsub - binary subtraction -* gates - logical gates -* mimc - SNARK-friendly hash Minimal Multiplicative Complexity. - * https://eprint.iacr.org/2016/492.pdf - * zcash/zcash#2233 -* smt - Sparse Merkle Tree - * https://ethresear.ch/t/optimizing-sparse-merkle-trees/3751 -* montgomery https://en.wikipedia.org/wiki/Montgomery_curve - -## Circuits - -### sha256 - -Folder containing the implementation of sha256 hash circuit. - -### smt - -Folder containing the circuit implementation of Sparse Merkle Trees. - -### aliascheck - -- `AliasCheck()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### babyjub - -Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby_jubjub) in twisted Edwards form. (TODO: Expose here the characteristics of the curve?) - - -- `BabyAdd()` - - - DESCRIPTION - - It adds two points on the Baby Jubjub curve. More specifically, given two points P1 = (`x1`, `y1`) and P2 = (`x2`, `y2`) it returns a point P3 = (`xout`, `yout`) such that - - (`xout`, `yout`) = (`x1`,`y1`) + (`x2`,`y2`) - = ((`x1y2`+`y1x2`)/(1+`dx1x2y1y2`)),(`y1y2`-`ax1x2`)/(1-`dx1x2y1y2`)) - - - SCHEMA - ``` - var a var d - | | - | | - ______v_________v_______ - input x1 ----> | | - input y1 ----> | BabyAdd() | ----> output xout - input x2 ----> | | ----> output yout - input y2 ----> |________________________| - ``` - - - INPUTS - - | Input | Representation | Description | | - | ------------- | ------------- | ------------- | ------------- | - | `x1` | Bigint | Field element of Fp | First coordinate of a point (x1, y1) on E. | - | `y1` | Bigint | Field element of Fp | Second coordinate of a point (x1, y1) on E. | - | `x2` | Bigint | Field element of Fp | First coordinate of a point (x2, y2) on E. | - | `y2` | Bigint | Field element of Fp | Second coordinate of a point (x2, y2) on E. | - - Requirement: at least `x1`!=`x2` or `y1`!=`y2`. - - - OUTPUT - - | Input | Representation | Description | | - | ------------- | ------------- | ------------- | ------------- | - | `xout` | Bigint | Field element of Fp | First coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). | - | `yout` | Bigint | Field element of Fp | Second coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). | - - - BENCHMARKS (constraints) - - - EXAMPLE - -- `BabyDbl()` - - DESCRIPTION : doubles a point (`xout`,`yout`) = 2*(`x`,`y`). - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `BabyCheck()` - - - DESCRIPTION : checks if a given point is in the curve. - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `BabyPbk()` - - - DESCRIPTION: : given a private key, it returns the associated public key. - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - - -### binsub - -- `BinSub(n)` - - - DESCRIPTION: binary substraction. - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### binsum - -- `nbits(a)` - - - DESCRIPTION : binary sum. - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `BinSum(n, ops)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### bitify - -- `Num2Bits()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Num2Bits_strict()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Bits2Num()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Bits2Num_strict()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Num2BitsNeg()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### comparators - -- `IsZero() ` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `IsEqual()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `ForceEqualIfEnabled()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `LessThan()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `GreaterThan()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `GreaterEqThan()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### compconstant - -- `CompConstant(ct)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### eddsa - -Edwards Digital Signature Algorithm in Baby Jubjbub (link a eddsa) - -- `EdDSAVerifier(n)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### eddsamimc - -- `EdDSAMiMCVerifier()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### eddsamimcsponge - -- `EdDSAMiMCSpongeVerifier()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### eddsaposeidon - -- `EdDSAPoseidonVerifier()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### escalarmul - -- `EscalarMulWindow(base, k)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `EscalarMul(n, base)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### escalarmulany - -- `Multiplexor2()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `BitElementMulAny()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `SegmentMulAny(n)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `EscalarMulAny(n)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### escalarmulfix - -- `WindowMulFix()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `SegmentMulFix(nWindows)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `EscalarMulFix(n, BASE)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### escalarmulw4table - -- `pointAdd` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `EscalarMulW4Table` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### gates - -- `XOR` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `AND` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `OR` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `NOT` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `NAND` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `NOR` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `MultiAND` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### mimc - -Implementation of MiMC-7 hash in Fp being... (link to description of the hash) - -- `MiMC7(nrounds)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `MultiMiMC7(nInputs, nRounds)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### mimcsponge - -- `MiMCSponge(nInputs, nRounds, nOutputs)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `MiMCFeistel(nrounds)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### montgomery - -- `Edwards2Montgomery()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Montgomery2Edwards()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `MontgomeryAdd()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `MontgomeryDouble()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### multiplexer - -- `log2(a)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `EscalarProduct(w)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Decoder(w)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Multiplexer(wIn, nIn)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### mux1 - -- `MultiMux1(n)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Mux1()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### mux2 - -- `MultiMux2(n)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Mux2()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### mux3 - -- `MultiMux3(n)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Mux3()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### mux4 - -- `MultiMux4(n)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Mux4()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### pedersen_old - -Old version of the Pedersen hash (do not use any -more?). - -### pedersen - -- `Window4()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Segment(nWindows)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Pedersen(n)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### pointbits - -- `sqrt(n)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Bits2Point()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Bits2Point_Strict()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Point2Bits` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Point2Bits_Strict` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### poseidon - -Implementation of Poseidon hash function (LINK) - -- `Sigma()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Ark(t, C, r)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Mix(t, M)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -- `Poseidon(nInputs)` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### sign - -- `Sign()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE - -### switcher - -- `Switcher()` - - - DESCRIPTION - - SCHEMA - - INPUT - - OUTPUT - - BENCHMARKS - - EXAMPLE diff --git a/prover/circom/circuits/aliascheck.circom b/prover/circom/circuits/aliascheck.circom deleted file mode 100644 index 1c5a5f87..00000000 --- a/prover/circom/circuits/aliascheck.circom +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "compconstant.circom"; - - -template AliasCheck() { - - signal input in[254]; - - component compConstant = CompConstant(-1); - - for (var i=0; i<254; i++) in[i] ==> compConstant.in[i]; - - compConstant.out === 0; -} diff --git a/prover/circom/circuits/babyjub.circom b/prover/circom/circuits/babyjub.circom deleted file mode 100644 index 36810fee..00000000 --- a/prover/circom/circuits/babyjub.circom +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "bitify.circom"; -include "escalarmulfix.circom"; - -template BabyAdd() { - signal input x1; - signal input y1; - signal input x2; - signal input y2; - signal output xout; - signal output yout; - - signal beta; - signal gamma; - signal delta; - signal tau; - - var a = 168700; - var d = 168696; - - beta <== x1*y2; - gamma <== y1*x2; - delta <== (-a*x1+y1)*(x2 + y2); - tau <== beta * gamma; - - xout <-- (beta + gamma) / (1+ d*tau); - (1+ d*tau) * xout === (beta + gamma); - - yout <-- (delta + a*beta - gamma) / (1-d*tau); - (1-d*tau)*yout === (delta + a*beta - gamma); -} - -template BabyDbl() { - signal input x; - signal input y; - signal output xout; - signal output yout; - - component adder = BabyAdd(); - adder.x1 <== x; - adder.y1 <== y; - adder.x2 <== x; - adder.y2 <== y; - - adder.xout ==> xout; - adder.yout ==> yout; -} - - -template BabyCheck() { - signal input x; - signal input y; - - signal x2; - signal y2; - - var a = 168700; - var d = 168696; - - x2 <== x*x; - y2 <== y*y; - - a*x2 + y2 === 1 + d*x2*y2; -} - -// Extracts the public key from private key -template BabyPbk() { - signal input in; - signal output Ax; - signal output Ay; - - var BASE8[2] = [ - 5299619240641551281634865583518297030282874472190772894086521144482721001553, - 16950150798460657717958625567821834550301663161624707787222815936182638968203 - ]; - - component pvkBits = Num2Bits(253); - pvkBits.in <== in; - - component mulFix = EscalarMulFix(253, BASE8); - - var i; - for (i=0; i<253; i++) { - mulFix.e[i] <== pvkBits.out[i]; - } - Ax <== mulFix.out[0]; - Ay <== mulFix.out[1]; -} diff --git a/prover/circom/circuits/binsub.circom b/prover/circom/circuits/binsub.circom deleted file mode 100644 index a20fbf81..00000000 --- a/prover/circom/circuits/binsub.circom +++ /dev/null @@ -1,74 +0,0 @@ - /* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ - -/* -This component creates a binary substraction. - - -Main Constraint: - (in[0][0] * 2^0 + in[0][1] * 2^1 + ..... + in[0][n-1] * 2^(n-1)) + - + 2^n - - (in[1][0] * 2^0 + in[1][1] * 2^1 + ..... + in[1][n-1] * 2^(n-1)) - === - out[0] * 2^0 + out[1] * 2^1 + + out[n-1] *2^(n-1) + aux - - - out[0] * (out[0] - 1) === 0 - out[1] * (out[0] - 1) === 0 - . - . - . - out[n-1] * (out[n-1] - 1) === 0 - aux * (aux-1) == 0 - -*/ -pragma circom 2.0.0; - -template BinSub(n) { - signal input in[2][n]; - signal output out[n]; - - signal aux; - - var lin = 2**n; - var lout = 0; - - var i; - - for (i=0; i> i) & 1; - - // Ensure out is binary - out[i] * (out[i] - 1) === 0; - - lout = lout + out[i]*(2**i); - } - - aux <-- (lin >> n) & 1; - aux*(aux-1) === 0; - lout = lout + aux*(2**n); - - // Ensure the sum; - lin === lout; -} diff --git a/prover/circom/circuits/binsum.circom b/prover/circom/circuits/binsum.circom deleted file mode 100644 index 28c7fcce..00000000 --- a/prover/circom/circuits/binsum.circom +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ - -/* - -Binary Sum -========== - -This component creates a binary sum componet of ops operands and n bits each operand. - -e is Number of carries: Depends on the number of operands in the input. - -Main Constraint: - in[0][0] * 2^0 + in[0][1] * 2^1 + ..... + in[0][n-1] * 2^(n-1) + - + in[1][0] * 2^0 + in[1][1] * 2^1 + ..... + in[1][n-1] * 2^(n-1) + - + .. - + in[ops-1][0] * 2^0 + in[ops-1][1] * 2^1 + ..... + in[ops-1][n-1] * 2^(n-1) + - === - out[0] * 2^0 + out[1] * 2^1 + + out[n+e-1] *2(n+e-1) - -To waranty binary outputs: - - out[0] * (out[0] - 1) === 0 - out[1] * (out[0] - 1) === 0 - . - . - . - out[n+e-1] * (out[n+e-1] - 1) == 0 - - */ - - -/* - This function calculates the number of extra bits in the output to do the full sum. - */ - pragma circom 2.0.0; - -function nbits(a) { - var n = 1; - var r = 0; - while (n-1> k) & 1; - - // Ensure out is binary - out[k] * (out[k] - 1) === 0; - - lout += out[k] * e2; - - e2 = e2+e2; - } - - // Ensure the sum; - - lin === lout; -} diff --git a/prover/circom/circuits/bitify.circom b/prover/circom/circuits/bitify.circom deleted file mode 100644 index bfdd4e82..00000000 --- a/prover/circom/circuits/bitify.circom +++ /dev/null @@ -1,106 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "comparators.circom"; -include "aliascheck.circom"; - - -template Num2Bits(n) { - signal input in; - signal output out[n]; - var lc1=0; - - var e2=1; - for (var i = 0; i> i) & 1; - out[i] * (out[i] -1 ) === 0; - lc1 += out[i] * e2; - e2 = e2+e2; - } - - lc1 === in; -} - -template Num2Bits_strict() { - signal input in; - signal output out[254]; - - component aliasCheck = AliasCheck(); - component n2b = Num2Bits(254); - in ==> n2b.in; - - for (var i=0; i<254; i++) { - n2b.out[i] ==> out[i]; - n2b.out[i] ==> aliasCheck.in[i]; - } -} - -template Bits2Num(n) { - signal input in[n]; - signal output out; - var lc1=0; - - var e2 = 1; - for (var i = 0; i out; -} - -template Bits2Num_strict() { - signal input in[254]; - signal output out; - - component aliasCheck = AliasCheck(); - component b2n = Bits2Num(254); - - for (var i=0; i<254; i++) { - in[i] ==> b2n.in[i]; - in[i] ==> aliasCheck.in[i]; - } - - b2n.out ==> out; -} - -template Num2BitsNeg(n) { - signal input in; - signal output out[n]; - var lc1=0; - - component isZero; - - isZero = IsZero(); - - var neg = n == 0 ? 0 : 2**n - in; - - for (var i = 0; i> i) & 1; - out[i] * (out[i] -1 ) === 0; - lc1 += out[i] * 2**i; - } - - in ==> isZero.in; - - - - lc1 + isZero.out * 2**n === 2**n - in; -} diff --git a/prover/circom/circuits/comparators.circom b/prover/circom/circuits/comparators.circom deleted file mode 100644 index bfed0320..00000000 --- a/prover/circom/circuits/comparators.circom +++ /dev/null @@ -1,141 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "bitify.circom"; -include "binsum.circom"; - -template IsZero() { - signal input in; - signal output out; - - signal inv; - - inv <-- in!=0 ? 1/in : 0; - - out <== -in*inv +1; - in*out === 0; -} - - -template IsEqual() { - signal input in[2]; - signal output out; - - component isz = IsZero(); - - in[1] - in[0] ==> isz.in; - - isz.out ==> out; -} - -template ForceEqualIfEnabled() { - signal input enabled; - signal input in[2]; - - component isz = IsZero(); - - in[1] - in[0] ==> isz.in; - - (1 - isz.out)*enabled === 0; -} - -/* -// N is the number of bits the input have. -// The MSF is the sign bit. -template LessThan(n) { - signal input in[2]; - signal output out; - - component num2Bits0; - component num2Bits1; - - component adder; - - adder = BinSum(n, 2); - - num2Bits0 = Num2Bits(n); - num2Bits1 = Num2BitsNeg(n); - - in[0] ==> num2Bits0.in; - in[1] ==> num2Bits1.in; - - var i; - for (i=0;i adder.in[0][i]; - num2Bits1.out[i] ==> adder.in[1][i]; - } - - adder.out[n-1] ==> out; -} -*/ - -template LessThan(n) { - assert(n <= 252); - signal input in[2]; - signal output out; - - component n2b = Num2Bits(n+1); - - n2b.in <== in[0]+ (1< out; -} - -// N is the number of bits the input have. -// The MSF is the sign bit. -template GreaterThan(n) { - signal input in[2]; - signal output out; - - component lt = LessThan(n); - - lt.in[0] <== in[1]; - lt.in[1] <== in[0]; - lt.out ==> out; -} - -// N is the number of bits the input have. -// The MSF is the sign bit. -template GreaterEqThan(n) { - signal input in[2]; - signal output out; - - component lt = LessThan(n); - - lt.in[0] <== in[1]; - lt.in[1] <== in[0]+1; - lt.out ==> out; -} - diff --git a/prover/circom/circuits/compconstant.circom b/prover/circom/circuits/compconstant.circom deleted file mode 100644 index 1bca83a5..00000000 --- a/prover/circom/circuits/compconstant.circom +++ /dev/null @@ -1,74 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "bitify.circom"; - -// Returns 1 if in (in binary) > ct - -template CompConstant(ct) { - signal input in[254]; - signal output out; - - signal parts[127]; - signal sout; - - var clsb; - var cmsb; - var slsb; - var smsb; - - var sum=0; - - var b = (1 << 128) -1; - var a = 1; - var e = 1; - var i; - - for (i=0;i<127; i++) { - clsb = (ct >> (i*2)) & 1; - cmsb = (ct >> (i*2+1)) & 1; - slsb = in[i*2]; - smsb = in[i*2+1]; - - if ((cmsb==0)&&(clsb==0)) { - parts[i] <== -b*smsb*slsb + b*smsb + b*slsb; - } else if ((cmsb==0)&&(clsb==1)) { - parts[i] <== a*smsb*slsb - a*slsb + b*smsb - a*smsb + a; - } else if ((cmsb==1)&&(clsb==0)) { - parts[i] <== b*smsb*slsb - a*smsb + a; - } else { - parts[i] <== -a*smsb*slsb + a; - } - - sum = sum + parts[i]; - - b = b -e; - a = a +e; - e = e*2; - } - - sout <== sum; - - component num2bits = Num2Bits(135); - - num2bits.in <== sout; - - out <== num2bits.out[127]; -} diff --git a/prover/circom/circuits/eddsa.circom b/prover/circom/circuits/eddsa.circom deleted file mode 100644 index 04b5f87c..00000000 --- a/prover/circom/circuits/eddsa.circom +++ /dev/null @@ -1,139 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "compconstant.circom"; -include "pointbits.circom"; -include "pedersen.circom"; -include "escalarmulany.circom"; -include "escalarmulfix.circom"; - -template EdDSAVerifier(n) { - signal input msg[n]; - - signal input A[256]; - signal input R8[256]; - signal input S[256]; - - signal Ax; - signal Ay; - - signal R8x; - signal R8y; - - var i; - -// Ensure S compConstant.in[i]; - } - compConstant.out === 0; - S[254] === 0; - S[255] === 0; - -// Convert A to Field elements (And verify A) - - component bits2pointA = Bits2Point_Strict(); - - for (i=0; i<256; i++) { - bits2pointA.in[i] <== A[i]; - } - Ax <== bits2pointA.out[0]; - Ay <== bits2pointA.out[1]; - -// Convert R8 to Field elements (And verify R8) - - component bits2pointR8 = Bits2Point_Strict(); - - for (i=0; i<256; i++) { - bits2pointR8.in[i] <== R8[i]; - } - R8x <== bits2pointR8.out[0]; - R8y <== bits2pointR8.out[1]; - -// Calculate the h = H(R,A, msg) - - component hash = Pedersen(512+n); - - for (i=0; i<256; i++) { - hash.in[i] <== R8[i]; - hash.in[256+i] <== A[i]; - } - for (i=0; i. -*/ -pragma circom 2.0.0; - -include "compconstant.circom"; -include "pointbits.circom"; -include "mimc.circom"; -include "bitify.circom"; -include "escalarmulany.circom"; -include "escalarmulfix.circom"; - -template EdDSAMiMCVerifier() { - signal input enabled; - signal input Ax; - signal input Ay; - - signal input S; - signal input R8x; - signal input R8y; - - signal input M; - - var i; - -// Ensure S compConstant.in[i]; - } - compConstant.in[253] <== 0; - compConstant.out === 0; - -// Calculate the h = H(R,A, msg) - - component hash = MultiMiMC7(5, 91); - hash.in[0] <== R8x; - hash.in[1] <== R8y; - hash.in[2] <== Ax; - hash.in[3] <== Ay; - hash.in[4] <== M; - hash.k <== 0; - - component h2bits = Num2Bits_strict(); - h2bits.in <== hash.out; - -// Calculate second part of the right side: right2 = h*8*A - - // Multiply by 8 by adding it 3 times. This also ensure that the result is in - // the subgroup. - component dbl1 = BabyDbl(); - dbl1.x <== Ax; - dbl1.y <== Ay; - component dbl2 = BabyDbl(); - dbl2.x <== dbl1.xout; - dbl2.y <== dbl1.yout; - component dbl3 = BabyDbl(); - dbl3.x <== dbl2.xout; - dbl3.y <== dbl2.yout; - - // We check that A is not zero. - component isZero = IsZero(); - isZero.in <== dbl3.x; - isZero.out === 0; - - component mulAny = EscalarMulAny(254); - for (i=0; i<254; i++) { - mulAny.e[i] <== h2bits.out[i]; - } - mulAny.p[0] <== dbl3.xout; - mulAny.p[1] <== dbl3.yout; - - -// Compute the right side: right = R8 + right2 - - component addRight = BabyAdd(); - addRight.x1 <== R8x; - addRight.y1 <== R8y; - addRight.x2 <== mulAny.out[0]; - addRight.y2 <== mulAny.out[1]; - -// Calculate left side of equation left = S*B8 - - var BASE8[2] = [ - 5299619240641551281634865583518297030282874472190772894086521144482721001553, - 16950150798460657717958625567821834550301663161624707787222815936182638968203 - ]; - component mulFix = EscalarMulFix(253, BASE8); - for (i=0; i<253; i++) { - mulFix.e[i] <== snum2bits.out[i]; - } - -// Do the comparation left == right if enabled; - - component eqCheckX = ForceEqualIfEnabled(); - eqCheckX.enabled <== enabled; - eqCheckX.in[0] <== mulFix.out[0]; - eqCheckX.in[1] <== addRight.xout; - - component eqCheckY = ForceEqualIfEnabled(); - eqCheckY.enabled <== enabled; - eqCheckY.in[0] <== mulFix.out[1]; - eqCheckY.in[1] <== addRight.yout; -} diff --git a/prover/circom/circuits/eddsamimcsponge.circom b/prover/circom/circuits/eddsamimcsponge.circom deleted file mode 100644 index 3267c455..00000000 --- a/prover/circom/circuits/eddsamimcsponge.circom +++ /dev/null @@ -1,124 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "compconstant.circom"; -include "pointbits.circom"; -include "mimcsponge.circom"; -include "bitify.circom"; -include "escalarmulany.circom"; -include "escalarmulfix.circom"; - -template EdDSAMiMCSpongeVerifier() { - signal input enabled; - signal input Ax; - signal input Ay; - - signal input S; - signal input R8x; - signal input R8y; - - signal input M; - - var i; - -// Ensure S compConstant.in[i]; - } - compConstant.in[253] <== 0; - compConstant.out === 0; - -// Calculate the h = H(R,A, msg) - - component hash = MiMCSponge(5, 220, 1); - hash.ins[0] <== R8x; - hash.ins[1] <== R8y; - hash.ins[2] <== Ax; - hash.ins[3] <== Ay; - hash.ins[4] <== M; - hash.k <== 0; - - component h2bits = Num2Bits_strict(); - h2bits.in <== hash.outs[0]; - -// Calculate second part of the right side: right2 = h*8*A - - // Multiply by 8 by adding it 3 times. This also ensure that the result is in - // the subgroup. - component dbl1 = BabyDbl(); - dbl1.x <== Ax; - dbl1.y <== Ay; - component dbl2 = BabyDbl(); - dbl2.x <== dbl1.xout; - dbl2.y <== dbl1.yout; - component dbl3 = BabyDbl(); - dbl3.x <== dbl2.xout; - dbl3.y <== dbl2.yout; - - // We check that A is not zero. - component isZero = IsZero(); - isZero.in <== dbl3.x; - isZero.out === 0; - - component mulAny = EscalarMulAny(254); - for (i=0; i<254; i++) { - mulAny.e[i] <== h2bits.out[i]; - } - mulAny.p[0] <== dbl3.xout; - mulAny.p[1] <== dbl3.yout; - - -// Compute the right side: right = R8 + right2 - - component addRight = BabyAdd(); - addRight.x1 <== R8x; - addRight.y1 <== R8y; - addRight.x2 <== mulAny.out[0]; - addRight.y2 <== mulAny.out[1]; - -// Calculate left side of equation left = S*B8 - - var BASE8[2] = [ - 5299619240641551281634865583518297030282874472190772894086521144482721001553, - 16950150798460657717958625567821834550301663161624707787222815936182638968203 - ]; - component mulFix = EscalarMulFix(253, BASE8); - for (i=0; i<253; i++) { - mulFix.e[i] <== snum2bits.out[i]; - } - -// Do the comparation left == right if enabled; - - component eqCheckX = ForceEqualIfEnabled(); - eqCheckX.enabled <== enabled; - eqCheckX.in[0] <== mulFix.out[0]; - eqCheckX.in[1] <== addRight.xout; - - component eqCheckY = ForceEqualIfEnabled(); - eqCheckY.enabled <== enabled; - eqCheckY.in[0] <== mulFix.out[1]; - eqCheckY.in[1] <== addRight.yout; -} diff --git a/prover/circom/circuits/eddsaposeidon.circom b/prover/circom/circuits/eddsaposeidon.circom deleted file mode 100644 index 1fce1f32..00000000 --- a/prover/circom/circuits/eddsaposeidon.circom +++ /dev/null @@ -1,123 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "compconstant.circom"; -include "poseidon.circom"; -include "bitify.circom"; -include "escalarmulany.circom"; -include "escalarmulfix.circom"; - -template EdDSAPoseidonVerifier() { - signal input enabled; - signal input Ax; - signal input Ay; - - signal input S; - signal input R8x; - signal input R8y; - - signal input M; - - var i; - -// Ensure S compConstant.in[i]; - } - compConstant.in[253] <== 0; - compConstant.out*enabled === 0; - -// Calculate the h = H(R,A, msg) - - component hash = Poseidon(5); - - hash.inputs[0] <== R8x; - hash.inputs[1] <== R8y; - hash.inputs[2] <== Ax; - hash.inputs[3] <== Ay; - hash.inputs[4] <== M; - - component h2bits = Num2Bits_strict(); - h2bits.in <== hash.out; - -// Calculate second part of the right side: right2 = h*8*A - - // Multiply by 8 by adding it 3 times. This also ensure that the result is in - // the subgroup. - component dbl1 = BabyDbl(); - dbl1.x <== Ax; - dbl1.y <== Ay; - component dbl2 = BabyDbl(); - dbl2.x <== dbl1.xout; - dbl2.y <== dbl1.yout; - component dbl3 = BabyDbl(); - dbl3.x <== dbl2.xout; - dbl3.y <== dbl2.yout; - - // We check that A is not zero. - component isZero = IsZero(); - isZero.in <== dbl3.x; - isZero.out*enabled === 0; - - component mulAny = EscalarMulAny(254); - for (i=0; i<254; i++) { - mulAny.e[i] <== h2bits.out[i]; - } - mulAny.p[0] <== dbl3.xout; - mulAny.p[1] <== dbl3.yout; - - -// Compute the right side: right = R8 + right2 - - component addRight = BabyAdd(); - addRight.x1 <== R8x; - addRight.y1 <== R8y; - addRight.x2 <== mulAny.out[0]; - addRight.y2 <== mulAny.out[1]; - -// Calculate left side of equation left = S*B8 - - var BASE8[2] = [ - 5299619240641551281634865583518297030282874472190772894086521144482721001553, - 16950150798460657717958625567821834550301663161624707787222815936182638968203 - ]; - component mulFix = EscalarMulFix(253, BASE8); - for (i=0; i<253; i++) { - mulFix.e[i] <== snum2bits.out[i]; - } - -// Do the comparation left == right if enabled; - - component eqCheckX = ForceEqualIfEnabled(); - eqCheckX.enabled <== enabled; - eqCheckX.in[0] <== mulFix.out[0]; - eqCheckX.in[1] <== addRight.xout; - - component eqCheckY = ForceEqualIfEnabled(); - eqCheckY.enabled <== enabled; - eqCheckY.in[0] <== mulFix.out[1]; - eqCheckY.in[1] <== addRight.yout; -} diff --git a/prover/circom/circuits/escalarmul.circom b/prover/circom/circuits/escalarmul.circom deleted file mode 100644 index 809d9957..00000000 --- a/prover/circom/circuits/escalarmul.circom +++ /dev/null @@ -1,166 +0,0 @@ - /* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ - -/* - - ┏━━━━━━━━━━━┓ - ┃ ┃ - ┃ ┃ - (inx, iny) ══════════════════════════════════════════▶┃ EC Point ┃ - ┃ ╠═▶ (outx, outy) - ╔══▶┃ Adder ┃ - ║ ┃ ┃ - ║ ┃ ┃ - ║ ┃ ┃ - ┏━━━━━━━━━━━┓ ┏━━━━━━━━━━━━┓ ║ ┗━━━━━━━━━━━┛ - ┃ ┃ ┃ ┃ ║ - ┃ ┃ ┃ ┃ ║ - ┃ ╠═══(p0x,p0y)═══▶┃ ┃ ║ - ┃ ╠═══(p1x,p1y)═══▶┃ ┃ ║ - ┃ ╠═══(p2x,p2y)═══▶┃ ┃ ║ - ┃ ╠═══(p3x,p3y)═══▶┃ ┃ ║ - ┃ ╠═══(p4x,p4y)═══▶┃ ┃ ║ - ┃ ╠═══(p5x,p5y)═══▶┃ ┃ ║ - ┃ ╠═══(p6x,p6y)═══▶┃ ┃ ║ - ┃ Constant ╠═══(p7x,p7y)═══▶┃ ┃ ║ - ┃ Points ┃ ┃ Mux4 ╠══╝ - ┃ ╠═══(p8x,p8y)═══▶┃ ┃ - ┃ ╠═══(p9x,p9y)═══▶┃ ┃ - ┃ ╠══(p10x,p10y)══▶┃ ┃ - ┃ ╠══(p11x,p11y)══▶┃ ┃ - ┃ ╠══(p12x,p12y)══▶┃ ┃ - ┃ ╠══(p13x,p13y)══▶┃ ┃ - ┃ ╠══(p14x,p14y)══▶┃ ┃ - ┃ ╠══(p15x,p15y)══▶┃ ┃ - ┃ ┃ ┃ ┃ - ┃ ┃ ┃ ┃ - ┗━━━━━━━━━━━┛ ┗━━━━━━━━━━━━┛ - ▲ ▲ ▲ ▲ - │ │ │ │ - s0 ─────────────────────────────────┘ │ │ │ - s1 ────────────────────────────────────┘ │ │ - s2 ───────────────────────────────────────┘ │ - s3 ──────────────────────────────────────────┘ - - - */ -pragma circom 2.0.0; - -include "mux4.circom"; -include "escalarmulw4table.circom"; -include "babyjub.circom"; - -template EscalarMulWindow(base, k) { - - signal input in[2]; - signal input sel[4]; - signal output out[2]; - - var table[16][2]; - component mux; - component adder; - - var i; - - table = EscalarMulW4Table(base, k); - mux = MultiMux4(2); - adder = BabyAdd(); - - for (i=0; i<4; i++) { - sel[i] ==> mux.s[i]; - } - - for (i=0; i<16; i++) { - mux.c[0][i] <== table[i][0]; - mux.c[1][i] <== table[i][1]; - } - - in[0] ==> adder.x1; - in[1] ==> adder.y1; - - mux.out[0] ==> adder.x2; - mux.out[1] ==> adder.y2; - - adder.xout ==> out[0]; - adder.yout ==> out[1]; -} - -/* - - - ┏━━━━━━━━━┓ ┏━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━┓ - ┃ ┃ ┃ ┃ ┃ ┃ - inp ════▶┃Window(0)┃═════▶┃Window(1)┃════════ . . . . ═════════▶┃ Window(nBlocks-1) ┃═════▶ out - ┃ ┃ ┃ ┃ ┃ ┃ - ┗━━━━━━━━━┛ ┗━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━━┛ - ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ - in[0]─────────┘ │ │ │ │ │ │ │ │ │ │ │ - in[1]───────────┘ │ │ │ │ │ │ │ │ │ │ - in[2]─────────────┘ │ │ │ │ │ │ │ 0 0 - in[3]───────────────┘ │ │ │ │ │ │ - in[4]──────────────────────────┘ │ │ │ │ │ - in[5]────────────────────────────┘ │ │ │ │ - in[6]──────────────────────────────┘ │ │ │ - in[7]────────────────────────────────┘ │ │ - . │ │ - . │ │ - in[n-2]─────────────────────────────────────────────────────────────────────┘ │ - in[n-1]───────────────────────────────────────────────────────────────────────┘ - - */ - -template EscalarMul(n, base) { - signal input in[n]; - signal input inp[2]; // Point input to be added - signal output out[2]; - - var nBlocks = ((n-1)>>2)+1; - var i; - var j; - - component windows[nBlocks]; - - // Construct the windows - for (i=0; i= n) { - windows[i].sel[j] <== 0; - } else { - windows[i].sel[j] <== in[i*4+j]; - } - } - } - - // Start with generator - windows[0].in[0] <== inp[0]; - windows[0].in[1] <== inp[1]; - - for(i=0; i windows[i+1].in[0]; - windows[i].out[1] ==> windows[i+1].in[1]; - } - - windows[nBlocks-1].out[0] ==> out[0]; - windows[nBlocks-1].out[1] ==> out[1]; -} diff --git a/prover/circom/circuits/escalarmulany.circom b/prover/circom/circuits/escalarmulany.circom deleted file mode 100644 index f07fe7d5..00000000 --- a/prover/circom/circuits/escalarmulany.circom +++ /dev/null @@ -1,197 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "montgomery.circom"; -include "babyjub.circom"; -include "comparators.circom"; - -template Multiplexor2() { - signal input sel; - signal input in[2][2]; - signal output out[2]; - - out[0] <== (in[1][0] - in[0][0])*sel + in[0][0]; - out[1] <== (in[1][1] - in[0][1])*sel + in[0][1]; -} - -template BitElementMulAny() { - signal input sel; - signal input dblIn[2]; - signal input addIn[2]; - signal output dblOut[2]; - signal output addOut[2]; - - component doubler = MontgomeryDouble(); - component adder = MontgomeryAdd(); - component selector = Multiplexor2(); - - - sel ==> selector.sel; - - dblIn[0] ==> doubler.in[0]; - dblIn[1] ==> doubler.in[1]; - doubler.out[0] ==> adder.in1[0]; - doubler.out[1] ==> adder.in1[1]; - addIn[0] ==> adder.in2[0]; - addIn[1] ==> adder.in2[1]; - addIn[0] ==> selector.in[0][0]; - addIn[1] ==> selector.in[0][1]; - adder.out[0] ==> selector.in[1][0]; - adder.out[1] ==> selector.in[1][1]; - - doubler.out[0] ==> dblOut[0]; - doubler.out[1] ==> dblOut[1]; - selector.out[0] ==> addOut[0]; - selector.out[1] ==> addOut[1]; -} - -// p is montgomery point -// n must be <= 248 -// returns out in twisted edwards -// Double is in montgomery to be linked; - -template SegmentMulAny(n) { - signal input e[n]; - signal input p[2]; - signal output out[2]; - signal output dbl[2]; - - component bits[n-1]; - - component e2m = Edwards2Montgomery(); - - p[0] ==> e2m.in[0]; - p[1] ==> e2m.in[1]; - - var i; - - bits[0] = BitElementMulAny(); - e2m.out[0] ==> bits[0].dblIn[0]; - e2m.out[1] ==> bits[0].dblIn[1]; - e2m.out[0] ==> bits[0].addIn[0]; - e2m.out[1] ==> bits[0].addIn[1]; - e[1] ==> bits[0].sel; - - for (i=1; i bits[i].dblIn[0]; - bits[i-1].dblOut[1] ==> bits[i].dblIn[1]; - bits[i-1].addOut[0] ==> bits[i].addIn[0]; - bits[i-1].addOut[1] ==> bits[i].addIn[1]; - e[i+1] ==> bits[i].sel; - } - - bits[n-2].dblOut[0] ==> dbl[0]; - bits[n-2].dblOut[1] ==> dbl[1]; - - component m2e = Montgomery2Edwards(); - - bits[n-2].addOut[0] ==> m2e.in[0]; - bits[n-2].addOut[1] ==> m2e.in[1]; - - component eadder = BabyAdd(); - - m2e.out[0] ==> eadder.x1; - m2e.out[1] ==> eadder.y1; - -p[0] ==> eadder.x2; - p[1] ==> eadder.y2; - - component lastSel = Multiplexor2(); - - e[0] ==> lastSel.sel; - eadder.xout ==> lastSel.in[0][0]; - eadder.yout ==> lastSel.in[0][1]; - m2e.out[0] ==> lastSel.in[1][0]; - m2e.out[1] ==> lastSel.in[1][1]; - - lastSel.out[0] ==> out[0]; - lastSel.out[1] ==> out[1]; -} - -// This function assumes that p is in the subgroup and it is different to 0 - -template EscalarMulAny(n) { - signal input e[n]; // Input in binary format - signal input p[2]; // Point (Twisted format) - signal output out[2]; // Point (Twisted format) - - var nsegments = (n-1)\148 +1; - var nlastsegment = n - (nsegments-1)*148; - - component segments[nsegments]; - component doublers[nsegments-1]; - component m2e[nsegments-1]; - component adders[nsegments-1]; - component zeropoint = IsZero(); - zeropoint.in <== p[0]; - - var s; - var i; - var nseg; - - for (s=0; s segments[s].e[i]; - } - - if (s==0) { - // force G8 point if input point is zero - segments[s].p[0] <== p[0] + (5299619240641551281634865583518297030282874472190772894086521144482721001553 - p[0])*zeropoint.out; - segments[s].p[1] <== p[1] + (16950150798460657717958625567821834550301663161624707787222815936182638968203 - p[1])*zeropoint.out; - } else { - doublers[s-1] = MontgomeryDouble(); - m2e[s-1] = Montgomery2Edwards(); - adders[s-1] = BabyAdd(); - - segments[s-1].dbl[0] ==> doublers[s-1].in[0]; - segments[s-1].dbl[1] ==> doublers[s-1].in[1]; - - doublers[s-1].out[0] ==> m2e[s-1].in[0]; - doublers[s-1].out[1] ==> m2e[s-1].in[1]; - - m2e[s-1].out[0] ==> segments[s].p[0]; - m2e[s-1].out[1] ==> segments[s].p[1]; - - if (s==1) { - segments[s-1].out[0] ==> adders[s-1].x1; - segments[s-1].out[1] ==> adders[s-1].y1; - } else { - adders[s-2].xout ==> adders[s-1].x1; - adders[s-2].yout ==> adders[s-1].y1; - } - segments[s].out[0] ==> adders[s-1].x2; - segments[s].out[1] ==> adders[s-1].y2; - } - } - - if (nsegments == 1) { - segments[0].out[0]*(1-zeropoint.out) ==> out[0]; - segments[0].out[1]+(1-segments[0].out[1])*zeropoint.out ==> out[1]; - } else { - adders[nsegments-2].xout*(1-zeropoint.out) ==> out[0]; - adders[nsegments-2].yout+(1-adders[nsegments-2].yout)*zeropoint.out ==> out[1]; - } -} diff --git a/prover/circom/circuits/escalarmulfix.circom b/prover/circom/circuits/escalarmulfix.circom deleted file mode 100644 index 4669d36f..00000000 --- a/prover/circom/circuits/escalarmulfix.circom +++ /dev/null @@ -1,299 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "mux3.circom"; -include "montgomery.circom"; -include "babyjub.circom"; - -/* - Window of 3 elements, it calculates - out = base + base*in[0] + 2*base*in[1] + 4*base*in[2] - out4 = 4*base - - The result should be compensated. - */ - -/* - - The scalar is s = a0 + a1*2^3 + a2*2^6 + ...... + a81*2^243 - First We calculate Q = B + 2^3*B + 2^6*B + ......... + 2^246*B - - Then we calculate S1 = 2*2^246*B + (1 + a0)*B + (2^3 + a1)*B + .....+ (2^243 + a81)*B - - And Finaly we compute the result: RES = SQ - Q - - As you can see the input of the adders cannot be equal nor zero, except for the last - substraction that it's done in montgomery. - - A good way to see it is that the accumulator input of the adder >= 2^247*B and the other input - is the output of the windows that it's going to be <= 2^246*B - */ -template WindowMulFix() { - signal input in[3]; - signal input base[2]; - signal output out[2]; - signal output out8[2]; // Returns 8*Base (To be linked) - - component mux = MultiMux3(2); - - mux.s[0] <== in[0]; - mux.s[1] <== in[1]; - mux.s[2] <== in[2]; - - component dbl2 = MontgomeryDouble(); - component adr3 = MontgomeryAdd(); - component adr4 = MontgomeryAdd(); - component adr5 = MontgomeryAdd(); - component adr6 = MontgomeryAdd(); - component adr7 = MontgomeryAdd(); - component adr8 = MontgomeryAdd(); - -// in[0] -> 1*BASE - - mux.c[0][0] <== base[0]; - mux.c[1][0] <== base[1]; - -// in[1] -> 2*BASE - dbl2.in[0] <== base[0]; - dbl2.in[1] <== base[1]; - mux.c[0][1] <== dbl2.out[0]; - mux.c[1][1] <== dbl2.out[1]; - -// in[2] -> 3*BASE - adr3.in1[0] <== base[0]; - adr3.in1[1] <== base[1]; - adr3.in2[0] <== dbl2.out[0]; - adr3.in2[1] <== dbl2.out[1]; - mux.c[0][2] <== adr3.out[0]; - mux.c[1][2] <== adr3.out[1]; - -// in[3] -> 4*BASE - adr4.in1[0] <== base[0]; - adr4.in1[1] <== base[1]; - adr4.in2[0] <== adr3.out[0]; - adr4.in2[1] <== adr3.out[1]; - mux.c[0][3] <== adr4.out[0]; - mux.c[1][3] <== adr4.out[1]; - -// in[4] -> 5*BASE - adr5.in1[0] <== base[0]; - adr5.in1[1] <== base[1]; - adr5.in2[0] <== adr4.out[0]; - adr5.in2[1] <== adr4.out[1]; - mux.c[0][4] <== adr5.out[0]; - mux.c[1][4] <== adr5.out[1]; - -// in[5] -> 6*BASE - adr6.in1[0] <== base[0]; - adr6.in1[1] <== base[1]; - adr6.in2[0] <== adr5.out[0]; - adr6.in2[1] <== adr5.out[1]; - mux.c[0][5] <== adr6.out[0]; - mux.c[1][5] <== adr6.out[1]; - -// in[6] -> 7*BASE - adr7.in1[0] <== base[0]; - adr7.in1[1] <== base[1]; - adr7.in2[0] <== adr6.out[0]; - adr7.in2[1] <== adr6.out[1]; - mux.c[0][6] <== adr7.out[0]; - mux.c[1][6] <== adr7.out[1]; - -// in[7] -> 8*BASE - adr8.in1[0] <== base[0]; - adr8.in1[1] <== base[1]; - adr8.in2[0] <== adr7.out[0]; - adr8.in2[1] <== adr7.out[1]; - mux.c[0][7] <== adr8.out[0]; - mux.c[1][7] <== adr8.out[1]; - - out8[0] <== adr8.out[0]; - out8[1] <== adr8.out[1]; - - out[0] <== mux.out[0]; - out[1] <== mux.out[1]; -} - - -/* - This component does a multiplication of a escalar times a fix base - Signals: - e: The scalar in bits - base: the base point in edwards format - out: The result - dbl: Point in Edwards to be linked to the next segment. - */ - -template SegmentMulFix(nWindows) { - signal input e[nWindows*3]; - signal input base[2]; - signal output out[2]; - signal output dbl[2]; - - var i; - var j; - - // Convert the base to montgomery - - component e2m = Edwards2Montgomery(); - e2m.in[0] <== base[0]; - e2m.in[1] <== base[1]; - - component windows[nWindows]; - component adders[nWindows]; - component cadders[nWindows]; - - // In the last step we add an extra doubler so that numbers do not match. - component dblLast = MontgomeryDouble(); - - for (i=0; i out[0]; - cAdd.yout ==> out[1]; - - windows[nWindows-1].out8[0] ==> dbl[0]; - windows[nWindows-1].out8[1] ==> dbl[1]; -} - - -/* -This component multiplies a escalar times a fixed point BASE (twisted edwards format) - Signals - e: The escalar in binary format - out: The output point in twisted edwards - */ -template EscalarMulFix(n, BASE) { - signal input e[n]; // Input in binary format - signal output out[2]; // Point (Twisted format) - - var nsegments = (n-1)\246 +1; // 249 probably would work. But I'm not sure and for security I keep 246 - var nlastsegment = n - (nsegments-1)*249; - - component segments[nsegments]; - - component m2e[nsegments-1]; - component adders[nsegments-1]; - - var s; - var i; - var nseg; - var nWindows; - - for (s=0; s m2e[s-1].in[0]; - segments[s-1].dbl[1] ==> m2e[s-1].in[1]; - - m2e[s-1].out[0] ==> segments[s].base[0]; - m2e[s-1].out[1] ==> segments[s].base[1]; - - if (s==1) { - segments[s-1].out[0] ==> adders[s-1].x1; - segments[s-1].out[1] ==> adders[s-1].y1; - } else { - adders[s-2].xout ==> adders[s-1].x1; - adders[s-2].yout ==> adders[s-1].y1; - } - segments[s].out[0] ==> adders[s-1].x2; - segments[s].out[1] ==> adders[s-1].y2; - } - } - - if (nsegments == 1) { - segments[0].out[0] ==> out[0]; - segments[0].out[1] ==> out[1]; - } else { - adders[nsegments-2].xout ==> out[0]; - adders[nsegments-2].yout ==> out[1]; - } -} diff --git a/prover/circom/circuits/escalarmulw4table.circom b/prover/circom/circuits/escalarmulw4table.circom deleted file mode 100644 index 25c095af..00000000 --- a/prover/circom/circuits/escalarmulw4table.circom +++ /dev/null @@ -1,52 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -function pointAdd(x1,y1,x2,y2) { - var a = 168700; - var d = 168696; - - var res[2]; - res[0] = (x1*y2 + y1*x2) / (1 + d*x1*x2*y1*y2); - res[1] = (y1*y2 - a*x1*x2) / (1 - d*x1*x2*y1*y2); - return res; -} - -function EscalarMulW4Table(base, k) { - var out[16][2]; - - var i; - var p[2]; - - var dbl[2] = base; - - for (i=0; i. -*/ -pragma circom 2.0.0; - -template XOR() { - signal input a; - signal input b; - signal output out; - - out <== a + b - 2*a*b; -} - -template AND() { - signal input a; - signal input b; - signal output out; - - out <== a*b; -} - -template OR() { - signal input a; - signal input b; - signal output out; - - out <== a + b - a*b; -} - -template NOT() { - signal input in; - signal output out; - - out <== 1 + in - 2*in; -} - -template NAND() { - signal input a; - signal input b; - signal output out; - - out <== 1 - a*b; -} - -template NOR() { - signal input a; - signal input b; - signal output out; - - out <== a*b + 1 - a - b; -} - -template MultiAND(n) { - signal input in[n]; - signal output out; - component and1; - component and2; - component ands[2]; - if (n==1) { - out <== in[0]; - } else if (n==2) { - and1 = AND(); - and1.a <== in[0]; - and1.b <== in[1]; - out <== and1.out; - } else { - and2 = AND(); - var n1 = n\2; - var n2 = n-n\2; - ands[0] = MultiAND(n1); - ands[1] = MultiAND(n2); - var i; - for (i=0; i. -*/ -pragma circom 2.0.0; - -template MiMC7(nrounds) { - signal input x_in; - signal input k; - signal output out; - - var c[91] = [ - 0, - 20888961410941983456478427210666206549300505294776164667214940546594746570981, - 15265126113435022738560151911929040668591755459209400716467504685752745317193, - 8334177627492981984476504167502758309043212251641796197711684499645635709656, - 1374324219480165500871639364801692115397519265181803854177629327624133579404, - 11442588683664344394633565859260176446561886575962616332903193988751292992472, - 2558901189096558760448896669327086721003508630712968559048179091037845349145, - 11189978595292752354820141775598510151189959177917284797737745690127318076389, - 3262966573163560839685415914157855077211340576201936620532175028036746741754, - 17029914891543225301403832095880481731551830725367286980611178737703889171730, - 4614037031668406927330683909387957156531244689520944789503628527855167665518, - 19647356996769918391113967168615123299113119185942498194367262335168397100658, - 5040699236106090655289931820723926657076483236860546282406111821875672148900, - 2632385916954580941368956176626336146806721642583847728103570779270161510514, - 17691411851977575435597871505860208507285462834710151833948561098560743654671, - 11482807709115676646560379017491661435505951727793345550942389701970904563183, - 8360838254132998143349158726141014535383109403565779450210746881879715734773, - 12663821244032248511491386323242575231591777785787269938928497649288048289525, - 3067001377342968891237590775929219083706800062321980129409398033259904188058, - 8536471869378957766675292398190944925664113548202769136103887479787957959589, - 19825444354178182240559170937204690272111734703605805530888940813160705385792, - 16703465144013840124940690347975638755097486902749048533167980887413919317592, - 13061236261277650370863439564453267964462486225679643020432589226741411380501, - 10864774797625152707517901967943775867717907803542223029967000416969007792571, - 10035653564014594269791753415727486340557376923045841607746250017541686319774, - 3446968588058668564420958894889124905706353937375068998436129414772610003289, - 4653317306466493184743870159523234588955994456998076243468148492375236846006, - 8486711143589723036499933521576871883500223198263343024003617825616410932026, - 250710584458582618659378487568129931785810765264752039738223488321597070280, - 2104159799604932521291371026105311735948154964200596636974609406977292675173, - 16313562605837709339799839901240652934758303521543693857533755376563489378839, - 6032365105133504724925793806318578936233045029919447519826248813478479197288, - 14025118133847866722315446277964222215118620050302054655768867040006542798474, - 7400123822125662712777833064081316757896757785777291653271747396958201309118, - 1744432620323851751204287974553233986555641872755053103823939564833813704825, - 8316378125659383262515151597439205374263247719876250938893842106722210729522, - 6739722627047123650704294650168547689199576889424317598327664349670094847386, - 21211457866117465531949733809706514799713333930924902519246949506964470524162, - 13718112532745211817410303291774369209520657938741992779396229864894885156527, - 5264534817993325015357427094323255342713527811596856940387954546330728068658, - 18884137497114307927425084003812022333609937761793387700010402412840002189451, - 5148596049900083984813839872929010525572543381981952060869301611018636120248, - 19799686398774806587970184652860783461860993790013219899147141137827718662674, - 19240878651604412704364448729659032944342952609050243268894572835672205984837, - 10546185249390392695582524554167530669949955276893453512788278945742408153192, - 5507959600969845538113649209272736011390582494851145043668969080335346810411, - 18177751737739153338153217698774510185696788019377850245260475034576050820091, - 19603444733183990109492724100282114612026332366576932662794133334264283907557, - 10548274686824425401349248282213580046351514091431715597441736281987273193140, - 1823201861560942974198127384034483127920205835821334101215923769688644479957, - 11867589662193422187545516240823411225342068709600734253659804646934346124945, - 18718569356736340558616379408444812528964066420519677106145092918482774343613, - 10530777752259630125564678480897857853807637120039176813174150229243735996839, - 20486583726592018813337145844457018474256372770211860618687961310422228379031, - 12690713110714036569415168795200156516217175005650145422920562694422306200486, - 17386427286863519095301372413760745749282643730629659997153085139065756667205, - 2216432659854733047132347621569505613620980842043977268828076165669557467682, - 6309765381643925252238633914530877025934201680691496500372265330505506717193, - 20806323192073945401862788605803131761175139076694468214027227878952047793390, - 4037040458505567977365391535756875199663510397600316887746139396052445718861, - 19948974083684238245321361840704327952464170097132407924861169241740046562673, - 845322671528508199439318170916419179535949348988022948153107378280175750024, - 16222384601744433420585982239113457177459602187868460608565289920306145389382, - 10232118865851112229330353999139005145127746617219324244541194256766741433339, - 6699067738555349409504843460654299019000594109597429103342076743347235369120, - 6220784880752427143725783746407285094967584864656399181815603544365010379208, - 6129250029437675212264306655559561251995722990149771051304736001195288083309, - 10773245783118750721454994239248013870822765715268323522295722350908043393604, - 4490242021765793917495398271905043433053432245571325177153467194570741607167, - 19596995117319480189066041930051006586888908165330319666010398892494684778526, - 837850695495734270707668553360118467905109360511302468085569220634750561083, - 11803922811376367215191737026157445294481406304781326649717082177394185903907, - 10201298324909697255105265958780781450978049256931478989759448189112393506592, - 13564695482314888817576351063608519127702411536552857463682060761575100923924, - 9262808208636973454201420823766139682381973240743541030659775288508921362724, - 173271062536305557219323722062711383294158572562695717740068656098441040230, - 18120430890549410286417591505529104700901943324772175772035648111937818237369, - 20484495168135072493552514219686101965206843697794133766912991150184337935627, - 19155651295705203459475805213866664350848604323501251939850063308319753686505, - 11971299749478202793661982361798418342615500543489781306376058267926437157297, - 18285310723116790056148596536349375622245669010373674803854111592441823052978, - 7069216248902547653615508023941692395371990416048967468982099270925308100727, - 6465151453746412132599596984628739550147379072443683076388208843341824127379, - 16143532858389170960690347742477978826830511669766530042104134302796355145785, - 19362583304414853660976404410208489566967618125972377176980367224623492419647, - 1702213613534733786921602839210290505213503664731919006932367875629005980493, - 10781825404476535814285389902565833897646945212027592373510689209734812292327, - 4212716923652881254737947578600828255798948993302968210248673545442808456151, - 7594017890037021425366623750593200398174488805473151513558919864633711506220, - 18979889247746272055963929241596362599320706910852082477600815822482192194401, - 13602139229813231349386885113156901793661719180900395818909719758150455500533 - ]; - - var t; - signal t2[nrounds]; - signal t4[nrounds]; - signal t6[nrounds]; - signal t7[nrounds-1]; - - for (var i=0; i nRounds should be 220 -template MiMCSponge(nInputs, nRounds, nOutputs) { - signal input ins[nInputs]; - signal input k; - signal output outs[nOutputs]; - - var i; - - // S = R||C - component S[nInputs + nOutputs - 1]; - - for (i = 0; i < nInputs; i++) { - S[i] = MiMCFeistel(nRounds); - S[i].k <== k; - if (i == 0) { - S[i].xL_in <== ins[0]; - S[i].xR_in <== 0; - } else { - S[i].xL_in <== S[i-1].xL_out + ins[i]; - S[i].xR_in <== S[i-1].xR_out; - } - } - - outs[0] <== S[nInputs - 1].xL_out; - - for (i = 0; i < nOutputs - 1; i++) { - S[nInputs + i] = MiMCFeistel(nRounds); - S[nInputs + i].k <== k; - S[nInputs + i].xL_in <== S[nInputs + i - 1].xL_out; - S[nInputs + i].xR_in <== S[nInputs + i - 1].xR_out; - outs[i + 1] <== S[nInputs + i].xL_out; - } -} - -template MiMCFeistel(nrounds) { - signal input xL_in; - signal input xR_in; - signal input k; - signal output xL_out; - signal output xR_out; - - // doesn't contain the first and last round constants, which are always zero - var c_partial[218] = [ - 7120861356467848435263064379192047478074060781135320967663101236819528304084, - 5024705281721889198577876690145313457398658950011302225525409148828000436681, - 17980351014018068290387269214713820287804403312720763401943303895585469787384, - 19886576439381707240399940949310933992335779767309383709787331470398675714258, - 1213715278223786725806155661738676903520350859678319590331207960381534602599, - 18162138253399958831050545255414688239130588254891200470934232514682584734511, - 7667462281466170157858259197976388676420847047604921256361474169980037581876, - 7207551498477838452286210989212982851118089401128156132319807392460388436957, - 9864183311657946807255900203841777810810224615118629957816193727554621093838, - 4798196928559910300796064665904583125427459076060519468052008159779219347957, - 17387238494588145257484818061490088963673275521250153686214197573695921400950, - 10005334761930299057035055370088813230849810566234116771751925093634136574742, - 11897542014760736209670863723231849628230383119798486487899539017466261308762, - 16771780563523793011283273687253985566177232886900511371656074413362142152543, - 749264854018824809464168489785113337925400687349357088413132714480582918506, - 3683645737503705042628598550438395339383572464204988015434959428676652575331, - 7556750851783822914673316211129907782679509728346361368978891584375551186255, - 20391289379084797414557439284689954098721219201171527383291525676334308303023, - 18146517657445423462330854383025300323335289319277199154920964274562014376193, - 8080173465267536232534446836148661251987053305394647905212781979099916615292, - 10796443006899450245502071131975731672911747129805343722228413358507805531141, - 5404287610364961067658660283245291234008692303120470305032076412056764726509, - 4623894483395123520243967718315330178025957095502546813929290333264120223168, - 16845753148201777192406958674202574751725237939980634861948953189320362207797, - 4622170486584704769521001011395820886029808520586507873417553166762370293671, - 16688277490485052681847773549197928630624828392248424077804829676011512392564, - 11878652861183667748838188993669912629573713271883125458838494308957689090959, - 2436445725746972287496138382764643208791713986676129260589667864467010129482, - 1888098689545151571063267806606510032698677328923740058080630641742325067877, - 148924106504065664829055598316821983869409581623245780505601526786791681102, - 18875020877782404439294079398043479420415331640996249745272087358069018086569, - 15189693413320228845990326214136820307649565437237093707846682797649429515840, - 19669450123472657781282985229369348220906547335081730205028099210442632534079, - 5521922218264623411380547905210139511350706092570900075727555783240701821773, - 4144769320246558352780591737261172907511489963810975650573703217887429086546, - 10097732913112662248360143041019433907849917041759137293018029019134392559350, - 1720059427972723034107765345743336447947522473310069975142483982753181038321, - 6302388219880227251325608388535181451187131054211388356563634768253301290116, - 6745410632962119604799318394592010194450845483518862700079921360015766217097, - 10858157235265583624235850660462324469799552996870780238992046963007491306222, - 20241898894740093733047052816576694435372877719072347814065227797906130857593, - 10165780782761211520836029617746977303303335603838343292431760011576528327409, - 2832093654883670345969792724123161241696170611611744759675180839473215203706, - 153011722355526826233082383360057587249818749719433916258246100068258954737, - 20196970640587451358539129330170636295243141659030208529338914906436009086943, - 3180973917010545328313139835982464870638521890385603025657430208141494469656, - 17198004293191777441573635123110935015228014028618868252989374962722329283022, - 7642160509228669138628515458941659189680509753651629476399516332224325757132, - 19346204940546791021518535594447257347218878114049998691060016493806845179755, - 11501810868606870391127866188394535330696206817602260610801897042898616817272, - 3113973447392053821824427670386252797811804954746053461397972968381571297505, - 6545064306297957002139416752334741502722251869537551068239642131448768236585, - 5203908808704813498389265425172875593837960384349653691918590736979872578408, - 2246692432011290582160062129070762007374502637007107318105405626910313810224, - 11760570435432189127645691249600821064883781677693087773459065574359292849137, - 5543749482491340532547407723464609328207990784853381797689466144924198391839, - 8837549193990558762776520822018694066937602576881497343584903902880277769302, - 12855514863299373699594410385788943772765811961581749194183533625311486462501, - 5363660674689121676875069134269386492382220935599781121306637800261912519729, - 13162342403579303950549728848130828093497701266240457479693991108217307949435, - 916941639326869583414469202910306428966657806899788970948781207501251816730, - 15618589556584434434009868216186115416835494805174158488636000580759692174228, - 8959562060028569701043973060670353733575345393653685776974948916988033453971, - 16390754464333401712265575949874369157699293840516802426621216808905079127650, - 168282396747788514908709091757591226095443902501365500003618183905496160435, - 8327443473179334761744301768309008451162322941906921742120510244986704677004, - 17213012626801210615058753489149961717422101711567228037597150941152495100640, - 10394369641533736715250242399198097296122982486516256408681925424076248952280, - 17784386835392322654196171115293700800825771210400152504776806618892170162248, - 16533189939837087893364000390641148516479148564190420358849587959161226782982, - 18725396114211370207078434315900726338547621160475533496863298091023511945076, - 7132325028834551397904855671244375895110341505383911719294705267624034122405, - 148317947440800089795933930720822493695520852448386394775371401743494965187, - 19001050671757720352890779127693793630251266879994702723636759889378387053056, - 18824274411769830274877839365728651108434404855803844568234862945613766611460, - 12771414330193951156383998390424063470766226667986423961689712557338777174205, - 11332046574800279729678603488745295198038913503395629790213378101166488244657, - 9607550223176946388146938069307456967842408600269548190739947540821716354749, - 8756385288462344550200229174435953103162307705310807828651304665320046782583, - 176061952957067086877570020242717222844908281373122372938833890096257042779, - 12200212977482648306758992405065921724409841940671166017620928947866825250857, - 10868453624107875516866146499877130701929063632959660262366632833504750028858, - 2016095394399807253596787752134573207202567875457560571095586743878953450738, - 21815578223768330433802113452339488275704145896544481092014911825656390567514, - 4923772847693564777744725640710197015181591950368494148029046443433103381621, - 1813584943682214789802230765734821149202472893379265320098816901270224589984, - 10810123816265612772922113403831964815724109728287572256602010709288980656498, - 1153669123397255702524721206511185557982017410156956216465120456256288427021, - 5007518659266430200134478928344522649876467369278722765097865662497773767152, - 2511432546938591792036639990606464315121646668029252285288323664350666551637, - 32883284540320451295484135704808083452381176816565850047310272290579727564, - 10484856914279112612610993418405543310546746652738541161791501150994088679557, - 2026733759645519472558796412979210009170379159866522399881566309631434814953, - 14731806221235869882801331463708736361296174006732553130708107037190460654379, - 14740327483193277147065845135561988641238516852487657117813536909482068950652, - 18787428285295558781869865751953016580493190547148386433580291216673009884554, - 3804047064713122820157099453648459188816376755739202017447862327783289895072, - 16709604795697901641948603019242067672006293290826991671766611326262532802914, - 11061717085931490100602849654034280576915102867237101935487893025907907250695, - 2821730726367472966906149684046356272806484545281639696873240305052362149654, - 17467794879902895769410571945152708684493991588672014763135370927880883292655, - 1571520786233540988201616650622796363168031165456869481368085474420849243232, - 10041051776251223165849354194892664881051125330236567356945669006147134614302, - 3981753758468103976812813304477670033098707002886030847251581853700311567551, - 4365864398105436789177703571412645548020537580493599380018290523813331678900, - 2391801327305361293476178683853802679507598622000359948432171562543560193350, - 214219368547551689972421167733597094823289857206402800635962137077096090722, - 18192064100315141084242006659317257023098826945893371479835220462302399655674, - 15487549757142039139328911515400805508248576685795694919457041092150651939253, - 10142447197759703415402259672441315777933858467700579946665223821199077641122, - 11246573086260753259993971254725613211193686683988426513880826148090811891866, - 6574066859860991369704567902211886840188702386542112593710271426704432301235, - 11311085442652291634822798307831431035776248927202286895207125867542470350078, - 20977948360215259915441258687649465618185769343138135384346964466965010873779, - 792781492853909872425531014397300057232399608769451037135936617996830018501, - 5027602491523497423798779154966735896562099398367163998686335127580757861872, - 14595204575654316237672764823862241845410365278802914304953002937313300553572, - 13973538843621261113924259058427434053808430378163734641175100160836376897004, - 16395063164993626722686882727042150241125309409717445381854913964674649318585, - 8465768840047024550750516678171433288207841931251654898809033371655109266663, - 21345603324471810861925019445720576814602636473739003852898308205213912255830, - 21171984405852590343970239018692870799717057961108910523876770029017785940991, - 10761027113757988230637066281488532903174559953630210849190212601991063767647, - 6678298831065390834922566306988418588227382406175769592902974103663687992230, - 4993662582188632374202316265508850988596880036291765531885657575099537176757, - 18364168158495573675698600238443218434246806358811328083953887470513967121206, - 3506345610354615013737144848471391553141006285964325596214723571988011984829, - 248732676202643792226973868626360612151424823368345645514532870586234380100, - 10090204501612803176317709245679152331057882187411777688746797044706063410969, - 21297149835078365363970699581821844234354988617890041296044775371855432973500, - 16729368143229828574342820060716366330476985824952922184463387490091156065099, - 4467191506765339364971058668792642195242197133011672559453028147641428433293, - 8677548159358013363291014307402600830078662555833653517843708051504582990832, - 1022951765127126818581466247360193856197472064872288389992480993218645055345, - 1888195070251580606973417065636430294417895423429240431595054184472931224452, - 4221265384902749246920810956363310125115516771964522748896154428740238579824, - 2825393571154632139467378429077438870179957021959813965940638905853993971879, - 19171031072692942278056619599721228021635671304612437350119663236604712493093, - 10780807212297131186617505517708903709488273075252405602261683478333331220733, - 18230936781133176044598070768084230333433368654744509969087239465125979720995, - 16901065971871379877929280081392692752968612240624985552337779093292740763381, - 146494141603558321291767829522948454429758543710648402457451799015963102253, - 2492729278659146790410698334997955258248120870028541691998279257260289595548, - 2204224910006646535594933495262085193210692406133533679934843341237521233504, - 16062117410185840274616925297332331018523844434907012275592638570193234893570, - 5894928453677122829055071981254202951712129328678534592916926069506935491729, - 4947482739415078212217504789923078546034438919537985740403824517728200332286, - 16143265650645676880461646123844627780378251900510645261875867423498913438066, - 397690828254561723549349897112473766901585444153303054845160673059519614409, - 11272653598912269895509621181205395118899451234151664604248382803490621227687, - 15566927854306879444693061574322104423426072650522411176731130806720753591030, - 14222898219492484180162096141564251903058269177856173968147960855133048449557, - 16690275395485630428127725067513114066329712673106153451801968992299636791385, - 3667030990325966886479548860429670833692690972701471494757671819017808678584, - 21280039024501430842616328642522421302481259067470872421086939673482530783142, - 15895485136902450169492923978042129726601461603404514670348703312850236146328, - 7733050956302327984762132317027414325566202380840692458138724610131603812560, - 438123800976401478772659663183448617575635636575786782566035096946820525816, - 814913922521637742587885320797606426167962526342166512693085292151314976633, - 12368712287081330853637674140264759478736012797026621876924395982504369598764, - 2494806857395134874309386694756263421445039103814920780777601708371037591569, - 16101132301514338989512946061786320637179843435886825102406248183507106312877, - 6252650284989960032925831409804233477770646333900692286731621844532438095656, - 9277135875276787021836189566799935097400042171346561246305113339462708861695, - 10493603554686607050979497281838644324893776154179810893893660722522945589063, - 8673089750662709235894359384294076697329948991010184356091130382437645649279, - 9558393272910366944245875920138649617479779893610128634419086981339060613250, - 19012287860122586147374214541764572282814469237161122489573881644994964647218, - 9783723818270121678386992630754842961728702994964214799008457449989291229500, - 15550788416669474113213749561488122552422887538676036667630838378023479382689, - 15016165746156232864069722572047169071786333815661109750860165034341572904221, - 6506225705710197163670556961299945987488979904603689017479840649664564978574, - 10796631184889302076168355684722130903785890709107732067446714470783437829037, - 19871836214837460419845806980869387567383718044439891735114283113359312279540, - 20871081766843466343749609089986071784031203517506781251203251608363835140622, - 5100105771517691442278432864090229416166996183792075307747582375962855820797, - 8777887112076272395250620301071581171386440850451972412060638225741125310886, - 5300440870136391278944213332144327695659161151625757537632832724102670898756, - 1205448543652932944633962232545707633928124666868453915721030884663332604536, - 5542499997310181530432302492142574333860449305424174466698068685590909336771, - 11028094245762332275225364962905938096659249161369092798505554939952525894293, - 19187314764836593118404597958543112407224947638377479622725713735224279297009, - 17047263688548829001253658727764731047114098556534482052135734487985276987385, - 19914849528178967155534624144358541535306360577227460456855821557421213606310, - 2929658084700714257515872921366736697080475676508114973627124569375444665664, - 15092262360719700162343163278648422751610766427236295023221516498310468956361, - 21578580340755653236050830649990190843552802306886938815497471545814130084980, - 1258781501221760320019859066036073675029057285507345332959539295621677296991, - 3819598418157732134449049289585680301176983019643974929528867686268702720163, - 8653175945487997845203439345797943132543211416447757110963967501177317426221, - 6614652990340435611114076169697104582524566019034036680161902142028967568142, - 19212515502973904821995111796203064175854996071497099383090983975618035391558, - 18664315914479294273286016871365663486061896605232511201418576829062292269769, - 11498264615058604317482574216318586415670903094838791165247179252175768794889, - 10814026414212439999107945133852431304483604215416531759535467355316227331774, - 17566185590731088197064706533119299946752127014428399631467913813769853431107, - 14016139747289624978792446847000951708158212463304817001882956166752906714332, - 8242601581342441750402731523736202888792436665415852106196418942315563860366, - 9244680976345080074252591214216060854998619670381671198295645618515047080988, - 12216779172735125538689875667307129262237123728082657485828359100719208190116, - 10702811721859145441471328511968332847175733707711670171718794132331147396634, - 6479667912792222539919362076122453947926362746906450079329453150607427372979, - 15117544653571553820496948522381772148324367479772362833334593000535648316185, - 6842203153996907264167856337497139692895299874139131328642472698663046726780, - 12732823292801537626009139514048596316076834307941224506504666470961250728055, - 6936272626871035740815028148058841877090860312517423346335878088297448888663, - 17297554111853491139852678417579991271009602631577069694853813331124433680030, - 16641596134749940573104316021365063031319260205559553673368334842484345864859, - 7400481189785154329569470986896455371037813715804007747228648863919991399081, - 2273205422216987330510475127669563545720586464429614439716564154166712854048, - 15162538063742142685306302282127534305212832649282186184583465569986719234456, - 5628039096440332922248578319648483863204530861778160259559031331287721255522, - 16085392195894691829567913404182676871326863890140775376809129785155092531260, - 14227467863135365427954093998621993651369686288941275436795622973781503444257, - 18224457394066545825553407391290108485121649197258948320896164404518684305122, - 274945154732293792784580363548970818611304339008964723447672490026510689427, - 11050822248291117548220126630860474473945266276626263036056336623671308219529, - 2119542016932434047340813757208803962484943912710204325088879681995922344971 - ]; - - var t; - signal t2[nrounds]; - signal t4[nrounds]; - signal xL[nrounds-1]; - signal xR[nrounds-1]; - - var c; - for (var i=0; i. -*/ - -/* - Source: https://en.wikipedia.org/wiki/Montgomery_curve - - 1 + y 1 + y - [u, v] = [ ------- , ---------- ] - 1 - y (1 - y)x - - */ - pragma circom 2.0.0; - -template Edwards2Montgomery() { - signal input in[2]; - signal output out[2]; - - out[0] <-- (1 + in[1]) / (1 - in[1]); - out[1] <-- out[0] / in[0]; - - - out[0] * (1-in[1]) === (1 + in[1]); - out[1] * in[0] === out[0]; -} - -/* - - u u - 1 - [x, y] = [ ---, ------- ] - v u + 1 - - */ -template Montgomery2Edwards() { - signal input in[2]; - signal output out[2]; - - out[0] <-- in[0] / in[1]; - out[1] <-- (in[0] - 1) / (in[0] + 1); - - out[0] * in[1] === in[0]; - out[1] * (in[0] + 1) === in[0] - 1; -} - - -/* - x2 - x1 - lamda = --------- - y2 - y1 - - x3 + A + x1 + x2 - x3 = B * lamda^2 - A - x1 -x2 => lamda^2 = ------------------ - B - - y3 = (2*x1 + x2 + A)*lamda - B*lamda^3 - y1 => - - - => y3 = lamda * ( 2*x1 + x2 + A - x3 - A - x1 - x2) - y1 => - - => y3 = lamda * ( x1 - x3 ) - y1 - ----------- - - y2 - y1 - lamda = --------- - x2 - x1 - - x3 = B * lamda^2 - A - x1 -x2 - - y3 = lamda * ( x1 - x3 ) - y1 - - */ - -template MontgomeryAdd() { - signal input in1[2]; - signal input in2[2]; - signal output out[2]; - - var a = 168700; - var d = 168696; - - var A = (2 * (a + d)) / (a - d); - var B = 4 / (a - d); - - signal lamda; - - lamda <-- (in2[1] - in1[1]) / (in2[0] - in1[0]); - lamda * (in2[0] - in1[0]) === (in2[1] - in1[1]); - - out[0] <== B*lamda*lamda - A - in1[0] -in2[0]; - out[1] <== lamda * (in1[0] - out[0]) - in1[1]; -} - -/* - - x1_2 = x1*x1 - - 3*x1_2 + 2*A*x1 + 1 - lamda = --------------------- - 2*B*y1 - - x3 = B * lamda^2 - A - x1 -x1 - - y3 = lamda * ( x1 - x3 ) - y1 - - */ -template MontgomeryDouble() { - signal input in[2]; - signal output out[2]; - - var a = 168700; - var d = 168696; - - var A = (2 * (a + d)) / (a - d); - var B = 4 / (a - d); - - signal lamda; - signal x1_2; - - x1_2 <== in[0] * in[0]; - - lamda <-- (3*x1_2 + 2*A*in[0] + 1 ) / (2*B*in[1]); - lamda * (2*B*in[1]) === (3*x1_2 + 2*A*in[0] + 1 ); - - out[0] <== B*lamda*lamda - A - 2*in[0]; - out[1] <== lamda * (in[0] - out[0]) - in[1]; -} diff --git a/prover/circom/circuits/multiplexer.circom b/prover/circom/circuits/multiplexer.circom deleted file mode 100644 index 848e31e4..00000000 --- a/prover/circom/circuits/multiplexer.circom +++ /dev/null @@ -1,115 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ - -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ - -// --> Assignation without constraint -// <-- Assignation without constraint -// === Constraint -// <== Assignation with constraint -// ==> Assignation with constraint -// All variables are members of the field F[p] -// https://github.com/zcash-hackworks/sapling-crypto -// https://github.com/ebfull/bellman - -/* -function log2(a) { - if (a==0) { - return 0; - } - let n = 1; - let r = 1; - while (n success; - success * (success -1) === 0; -} - - -template Multiplexer(wIn, nIn) { - signal input inp[nIn][wIn]; - signal input sel; - signal output out[wIn]; - component dec = Decoder(nIn); - component ep[wIn]; - - for (var k=0; k dec.inp; - for (var j=0; j ep[j].in1[k]; - dec.out[k] ==> ep[j].in2[k]; - } - ep[j].out ==> out[j]; - } - dec.success === 1; -} diff --git a/prover/circom/circuits/mux1.circom b/prover/circom/circuits/mux1.circom deleted file mode 100644 index 444cb849..00000000 --- a/prover/circom/circuits/mux1.circom +++ /dev/null @@ -1,48 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -template MultiMux1(n) { - signal input c[n][2]; // Constants - signal input s; // Selector - signal output out[n]; - - for (var i=0; i mux.s; - - mux.out[0] ==> out; -} diff --git a/prover/circom/circuits/mux2.circom b/prover/circom/circuits/mux2.circom deleted file mode 100644 index 557539bf..00000000 --- a/prover/circom/circuits/mux2.circom +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -template MultiMux2(n) { - signal input c[n][4]; // Constants - signal input s[2]; // Selector - signal output out[n]; - - signal a10[n]; - signal a1[n]; - signal a0[n]; - signal a[n]; - - signal s10; - s10 <== s[1] * s[0]; - - for (var i=0; i mux.s[i]; - } - - mux.out[0] ==> out; -} diff --git a/prover/circom/circuits/mux3.circom b/prover/circom/circuits/mux3.circom deleted file mode 100644 index 4be5f7c6..00000000 --- a/prover/circom/circuits/mux3.circom +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -template MultiMux3(n) { - signal input c[n][8]; // Constants - signal input s[3]; // Selector - signal output out[n]; - - signal a210[n]; - signal a21[n]; - signal a20[n]; - signal a2[n]; - - signal a10[n]; - signal a1[n]; - signal a0[n]; - signal a[n]; - - // 4 constrains for the intermediary variables - signal s10; - s10 <== s[1] * s[0]; - - for (var i=0; i mux.s[i]; - } - - mux.out[0] ==> out; -} diff --git a/prover/circom/circuits/mux4.circom b/prover/circom/circuits/mux4.circom deleted file mode 100644 index 01e98bc8..00000000 --- a/prover/circom/circuits/mux4.circom +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -template MultiMux4(n) { - signal input c[n][16]; // Constants - signal input s[4]; // Selector - signal output out[n]; - - signal a3210[n]; - signal a321[n]; - signal a320[n]; - signal a310[n]; - signal a32[n]; - signal a31[n]; - signal a30[n]; - signal a3[n]; - - signal a210[n]; - signal a21[n]; - signal a20[n]; - signal a10[n]; - signal a2[n]; - signal a1[n]; - signal a0[n]; - signal a[n]; - - // 4 constrains for the intermediary variables - signal s10; - s10 <== s[1] * s[0]; - signal s20; - s20 <== s[2] * s[0]; - signal s21; - s21 <== s[2] * s[1]; - signal s210; - s210 <== s21 * s[0]; - - - for (var i=0; i mux.s[i]; - } - - mux.out[0] ==> out; -} diff --git a/prover/circom/circuits/pedersen.circom b/prover/circom/circuits/pedersen.circom deleted file mode 100644 index a29f4863..00000000 --- a/prover/circom/circuits/pedersen.circom +++ /dev/null @@ -1,257 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "montgomery.circom"; -include "mux3.circom"; -include "babyjub.circom"; - -template Window4() { - signal input in[4]; - signal input base[2]; - signal output out[2]; - signal output out8[2]; // Returns 8*Base (To be linked) - - component mux = MultiMux3(2); - - mux.s[0] <== in[0]; - mux.s[1] <== in[1]; - mux.s[2] <== in[2]; - - component dbl2 = MontgomeryDouble(); - component adr3 = MontgomeryAdd(); - component adr4 = MontgomeryAdd(); - component adr5 = MontgomeryAdd(); - component adr6 = MontgomeryAdd(); - component adr7 = MontgomeryAdd(); - component adr8 = MontgomeryAdd(); - -// in[0] -> 1*BASE - - mux.c[0][0] <== base[0]; - mux.c[1][0] <== base[1]; - -// in[1] -> 2*BASE - dbl2.in[0] <== base[0]; - dbl2.in[1] <== base[1]; - mux.c[0][1] <== dbl2.out[0]; - mux.c[1][1] <== dbl2.out[1]; - -// in[2] -> 3*BASE - adr3.in1[0] <== base[0]; - adr3.in1[1] <== base[1]; - adr3.in2[0] <== dbl2.out[0]; - adr3.in2[1] <== dbl2.out[1]; - mux.c[0][2] <== adr3.out[0]; - mux.c[1][2] <== adr3.out[1]; - -// in[3] -> 4*BASE - adr4.in1[0] <== base[0]; - adr4.in1[1] <== base[1]; - adr4.in2[0] <== adr3.out[0]; - adr4.in2[1] <== adr3.out[1]; - mux.c[0][3] <== adr4.out[0]; - mux.c[1][3] <== adr4.out[1]; - -// in[4] -> 5*BASE - adr5.in1[0] <== base[0]; - adr5.in1[1] <== base[1]; - adr5.in2[0] <== adr4.out[0]; - adr5.in2[1] <== adr4.out[1]; - mux.c[0][4] <== adr5.out[0]; - mux.c[1][4] <== adr5.out[1]; - -// in[5] -> 6*BASE - adr6.in1[0] <== base[0]; - adr6.in1[1] <== base[1]; - adr6.in2[0] <== adr5.out[0]; - adr6.in2[1] <== adr5.out[1]; - mux.c[0][5] <== adr6.out[0]; - mux.c[1][5] <== adr6.out[1]; - -// in[6] -> 7*BASE - adr7.in1[0] <== base[0]; - adr7.in1[1] <== base[1]; - adr7.in2[0] <== adr6.out[0]; - adr7.in2[1] <== adr6.out[1]; - mux.c[0][6] <== adr7.out[0]; - mux.c[1][6] <== adr7.out[1]; - -// in[7] -> 8*BASE - adr8.in1[0] <== base[0]; - adr8.in1[1] <== base[1]; - adr8.in2[0] <== adr7.out[0]; - adr8.in2[1] <== adr7.out[1]; - mux.c[0][7] <== adr8.out[0]; - mux.c[1][7] <== adr8.out[1]; - - out8[0] <== adr8.out[0]; - out8[1] <== adr8.out[1]; - - out[0] <== mux.out[0]; - out[1] <== - mux.out[1]*2*in[3] + mux.out[1]; // Negate y if in[3] is one -} - - -template Segment(nWindows) { - signal input in[nWindows*4]; - signal input base[2]; - signal output out[2]; - - var i; - var j; - - // Convert the base to montgomery - - component e2m = Edwards2Montgomery(); - e2m.in[0] <== base[0]; - e2m.in[1] <== base[1]; - - component windows[nWindows]; - component doublers1[nWindows-1]; - component doublers2[nWindows-1]; - component adders[nWindows-1]; - for (i=0; i 1) { - m2e.in[0] <== adders[nWindows-2].out[0]; - m2e.in[1] <== adders[nWindows-2].out[1]; - } else { - m2e.in[0] <== windows[0].out[0]; - m2e.in[1] <== windows[0].out[1]; - } - - out[0] <== m2e.out[0]; - out[1] <== m2e.out[1]; -} - -template Pedersen(n) { - signal input in[n]; - signal output out[2]; - - var BASE[10][2] = [ - [10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317], - [2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094], - [5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896], - [7107336197374528537877327281242680114152313102022415488494307685842428166594,2857869773864086953506483169737724679646433914307247183624878062391496185654], - [20265828622013100949498132415626198973119240347465898028410217039057588424236,1160461593266035632937973507065134938065359936056410650153315956301179689506], - [1487999857809287756929114517587739322941449154962237464737694709326309567994,14017256862867289575056460215526364897734808720610101650676790868051368668003], - [14618644331049802168996997831720384953259095788558646464435263343433563860015,13115243279999696210147231297848654998887864576952244320558158620692603342236], - [6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695], - [3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506], - [18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481] - - ]; - - var nSegments = ((n-1)\200)+1; - - component segments[nSegments]; - - var i; - var j; - var nBits; - var nWindows; - for (i=0; i1) { - packPoint.in[0] <== adders[nSegments-2].xout; - packPoint.in[1] <== adders[nSegments-2].yout; - } else { - packPoint.in[0] <== segments[0].out[0]; - packPoint.in[1] <== segments[0].out[1]; - } - - out[0] <== packPoint.out[0]; - out[1] <== packPoint.out[1]; -*/ - - if (nSegments>1) { - out[0] <== adders[nSegments-2].xout; - out[1] <== adders[nSegments-2].yout; - } else { - out[0] <== segments[0].out[0]; - out[1] <== segments[0].out[1]; - } -} - diff --git a/prover/circom/circuits/pedersen_old.circom b/prover/circom/circuits/pedersen_old.circom deleted file mode 100644 index c338e44f..00000000 --- a/prover/circom/circuits/pedersen_old.circom +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "escalarmul.circom"; - -template Pedersen(n) { - signal input in[n]; - signal output out[2]; - - var nexps = ((n-1) \ 250) + 1; - var nlastbits = n - (nexps-1)*250; - - component escalarMuls[nexps]; - - var PBASE[10][2] = [ - [10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317], - [2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094], - [5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896], - [7107336197374528537877327281242680114152313102022415488494307685842428166594,2857869773864086953506483169737724679646433914307247183624878062391496185654], - [20265828622013100949498132415626198973119240347465898028410217039057588424236,1160461593266035632937973507065134938065359936056410650153315956301179689506], - [1487999857809287756929114517587739322941449154962237464737694709326309567994,14017256862867289575056460215526364897734808720610101650676790868051368668003], - [14618644331049802168996997831720384953259095788558646464435263343433563860015,13115243279999696210147231297848654998887864576952244320558158620692603342236], - [6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695], - [3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506], - [18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481] - - ]; - - var i; - var j; - var nexpbits; - for (i=0; i out[0]; - escalarMuls[nexps-1].out[1] ==> out[1]; -} diff --git a/prover/circom/circuits/pointbits.circom b/prover/circom/circuits/pointbits.circom deleted file mode 100644 index fa6007db..00000000 --- a/prover/circom/circuits/pointbits.circom +++ /dev/null @@ -1,164 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "bitify.circom"; -include "aliascheck.circom"; -include "compconstant.circom"; -include "babyjub.circom"; - - -function sqrt(n) { - - if (n == 0) { - return 0; - } - - // Test that have solution - var res = n ** ((-1) >> 1); -// if (res!=1) assert(false, "SQRT does not exists"); - if (res!=1) return 0; - - var m = 28; - var c = 19103219067921713944291392827692070036145651957329286315305642004821462161904; - var t = n ** 81540058820840996586704275553141814055101440848469862132140264610111; - var r = n ** ((81540058820840996586704275553141814055101440848469862132140264610111+1)>>1); - var sq; - var i; - var b; - var j; - - while ((r != 0)&&(t != 1)) { - sq = t*t; - i = 1; - while (sq!=1) { - i++; - sq = sq*sq; - } - - // b = c ^ m-i-1 - b = c; - for (j=0; j< m-i-1; j ++) b = b*b; - - m = i; - c = b*b; - t = t*c; - r = r*b; - } - - if (r < 0 ) { - r = -r; - } - - return r; -} - - -template Bits2Point() { - signal input in[256]; - signal output out[2]; -} - -template Bits2Point_Strict() { - signal input in[256]; - signal output out[2]; - - var i; - - // Check aliasing - component aliasCheckY = AliasCheck(); - for (i=0; i<254; i++) { - aliasCheckY.in[i] <== in[i]; - } - in[254] === 0; - - component b2nY = Bits2Num(254); - for (i=0; i<254; i++) { - b2nY.in[i] <== in[i]; - } - - out[1] <== b2nY.out; - - var a = 168700; - var d = 168696; - - var y2 = out[1] * out[1]; - - var x = sqrt( (1-y2)/(a - d*y2) ); - - if (in[255] == 1) x = -x; - - out[0] <-- x; - - component babyCheck = BabyCheck(); - babyCheck.x <== out[0]; - babyCheck.y <== out[1]; - - component n2bX = Num2Bits(254); - n2bX.in <== out[0]; - component aliasCheckX = AliasCheck(); - for (i=0; i<254; i++) { - aliasCheckX.in[i] <== n2bX.out[i]; - } - - component signCalc = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808); - for (i=0; i<254; i++) { - signCalc.in[i] <== n2bX.out[i]; - } - - signCalc.out === in[255]; -} - - -template Point2Bits() { - signal input in[2]; - signal output out[256]; - - -} - -template Point2Bits_Strict() { - signal input in[2]; - signal output out[256]; - - var i; - - component n2bX = Num2Bits(254); - n2bX.in <== in[0]; - component n2bY = Num2Bits(254); - n2bY.in <== in[1]; - - component aliasCheckX = AliasCheck(); - component aliasCheckY = AliasCheck(); - for (i=0; i<254; i++) { - aliasCheckX.in[i] <== n2bX.out[i]; - aliasCheckY.in[i] <== n2bY.out[i]; - } - - component signCalc = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808); - for (i=0; i<254; i++) { - signCalc.in[i] <== n2bX.out[i]; - } - - for (i=0; i<254; i++) { - out[i] <== n2bY.out[i]; - } - out[254] <== 0; - out[255] <== signCalc.out; -} diff --git a/prover/circom/circuits/poseidon.circom b/prover/circom/circuits/poseidon.circom deleted file mode 100644 index 1c45ab95..00000000 --- a/prover/circom/circuits/poseidon.circom +++ /dev/null @@ -1,208 +0,0 @@ -pragma circom 2.0.0; - -include "./poseidon_constants.circom"; - -template Sigma() { - signal input in; - signal output out; - - signal in2; - signal in4; - - in2 <== in*in; - in4 <== in2*in2; - - out <== in4*in; -} - -template Ark(t, C, r) { - signal input in[t]; - signal output out[t]; - - for (var i=0; i0) { - ark[0].in[j] <== inputs[j-1]; - } else { - ark[0].in[j] <== initialState; - } - } - - for (var r = 0; r < nRoundsF\2-1; r++) { - for (var j=0; j0) { - ark[i].in[j] <== inputs[j-1]; - } else { - ark[i].in[j] <== 0; - } - } else { - ark[i].in[j] <== mix[i-1].out[j]; - } - } - - if (i < nRoundsF/2 || i >= nRoundsP + nRoundsF/2) { - k = i < nRoundsF/2 ? i : i - nRoundsP; - mix[i] = Mix(t, M); - for (var j=0; j. -*/ - -/* Ch - -000 0 -001 1 -010 0 -011 1 -100 0 -101 0 -110 1 -111 1 - -out = a&b ^ (!a)&c => - -out = a*(b-c) + c - -*/ -pragma circom 2.0.0; - -template Ch_t(n) { - signal input a[n]; - signal input b[n]; - signal input c[n]; - signal output out[n]; - - for (var k=0; k. -*/ -pragma circom 2.0.0; - -template H(x) { - signal output out[32]; - var c[8] = [0x6a09e667, - 0xbb67ae85, - 0x3c6ef372, - 0xa54ff53a, - 0x510e527f, - 0x9b05688c, - 0x1f83d9ab, - 0x5be0cd19]; - - for (var i=0; i<32; i++) { - out[i] <== (c[x] >> i) & 1; - } -} - -template K(x) { - signal output out[32]; - var c[64] = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 - ]; - - for (var i=0; i<32; i++) { - out[i] <== (c[x] >> i) & 1; - } -} diff --git a/prover/circom/circuits/sha256/main.circom b/prover/circom/circuits/sha256/main.circom deleted file mode 100644 index 88d69d6f..00000000 --- a/prover/circom/circuits/sha256/main.circom +++ /dev/null @@ -1,35 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "sha256_2.circom"; - -template Main() { - signal input a; - signal input b; - signal output out; - - component sha256_2 = Sha256_2(); - - sha256_2.a <== a; - sha256_2.b <== a; - out <== sha256_2.out; -} - -component main = Main(); diff --git a/prover/circom/circuits/sha256/maj.circom b/prover/circom/circuits/sha256/maj.circom deleted file mode 100644 index 1c0940c2..00000000 --- a/prover/circom/circuits/sha256/maj.circom +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ - -/* Maj function for sha256 - -out = a&b ^ a&c ^ b&c => - -out = a*b + a*c + b*c - 2*a*b*c => - -out = a*( b + c - 2*b*c ) + b*c => - -mid = b*c -out = a*( b + c - 2*mid ) + mid - -*/ -pragma circom 2.0.0; - -template Maj_t(n) { - signal input a[n]; - signal input b[n]; - signal input c[n]; - signal output out[n]; - signal mid[n]; - - for (var k=0; k. -*/ -pragma circom 2.0.0; - -template RotR(n, r) { - signal input in[n]; - signal output out[n]; - - for (var i=0; i> k)&1; - } - - component ha0 = H(0); - component hb0 = H(1); - component hc0 = H(2); - component hd0 = H(3); - component he0 = H(4); - component hf0 = H(5); - component hg0 = H(6); - component hh0 = H(7); - - component sha256compression[nBlocks]; - - for (i=0; i. -*/ -pragma circom 2.0.0; - -include "constants.circom"; -include "sha256compression.circom"; -include "../bitify.circom"; - -template Sha256_2() { - signal input a; - signal input b; - signal output out; - - var i; - var k; - - component bits2num = Bits2Num(216); - component num2bits[2]; - - num2bits[0] = Num2Bits(216); - num2bits[1] = Num2Bits(216); - - num2bits[0].in <== a; - num2bits[1].in <== b; - - - component sha256compression = Sha256compression() ; - - component ha0 = H(0); - component hb0 = H(1); - component hc0 = H(2); - component hd0 = H(3); - component he0 = H(4); - component hf0 = H(5); - component hg0 = H(6); - component hh0 = H(7); - - for (k=0; k<32; k++ ) { - sha256compression.hin[0*32+k] <== ha0.out[k]; - sha256compression.hin[1*32+k] <== hb0.out[k]; - sha256compression.hin[2*32+k] <== hc0.out[k]; - sha256compression.hin[3*32+k] <== hd0.out[k]; - sha256compression.hin[4*32+k] <== he0.out[k]; - sha256compression.hin[5*32+k] <== hf0.out[k]; - sha256compression.hin[6*32+k] <== hg0.out[k]; - sha256compression.hin[7*32+k] <== hh0.out[k]; - } - - for (i=0; i<216; i++) { - sha256compression.inp[i] <== num2bits[0].out[215-i]; - sha256compression.inp[i+216] <== num2bits[1].out[215-i]; - } - - sha256compression.inp[432] <== 1; - - for (i=433; i<503; i++) { - sha256compression.inp[i] <== 0; - } - - sha256compression.inp[503] <== 1; - sha256compression.inp[504] <== 1; - sha256compression.inp[505] <== 0; - sha256compression.inp[506] <== 1; - sha256compression.inp[507] <== 1; - sha256compression.inp[508] <== 0; - sha256compression.inp[509] <== 0; - sha256compression.inp[510] <== 0; - sha256compression.inp[511] <== 0; - - for (i=0; i<216; i++) { - bits2num.in[i] <== sha256compression.out[255-i]; - } - - out <== bits2num.out; -} diff --git a/prover/circom/circuits/sha256/sha256compression.circom b/prover/circom/circuits/sha256/sha256compression.circom deleted file mode 100644 index 98f7c986..00000000 --- a/prover/circom/circuits/sha256/sha256compression.circom +++ /dev/null @@ -1,166 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "constants.circom"; -include "t1.circom"; -include "t2.circom"; -include "../binsum.circom"; -include "sigmaplus.circom"; -include "sha256compression_function.circom"; - - -template Sha256compression() { - signal input hin[256]; - signal input inp[512]; - signal output out[256]; - signal a[65][32]; - signal b[65][32]; - signal c[65][32]; - signal d[65][32]; - signal e[65][32]; - signal f[65][32]; - signal g[65][32]; - signal h[65][32]; - signal w[64][32]; - - - var outCalc[256] = sha256compression(hin, inp); - - var i; - for (i=0; i<256; i++) out[i] <-- outCalc[i]; - - component sigmaPlus[48]; - for (i=0; i<48; i++) sigmaPlus[i] = SigmaPlus(); - - component ct_k[64]; - for (i=0; i<64; i++) ct_k[i] = K(i); - - component t1[64]; - for (i=0; i<64; i++) t1[i] = T1(); - - component t2[64]; - for (i=0; i<64; i++) t2[i] = T2(); - - component suma[64]; - for (i=0; i<64; i++) suma[i] = BinSum(32, 2); - - component sume[64]; - for (i=0; i<64; i++) sume[i] = BinSum(32, 2); - - component fsum[8]; - for (i=0; i<8; i++) fsum[i] = BinSum(32, 2); - - var k; - var t; - - for (t=0; t<64; t++) { - if (t<16) { - for (k=0; k<32; k++) { - w[t][k] <== inp[t*32+31-k]; - } - } else { - for (k=0; k<32; k++) { - sigmaPlus[t-16].in2[k] <== w[t-2][k]; - sigmaPlus[t-16].in7[k] <== w[t-7][k]; - sigmaPlus[t-16].in15[k] <== w[t-15][k]; - sigmaPlus[t-16].in16[k] <== w[t-16][k]; - } - - for (k=0; k<32; k++) { - w[t][k] <== sigmaPlus[t-16].out[k]; - } - } - } - - for (k=0; k<32; k++ ) { - a[0][k] <== hin[k]; - b[0][k] <== hin[32*1 + k]; - c[0][k] <== hin[32*2 + k]; - d[0][k] <== hin[32*3 + k]; - e[0][k] <== hin[32*4 + k]; - f[0][k] <== hin[32*5 + k]; - g[0][k] <== hin[32*6 + k]; - h[0][k] <== hin[32*7 + k]; - } - - for (t = 0; t<64; t++) { - for (k=0; k<32; k++) { - t1[t].h[k] <== h[t][k]; - t1[t].e[k] <== e[t][k]; - t1[t].f[k] <== f[t][k]; - t1[t].g[k] <== g[t][k]; - t1[t].k[k] <== ct_k[t].out[k]; - t1[t].w[k] <== w[t][k]; - - t2[t].a[k] <== a[t][k]; - t2[t].b[k] <== b[t][k]; - t2[t].c[k] <== c[t][k]; - } - - for (k=0; k<32; k++) { - sume[t].in[0][k] <== d[t][k]; - sume[t].in[1][k] <== t1[t].out[k]; - - suma[t].in[0][k] <== t1[t].out[k]; - suma[t].in[1][k] <== t2[t].out[k]; - } - - for (k=0; k<32; k++) { - h[t+1][k] <== g[t][k]; - g[t+1][k] <== f[t][k]; - f[t+1][k] <== e[t][k]; - e[t+1][k] <== sume[t].out[k]; - d[t+1][k] <== c[t][k]; - c[t+1][k] <== b[t][k]; - b[t+1][k] <== a[t][k]; - a[t+1][k] <== suma[t].out[k]; - } - } - - for (k=0; k<32; k++) { - fsum[0].in[0][k] <== hin[32*0+k]; - fsum[0].in[1][k] <== a[64][k]; - fsum[1].in[0][k] <== hin[32*1+k]; - fsum[1].in[1][k] <== b[64][k]; - fsum[2].in[0][k] <== hin[32*2+k]; - fsum[2].in[1][k] <== c[64][k]; - fsum[3].in[0][k] <== hin[32*3+k]; - fsum[3].in[1][k] <== d[64][k]; - fsum[4].in[0][k] <== hin[32*4+k]; - fsum[4].in[1][k] <== e[64][k]; - fsum[5].in[0][k] <== hin[32*5+k]; - fsum[5].in[1][k] <== f[64][k]; - fsum[6].in[0][k] <== hin[32*6+k]; - fsum[6].in[1][k] <== g[64][k]; - fsum[7].in[0][k] <== hin[32*7+k]; - fsum[7].in[1][k] <== h[64][k]; - } - - for (k=0; k<32; k++) { - out[31-k] === fsum[0].out[k]; - out[32+31-k] === fsum[1].out[k]; - out[64+31-k] === fsum[2].out[k]; - out[96+31-k] === fsum[3].out[k]; - out[128+31-k] === fsum[4].out[k]; - out[160+31-k] === fsum[5].out[k]; - out[192+31-k] === fsum[6].out[k]; - out[224+31-k] === fsum[7].out[k]; - } -} diff --git a/prover/circom/circuits/sha256/sha256compression_function.circom b/prover/circom/circuits/sha256/sha256compression_function.circom deleted file mode 100644 index 9f8d5b86..00000000 --- a/prover/circom/circuits/sha256/sha256compression_function.circom +++ /dev/null @@ -1,112 +0,0 @@ -// signal input hin[256]; -// signal input inp[512]; -// signal output out[256]; -pragma circom 2.0.0; - -function rrot(x, n) { - return ((x >> n) | (x << (32-n))) & 0xFFFFFFFF; -} - -function bsigma0(x) { - return rrot(x,2) ^ rrot(x,13) ^ rrot(x,22); -} - -function bsigma1(x) { - return rrot(x,6) ^ rrot(x,11) ^ rrot(x,25); -} - -function ssigma0(x) { - return rrot(x,7) ^ rrot(x,18) ^ (x >> 3); -} - -function ssigma1(x) { - return rrot(x,17) ^ rrot(x,19) ^ (x >> 10); -} - -function Maj(x, y, z) { - return (x&y) ^ (x&z) ^ (y&z); -} - -function Ch(x, y, z) { - return (x & y) ^ ((0xFFFFFFFF ^x) & z); -} - -function sha256K(i) { - var k[64] = [ - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 - ]; - return k[i]; -} - -function sha256compression(hin, inp) { - var H[8]; - var a; - var b; - var c; - var d; - var e; - var f; - var g; - var h; - var out[256]; - for (var i=0; i<8; i++) { - H[i] = 0; - for (var j=0; j<32; j++) { - H[i] += hin[i*32+j] << j; - } - } - a=H[0]; - b=H[1]; - c=H[2]; - d=H[3]; - e=H[4]; - f=H[5]; - g=H[6]; - h=H[7]; - var w[64]; - var T1; - var T2; - for (var i=0; i<64; i++) { - if (i<16) { - w[i]=0; - for (var j=0; j<32; j++) { - w[i] += inp[i*32+31-j]<> j) & 1; - } - } - return out; -} diff --git a/prover/circom/circuits/sha256/shift.circom b/prover/circom/circuits/sha256/shift.circom deleted file mode 100644 index 317cd328..00000000 --- a/prover/circom/circuits/sha256/shift.circom +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -template ShR(n, r) { - signal input in[n]; - signal output out[n]; - - for (var i=0; i= n) { - out[i] <== 0; - } else { - out[i] <== in[ i+r ]; - } - } -} - diff --git a/prover/circom/circuits/sha256/sigma.circom b/prover/circom/circuits/sha256/sigma.circom deleted file mode 100644 index bcb0b805..00000000 --- a/prover/circom/circuits/sha256/sigma.circom +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "xor3.circom"; -include "rotate.circom"; -include "shift.circom"; - -template SmallSigma(ra, rb, rc) { - signal input in[32]; - signal output out[32]; - var k; - - component rota = RotR(32, ra); - component rotb = RotR(32, rb); - component shrc = ShR(32, rc); - - for (k=0; k<32; k++) { - rota.in[k] <== in[k]; - rotb.in[k] <== in[k]; - shrc.in[k] <== in[k]; - } - - component xor3 = Xor3(32); - for (k=0; k<32; k++) { - xor3.a[k] <== rota.out[k]; - xor3.b[k] <== rotb.out[k]; - xor3.c[k] <== shrc.out[k]; - } - - for (k=0; k<32; k++) { - out[k] <== xor3.out[k]; - } -} - -template BigSigma(ra, rb, rc) { - signal input in[32]; - signal output out[32]; - var k; - - component rota = RotR(32, ra); - component rotb = RotR(32, rb); - component rotc = RotR(32, rc); - for (k=0; k<32; k++) { - rota.in[k] <== in[k]; - rotb.in[k] <== in[k]; - rotc.in[k] <== in[k]; - } - - component xor3 = Xor3(32); - - for (k=0; k<32; k++) { - xor3.a[k] <== rota.out[k]; - xor3.b[k] <== rotb.out[k]; - xor3.c[k] <== rotc.out[k]; - } - - for (k=0; k<32; k++) { - out[k] <== xor3.out[k]; - } -} diff --git a/prover/circom/circuits/sha256/sigmaplus.circom b/prover/circom/circuits/sha256/sigmaplus.circom deleted file mode 100644 index 35e3300a..00000000 --- a/prover/circom/circuits/sha256/sigmaplus.circom +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "../binsum.circom"; -include "sigma.circom"; - -template SigmaPlus() { - signal input in2[32]; - signal input in7[32]; - signal input in15[32]; - signal input in16[32]; - signal output out[32]; - var k; - - component sigma1 = SmallSigma(17,19,10); - component sigma0 = SmallSigma(7, 18, 3); - for (k=0; k<32; k++) { - sigma1.in[k] <== in2[k]; - sigma0.in[k] <== in15[k]; - } - - component sum = BinSum(32, 4); - for (k=0; k<32; k++) { - sum.in[0][k] <== sigma1.out[k]; - sum.in[1][k] <== in7[k]; - sum.in[2][k] <== sigma0.out[k]; - sum.in[3][k] <== in16[k]; - } - - for (k=0; k<32; k++) { - out[k] <== sum.out[k]; - } -} diff --git a/prover/circom/circuits/sha256/t1.circom b/prover/circom/circuits/sha256/t1.circom deleted file mode 100644 index e606772f..00000000 --- a/prover/circom/circuits/sha256/t1.circom +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "../binsum.circom"; -include "sigma.circom"; -include "ch.circom"; - -template T1() { - signal input h[32]; - signal input e[32]; - signal input f[32]; - signal input g[32]; - signal input k[32]; - signal input w[32]; - signal output out[32]; - - var ki; - - component ch = Ch_t(32); - component bigsigma1 = BigSigma(6, 11, 25); - - for (ki=0; ki<32; ki++) { - bigsigma1.in[ki] <== e[ki]; - ch.a[ki] <== e[ki]; - ch.b[ki] <== f[ki]; - ch.c[ki] <== g[ki]; - } - - component sum = BinSum(32, 5); - for (ki=0; ki<32; ki++) { - sum.in[0][ki] <== h[ki]; - sum.in[1][ki] <== bigsigma1.out[ki]; - sum.in[2][ki] <== ch.out[ki]; - sum.in[3][ki] <== k[ki]; - sum.in[4][ki] <== w[ki]; - } - - for (ki=0; ki<32; ki++) { - out[ki] <== sum.out[ki]; - } -} diff --git a/prover/circom/circuits/sha256/t2.circom b/prover/circom/circuits/sha256/t2.circom deleted file mode 100644 index 5a83d594..00000000 --- a/prover/circom/circuits/sha256/t2.circom +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "../binsum.circom"; -include "sigma.circom"; -include "maj.circom"; - -template T2() { - signal input a[32]; - signal input b[32]; - signal input c[32]; - signal output out[32]; - var k; - - component bigsigma0 = BigSigma(2, 13, 22); - component maj = Maj_t(32); - for (k=0; k<32; k++) { - bigsigma0.in[k] <== a[k]; - maj.a[k] <== a[k]; - maj.b[k] <== b[k]; - maj.c[k] <== c[k]; - } - - component sum = BinSum(32, 2); - - for (k=0; k<32; k++) { - sum.in[0][k] <== bigsigma0.out[k]; - sum.in[1][k] <== maj.out[k]; - } - - for (k=0; k<32; k++) { - out[k] <== sum.out[k]; - } -} diff --git a/prover/circom/circuits/sha256/xor3.circom b/prover/circom/circuits/sha256/xor3.circom deleted file mode 100644 index 9c21e4e2..00000000 --- a/prover/circom/circuits/sha256/xor3.circom +++ /dev/null @@ -1,45 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ - -/* Xor3 function for sha256 - -out = a ^ b ^ c => - -out = a+b+c - 2*a*b - 2*a*c - 2*b*c + 4*a*b*c => - -out = a*( 1 - 2*b - 2*c + 4*b*c ) + b + c - 2*b*c => - -mid = b*c -out = a*( 1 - 2*b -2*c + 4*mid ) + b + c - 2 * mid - -*/ -pragma circom 2.0.0; - -template Xor3(n) { - signal input a[n]; - signal input b[n]; - signal input c[n]; - signal output out[n]; - signal mid[n]; - - for (var k=0; k. -*/ -pragma circom 2.0.0; - -include "compconstant.circom"; - -template Sign() { - signal input in[254]; - signal output sign; - - component comp = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808); - - var i; - - for (i=0; i<254; i++) { - comp.in[i] <== in[i]; - } - - sign <== comp.out; -} diff --git a/prover/circom/circuits/smt/smthash_mimc.circom b/prover/circom/circuits/smt/smthash_mimc.circom deleted file mode 100644 index 272e5270..00000000 --- a/prover/circom/circuits/smt/smthash_mimc.circom +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "../mimc.circom"; - - -/* - Hash1 = H(1 | key | value) - */ - -template SMTHash1() { - signal input key; - signal input value; - signal output out; - - component h = MultiMiMC7(2, 91); // Constant - h.in[0] <== key; - h.in[1] <== value; - h.k <== 1; - - out <== h.out; -} - -/* - This component is used to create the 2 nodes. - - Hash2 = H(Hl | Hr) - */ - -template SMTHash2() { - signal input L; - signal input R; - signal output out; - - component h = MultiMiMC7(2, 91); // Constant - h.in[0] <== L; - h.in[1] <== R; - h.k <== 0; - - out <== h.out; -} diff --git a/prover/circom/circuits/smt/smthash_poseidon.circom b/prover/circom/circuits/smt/smthash_poseidon.circom deleted file mode 100644 index aa6b8b3a..00000000 --- a/prover/circom/circuits/smt/smthash_poseidon.circom +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ -pragma circom 2.0.0; - -include "../poseidon.circom"; - - -/* - Hash1 = H(1 | key | value) - */ - -template SMTHash1() { - signal input key; - signal input value; - signal output out; - - component h = Poseidon(3); // Constant - h.inputs[0] <== key; - h.inputs[1] <== value; - h.inputs[2] <== 1; - - out <== h.out; -} - -/* - This component is used to create the 2 nodes. - - Hash2 = H(Hl | Hr) - */ - -template SMTHash2() { - signal input L; - signal input R; - signal output out; - - component h = Poseidon(2); // Constant - h.inputs[0] <== L; - h.inputs[1] <== R; - - out <== h.out; -} diff --git a/prover/circom/circuits/smt/smtlevins.circom b/prover/circom/circuits/smt/smtlevins.circom deleted file mode 100644 index a03ae50a..00000000 --- a/prover/circom/circuits/smt/smtlevins.circom +++ /dev/null @@ -1,103 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ - -/* - -This component finds the level where the oldInsert is done. -The rules are: - -levIns[i] == 1 if its level and all the child levels have a sibling of 0 and -the parent level has a sibling != 0. Considere that the root level always has -a parent with a sibling != 0. - - - ┌──────────────┐ - │ │ - │ │───▶ levIns[0] <== (1-done[i]) - │ │ - └──────────────┘ - ▲ - │ - │ - done[0] - - - - done[i-1] <== levIns[i] + done[i] - ▲ - │ - │ - ┌───────────┐ ┌──────────────┐ - │ │ │ │ - sibling[i-1]───▶│IsZero[i-1]│─▶│ │───▶ levIns[i] <== (1-done[i])*(1-isZero[i-1].out) - │ │ │ │ - └───────────┘ └──────────────┘ - ▲ - │ - │ - done[i] - - - - done[n-2] <== levIns[n-1] - ▲ - │ - │ - ┌───────────┐ ┌──────────────┐ - │ │ │ │ - sibling[n-2]───▶│IsZero[n-2]│─▶│ │────▶ levIns[n-1] <== (1-isZero[n-2].out) - │ │ │ │ - └───────────┘ └──────────────┘ - - ┌───────────┐ - │ │ - sibling[n-1]───▶│IsZero[n-1]│────▶ === 0 - │ │ - └───────────┘ - - */ - pragma circom 2.0.0; - -template SMTLevIns(nLevels) { - signal input enabled; - signal input siblings[nLevels]; - signal output levIns[nLevels]; - signal done[nLevels-1]; // Indicates if the insLevel has aready been detected. - - var i; - - component isZero[nLevels]; - - for (i=0; i0; i--) { - levIns[i] <== (1-done[i])*(1-isZero[i-1].out); - done[i-1] <== levIns[i] + done[i]; - } - - levIns[0] <== (1-done[0]); -} diff --git a/prover/circom/circuits/smt/smtprocessor.circom b/prover/circom/circuits/smt/smtprocessor.circom deleted file mode 100644 index b75f17c7..00000000 --- a/prover/circom/circuits/smt/smtprocessor.circom +++ /dev/null @@ -1,261 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ - -/*************************************************************************************************** - -SMTProcessor: Sparse Merkle Tree processor is a component to verify an insert/update/delete elements -into the Sparse Merkle tree. - - -Insert to an empty leaf -======================= - - STATE OLD STATE NEW STATE - ===== ========= ========= - - oldRoot newRoot - ▲ ▲ - │ │ - ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ - top │Sibling├────▶┃ Hash ┃◀─┐ │Sibling├────▶┃ Hash ┃◀─┐ - └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ - │ │ - │ │ - ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ - top ┌─────▶┃ Hash ┃◀──┤Sibling│ ┌─────▶┃ Hash ┃◀──┤Sibling│ - │ ┗━━━━━━━┛ └───────┘ │ ┗━━━━━━━┛ └───────┘ - │ │ - │ │ - ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ - top │Sibling├──▶┃ Hash ┃◀─────┐ │Sibling├──▶┃ Hash ┃◀─────┐ - └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ - │ │ - │ │ - ┌────┴────┐ ┌────┴────┐ - old0 │ 0 │ │New1Leaf │ - └─────────┘ └─────────┘ - - - ┏━━━━━━━┓ ┏━━━━━━━┓ - na ┃ Hash ┃ ┃ Hash ┃ - ┗━━━━━━━┛ ┗━━━━━━━┛ - - - ┏━━━━━━━┓ ┏━━━━━━━┓ - na ┃ Hash ┃ ┃ Hash ┃ - ┗━━━━━━━┛ ┗━━━━━━━┛ - - - -Insert to a used leaf. -===================== - - STATE OLD STATE NEW STATE - ===== ========= ========= - - - oldRoot newRoot - ▲ ▲ - │ │ - ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ - top │Sibling├────▶┃ Hash ┃◀─┐ │Sibling├────▶┃ Hash ┃◀─┐ - └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ - │ │ - │ │ - ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ - top ┌─────▶┃ Hash ┃◀──┤Sibling│ ┌─────▶┃ Hash ┃◀──┤Sibling│ - │ ┗━━━━━━━┛ └───────┘ │ ┗━━━━━━━┛ └───────┘ - │ │ - │ │ - ┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ - top │Sibling├──▶┃ Hash ┃◀─────┐ │Sibling├──▶┃ Hash ┃◀─────┐ - └───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │ - │ │ - │ │ - ┌────┴────┐ ┏━━━┻━━━┓ ┌───────┐ - bot │Old1Leaf │ ┌─────▶┃ Hash ┃◀──┼─ 0 │ - └─────────┘ │ ┗━━━━━━━┛ └───────┘ - │ - │ - ┏━━━━━━━┓ ┌───────┐ ┏━━━┻━━━┓ - bot ┃ Hash ┃ │ 0 ─┼──▶┃ Hash ┃◀─────┐ - ┗━━━━━━━┛ └───────┘ ┗━━━━━━━┛ │ - │ - │ - ┏━━━━━━━┓ ┏━━━┻━━━┓ ┌───────┐ - bot ┃ Hash ┃ ┌─────▶┃ Hash ┃◀──│ 0 │ - ┗━━━━━━━┛ │ ┗━━━━━━━┛ └───────┘ - │ - │ - ┏━━━━━━━┓ ┌─────────┐ ┏━━━┻━━━┓ ┌─────────┐ - new1 ┃ Hash ┃ │Old1Leaf ├──▶┃ Hash ┃◀──│New1Leaf │ - ┗━━━━━━━┛ └─────────┘ ┗━━━━━━━┛ └─────────┘ - - - ┏━━━━━━━┓ ┏━━━━━━━┓ - na ┃ Hash ┃ ┃ Hash ┃ - ┗━━━━━━━┛ ┗━━━━━━━┛ - - - ┏━━━━━━━┓ ┏━━━━━━━┓ - na ┃ Hash ┃ ┃ Hash ┃ - ┗━━━━━━━┛ ┗━━━━━━━┛ - - -Fnction -fnc[0] fnc[1] -0 0 NOP -0 1 UPDATE -1 0 INSERT -1 1 DELETE - - -***************************************************************************************************/ -pragma circom 2.0.0; - -include "../gates.circom"; -include "../bitify.circom"; -include "../comparators.circom"; -include "../switcher.circom"; -include "smtlevins.circom"; -include "smtprocessorlevel.circom"; -include "smtprocessorsm.circom"; -include "smthash_poseidon.circom"; - -template SMTProcessor(nLevels) { - signal input oldRoot; - signal output newRoot; - signal input siblings[nLevels]; - signal input oldKey; - signal input oldValue; - signal input isOld0; - signal input newKey; - signal input newValue; - signal input fnc[2]; - - signal enabled; - - var i; - - enabled <== fnc[0] + fnc[1] - fnc[0]*fnc[1]; - - component hash1Old = SMTHash1(); - hash1Old.key <== oldKey; - hash1Old.value <== oldValue; - - component hash1New = SMTHash1(); - hash1New.key <== newKey; - hash1New.value <== newValue; - - component n2bOld = Num2Bits_strict(); - component n2bNew = Num2Bits_strict(); - - n2bOld.in <== oldKey; - n2bNew.in <== newKey; - - component smtLevIns = SMTLevIns(nLevels); - for (i=0; i. -*/ - -/****** - -SMTProcessorLevel - -This circuit has 2 hash - -Outputs according to the state. - -State oldRoot newRoot -===== ======= ======= -top H'(oldChild, sibling) H'(newChild, sibling) -old0 0 new1leaf -bot old1leaf H'(newChild, 0) -new1 old1leaf H'(new1leaf, old1leaf) -na 0 0 - -upd old1leaf new1leaf - -H' is the Hash function with the inputs shifted acordingly. - -*****/ -pragma circom 2.0.0; - - -template SMTProcessorLevel() { - signal input st_top; - signal input st_old0; - signal input st_bot; - signal input st_new1; - signal input st_na; - signal input st_upd; - - signal output oldRoot; - signal output newRoot; - signal input sibling; - signal input old1leaf; - signal input new1leaf; - signal input newlrbit; - signal input oldChild; - signal input newChild; - - signal aux[4]; - - component oldProofHash = SMTHash2(); - component newProofHash = SMTHash2(); - - component oldSwitcher = Switcher(); - component newSwitcher = Switcher(); - - // Old side - - oldSwitcher.L <== oldChild; - oldSwitcher.R <== sibling; - - oldSwitcher.sel <== newlrbit; - oldProofHash.L <== oldSwitcher.outL; - oldProofHash.R <== oldSwitcher.outR; - - aux[0] <== old1leaf * (st_bot + st_new1 + st_upd); - oldRoot <== aux[0] + oldProofHash.out * st_top; - - // New side - - aux[1] <== newChild * ( st_top + st_bot); - newSwitcher.L <== aux[1] + new1leaf*st_new1; - - aux[2] <== sibling*st_top; - newSwitcher.R <== aux[2] + old1leaf*st_new1; - - newSwitcher.sel <== newlrbit; - newProofHash.L <== newSwitcher.outL; - newProofHash.R <== newSwitcher.outR; - - aux[3] <== newProofHash.out * (st_top + st_bot + st_new1); - newRoot <== aux[3] + new1leaf * (st_old0 + st_upd); -} diff --git a/prover/circom/circuits/smt/smtprocessorsm.circom b/prover/circom/circuits/smt/smtprocessorsm.circom deleted file mode 100644 index e40356f9..00000000 --- a/prover/circom/circuits/smt/smtprocessorsm.circom +++ /dev/null @@ -1,165 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ - -/*************************************************************************************************** -Each level on a SMTProcessor has a state. - -The state of the level depends on the state of te botom level and on `xor` and -`is0` signals. - -`isOldLev` 1 when is the level where oldLeaf is. - -`xor` signal is 0 if the index bit at the current level is the same in the old -and the new index, and 1 if it is different. - -`is0` signal, is 1 if we are inserting/deleting in an empty leaf and 0 if we -are inserting/deleting in a leaf that contains an element. - -The states are: - -top: While the index bits of the old and new insex in the top level is the same, whe are in the top state. -old0: When the we reach insert level, we go to old0 state -if `is0`=1. -btn: Once in insert level and `is0` =0 we go to btn or new1 level if xor=1 -new1: This level is reached when xor=1. Here is where we insert/delete the hash of the -old and the new trees with just one element. -na: Not appliable. After processing it, we go to the na level. - - -Fnction -fnc[0] fnc[1] -0 0 NOP -0 1 UPDATE -1 0 INSERT -1 1 DELETE - - - ########### - # # - ┌────────────────────────────▶# upd #─────────────────────┐ - │ ## ## │ - │ ######### │ - levIns=1 │ │ - fnc[0]=0 │ │ any - │ │ - │ │ - │ │ - │ ########### │ - │ levIns=1 # # │ - levIns=0 │ is0=1 ┌────────────▶# old0 #────────┐ │ any - ┌─────┐ │ fnc[0]=1│ ## ## │ │ ┌──────┐ - │ │ │ │ ######### │ any │ │ │ - │ ▼ │ │ │ ▼ ▼ │ - │ ########### │ │ ########### │ - │ # # ────────────┘ └────────▶# #│ - └──# top # # na # - ## ## ───────────────────┐ levIns=1 ┌──▶## ## - ######### │ is0=0 │ ######### - │ │ fnc[0]=1 │ - │ │ xor=1 ########### │ any - │ └──────────────────▶# # │ - │ # new1 #──┘ - │ ## ## - └────────────────────────────────┐ ######### - levIns=1 │ ▲ - is0=0 │ ┌─────┘ - fnc[0]=1 │ ###########│ xor=1 - xor=0 │ # # - ▼# btn # - ## ## - #########◀───────┐ - │ │ - │ │ - └────────────┘ - xor=0 - -***************************************************************************************************/ -pragma circom 2.0.0; - -template SMTProcessorSM() { - signal input xor; - signal input is0; - signal input levIns; - signal input fnc[2]; - - signal input prev_top; - signal input prev_old0; - signal input prev_bot; - signal input prev_new1; - signal input prev_na; - signal input prev_upd; - - signal output st_top; - signal output st_old0; - signal output st_bot; - signal output st_new1; - signal output st_na; - signal output st_upd; - - signal aux1; - signal aux2; - - aux1 <== prev_top * levIns; - aux2 <== aux1*fnc[0]; // prev_top * levIns * fnc[0] - - // st_top = prev_top*(1-levIns) - // = + prev_top - // - prev_top * levIns = aux1 - - st_top <== prev_top - aux1; - - // st_old0 = prev_top * levIns * is0 * fnc[0] - // = + prev_top * levIns * is0 * fnc[0] = aux2 * is0 - - st_old0 <== aux2 * is0; // prev_top * levIns * is0 * fnc[0] - - // st_new1 = prev_top * levIns * (1-is0)*fnc[0] * xor + prev_bot*xor = - // = + prev_top * levIns * fnc[0] * xor = aux2 * xor - // - prev_top * levIns * is0 * fnc[0] * xor = st_old0 * xor - // + prev_bot * xor = prev_bot * xor - - st_new1 <== (aux2 - st_old0 + prev_bot)*xor; - - - // st_bot = prev_top * levIns * (1-is0)*fnc[0] * (1-xor) + prev_bot*(1-xor); - // = + prev_top * levIns * fnc[0] - // - prev_top * levIns * is0 * fnc[0] - // - prev_top * levIns * fnc[0] * xor - // + prev_top * levIns * is0 * fnc[0] * xor - // + prev_bot - // - prev_bot * xor - - st_bot <== (1-xor) * (aux2 - st_old0 + prev_bot); - - - // st_upd = prev_top * (1-fnc[0]) *levIns; - // = + prev_top * levIns - // - prev_top * levIns * fnc[0] - - st_upd <== aux1 - aux2; - - // st_na = prev_new1 + prev_old0 + prev_na + prev_upd; - // = + prev_new1 - // + prev_old0 - // + prev_na - // + prev_upd - - st_na <== prev_new1 + prev_old0 + prev_na + prev_upd; - -} diff --git a/prover/circom/circuits/smt/smtverifier.circom b/prover/circom/circuits/smt/smtverifier.circom deleted file mode 100644 index 152eba38..00000000 --- a/prover/circom/circuits/smt/smtverifier.circom +++ /dev/null @@ -1,138 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ - -/* - -SMTVerifier is a component to verify inclusion/exclusion of an element in the tree - - -fnc: 0 -> VERIFY INCLUSION - 1 -> VERIFY NOT INCLUSION - - */ - pragma circom 2.0.0; - - -include "../gates.circom"; -include "../bitify.circom"; -include "../comparators.circom"; -include "../switcher.circom"; -include "smtlevins.circom"; -include "smtverifierlevel.circom"; -include "smtverifiersm.circom"; -include "smthash_poseidon.circom"; - -template SMTVerifier(nLevels) { - signal input enabled; - signal input root; - signal input siblings[nLevels]; - signal input oldKey; - signal input oldValue; - signal input isOld0; - signal input key; - signal input value; - signal input fnc; - - var i; - - component hash1Old = SMTHash1(); - hash1Old.key <== oldKey; - hash1Old.value <== oldValue; - - component hash1New = SMTHash1(); - hash1New.key <== key; - hash1New.value <== value; - - component n2bOld = Num2Bits_strict(); - component n2bNew = Num2Bits_strict(); - - n2bOld.in <== oldKey; - n2bNew.in <== key; - - component smtLevIns = SMTLevIns(nLevels); - for (i=0; i. -*/ - -/****** - -SMTVerifierLevel - -This circuit has 1 hash - -Outputs according to the state. - -State root -===== ======= -top H'(child, sibling) -i0 0 -iold old1leaf -inew new1leaf -na 0 - -H' is the Hash function with the inputs shifted acordingly. - -*****/ -pragma circom 2.0.0; - -template SMTVerifierLevel() { - signal input st_top; - signal input st_i0; - signal input st_iold; - signal input st_inew; - signal input st_na; - - signal output root; - signal input sibling; - signal input old1leaf; - signal input new1leaf; - signal input lrbit; - signal input child; - - signal aux[2]; - - component proofHash = SMTHash2(); - component switcher = Switcher(); - - switcher.L <== child; - switcher.R <== sibling; - - switcher.sel <== lrbit; - proofHash.L <== switcher.outL; - proofHash.R <== switcher.outR; - - aux[0] <== proofHash.out * st_top; - aux[1] <== old1leaf*st_iold; - - root <== aux[0] + aux[1] + new1leaf*st_inew; -} diff --git a/prover/circom/circuits/smt/smtverifiersm.circom b/prover/circom/circuits/smt/smtverifiersm.circom deleted file mode 100644 index 63d2c41e..00000000 --- a/prover/circom/circuits/smt/smtverifiersm.circom +++ /dev/null @@ -1,106 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ - -/* -Each level in the SMTVerifier has a state. - -This is the state machine. - -The signals are - -levIns: 1 if we are in the level where the insertion should happen -xor: 1 if the bitKey of the old and new keys are different in this level -is0: Input that indicates that the oldKey is 0 -fnc: 0 -> VERIFY INCLUSION - 1 -> VERIFY NOT INCLUSION - -err state is not a state itself. It's a lack of state. - -The end of the last level will have to be `na` - - levIns=0 any - ┌────┐ ┌────┐ - │ │ │ │ - │ ▼ levIns=1 ▼ │ - │ ########### is0=1 ########### ########### │ - │ # # fnc=1 # # any # # │ - └──# top # ─────────────────────▶# i0 #───────────────▶# na #──┘ - ## ## ──────────┐ ## ## ┌───────▶## ## - ########─────────────┐│ ######### │┌────────▶######### - ││ levIns=1 ││ - ││ is0=0 ########### ││ - ││ fnc=1 # # any│ - │└──────────▶ # iold #────────┘│ - │ ## ## │ - │ ######### │ - │ │ - │ levIns=1 ########### │ - │ fnc=0 # # any - └────────────▶# inew #─────────┘ - ## ## - ######### - - */ - pragma circom 2.0.0; - - -template SMTVerifierSM() { - signal input is0; - signal input levIns; - signal input fnc; - - signal input prev_top; - signal input prev_i0; - signal input prev_iold; - signal input prev_inew; - signal input prev_na; - - signal output st_top; - signal output st_i0; - signal output st_iold; - signal output st_inew; - signal output st_na; - - signal prev_top_lev_ins; - signal prev_top_lev_ins_fnc; - - prev_top_lev_ins <== prev_top * levIns; - prev_top_lev_ins_fnc <== prev_top_lev_ins*fnc; // prev_top * levIns * fnc - - // st_top = prev_top * (1-levIns) - // = + prev_top - // - prev_top * levIns - st_top <== prev_top - prev_top_lev_ins; - - // st_inew = prev_top * levIns * (1-fnc) - // = + prev_top * levIns - // - prev_top * levIns * fnc - st_inew <== prev_top_lev_ins - prev_top_lev_ins_fnc; - - // st_iold = prev_top * levIns * (1-is0)*fnc - // = + prev_top * levIns * fnc - // - prev_top * levIns * fnc * is0 - st_iold <== prev_top_lev_ins_fnc * (1 - is0); - - // st_i0 = prev_top * levIns * is0 - // = + prev_top * levIns * is0 - st_i0 <== prev_top_lev_ins * is0; - - st_na <== prev_na + prev_inew + prev_iold + prev_i0; -} diff --git a/prover/circom/circuits/switcher.circom b/prover/circom/circuits/switcher.circom deleted file mode 100644 index e2e19a63..00000000 --- a/prover/circom/circuits/switcher.circom +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright 2018 0KIMS association. - - This file is part of circom (Zero Knowledge Circuit Compiler). - - circom is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - circom is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with circom. If not, see . -*/ - -/* - Assume sel is binary. - - If sel == 0 then outL = L and outR=R - If sel == 1 then outL = R and outR=L - - */ - -pragma circom 2.0.0; - -template Switcher() { - signal input sel; - signal input L; - signal input R; - signal output outL; - signal output outR; - - signal aux; - - aux <== (R-L)*sel; // We create aux in order to have only one multiplication - outL <== aux + L; - outR <== -aux + R; -} diff --git a/prover/circom/ed25519/inputs.json b/prover/circom/ed25519/inputs.json deleted file mode 100644 index c07f0bf4..00000000 --- a/prover/circom/ed25519/inputs.json +++ /dev/null @@ -1,829 +0,0 @@ -{ - "msg": [ - "1", - "1", - "1", - "1", - "0", - "1", - "0", - "1", - "0", - "1", - "0", - "0", - "0", - "0", - "0", - "1" - ], - "A": [ - "0", - "0", - "1", - "1", - "1", - "1", - "1", - "1", - "1", - "0", - "0", - "0", - "1", - "0", - "1", - "0", - "1", - "0", - "1", - "1", - "0", - "0", - "1", - "1", - "0", - "1", - "1", - "1", - "0", - "0", - "0", - "1", - "0", - "1", - "0", - "0", - "0", - "1", - "1", - "0", - "0", - "0", - "0", - "1", - "1", - "0", - "0", - "0", - "1", - "0", - "0", - "0", - "0", - "1", - "0", - "1", - "1", - "1", - "0", - "0", - "0", - "1", - "0", - "1", - "1", - "0", - "1", - "1", - "0", - "0", - "0", - "1", - "0", - "0", - "1", - "0", - "0", - "1", - "0", - "1", - "0", - "1", - "1", - "1", - "1", - "1", - "1", - "0", - "0", - "0", - "0", - "0", - "1", - "0", - "1", - "1", - "0", - "1", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "1", - "1", - "0", - "0", - "0", - "0", - "0", - "0", - "1", - "1", - "1", - "1", - "0", - "0", - "0", - "1", - "1", - "0", - "1", - "0", - "0", - "0", - "0", - "1", - "0", - "0", - "0", - "0", - "0", - "1", - "1", - "0", - "1", - "0", - "0", - "0", - "1", - "0", - "1", - "1", - "0", - "1", - "1", - "1", - "1", - "1", - "0", - "0", - "1", - "0", - "0", - "0", - "0", - "1", - "0", - "1", - "1", - "1", - "0", - "1", - "1", - "1", - "0", - "0", - "1", - "1", - "0", - "0", - "1", - "1", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "1", - "1", - "0", - "1", - "0", - "1", - "1", - "0", - "1", - "1", - "1", - "0", - "1", - "0", - "1", - "1", - "0", - "1", - "0", - "1", - "1", - "1", - "1", - "0", - "0", - "0", - "1", - "0", - "0", - "1", - "1", - "0", - "1", - "0", - "1", - "0", - "0", - "0", - "0", - "0", - "0", - "1", - "0", - "0", - "1", - "0", - "0", - "0", - "0", - "0", - "1", - "0", - "0", - "1", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "1", - "1", - "0", - "1", - "0", - "0", - "1", - "0", - "0" - ], - "R8": [ - "0", - "1", - "0", - "0", - "0", - "1", - "1", - "0", - "1", - "0", - "0", - "0", - "1", - "0", - "0", - "1", - "0", - "1", - "1", - "0", - "1", - "0", - "1", - "1", - "1", - "1", - "1", - "0", - "1", - "0", - "1", - "0", - "0", - "1", - "1", - "1", - "1", - "0", - "1", - "1", - "0", - "0", - "1", - "1", - "0", - "1", - "1", - "1", - "0", - "0", - "1", - "0", - "0", - "1", - "0", - "0", - "0", - "1", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "1", - "0", - "0", - "1", - "0", - "1", - "1", - "1", - "0", - "0", - "1", - "0", - "0", - "0", - "1", - "1", - "0", - "0", - "1", - "1", - "1", - "0", - "0", - "1", - "1", - "1", - "0", - "0", - "1", - "0", - "1", - "0", - "1", - "1", - "1", - "0", - "0", - "0", - "1", - "1", - "1", - "1", - "1", - "0", - "1", - "1", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "1", - "1", - "0", - "0", - "0", - "1", - "0", - "1", - "0", - "0", - "1", - "1", - "0", - "0", - "0", - "0", - "1", - "0", - "1", - "0", - "0", - "1", - "1", - "1", - "0", - "0", - "0", - "1", - "0", - "0", - "1", - "0", - "0", - "1", - "0", - "0", - "0", - "1", - "0", - "1", - "0", - "0", - "1", - "0", - "0", - "0", - "0", - "1", - "0", - "0", - "1", - "0", - "1", - "1", - "1", - "0", - "0", - "1", - "0", - "1", - "1", - "1", - "0", - "0", - "0", - "0", - "1", - "0", - "0", - "0", - "1", - "0", - "0", - "1", - "1", - "1", - "1", - "0", - "1", - "0", - "0", - "1", - "1", - "0", - "1", - "1", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "0", - "1", - "1", - "1", - "1", - "0", - "1", - "0", - "1", - "1", - "1", - "1", - "0", - "1", - "1", - "0", - "1", - "1", - "0", - "1", - "0", - "1", - "1", - "0", - "1", - "0", - "1", - "1", - "0", - "0", - "0", - "0", - "1", - "1", - "0", - "0", - "1", - "1", - "0", - "1", - "0", - "1" - ], - "S": [ - "0", - "0", - "0", - "1", - "1", - "0", - "0", - "0", - "1", - "1", - "1", - "1", - "1", - "1", - "1", - "1", - "1", - "1", - "0", - "1", - "1", - "0", - "0", - "1", - "1", - "1", - "0", - "0", - "1", - "0", - "1", - "0", - "1", - "0", - "1", - "1", - "0", - "0", - "0", - "1", - "0", - "1", - "1", - "0", - "1", - "0", - "0", - "0", - "0", - "1", - "0", - "0", - "1", - "1", - "1", - "1", - "0", - "0", - "0", - "0", - "1", - "0", - "0", - "1", - "0", - "1", - "1", - "1", - "0", - "1", - "0", - "1", - "1", - "1", - "1", - "0", - "0", - "1", - "1", - "0", - "1", - "1", - "1", - "0", - "1", - "1", - "1", - "1", - "0", - "0", - "0", - "0", - "0", - "1", - "1", - "0", - "0", - "0", - "0", - "1", - "1", - "0", - "0", - "1", - "1", - "0", - "1", - "1", - "0", - "0", - "1", - "0", - "0", - "1", - "1", - "0", - "0", - "0", - "1", - "1", - "1", - "0", - "0", - "1", - "1", - "0", - "1", - "0", - "0", - "1", - "0", - "1", - "0", - "0", - "1", - "0", - "0", - "0", - "1", - "1", - "1", - "1", - "1", - "0", - "1", - "0", - "1", - "0", - "1", - "0", - "0", - "0", - "1", - "0", - "0", - "1", - "0", - "1", - "1", - "1", - "1", - "0", - "0", - "0", - "1", - "1", - "1", - "0", - "0", - "1", - "1", - "1", - "0", - "1", - "1", - "0", - "0", - "1", - "0", - "0", - "1", - "0", - "1", - "1", - "1", - "0", - "1", - "1", - "0", - "0", - "0", - "1", - "0", - "0", - "0", - "0", - "0", - "0", - "1", - "1", - "1", - "1", - "1", - "0", - "0", - "1", - "0", - "0", - "0", - "1", - "1", - "1", - "1", - "1", - "0", - "1", - "0", - "1", - "1", - "1", - "0", - "0", - "1", - "1", - "0", - "1", - "0", - "1", - "0", - "1", - "1", - "1", - "0", - "1", - "1", - "1", - "1", - "0", - "0", - "0", - "0", - "0", - "1", - "0", - "0", - "0", - "1", - "1", - "0", - "1", - "0", - "1", - "0", - "0", - "0" - ], - "PointA": [ - [ - "4730506516830149311053058", - "16492541847767404437354919", - "29355681060784451154336116" - ], - [ - "37044855473276001117360636", - "36044041573171652573795971", - "11334344940228348385886412" - ], - ["1", "0", "0"], - [ - "36006434350668361313085412", - "3961809584842615293282987", - "31804254138239842479622482" - ] - ], - "PointR": [ - [ - "2328148767130699190453327", - "21019210829853924773317397", - "17422058868782080515274437" - ], - [ - "7439055530601725237301602", - "5010768007177350092543207", - "13528818393860270915128989" - ], - ["1", "0", "0"], - [ - "21834518600060388913341896", - "35467612521506016148096723", - "5257184083217746721055169" - ] - ] -} diff --git a/prover/circom/scheherazade.circom b/prover/circom/scheherazade.circom deleted file mode 100644 index 0f544160..00000000 --- a/prover/circom/scheherazade.circom +++ /dev/null @@ -1,16 +0,0 @@ -pragma circom 2.0.0; - -// a * b * b == 1001 -// a, b, and c must all be different, and all > 1 -// solution is: 7, 11, 13, in any permutation -template scheherazade() { - signal input a; - signal input b; - signal input c; - signal ab; - signal output d; - ab <== a*b; - d <== ab * c; - } - - component main = scheherazade(); \ No newline at end of file diff --git a/prover/circom/sudoku.circom b/prover/circom/sudoku.circom deleted file mode 100644 index 0ce911a4..00000000 --- a/prover/circom/sudoku.circom +++ /dev/null @@ -1,118 +0,0 @@ -pragma circom 2.0.0; - -include "circuits/comparators.circom"; -include "circuits/gates.circom"; - -template InRange(bits) { - signal input value; - signal input lower; - signal input upper; - signal output out; - - component upperBound = LessEqThan(bits); - upperBound.in[0] <== value; - upperBound.in[1] <== upper; - - component lowerBound = GreaterEqThan(bits); - lowerBound.in[0] <== value; - lowerBound.in[1] <== lower; - - out <== upperBound.out*lowerBound.out; -} - -template ContainsAll(SIZE) { - signal input in[SIZE]; - - component is_equal[SIZE][SIZE]; - for (var i = 0;i < SIZE;i++) { - for (var j = 0;j < SIZE;j++) { - is_equal[i][j] = IsEqual(); - } - } - - for (var i = 0;i < SIZE;i++) { - for (var j = 0;j < SIZE;j++) { - is_equal[i][j].in[0] <== in[i]; - is_equal[i][j].in[1] <== (i == j) ? 0 : in[j]; - is_equal[i][j].out === 0; - } - } -} - -template Main(SIZE, SUBSIZE) { - signal input unsolved_grid[SIZE][SIZE]; - signal input solved_grid[SIZE][SIZE]; - - component range_checkers[SIZE][SIZE][2]; - component is_solution[SIZE][SIZE]; - component is_equal[SIZE][SIZE]; - component is_valid[SIZE][SIZE]; - component row_checkers[SIZE]; - component col_checkers[SIZE]; - component submat_checkers[SIZE]; - for (var i = 0;i < SIZE;i++) { - row_checkers[i] = ContainsAll(SIZE); - col_checkers[i] = ContainsAll(SIZE); - submat_checkers[i] = ContainsAll(SIZE); - for (var j = 0;j < SIZE;j++) { - for (var k = 0;k < 2;k++) { - range_checkers[i][j][k] = InRange(4); - } - - is_solution[i][j] = IsZero(); - is_equal[i][j] = IsEqual(); - is_valid[i][j] = OR(); - } - } - - // Assert input grids are valid and solved grid matches unsolved grid - for (var i = 0;i < SIZE;i++) { - for (var j = 0;j < SIZE;j++) { - range_checkers[i][j][0].value <== solved_grid[i][j]; - range_checkers[i][j][0].upper <== SIZE; - range_checkers[i][j][0].lower <== 1; - range_checkers[i][j][0].out === 1; - - range_checkers[i][j][1].value <== unsolved_grid[i][j]; - range_checkers[i][j][1].upper <== SIZE; - range_checkers[i][j][1].lower <== 0; - range_checkers[i][j][1].out === 1; - - is_solution[i][j].in <== unsolved_grid[i][j]; - - is_equal[i][j].in[0] <== solved_grid[i][j]; - is_equal[i][j].in[1] <== unsolved_grid[i][j]; - - is_valid[i][j].a <== is_equal[i][j].out; - is_valid[i][j].b <== is_solution[i][j].out; - is_valid[i][j].out === 1; - } - } - - // Check rows - for (var i = 0;i < SIZE;i++) { - for (var j = 0;j < SIZE;j++) { - row_checkers[i].in[j] <== solved_grid[i][j]; - } - } - - // Check columns - for (var i = 0;i < SIZE;i++) { - for (var j = 0;j < SIZE;j++) { - col_checkers[i].in[j] <== solved_grid[j][i]; - } - } - - // Check submatrices - for (var i = 0;i < SIZE;i += SUBSIZE) { - for (var j = 0;j < SIZE;j += SUBSIZE) { - for (var k = 0;k < SUBSIZE;k++) { - for (var l = 0;l < SUBSIZE;l++) { - submat_checkers[i + j / SUBSIZE].in[k*SUBSIZE + l] <== solved_grid[i + k][j + l]; - } - } - } - } -} - -component main {public [unsolved_grid]} = Main(9, 3); diff --git a/prover/circom/sudoku.json b/prover/circom/sudoku.json deleted file mode 100644 index 0a63ca11..00000000 --- a/prover/circom/sudoku.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "unsolved_grid": [ - [6, 0, 3, 2, 0, 5, 4, 7, 0], - [7, 9, 1, 4, 6, 0, 0, 2, 8], - [5, 2, 4, 9, 0, 0, 1, 6, 0], - [0, 4, 0, 0, 5, 7, 3, 0, 0], - [3, 1, 0, 6, 8, 0, 7, 4, 2], - [0, 7, 0, 3, 4, 2, 0, 0, 0], - [0, 0, 0, 5, 2, 4, 0, 0, 0], - [1, 0, 0, 7, 3, 0, 0, 0, 4], - [0, 3, 0, 0, 9, 1, 0, 0, 7] - ], - "solved_grid": [ - [6, 8, 3, 2, 1, 5, 4, 7, 9], - [7, 9, 1, 4, 6, 3, 5, 2, 8], - [5, 2, 4, 9, 7, 8, 1, 6, 3], - [2, 4, 9, 1, 5, 7, 3, 8, 6], - [3, 1, 5, 6, 8, 9, 7, 4, 2], - [8, 7, 6, 3, 4, 2, 9, 1, 5], - [9, 6, 7, 5, 2, 4, 8, 3, 1], - [1, 5, 8, 7, 3, 6, 2, 9, 4], - [4, 3, 2, 8, 9, 1, 6, 5, 7] - ] -} diff --git a/prover/circom/sudoku_inputs.json b/prover/circom/sudoku_inputs.json deleted file mode 100644 index f6c4c6eb..00000000 --- a/prover/circom/sudoku_inputs.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "inputs": [ - 6, 0, 3, 2, 0, 5, 4, 7, 0, 7, 9, 1, 4, 6, 0, 0, 2, 8, 5, 2, 4, 9, 0, 0, 1, - 6, 0, 0, 4, 0, 0, 5, 7, 3, 0, 0, 3, 1, 0, 6, 8, 0, 7, 4, 2, 0, 7, 0, 3, 4, - 2, 0, 0, 0, 0, 0, 0, 5, 2, 4, 0, 0, 0, 1, 0, 0, 7, 3, 0, 0, 0, 4, 0, 3, 0, - 0, 9, 1, 0, 0, 7 - ] -} diff --git a/prover/circom/sudoku_wrong.json b/prover/circom/sudoku_wrong.json deleted file mode 100644 index 39d51a67..00000000 --- a/prover/circom/sudoku_wrong.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "inputs": [ - 4, 0, 3, 2, 0, 5, 4, 7, 0, 7, 9, 1, 4, 6, 0, 0, 2, 8, 5, 2, 4, 9, 0, 0, 1, - 6, 0, 0, 4, 0, 0, 5, 7, 3, 0, 0, 3, 1, 0, 6, 8, 0, 7, 4, 2, 0, 7, 0, 3, 4, - 2, 0, 0, 0, 0, 0, 0, 5, 2, 4, 0, 0, 0, 1, 0, 0, 7, 3, 0, 0, 0, 4, 0, 3, 0, - 0, 9, 1, 0, 0, 7 - ] -} diff --git a/prover/deployments/README.md b/prover/deployments/README.md deleted file mode 100644 index 6484bd95..00000000 --- a/prover/deployments/README.md +++ /dev/null @@ -1,17 +0,0 @@ -## Deployments - -Deployed program will be written to and read from here. - -They are JSON files with a UUID as file name. - -E.g.: "4be4dfab-efc8-48b8-a2aa-edcdb0618020.json" - -They consist of a `created` timestamp and an R1CS circuit encoded as base64. - -For example: -``` -{ - "created": 1687847784629, - "r1cs": "cjFjcwEAAAADAAAAAgAAAPAAAAAAAAAAAQAAAAIAAAAAAADwk/XhQ5FwuXlI6DMoXViBgbZFULgpoDHhck5kMAEAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAABQAAAAAAAPCT9eFDkXC5eUjoMyhdWIGBtkVQuCmgMeFyTmQwAQAAAAUAAAAAAADwk/XhQ5FwuXlI6DMoXViBgbZFULgpoDHhck5kMAEAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAABj8/++T9eFDkXC5eUjoMyhdWIGBtkVQuCmgMeFyTmQwAQAAAEAAAAAAAAAAIAAAAAEAAPCT9eFDkXC5eUjoMyhdWIGBtkVQuCmgMeFyTmQwBgAAAAEAAAAAAAAAAwAAAAcAAAAAAAAAAgAAAAMAAAAwAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAACAAAAAAAAAAMAAAAAAAAABAAAAAAAAAAFAAAAAAAAAA" -} -``` diff --git a/prover/deployments/window-post-inputs.json b/prover/deployments/window-post-inputs.json deleted file mode 100644 index c4f249a4..00000000 --- a/prover/deployments/window-post-inputs.json +++ /dev/null @@ -1 +0,0 @@ -{"post_config":"{\"api_version\":\"V1_1_0\",\"challenge_count\":10,\"priority\":false,\"sector_count\":2,\"sector_size\":536870912,\"typ\":\"Window\"}","proof":"empty","pub_inputs":"{\"k\":null,\"prover_id\":[9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9],\"randomness\":[44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44],\"sectors\":[{\"comm_r\":[216,149,220,160,104,89,90,115,8,196,58,119,27,9,204,133,212,148,252,117,110,78,255,148,1,208,240,135,56,51,207,47],\"id\":17537938916023967333}]}","pub_params":"{\"partitions\":null,\"priority\":false,\"vanilla_params\":{\"api_version\":\"V1_1_0\",\"challenge_count\":10,\"sector_count\":2,\"sector_size\":536870912}}","vanilla_proofs":"[{\"sectors\":[{\"comm_c\":[73,38,255,30,229,181,124,154,159,188,120,46,45,151,52,182,23,109,24,246,163,74,113,52,121,230,7,216,37,238,30,16],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":7},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":1},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":3},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":0},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":0},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":3},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":6},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":7},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":7},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":6},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":4}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":6},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":3},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":5},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":1},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":2},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":6},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":2}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":1},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":6},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":2},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":4},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":5},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":6}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":6},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":5},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":5},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":7},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":5},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":3},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":3},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":5},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":7},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":6},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":1},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":0},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":4},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":7},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":1},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":2},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":0},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":3}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":1},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":3},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":2},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":1},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":6},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":6},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":5},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":3},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":4},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":6},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":0}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":3},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":5},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":6},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":6},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":4},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":0},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[73,38,255,30,229,181,124,154,159,188,120,46,45,151,52,182,23,109,24,246,163,74,113,52,121,230,7,216,37,238,30,16],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":7},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":1},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":3},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":0},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":0},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":3},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":6},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":7},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":7},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":6},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":4}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":6},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":3},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":5},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":1},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":2},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":6},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":2}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":1},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":6},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":2},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":4},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":5},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":6}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":6},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":5},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":5},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":7},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":5},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":3},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":3},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":5},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":7},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":6},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":1},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":0},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":4},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":7},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":1},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":2},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":0},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":3}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":1},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":3},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":2},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":1},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":6},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":6},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":5},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":3},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":4},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":6},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":0}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}},{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":3},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":5},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":6},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":6},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":4},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":0},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]}]}]"} \ No newline at end of file diff --git a/prover/deployments/winning-post-inputs.json b/prover/deployments/winning-post-inputs.json deleted file mode 100644 index 42187dbc..00000000 --- a/prover/deployments/winning-post-inputs.json +++ /dev/null @@ -1 +0,0 @@ -{"post_config":"{\"api_version\":\"V1_1_0\",\"challenge_count\":66,\"priority\":true,\"sector_count\":1,\"sector_size\":536870912,\"typ\":\"Winning\"}","proof":"empty","pub_inputs":"{\"k\":null,\"prover_id\":[9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9],\"randomness\":[44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44],\"sectors\":[{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044},{\"comm_r\":[132,52,179,109,128,111,252,21,239,127,254,230,214,16,112,36,40,118,72,38,212,7,189,204,92,252,93,61,116,128,210,63],\"id\":12091210810259423044}]}","pub_params":"{\"partitions\":null,\"priority\":true,\"vanilla_params\":{\"api_version\":\"V1_1_0\",\"challenge_count\":1,\"sector_count\":66,\"sector_size\":536870912}}","vanilla_proofs":"[{\"sectors\":[{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":2},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":7},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":4},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":7},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":4}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":6},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":7},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":6},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":1},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":6},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":2}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":0},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":5},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":6}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":1},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":2},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":7},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":3},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":1},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":2},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":1},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":3},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":6},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":6},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":0},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":6},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":0},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":4}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":3},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":7},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":7},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":2},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":7},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":5},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":0}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":2},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":6},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":7},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":1},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":5},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":2},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":5},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":3}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":5},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":7},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":3},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":0},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":2},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":6}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":2},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":3},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":0},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":1},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":5},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":0}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":0},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":7},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":1}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":2},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":6},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":5},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":4}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":7},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":6},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":6},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":1},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":7},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":6},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":3},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":1},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":5},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":2},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":5}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":5},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":3},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":2},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":1},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":6},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":6},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":2}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":5},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":5},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":3},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":4},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":6},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":4},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":5},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":3},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":1},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":0},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":0}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":1},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":1},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":6},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":1},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":5},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":1}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":5},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":0},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":7},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":3},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":3}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":2},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":3},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":2},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":2},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":1},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":7},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":1},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":0},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":2},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":5},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":7},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":1},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":2}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":3},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":2},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":2}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":1},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":7},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":2},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":3},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":7},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":1}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":6},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":3},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":0},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":6},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":1},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":2},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":4},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":0}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":3},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":4},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":7},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":7},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":2},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":4}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":1},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":6},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":1},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":6},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":5},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":2}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":1},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":2},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":5},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":5},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":3}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":7},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":0},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":1},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":4},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":2},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":6}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":7},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":6},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":7},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":0},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":6},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":1},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":7},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":2},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":3},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":2},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":6},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":2}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":7},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":7},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":7},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":7},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":1},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":0}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":6},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":1},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":2},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":7},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":6},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":4},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":6}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":6},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":2},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":7},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":6},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":1},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":2},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":2}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":5},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":7},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":7},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":6},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":2}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":7},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":2},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":1},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":0},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":4}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":3},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":5},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":4},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":4}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":7},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":2},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":7},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":7},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":4},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":6}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":3},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":3},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":7},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":5},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":4},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":6},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":3}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":5},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":1},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":2},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":7},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":2},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":4}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":1},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":6},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":2},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":5}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":1},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":6},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":7},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":7},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":3}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":2},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":0},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":5},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":0},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":1}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":3},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":1},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":4},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":0},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":5}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":6},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":0},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":6},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":7},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":2}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":1},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":0},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":7},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":2},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":6},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":0},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":1}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":6},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":3},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":4},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":3},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":7},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":6},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":2},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":1}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":6},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":7},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":3},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":0},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":4},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":1},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":1},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":5}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":5},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":2},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":2},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":0},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":4}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":1},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":0},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":4},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":4},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":4},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":3}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":5},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":6},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":7},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":3},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":4},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":1},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":1},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":3}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":7},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":0},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":3},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":4},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":2}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":2},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":7},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":2},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":2},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":4},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":2}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":5},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":5},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":6},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":4},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":2},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":1},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":1},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":1},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":2},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":0},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":4},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":0}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":6},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":4},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":3},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":6},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":4},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":6},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":6}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":1},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":6},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":7},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":7},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":1},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":2},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":6}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":0},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":4},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":1},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":4},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":1}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":3},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":1},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":6},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":7},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":4},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":2},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":0}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":6},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":7},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":3},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":4},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":7},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":1},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":1}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":3},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":7},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":1},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":2},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":2},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":3},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":7},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":2}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":3},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":0}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":7},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":2},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":0},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":6},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":0},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":0},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":0},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":6},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":3},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":1},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":4},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":2},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":5},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":3}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":5},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":7},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":2},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":2},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":5},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":0},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":2},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":0}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":2},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":4},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":6},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":7},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":2},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":7}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":4},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":5},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":4},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":3},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":3},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":5},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":3},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":4}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]},{\"comm_c\":[94,32,230,197,99,73,250,124,111,129,191,248,72,164,215,148,10,190,56,67,10,200,25,30,125,54,5,182,123,78,214,15],\"comm_r_last\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89],\"inclusion_proofs\":[{\"data\":{\"Single\":{\"leaf\":[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,0,0,0,0,0,0],\"path\":{\"path\":[{\"hashes\":[[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,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,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,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,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,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,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,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]],\"index\":1},{\"hashes\":[[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63],[58,155,255,202,49,180,130,52,209,137,179,13,230,11,124,51,245,41,192,139,8,54,160,4,249,137,56,182,20,230,121,63]],\"index\":1},{\"hashes\":[[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31],[100,63,244,208,139,247,210,13,226,243,207,5,6,215,92,251,118,58,162,57,151,30,36,250,209,121,167,151,10,6,239,31]],\"index\":6},{\"hashes\":[[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53],[75,98,28,116,222,17,172,10,181,121,220,47,64,112,54,245,66,214,137,86,78,94,75,180,139,76,112,174,171,168,132,53]],\"index\":5},{\"hashes\":[[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41],[9,190,81,95,116,51,198,9,200,236,52,11,191,193,203,23,209,110,144,74,215,138,133,67,174,111,178,59,192,36,43,41]],\"index\":6},{\"hashes\":[[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24],[112,231,144,204,138,55,50,218,22,136,241,104,27,176,167,17,78,48,0,84,130,17,193,82,45,241,56,188,210,1,255,24]],\"index\":2},{\"hashes\":[[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99],[12,35,90,191,187,92,244,69,208,49,9,233,245,74,14,175,85,136,232,195,89,25,57,105,234,131,11,126,228,146,139,99]],\"index\":5},{\"hashes\":[[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47],[220,50,74,224,6,128,238,232,147,161,23,28,80,112,190,152,178,144,217,83,18,118,138,141,18,17,202,70,84,171,92,47]],\"index\":5}]},\"root\":[121,149,200,77,63,185,27,76,15,116,102,254,15,83,115,121,94,128,138,215,118,15,99,238,32,59,25,5,150,53,73,89]}}}]}]}]"} \ No newline at end of file diff --git a/prover/gev-core/Cargo.toml b/prover/gev-core/Cargo.toml deleted file mode 100644 index 7ed7e2e3..00000000 --- a/prover/gev-core/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "gev-core" -version = "0.1.0" -edition = "2021" - -[dependencies] -serde_json = "1.0.96" -serde = { version = "1.0", features = ["derive"] } -ark-serialize = { version = "^0.3.0", default-features = false, features = [ "derive" ] } -thiserror = "1.0.44" - -[lib] -crate-type = ["cdylib", "rlib"] - diff --git a/prover/gev-core/src/lib.rs b/prover/gev-core/src/lib.rs deleted file mode 100644 index b1ad3301..00000000 --- a/prover/gev-core/src/lib.rs +++ /dev/null @@ -1,145 +0,0 @@ -use serde::{Deserialize, Serialize}; -use std::fmt::{Display, Formatter, Result}; -use std::time::{SystemTime, UNIX_EPOCH}; -use thiserror::Error; - -#[derive(Default, Clone, Deserialize, Serialize, Debug)] -pub struct ResponseHeader { - pub success: bool, - pub message: String, -} - -#[derive(Default, Clone, Deserialize, Serialize, Debug)] -pub struct ProverInputs { - pub r1cs: String, - pub wtns: String, -} - -#[derive(Default, Clone, Serialize, Deserialize, Debug)] -pub struct ProofInfo { - pub algorithm: String, - pub proof: String, - pub vk: String, -} - -#[derive(Default, Clone, Deserialize, Serialize, Debug)] -pub struct VerifyInputs { - pub inputs: Vec, - pub proof_info: ProofInfo, -} - -#[derive(Default, Clone, Deserialize, Serialize, Debug)] -pub struct ProverResponse { - pub header: ResponseHeader, - pub proof_info: Option, -} - -#[derive(Default, Clone, Deserialize, Serialize, Debug)] -pub struct VerifyResponse { - pub header: ResponseHeader, -} - -#[derive(Error, Debug)] -pub enum GevulotError { - #[error("Error with base64 decoding")] - Base64DecodeError, - #[error("Error with base64 encoding")] - Base64EncodeError, - #[error("Error with canonical serialization")] - CanonicalDeserializeError, - #[error("Error with canonical deserialization")] - CanonicalSerializeError, - #[error("IO Error")] - ErrorIo, - #[error("Error with JSON serialization")] - JsonDeserializeError, - #[error("Error with JSON deserialization")] - JsonSerializeError, - #[error("Could not parse the r1cs file data")] - R1csParseError, - #[error("Could not parse the r1cs file data")] - WtnsParseError, - #[error("Error in Groth16 setup")] - Groth16SetupError, - #[error("Error in Groth16 verification")] - Groth16VerifyError, - #[error("Error in Marlin verification")] - MarlinVerifyError, - #[error("Filecoin window post error")] - FilecoinWindowPostError, - #[error("Filecoin winning post error")] - FilecoinWinningPostError, -} - -#[derive(PartialEq, Clone, Debug, Copy)] -pub enum GevulotAction { - Deploy, - Prove, - Verify, -} -impl From<&str> for GevulotAction { - fn from(input: &str) -> GevulotAction { - match input { - "deploy" => GevulotAction::Deploy, - "prove" => GevulotAction::Prove, - "verify" => GevulotAction::Verify, - _ => panic!("invalid action string: {input}"), - } - } -} - -#[derive(PartialEq, Clone, Debug, Copy)] -pub enum GevulotAlg { - Marlin, - Groth16, - WinningPost, - WindowPost, -} -impl From<&str> for GevulotAlg { - fn from(input: &str) -> GevulotAlg { - match input { - "marlin" => GevulotAlg::Marlin, - "groth16" => GevulotAlg::Groth16, - "winning-post" => GevulotAlg::WinningPost, - "window-post" => GevulotAlg::WindowPost, - _ => panic!("invalid algorithm string: {input}"), - } - } -} - -impl Display for GevulotAlg { - fn fmt(&self, f: &mut Formatter) -> Result { - match self { - GevulotAlg::Marlin => write!(f, "marlin"), - GevulotAlg::Groth16 => write!(f, "groth16"), - GevulotAlg::WinningPost => write!(f, "winning-post"), - GevulotAlg::WindowPost => write!(f, "window-post"), - } - } -} - -pub const PROVER_SUCCESS: &str = "Prover succeeded"; -pub const VERIFICATION_SUCCESS: &str = "Verification succeeded"; -pub const VERIFICATION_FAIL: &str = "Verification failed"; -pub const R1CS_PARSE_ERROR: &str = "error parsing R1CS file"; -pub const WTNS_PARSE_ERROR: &str = "error parsing WTNS file"; -pub const NOT_ON_CURVE: &str = "not on curve"; - -pub const TEST_SUDOKU_CORRECT: [u64; 81] = [ - 6, 0, 3, 2, 0, 5, 4, 7, 0, 7, 9, 1, 4, 6, 0, 0, 2, 8, 5, 2, 4, 9, 0, 0, 1, 6, 0, 0, 4, 0, 0, 5, - 7, 3, 0, 0, 3, 1, 0, 6, 8, 0, 7, 4, 2, 0, 7, 0, 3, 4, 2, 0, 0, 0, 0, 0, 0, 5, 2, 4, 0, 0, 0, 1, - 0, 0, 7, 3, 0, 0, 0, 4, 0, 3, 0, 0, 9, 1, 0, 0, 7, -]; - -pub const TEST_SUDOKU_WRONG: [u64; 81] = [ - 4, 0, 3, 2, 0, 5, 4, 7, 0, 7, 9, 1, 4, 6, 0, 0, 2, 8, 5, 2, 4, 9, 0, 0, 1, 6, 0, 0, 4, 0, 0, 5, - 7, 3, 0, 0, 3, 1, 0, 6, 8, 0, 7, 4, 2, 0, 7, 0, 3, 4, 2, 0, 0, 0, 0, 0, 0, 5, 2, 4, 0, 0, 0, 1, - 0, 0, 7, 3, 0, 0, 0, 4, 0, 3, 0, 0, 9, 1, 0, 0, 7, -]; - -pub fn get_millis() -> u64 { - SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_millis() as u64 -} diff --git a/prover/groth16/.gitignore b/prover/groth16/.gitignore deleted file mode 100644 index 9b5e101e..00000000 --- a/prover/groth16/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -target -Cargo.lock -.DS_Store -.idea -*.iml -*.ipynb_checkpoints -*.pyc -*.sage.py -params -*.swp -*.swo diff --git a/prover/groth16/CHANGELOG.md b/prover/groth16/CHANGELOG.md deleted file mode 100644 index 9f8719d5..00000000 --- a/prover/groth16/CHANGELOG.md +++ /dev/null @@ -1,54 +0,0 @@ -# CHANGELOG - -## Pending - -### Breaking changes - -### Features - -- [\#34](https://github.com/arkworks-rs/groth16/pull/34) Allow specifying custom R1CS to QAP reductions. - -### Improvements - -### Bug fixes - -## v0.3.0 - -### Breaking changes - -- [\#21](https://github.com/arkworks-rs/groth16/pull/21) Change the `generate_parameters` interface to take generators as input. - -### Features - -- [\#30](https://github.com/arkworks-rs/groth16/pull/30) Add proof input preprocessing. - -### Improvements - -### Bug fixes - -## v0.2.0 - -### Breaking changes - -- [\#4](https://github.com/arkworks-rs/groth16/pull/4) Change `groth16`'s logic to implement the `SNARK` trait. -- Minimum version on crates from `arkworks-rs/algebra` and `arkworks-rs/curves` is now `v0.2.0` -- [\#24](https://github.com/arkworks-rs/groth16/pull/24) Switch from `bench-utils` to `ark_std::perf_trace` - -### Features - -- [\#5](https://github.com/arkworks-rs/groth16/pull/5) Add R1CS constraints for the groth16 verifier. -- [\#8](https://github.com/arkworks-rs/groth16/pull/8) Add benchmarks for the prover -- [\#16](https://github.com/arkworks-rs/groth16/pull/16) Add proof re-randomization - -### Improvements - -- [\#9](https://github.com/arkworks-rs/groth16/pull/9) Improve memory consumption by manually dropping large vectors once they're no longer needed - -### Bug fixes - -- [c9bc5519](https://github.com/arkworks-rs/groth16/commit/885b9b569522f59a7eb428d1095f442ec9bc5519) Fix parallel feature flag -- [\#22](https://github.com/arkworks-rs/groth16/pull/22) Compile with `panic='abort'` in release mode, for safety of the library across FFI boundaries. - -## v0.1.0 - -_Initial release_ diff --git a/prover/groth16/CONTRIBUTING.md b/prover/groth16/CONTRIBUTING.md deleted file mode 100644 index b3152b35..00000000 --- a/prover/groth16/CONTRIBUTING.md +++ /dev/null @@ -1,65 +0,0 @@ -# Contributing - -Thank you for considering making contributions to `arkworks-rs/groth16`! - -Contributing to this repo can be done in several forms, such as participating in discussion or proposing code changes. -To ensure a smooth workflow for all contributors, the following general procedure for contributing has been established: - -1) Either open or find an issue you'd like to help with -2) Participate in thoughtful discussion on that issue -3) If you would like to contribute: - * If the issue is a feature proposal, ensure that the proposal has been accepted - * Ensure that nobody else has already begun working on this issue. - If they have, please try to contact them to collaborate - * If nobody has been assigned for the issue and you would like to work on it, make a comment on the issue to inform the community of your intentions to begin work. (So we can avoid duplication of efforts) - * We suggest using standard Github best practices for contributing: fork the repo, branch from the HEAD of master, make some commits on your branch, and submit a PR from the branch to master. - More detail on this is below - * Be sure to include a relevant change log entry in the Pending section of CHANGELOG.md (see file for log format) - * If the change is breaking, we may add migration instructions. - -Note that for very small or clear problems (such as typos), or well isolated improvements, it is not required to an open issue to submit a PR. -But be aware that for more complex problems/features touching multiple parts of the codebase, if a PR is opened before an adequate design discussion has taken place in a github issue, that PR runs a larger likelihood of being rejected. - -Looking for a good place to start contributing? How about checking out some good first issues - -## Branch Structure - -`groth16` has its default branch as `master`, which is where PRs are merged into. Releases will be periodically made, on no set schedule. -All other branches should be assumed to be miscellaneous feature development branches. - -All downstream users of the library should be using tagged versions of the library pulled from cargo. - -## How to work on a fork -Please skip this section if you're familiar with contributing to opensource github projects. - -First fork the repo from the github UI, and clone it locally. -Then in the repo, you want to add the repo you forked from as a new remote. You do this as: -```bash -git remote add upstream git@github.com:arkworks-rs/groth16.git -``` - -Then the way you make code contributions is to first think of a branch name that describes your change. -Then do the following: -```bash -git checkout master -git pull upstream master -git checkout -b $BRANCH_NAME -``` -and then work as normal on that branch, and pull request to upstream master when you're done =) - -## Updating documentation - -All PRs should aim to leave the code more documented than it started with. -Please don't assume that its easy to infer what the code is doing, -as that is usually not the case for these complex protocols. -(Even when you understand the paper!) - -Its often very useful to describe what is the high level view of what a code block is doing, -and either refer to the relevant section of a paper or include a short proof/argument for why it makes sense before the actual logic. - -## Performance improvements - -All performance improvements should be accompanied with benchmarks improving, or otherwise have it be clear that things have improved. -For some areas of the codebase, performance roughly follows the number of field multiplications, but there are also many areas where -hard to predict low level system effects such as cache locality and superscalar operations become important for performance. -Thus performance can often become very non-intuitive / diverge from minimizing the number of arithmetic operations. \ No newline at end of file diff --git a/prover/groth16/Cargo.toml b/prover/groth16/Cargo.toml deleted file mode 100644 index e8582895..00000000 --- a/prover/groth16/Cargo.toml +++ /dev/null @@ -1,138 +0,0 @@ -[package] -name = "ark-groth16" -version = "0.3.0" -authors = ["arkworks contributors"] -description = "An implementation of the Groth 2016 zkSNARK proof system" -homepage = "https://arkworks.rs" -repository = "https://github.com/arkworks-rs/groth16" -documentation = "https://docs.rs/ark-groth16/" -keywords = [ - "zero-knowledge", - "cryptography", - "zkSNARK", - "SNARK", - "Groth-Maller", -] -categories = ["cryptography"] -include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] -license = "MIT/Apache-2.0" -edition = "2021" - -################################# Dependencies ################################ - -[dependencies] -ark-ff = { 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, features = [ - "derive", -] } -ark-poly = { version = "0.4.0", default-features = false } -ark-std = { version = "0.4.0", default-features = false } -ark-relations = { version = "0.4.0", default-features = false } -ark-crypto-primitives = { version = "0.4.0", default-features = false, features = [ - "snark", -] } -ark-r1cs-std = { version = "0.4.0", default-features = false, optional = true } - -tracing = { version = "0.1", default-features = false, features = [ - "attributes", -], optional = true } -derivative = { version = "2.0", features = ["use_core"], optional = true } - -rayon = { version = "1", optional = true } - -gev-core = { path = "../gev-core" } -base64 = "0.21.2" -num-bigint = "0.4.3" -serde_json = "1.0.96" -serde = { version = "1.0", features = ["derive"] } -ark-bn254 = { version = "0.4.0", default-features = false, features = [ - "curve", -] } -r1cs-file = "0.3.0" -wtns-file = "0.1.5" - - -[dev-dependencies] -csv = { version = "1" } -ark-bls12-381 = { version = "0.4.0", default-features = false, features = [ - "curve", -] } -ark-bls12-377 = { version = "0.4.0", default-features = false, features = [ - "curve", -] } -ark-cp6-782 = { version = "0.4.0", default-features = false } -ark-mnt4-298 = { version = "0.4.0", default-features = false, features = [ - "r1cs", - "curve", -] } -ark-mnt6-298 = { version = "0.4.0", default-features = false, features = [ - "r1cs", -] } -ark-mnt4-753 = { version = "0.4.0", default-features = false, features = [ - "r1cs", - "curve", -] } -ark-mnt6-753 = { version = "0.4.0", default-features = false, features = [ - "r1cs", -] } -ark-r1cs-std = { version = "0.4.0", default-features = false } - -[features] -default = ["parallel"] -std = [ - "ark-ff/std", - "ark-ec/std", - "ark-poly/std", - "ark-relations/std", - "ark-crypto-primitives/std", - "ark-std/std", -] -parallel = [ - "std", - "ark-ff/parallel", - "ark-poly/parallel", - "ark-ec/parallel", - "ark-crypto-primitives/parallel", - "ark-std/parallel", - "rayon", -] -r1cs = ["ark-crypto-primitives/r1cs", "ark-r1cs-std", "tracing", "derivative"] -print-trace = ["ark-std/print-trace"] - -[[bench]] -name = "groth16-benches" -path = "benches/bench.rs" -harness = false -required-features = ["std"] - -[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 - -[lib] -crate-type = ["cdylib", "rlib"] - -[rust] -lld = true diff --git a/prover/groth16/LICENSE-APACHE b/prover/groth16/LICENSE-APACHE deleted file mode 100644 index 16fe87b0..00000000 --- a/prover/groth16/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -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. diff --git a/prover/groth16/LICENSE-MIT b/prover/groth16/LICENSE-MIT deleted file mode 100644 index 72dc60d8..00000000 --- a/prover/groth16/LICENSE-MIT +++ /dev/null @@ -1,19 +0,0 @@ -The MIT License (MIT) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/prover/groth16/README.md b/prover/groth16/README.md deleted file mode 100644 index b27cb773..00000000 --- a/prover/groth16/README.md +++ /dev/null @@ -1,53 +0,0 @@ -

ark-groth16

- -

- - - - -

- -The arkworks ecosystem consist of Rust libraries for designing and working with __zero knowledge succinct non-interactive arguments (zkSNARKs)__. This repository contains an efficient implementation of the zkSNARK of [[Groth16]](https://eprint.iacr.org/2016/260). - -This library is released under the MIT License and the Apache v2 License (see [License](#license)). - -**WARNING:** This is an academic proof-of-concept prototype, and in particular has not received careful code review. This implementation is NOT ready for production use. - -## Build guide - -The library compiles on the `stable` toolchain of the Rust compiler. To install the latest version of Rust, first install `rustup` by following the instructions [here](https://rustup.rs/), or via your platform's package manager. Once `rustup` is installed, install the Rust toolchain by invoking: -```bash -rustup install stable -``` - -After that, use `cargo`, the standard Rust build tool, to build the library: -```bash -git clone https://github.com/arkworks-rs/groth16.git -cargo build --release -``` - -This library comes with unit tests for each of the provided crates. Run the tests with: -```bash -cargo test -``` - -## License - -This library is licensed under either of the following licenses, at your discretion. - - * Apache License Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) - * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) - -Unless you explicitly state otherwise, any contribution submitted for inclusion in this library by you shall be dual licensed as above (as defined in the Apache v2 License), without any additional terms or conditions. - -## Acknowledgements - -This work was supported by: -a Google Faculty Award; -the National Science Foundation; -the UC Berkeley Center for Long-Term Cybersecurity; -and donations from the Ethereum Foundation, the Interchain Foundation, and Qtum. - -An earlier version of this library was developed as part of the paper *"[ZEXE: Enabling Decentralized Private Computation][zexe]"*. - -[zexe]: https://ia.cr/2018/962 diff --git a/prover/groth16/benches/bench.rs b/prover/groth16/benches/bench.rs deleted file mode 100644 index 18d0a277..00000000 --- a/prover/groth16/benches/bench.rs +++ /dev/null @@ -1,141 +0,0 @@ -// For benchmark, run: -// RAYON_NUM_THREADS=N cargo bench --no-default-features --features "std -// parallel" -- --nocapture where N is the number of threads you want to use (N -// = 1 for single-thread). - -use ark_bls12_381::{Bls12_381, Fr as BlsFr}; -use ark_crypto_primitives::SNARK; -use ark_ff::{PrimeField, UniformRand}; -use ark_groth16::Groth16; -use ark_mnt4_298::{Fr as MNT4Fr, MNT4_298}; -use ark_mnt4_753::{Fr as MNT4BigFr, MNT4_753}; -use ark_mnt6_298::{Fr as MNT6Fr, MNT6_298}; -use ark_mnt6_753::{Fr as MNT6BigFr, MNT6_753}; -use ark_relations::{ - lc, - r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}, -}; -use ark_std::ops::Mul; - -const NUM_PROVE_REPEATITIONS: usize = 10; -const NUM_VERIFY_REPEATITIONS: usize = 50; - -#[derive(Copy)] -struct DummyCircuit { - pub a: Option, - pub b: Option, - pub num_variables: usize, - pub num_constraints: usize, -} - -impl Clone for DummyCircuit { - fn clone(&self) -> Self { - DummyCircuit { - a: self.a.clone(), - b: self.b.clone(), - num_variables: self.num_variables.clone(), - num_constraints: self.num_constraints.clone(), - } - } -} - -impl ConstraintSynthesizer for DummyCircuit { - fn generate_constraints(self, cs: ConstraintSystemRef) -> Result<(), SynthesisError> { - let a = cs.new_witness_variable(|| self.a.ok_or(SynthesisError::AssignmentMissing))?; - let b = cs.new_witness_variable(|| self.b.ok_or(SynthesisError::AssignmentMissing))?; - let c = cs.new_input_variable(|| { - let a = self.a.ok_or(SynthesisError::AssignmentMissing)?; - let b = self.b.ok_or(SynthesisError::AssignmentMissing)?; - - Ok(a * b) - })?; - - for _ in 0..(self.num_variables - 3) { - let _ = cs.new_witness_variable(|| self.a.ok_or(SynthesisError::AssignmentMissing))?; - } - - for _ in 0..self.num_constraints - 1 { - cs.enforce_constraint(lc!() + a, lc!() + b, lc!() + c)?; - } - - cs.enforce_constraint(lc!(), lc!(), lc!())?; - - Ok(()) - } -} - -macro_rules! groth16_prove_bench { - ($bench_name:ident, $bench_field:ty, $bench_pairing_engine:ty) => { - let rng = &mut ark_std::test_rng(); - let c = DummyCircuit::<$bench_field> { - a: Some(<$bench_field>::rand(rng)), - b: Some(<$bench_field>::rand(rng)), - num_variables: 10, - num_constraints: 65536, - }; - - let (pk, _) = Groth16::<$bench_pairing_engine>::circuit_specific_setup(c, rng).unwrap(); - - let start = ark_std::time::Instant::now(); - - for _ in 0..NUM_PROVE_REPEATITIONS { - let _ = Groth16::<$bench_pairing_engine>::prove(&pk, c.clone(), rng).unwrap(); - } - - println!( - "per-constraint proving time for {}: {} ns/constraint", - stringify!($bench_pairing_engine), - start.elapsed().as_nanos() / NUM_PROVE_REPEATITIONS as u128 / 65536u128 - ); - }; -} - -macro_rules! groth16_verify_bench { - ($bench_name:ident, $bench_field:ty, $bench_pairing_engine:ty) => { - let rng = &mut ark_std::test_rng(); - let c = DummyCircuit::<$bench_field> { - a: Some(<$bench_field>::rand(rng)), - b: Some(<$bench_field>::rand(rng)), - num_variables: 10, - num_constraints: 65536, - }; - - let (pk, vk) = Groth16::<$bench_pairing_engine>::circuit_specific_setup(c, rng).unwrap(); - let proof = Groth16::<$bench_pairing_engine>::prove(&pk, c.clone(), rng).unwrap(); - - let v = c.a.unwrap().mul(c.b.unwrap()); - - let start = ark_std::time::Instant::now(); - - for _ in 0..NUM_VERIFY_REPEATITIONS { - let _ = Groth16::<$bench_pairing_engine>::verify(&vk, &vec![v], &proof).unwrap(); - } - - println!( - "verifying time for {}: {} ns", - stringify!($bench_pairing_engine), - start.elapsed().as_nanos() / NUM_VERIFY_REPEATITIONS as u128 - ); - }; -} - -fn bench_prove() { - groth16_prove_bench!(bls, BlsFr, Bls12_381); - groth16_prove_bench!(mnt4, MNT4Fr, MNT4_298); - groth16_prove_bench!(mnt6, MNT6Fr, MNT6_298); - groth16_prove_bench!(mnt4big, MNT4BigFr, MNT4_753); - groth16_prove_bench!(mnt6big, MNT6BigFr, MNT6_753); -} - -fn bench_verify() { - groth16_verify_bench!(bls, BlsFr, Bls12_381); - groth16_verify_bench!(mnt4, MNT4Fr, MNT4_298); - groth16_verify_bench!(mnt6, MNT6Fr, MNT6_298); - groth16_verify_bench!(mnt4big, MNT4BigFr, MNT4_753); - groth16_verify_bench!(mnt6big, MNT6BigFr, MNT6_753); -} - -fn main() { - bench_prove(); - bench_verify(); -} diff --git a/prover/groth16/examples/recursive-snark/constraints.rs b/prover/groth16/examples/recursive-snark/constraints.rs deleted file mode 100644 index 4d90fa2a..00000000 --- a/prover/groth16/examples/recursive-snark/constraints.rs +++ /dev/null @@ -1,364 +0,0 @@ -use algebra::{ - fields::{FftParameters, FpParameters}, - BigInteger, Field, PrimeField, -}; -use algebra_core::{PairingEngine, ToConstraintField}; -use core::ops::MulAssign; -use crypto_primitives::nizk::{ - constraints::NIZKVerifierGadget, - groth16::{ - constraints::{Groth16VerifierGadget, ProofVar, VerifyingKeyVar}, - Groth16, - }, -}; -use groth16::{Parameters, Proof}; -use r1cs_core::{lc, ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}; -use r1cs_std::{fields::fp::FpVar, pairing::PairingVar as PG, prelude::*}; -use std::marker::PhantomData; - -pub trait CurvePair -where - ::G1Projective: - MulAssign<::Fq>, - ::G2Projective: - MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, -{ - type TickGroup: PairingEngine< - Fq = ::Fr, - Fr = ::Fq, - >; - type TockGroup: PairingEngine; - - const TICK_CURVE: &'static str; - const TOCK_CURVE: &'static str; -} - -// Verifying InnerCircuit in MiddleCircuit -type InnerProofSystem = Groth16< - ::TickGroup, - InnerCircuit<<::TickGroup as PairingEngine>::Fr>, - <::TickGroup as PairingEngine>::Fr, ->; - -type InnerVerifierGadget = Groth16VerifierGadget<::TickGroup, PV>; -type InnerProofVar = ProofVar<::TickGroup, PV>; -type InnerVkVar = VerifyingKeyVar<::TickGroup, PV>; - -// Verifying MiddleCircuit in OuterCircuit -type MiddleProofSystem = Groth16< - ::TockGroup, - MiddleCircuit, - <::TockGroup as PairingEngine>::Fr, ->; -type MiddleVerifierGadget = Groth16VerifierGadget<::TockGroup, PV>; -type MiddleProofVar = ProofVar<::TockGroup, PV>; -type MiddleVkVar = VerifyingKeyVar<::TockGroup, PV>; - -pub struct InnerCircuit { - num_constraints: usize, - inputs: Vec, -} - -impl InnerCircuit { - pub fn new(num_constraints: usize, inputs: Vec) -> Self { - Self { - num_constraints, - inputs, - } - } -} - -impl ConstraintSynthesizer for InnerCircuit { - fn generate_constraints(self, cs: ConstraintSystemRef) -> Result<(), SynthesisError> { - assert!(self.inputs.len() >= 2); - assert!(self.num_constraints >= self.inputs.len()); - - let mut variables: Vec<_> = Vec::with_capacity(self.inputs.len()); - for input in self.inputs.into_iter() { - let input_var = cs.new_input_variable(|| Ok(input))?; - variables.push((input, input_var)); - } - - for i in 0..self.num_constraints { - let new_entry = { - let (input_1_val, input_1_var) = variables[i]; - let (input_2_val, input_2_var) = variables[i + 1]; - let result_val = input_1_val * input_2_val; - let result_var = cs.new_witness_variable(|| Ok(result_val))?; - cs.enforce_constraint( - lc!() + input_1_var, - lc!() + input_2_var, - lc!() + result_var, - )?; - (result_val, result_var) - }; - variables.push(new_entry); - } - Ok(()) - } -} - -pub struct MiddleCircuit> -where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, -{ - inputs: Vec<::Fr>, - params: Parameters, - proof: Proof, - _curve_pair: PhantomData, - _tick_pairing: PhantomData, -} - -impl> MiddleCircuit -where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, -{ - pub fn new( - inputs: Vec<::Fr>, - params: Parameters, - proof: Proof, - ) -> Self { - Self { - inputs, - params, - proof, - _curve_pair: PhantomData, - _tick_pairing: PhantomData, - } - } - - pub fn inputs( - inputs: &[::Fr], - ) -> Vec<::Fr> { - let input_bytes = inputs - .iter() - .flat_map(|input| { - input - .into_repr() - .as_ref() - .iter() - .flat_map(|l| l.to_le_bytes().to_vec()) - .collect::>() - }) - .collect::>(); - - input_bytes[..].to_field_elements().unwrap() - } -} - -impl ConstraintSynthesizer<::Fr> - for MiddleCircuit -where - C: CurvePair, - TickPairing: PG, - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, -{ - fn generate_constraints( - self, - cs: ConstraintSystemRef<::Fr>, - ) -> Result<(), SynthesisError> { - let params = self.params; - let proof = self.proof; - let inputs = self.inputs; - let input_gadgets; - - { - let ns = r1cs_core::ns!(cs, "Allocate Input"); - let cs = ns.cs(); - // Chain all input values in one large byte array. - let input_bytes = inputs - .into_iter() - .flat_map(|input| { - input - .into_repr() - .as_ref() - .iter() - .flat_map(|l| l.to_le_bytes().to_vec()) - .collect::>() - }) - .collect::>(); - - // Allocate this byte array as input packed into field elements. - let input_bytes = UInt8::new_input_vec(r1cs_core::ns!(cs, "Input"), &input_bytes[..])?; - // 40 byte - let element_size = - <<::Fr as PrimeField>::Params as FftParameters>::BigInt::NUM_LIMBS * 8; - input_gadgets = input_bytes - .chunks(element_size) - .map(|chunk| { - chunk - .iter() - .flat_map(|byte| byte.to_bits_le().unwrap()) - .collect::>() - }) - .collect::>(); - } - println!("|---- Num inputs for sub-SNARK: {}", input_gadgets.len()); - let num_constraints = cs.num_constraints(); - println!( - "|---- Num constraints to prepare inputs: {}", - num_constraints - ); - - let vk_var = - InnerVkVar::::new_witness(r1cs_core::ns!(cs, "Vk"), || Ok(¶ms.vk))?; - let proof_var = - InnerProofVar::::new_witness(r1cs_core::ns!(cs, "Proof"), || { - Ok(proof.clone()) - })?; - as NIZKVerifierGadget< - InnerProofSystem, - ::Fr, - >>::verify(&vk_var, input_gadgets.iter(), &proof_var)? - .enforce_equal(&Boolean::TRUE)?; - println!( - "|---- Num constraints for sub-SNARK verification: {}", - cs.num_constraints() - num_constraints - ); - Ok(()) - } -} - -pub struct OuterCircuit, TickPairing: PG> -where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, -{ - inputs: Vec<::Fr>, - params: Parameters, - proof: Proof, - _curve_pair: PhantomData, - _tock_pairing: PhantomData, - _tick_pairing: PhantomData, -} - -impl, TickPairing: PG> - OuterCircuit -where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, -{ - pub fn new( - inputs: Vec<::Fr>, - params: Parameters, - proof: Proof, - ) -> Self { - Self { - inputs, - params, - proof, - _curve_pair: PhantomData, - _tock_pairing: PhantomData, - _tick_pairing: PhantomData, - } - } -} - -impl, TickPairing: PG> - ConstraintSynthesizer<::Fr> - for OuterCircuit -where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, -{ - fn generate_constraints( - self, - cs: ConstraintSystemRef<::Fr>, - ) -> Result<(), SynthesisError> { - let params = self.params; - let proof = self.proof; - let inputs = self.inputs; - let mut input_gadgets = Vec::new(); - - { - let bigint_size = - <::Fr as PrimeField>::BigInt::NUM_LIMBS * 64; - let mut input_bits = Vec::new(); - let ns = r1cs_core::ns!(cs, "Allocate Input"); - let cs = ns.cs(); - - for input in inputs.into_iter() { - let input_gadget = FpVar::new_input(r1cs_core::ns!(cs, "Input"), || Ok(input))?; - let mut fp_bits = input_gadget.to_bits_le()?; - - // Use 320 bits per element. - for _ in fp_bits.len()..bigint_size { - fp_bits.push(Boolean::constant(false)); - } - input_bits.extend_from_slice(&fp_bits); - } - - // Pack input bits into field elements of the underlying circuit. - let max_size = 8 - * (<<::Fr as PrimeField>::Params as FpParameters>::CAPACITY / 8) - as usize; - let bigint_size = - <<::Fr as PrimeField>::Params as FftParameters>::BigInt::NUM_LIMBS * 64; - for chunk in input_bits.chunks(max_size) { - let mut chunk = chunk.to_vec(); - let len = chunk.len(); - for _ in len..bigint_size { - chunk.push(Boolean::constant(false)); - } - input_gadgets.push(chunk); - } - } - println!("|---- Num inputs for sub-SNARK: {}", input_gadgets.len()); - let num_constraints = cs.num_constraints(); - println!( - "|---- Num constraints to prepare inputs: {}", - num_constraints - ); - - let vk_var = - MiddleVkVar::::new_witness( - r1cs_core::ns!(cs, "Vk"), - || Ok(¶ms.vk), - )?; - let proof_var = - MiddleProofVar::::new_witness(r1cs_core::ns!(cs, "Proof"), || { - Ok(proof.clone()) - })?; - as NIZKVerifierGadget< - MiddleProofSystem, - ::Fr, - >>::verify(&vk_var, &input_gadgets, &proof_var)? - .enforce_equal(&Boolean::TRUE)?; - println!( - "|---- Num constraints for sub-SNARK verification: {}", - cs.num_constraints() - num_constraints - ); - Ok(()) - } -} diff --git a/prover/groth16/examples/recursive-snark/groth16.rs b/prover/groth16/examples/recursive-snark/groth16.rs deleted file mode 100644 index d21b31ed..00000000 --- a/prover/groth16/examples/recursive-snark/groth16.rs +++ /dev/null @@ -1,325 +0,0 @@ -#![warn(unused)] -#![deny( - trivial_casts, - trivial_numeric_casts, - variant_size_differences, - stable_features, - non_shorthand_field_patterns, - renamed_and_removed_lints, - private_in_public, - unsafe_code -)] - -use csv; -use std::ops::MulAssign; - -// For randomness (during paramgen and proof generation) -use algebra_core::{test_rng, PairingEngine}; - -// For benchmarking -use std::{ - env, - error::Error, - fs::OpenOptions, - path::PathBuf, - process, - time::{Duration, Instant}, -}; - -pub use algebra::{mnt4_298, mnt6_298, Field, ToConstraintField, UniformRand}; -use r1cs_std::pairing::PairingVar as PG; - -// We're going to use the Groth 16 proving system. -use groth16::{ - create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, -}; - -mod constraints; -use crate::constraints::{CurvePair, InnerCircuit, MiddleCircuit, OuterCircuit}; - -struct MNT46; -impl CurvePair for MNT46 { - type TickGroup = mnt4_298::MNT4_298; - type TockGroup = mnt6_298::MNT6_298; - const TICK_CURVE: &'static str = "MNT4_298"; - const TOCK_CURVE: &'static str = "MNT6_298"; -} -struct MNT64; -impl CurvePair for MNT64 { - type TickGroup = mnt6_298::MNT6_298; - type TockGroup = mnt4_298::MNT4_298; - const TICK_CURVE: &'static str = "MNT6_298"; - const TOCK_CURVE: &'static str = "MNT4_298"; -} - -fn main() -> Result<(), Box> { - let args: Vec = env::args().collect(); - if args.len() < 3 || args[1] == "-h" || args[1] == "--help" { - println!( - "\nHelp: Invoke this as []\n" - ); - println!(" defines the order in which the MNT4/6 curves should be used:"); - println!("46 (default) uses the MNT4_298 curve for the inner and outer circuit;"); - println!("64 uses the MNT6_298 curve for the inner and outer circuit."); - return Ok(()); - } - let num_constraints: usize = args[1].parse().unwrap(); - let output_file_path = PathBuf::from(args[2].clone()); - - if args.len() < 4 || args[3] == "46" { - run::( - num_constraints, - output_file_path, - ) - } else { - run::( - num_constraints, - output_file_path, - ) - } -} - -fn run, TockPairing: PG>( - num_constraints: usize, - output_file_path: PathBuf, -) -> Result<(), Box> -where - ::G1Projective: MulAssign<::Fq>, - ::G2Projective: MulAssign<::Fq>, - ::G1Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, - ::G2Affine: - ToConstraintField<<::Fr as Field>::BasePrimeField>, -{ - let mut wtr = if !output_file_path.exists() { - println!("Creating output file"); - let f = OpenOptions::new() - .create(true) - .append(true) - .open(output_file_path)?; - let mut wtr = csv::Writer::from_writer(f); - wtr.write_record(&[ - "num_constraints", - "setup_inner", - "prover_inner", - "setup_middle", - "prover_middle", - "setup_outer", - "prover_outer", - "verifier_outer", - ])?; - wtr - } else if output_file_path.is_file() { - let f = OpenOptions::new().append(true).open(output_file_path)?; - csv::Writer::from_writer(f) - } else { - println!("Path to output file does not point to a file."); - process::exit(1); - }; - // This may not be cryptographically safe, use - // `OsRng` (for example) in production software. - let rng = &mut test_rng(); - - // Let's benchmark stuff! - let samples = 1; - let mut total_setup_inner = Duration::new(0, 0); - let mut total_proving_inner = Duration::new(0, 0); - let mut total_setup_middle = Duration::new(0, 0); - let mut total_proving_middle = Duration::new(0, 0); - let mut total_setup_outer = Duration::new(0, 0); - let mut total_proving_outer = Duration::new(0, 0); - let mut total_verifying_outer = Duration::new(0, 0); - - // Just a place to put the proof data, so we can - // benchmark deserialization. - // let mut proof_vec = vec![]; - - for sample in 0..samples { - println!("Running sample {}/{}", sample + 1, samples); - let mut inputs: Vec<::Fr> = - Vec::with_capacity(num_constraints); - for _ in 0..num_constraints { - inputs.push(<::Fr as UniformRand>::rand( - rng, - )); - } - - // Create parameters for our inner circuit - println!("|-- Generating inner parameters ({})", C::TICK_CURVE); - let start = Instant::now(); - let params_inner = { - let c = InnerCircuit::<::Fr>::new( - num_constraints, - inputs.clone(), - ); - generate_random_parameters(c, rng)? - }; - total_setup_inner += start.elapsed(); - - // proof_vec.truncate(0); - println!("|-- Generating inner proof ({})", C::TICK_CURVE); - let start = Instant::now(); - let proof_inner = { - // Create an instance of our inner circuit (with the witness) - let c = InnerCircuit::new(num_constraints, inputs.clone()); - // Create a proof with our parameters. - create_random_proof(c, ¶ms_inner, rng)? - }; - total_proving_inner += start.elapsed(); - - // Verify inner proof. - let pvk = prepare_verifying_key(¶ms_inner.vk); - assert!(verify_proof(&pvk, &proof_inner, &inputs).unwrap()); - - // Create parameters for our middle circuit - println!("|-- Generating middle parameters ({})", C::TOCK_CURVE); - let start = Instant::now(); - let params_middle = { - let c = MiddleCircuit::::new( - inputs.clone(), - params_inner.clone(), - proof_inner.clone(), - ); - generate_random_parameters(c, rng)? - }; - total_setup_middle += start.elapsed(); - - // proof_vec.truncate(0); - println!("|-- Generating middle proof ({})", C::TOCK_CURVE); - let start = Instant::now(); - let proof_middle = { - // Create an instance of our middle circuit (with the witness) - let c = MiddleCircuit::::new( - inputs.clone(), - params_inner.clone(), - proof_inner.clone(), - ); - // Create a proof with our parameters. - create_random_proof(c, ¶ms_middle, rng)? - }; - total_proving_middle += start.elapsed(); - - { - let pvk = prepare_verifying_key(¶ms_middle.vk); - assert!(verify_proof( - &pvk, - &proof_middle, - &MiddleCircuit::::inputs(&inputs) - ) - .unwrap()); - } - - // Create parameters for our outer circuit - println!("|-- Generating outer parameters ({})", C::TICK_CURVE); - let start = Instant::now(); - let params_outer = { - let c = OuterCircuit::::new( - inputs.clone(), - params_middle.clone(), - proof_middle.clone(), - ); - generate_random_parameters::(c, rng)? - }; - - // Prepare the verification key (for proof verification) - let pvk = prepare_verifying_key(¶ms_outer.vk); - total_setup_outer += start.elapsed(); - - // proof_vec.truncate(0); - println!("|-- Generating outer proof ({})", C::TICK_CURVE); - let start = Instant::now(); - let proof_outer = { - // Create an instance of our outer circuit (with the witness) - let c = OuterCircuit::::new( - inputs.clone(), - params_middle.clone(), - proof_middle.clone(), - ); - // Create a proof with our parameters. - create_random_proof(c, ¶ms_outer, rng)? - }; - total_proving_outer += start.elapsed(); - - println!("|-- Verify outer proof ({})", C::TICK_CURVE); - let start = Instant::now(); - // let proof = Proof::read(&proof_vec[..]).unwrap(); - // Check the proof - let r = verify_proof(&pvk, &proof_outer, &inputs).unwrap(); - assert!(r); - total_verifying_outer += start.elapsed(); - } - - let setup_inner_avg = total_setup_inner / samples; - let setup_inner_avg = setup_inner_avg.subsec_nanos() as f64 / 1_000_000_000f64 - + (setup_inner_avg.as_secs() as f64); - - let proving_inner_avg = total_proving_inner / samples; - let proving_inner_avg = proving_inner_avg.subsec_nanos() as f64 / 1_000_000_000f64 - + (proving_inner_avg.as_secs() as f64); - - let setup_middle_avg = total_setup_middle / samples; - let setup_middle_avg = setup_middle_avg.subsec_nanos() as f64 / 1_000_000_000f64 - + (setup_middle_avg.as_secs() as f64); - - let proving_middle_avg = total_proving_middle / samples; - let proving_middle_avg = proving_middle_avg.subsec_nanos() as f64 / 1_000_000_000f64 - + (proving_middle_avg.as_secs() as f64); - - let setup_outer_avg = total_setup_outer / samples; - let setup_outer_avg = setup_outer_avg.subsec_nanos() as f64 / 1_000_000_000f64 - + (setup_outer_avg.as_secs() as f64); - - let proving_outer_avg = total_proving_outer / samples; - let proving_outer_avg = proving_outer_avg.subsec_nanos() as f64 / 1_000_000_000f64 - + (proving_outer_avg.as_secs() as f64); - - let verifying_outer_avg = total_verifying_outer / samples; - let verifying_outer_avg = verifying_outer_avg.subsec_nanos() as f64 / 1_000_000_000f64 - + (verifying_outer_avg.as_secs() as f64); - - println!( - "=== Benchmarking recursive Groth16 with {} constraints on inner circuit: ====", - num_constraints - ); - println!( - "Average setup time (inner circuit): {:?} seconds", - setup_inner_avg - ); - println!( - "Average proving time (inner circuit): {:?} seconds", - proving_inner_avg - ); - println!( - "Average setup time (middle circuit): {:?} seconds", - setup_middle_avg - ); - println!( - "Average proving time (middle circuit): {:?} seconds", - proving_middle_avg - ); - println!( - "Average setup time (outer circuit): {:?} seconds", - setup_outer_avg - ); - println!( - "Average proving time (outer circuit): {:?} seconds", - proving_outer_avg - ); - println!( - "Average verifying time (outer circuit): {:?} seconds", - verifying_outer_avg - ); - - wtr.write_record(&[ - format!("{}", num_constraints), - format!("{}", setup_inner_avg), - format!("{}", proving_inner_avg), - format!("{}", setup_middle_avg), - format!("{}", proving_middle_avg), - format!("{}", setup_outer_avg), - format!("{}", proving_outer_avg), - format!("{}", verifying_outer_avg), - ])?; - wtr.flush()?; - Ok(()) -} diff --git a/prover/groth16/examples/snark-scalability/constraints.rs b/prover/groth16/examples/snark-scalability/constraints.rs deleted file mode 100644 index 8a2ede0e..00000000 --- a/prover/groth16/examples/snark-scalability/constraints.rs +++ /dev/null @@ -1,78 +0,0 @@ -use ark_ff::Field; -use ark_relations::{ - lc, - r1cs::{ - ConstraintSynthesizer, ConstraintSystemRef, LinearCombination, SynthesisError, Variable, - }, -}; -use std::marker::PhantomData; - -pub struct Benchmark { - num_constraints: usize, - _engine: PhantomData, -} - -impl Benchmark { - pub fn new(num_constraints: usize) -> Self { - Self { - num_constraints, - _engine: PhantomData, - } - } -} - -impl ConstraintSynthesizer for Benchmark { - fn generate_constraints(self, cs: ConstraintSystemRef) -> Result<(), SynthesisError> { - let mut assignments = Vec::new(); - let mut a_val = F::one(); - let mut a_var = cs.new_input_variable(|| Ok(a_val))?; - assignments.push((a_val, a_var)); - - let mut b_val = F::one(); - let mut b_var = cs.new_input_variable(|| Ok(b_val))?; - assignments.push((a_val, a_var)); - - for i in 0..self.num_constraints - 1 { - if i % 2 != 0 { - let c_val = a_val * &b_val; - let c_var = cs.new_witness_variable(|| Ok(c_val))?; - - cs.enforce_constraint(lc!() + a_var, lc!() + b_var, lc!() + c_var)?; - - assignments.push((c_val, c_var)); - a_val = b_val; - a_var = b_var; - b_val = c_val; - b_var = c_var; - } else { - let c_val = a_val + &b_val; - let c_var = cs.new_witness_variable(|| Ok(c_val))?; - - cs.enforce_constraint(lc!() + a_var + b_var, lc!() + Variable::One, lc!() + c_var)?; - - assignments.push((c_val, c_var)); - a_val = b_val; - a_var = b_var; - b_val = c_val; - b_var = c_var; - } - } - - let mut a_lc = LinearCombination::zero(); - let mut b_lc = LinearCombination::zero(); - let mut c_val = F::zero(); - - for (val, var) in assignments { - a_lc = a_lc + var; - b_lc = b_lc + var; - c_val = c_val + &val; - } - c_val = c_val.square(); - - let c_var = cs.new_witness_variable(|| Ok(c_val))?; - - cs.enforce_constraint(lc!() + a_lc, lc!() + b_lc, lc!() + c_var)?; - - Ok(()) - } -} diff --git a/prover/groth16/examples/snark-scalability/groth16.rs b/prover/groth16/examples/snark-scalability/groth16.rs deleted file mode 100644 index 194c5c34..00000000 --- a/prover/groth16/examples/snark-scalability/groth16.rs +++ /dev/null @@ -1,143 +0,0 @@ -#![warn(unused)] -#![deny( - trivial_casts, - trivial_numeric_casts, - variant_size_differences, - stable_features, - non_shorthand_field_patterns, - renamed_and_removed_lints, - private_in_public, - unsafe_code -)] - -use csv; - -// For randomness (during paramgen and proof generation) -use ark_ff::One; -use ark_std::test_rng; - -// For benchmarking -use std::{ - error::Error, - time::{Duration, Instant}, -}; - -// Bring in some tools for using pairing-friendly curves -// We're going to use the BLS12-377 pairing-friendly elliptic curve. -use ark_bls12_377::{Bls12_377, Fr}; - -// We're going to use the Groth 16 proving system. -use ark_groth16::{ - create_random_proof, generate_random_parameters, prepare_verifying_key, verify_proof, -}; - -use std::{env, fs::OpenOptions, path::PathBuf, process}; - -mod constraints; -use crate::constraints::Benchmark; - -fn main() -> Result<(), Box> { - let args: Vec = env::args().collect(); - if args.len() < 3 || args[1] == "-h" || args[1] == "--help" { - println!("\nHelp: Invoke this as \n"); - } - let num_constraints: usize = args[1].parse().unwrap(); - let output_file_path = PathBuf::from(args[2].clone()); - let mut wtr = if !output_file_path.exists() { - println!("Creating output file"); - let f = OpenOptions::new() - .create(true) - .append(true) - .open(output_file_path)?; - let mut wtr = csv::Writer::from_writer(f); - wtr.write_record(&["num_constraints", "setup", "prover", "verifier"])?; - wtr - } else if output_file_path.is_file() { - let f = OpenOptions::new().append(true).open(output_file_path)?; - csv::Writer::from_writer(f) - } else { - println!("Path to output file does not point to a file."); - process::exit(1); - }; - // This may not be cryptographically safe, use - // `OsRng` (for example) in production software. - let rng = &mut test_rng(); - - // Let's benchmark stuff! - let samples = if num_constraints > 10000 { - 1 - } else if num_constraints > 4096 { - 2 - } else { - 4 - }; - let mut total_setup = Duration::new(0, 0); - let mut total_proving = Duration::new(0, 0); - let mut total_verifying = Duration::new(0, 0); - - // Just a place to put the proof data, so we can - // benchmark deserialization. - // let mut proof_vec = vec![]; - - for _ in 0..samples { - // Create parameters for our circuit - let start = Instant::now(); - let params = { - let c = Benchmark::::new(num_constraints); - generate_random_parameters::(c, rng)? - }; - - // Prepare the verification key (for proof verification) - let pvk = prepare_verifying_key(¶ms.vk); - total_setup += start.elapsed(); - - // proof_vec.truncate(0); - let start = Instant::now(); - let proof = { - // Create an instance of our circuit (with the witness) - let c = Benchmark::new(num_constraints); - // Create a proof with our parameters. - create_random_proof(c, ¶ms, rng)? - }; - - total_proving += start.elapsed(); - - let inputs: Vec<_> = [Fr::one(); 2].to_vec(); - - let start = Instant::now(); - // let proof = Proof::read(&proof_vec[..]).unwrap(); - // Check the proof - let r = verify_proof(&pvk, &proof, &inputs).unwrap(); - assert!(r); - total_verifying += start.elapsed(); - } - - let setup_avg = total_setup / samples; - let setup_avg = - setup_avg.subsec_nanos() as f64 / 1_000_000_000f64 + (setup_avg.as_secs() as f64); - - let proving_avg = total_proving / samples; - let proving_avg = - proving_avg.subsec_nanos() as f64 / 1_000_000_000f64 + (proving_avg.as_secs() as f64); - - let verifying_avg = total_verifying / samples; - let verifying_avg = - verifying_avg.subsec_nanos() as f64 / 1_000_000_000f64 + (verifying_avg.as_secs() as f64); - - println!( - "=== Benchmarking Groth16 with {} constraints: ====", - num_constraints - ); - println!("Average setup time: {:?} seconds", setup_avg); - println!("Average proving time: {:?} seconds", proving_avg); - println!("Average verifying time: {:?} seconds", verifying_avg); - - wtr.write_record(&[ - format!("{}", num_constraints), - format!("{}", setup_avg), - format!("{}", proving_avg), - format!("{}", verifying_avg), - ])?; - wtr.flush()?; - Ok(()) -} diff --git a/prover/groth16/rustfmt.toml b/prover/groth16/rustfmt.toml deleted file mode 100644 index 71712138..00000000 --- a/prover/groth16/rustfmt.toml +++ /dev/null @@ -1,9 +0,0 @@ -reorder_imports = true -wrap_comments = true -normalize_comments = true -use_try_shorthand = true -match_block_trailing_comma = true -use_field_init_shorthand = true -edition = "2018" -condense_wildcard_suffixes = true -merge_imports = true diff --git a/prover/groth16/scripts/install-hook.sh b/prover/groth16/scripts/install-hook.sh deleted file mode 100755 index eafcf818..00000000 --- a/prover/groth16/scripts/install-hook.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/env bash -# This script will install the provided directory ../.hooks as the hook -# directory for the present repo. See there for hooks, including a pre-commit -# hook that runs rustfmt on files before a commit. - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -HOOKS_DIR="${DIR}/../.hooks" - -git config core.hooksPath "$HOOKS_DIR" diff --git a/prover/groth16/scripts/linkify_changelog.py b/prover/groth16/scripts/linkify_changelog.py deleted file mode 100644 index 867ae14d..00000000 --- a/prover/groth16/scripts/linkify_changelog.py +++ /dev/null @@ -1,31 +0,0 @@ -import re -import sys -import fileinput -import os - -# Set this to the name of the repo, if you don't want it to be read from the filesystem. -# It assumes the changelog file is in the root of the repo. -repo_name = "" - -# This script goes through the provided file, and replaces any " \#", -# with the valid mark down formatted link to it. e.g. -# " [\#number](https://github.com/arkworks-rs/template/pull/) -# Note that if the number is for a an issue, github will auto-redirect you when you click the link. -# It is safe to run the script multiple times in succession. -# -# Example usage $ python3 linkify_changelog.py ../CHANGELOG.md -if len(sys.argv) < 2: - print("Must include path to changelog as the first argument to the script") - print("Example Usage: python3 linkify_changelog.py ../CHANGELOG.md") - exit() - -changelog_path = sys.argv[1] -if repo_name == "": - path = os.path.abspath(changelog_path) - components = path.split(os.path.sep) - repo_name = components[-2] - -for line in fileinput.input(inplace=True): - line = re.sub(r"\- #([0-9]*)", r"- [\\#\1](https://github.com/arkworks-rs/" + repo_name + r"/pull/\1)", line.rstrip()) - # edits the current file - print(line) \ No newline at end of file diff --git a/prover/groth16/src/api.rs b/prover/groth16/src/api.rs deleted file mode 100644 index 1fc7a3bf..00000000 --- a/prover/groth16/src/api.rs +++ /dev/null @@ -1,452 +0,0 @@ -use ark_bn254::{Bn254, Fr}; -use ark_ec::pairing::Pairing; -use ark_ff::PrimeField; -use ark_relations::r1cs::{ - ConstraintSynthesizer, ConstraintSystemRef, LinearCombination, SynthesisError, Variable, -}; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_std::{ - rand::{RngCore, SeedableRng}, - test_rng, - vec::Vec, -}; - -use base64::{engine::general_purpose, Engine as _}; - -use crate::{prepare_verifying_key, Groth16, PreparedVerifyingKey, Proof}; -use ark_crypto_primitives::snark::{CircuitSpecificSetupSNARK, SNARK}; -use ark_ff::{BigInteger, BigInteger256}; -use gev_core::*; -use r1cs_file::{FieldElement, R1csFile}; -use wtns_file::{FieldElement as WtnsFE, WtnsFile}; - -type Inputs = Vec<::ScalarField>; - -type ConstraintVec = Vec<(usize, ::ScalarField)>; -type Constraints = (ConstraintVec, ConstraintVec, ConstraintVec); - -#[derive(Clone)] -struct Circuit { - num_inputs: usize, - num_outputs: usize, - num_wires: usize, - constraints: Vec>, - witness: Vec, -} - -impl ConstraintSynthesizer for Circuit { - fn generate_constraints( - self, - cs: ConstraintSystemRef, - ) -> Result<(), SynthesisError> { - let w = &self.witness; - - let input_start = 1 + self.num_outputs; - let input_end = input_start + self.num_inputs; - - // the inputs are after ONE (constant, index 0) and the outputs (if any) - for i in 0..self.num_inputs { - cs.new_input_variable(|| Ok(w[i + input_start]))?; - } - // If any outputs, they start at index 1 - for wval in w.iter().take(self.num_outputs + 1) { - cs.new_witness_variable(|| Ok(*wval))?; - } - - for i in 0..self.num_wires - 1 - self.num_outputs { - cs.new_witness_variable(|| Ok(w[i + input_end]))?; - } - - let make_index = |index| { - if index < input_start { - Variable::Witness(index) - } else if index < input_end { - Variable::Instance(index - input_start + 1) - } else { - Variable::Witness(index - self.num_inputs) - } - }; - let make_lc = |lc_data: &[(usize, E::ScalarField)]| { - lc_data.iter().fold( - LinearCombination::::zero(), - |lc: LinearCombination, (index, coeff)| { - lc + (*coeff, make_index(*index)) - }, - ) - }; - - for constraint in &self.constraints { - cs.enforce_constraint( - make_lc(&constraint.0), - make_lc(&constraint.1), - make_lc(&constraint.2), - )?; - } - - Ok(()) - } -} - -fn create_circuit(prover_inputs: ProverInputs) -> Result, GevulotError> -where - E: Pairing, -{ - println!(" prover_inputs.r1cs len: {}", prover_inputs.r1cs.len()); - println!(" prover_inputs.wtns len: {}", prover_inputs.wtns.len()); - let r1cs_bytes: Vec = general_purpose::STANDARD_NO_PAD - .decode(prover_inputs.r1cs) - .expect("could not decode r1cs data from base64 string"); - let wtns_bytes: Vec = general_purpose::STANDARD_NO_PAD - .decode(prover_inputs.wtns) - .expect("could not decode wtns data from base64 string"); - - println!(" r1cs_bytes len: {}", r1cs_bytes.len()); - println!(" wtns_bytes len: {}", wtns_bytes.len()); - let r1cs_file = - R1csFile::<32>::read(r1cs_bytes.as_slice()).map_err(|_| GevulotError::R1csParseError)?; - - let wtns_file = - WtnsFile::<32>::read(wtns_bytes.as_slice()).map_err(|_| GevulotError::WtnsParseError)?; - - let mut witness: Vec = Vec::new(); - for fe in &wtns_file.witness.0 { - let fr = wtns_field_element_to_fr::(fe); - witness.push(fr); - } - - println!(" create_circuit"); - println!(" witness len: {}", witness.len()); - println!(" constraints len: {}", r1cs_file.constraints.0.len()); - println!(" header: {:?}", r1cs_file.header); - - let mut constraints: Vec> = Vec::with_capacity(r1cs_file.constraints.0.len()); - println!(" alloced constraints: {:?}", constraints); - - let mut nn = 0 as usize; - for c in &r1cs_file.constraints.0 { - let mut c0: Vec<(usize, E::ScalarField)> = Vec::new(); - for n in 0..c.0.len() { - let i = c.0[n].1 as usize; - let fr: ::ScalarField = r1cs_field_element_to_fr::(&c.0[n].0); - c0.push((i, fr)); - } - let mut c1: Vec<(usize, E::ScalarField)> = Vec::new(); - for n in 0..c.1.len() { - let i = c.1[n].1 as usize; - let fr = r1cs_field_element_to_fr::(&c.1[n].0); - c1.push((i, fr)); - } - let mut c2: Vec<(usize, E::ScalarField)> = Vec::new(); - for n in 0..c.2.len() { - let i = c.2[n].1 as usize; - let fr = r1cs_field_element_to_fr::(&c.2[n].0); - c2.push((i, fr)); - } - - nn += 1; - - if nn % 4000 == 0 { - println!(" constaints: {}", nn); - } - - let constraint = (c0, c1, c2); - constraints.push(constraint); - } - - println!(" constraints.len(): {:?}", constraints.len()); - - let num_inputs = r1cs_file.header.n_pub_in as usize; - let num_wires = r1cs_file.header.n_wires as usize - num_inputs; - let num_outputs = r1cs_file.header.n_pub_out as usize; - println!(" num_inputs: {:?}", num_inputs); - println!(" num_outputs: {:?}", num_outputs); - println!(" num_wires: {:?}", num_wires); - - Ok(Circuit { - num_inputs, - num_outputs, - num_wires, - constraints, - witness, - }) -} - -/// This is our Rust prover function -pub fn do_prove(inputs: ProverInputs) -> Result -where - E: Pairing, -{ - println!("groth16::do_prove"); - let start = get_millis(); - - let circ = create_circuit::(inputs)?; - let mut rng = ark_std::rand::rngs::StdRng::seed_from_u64(test_rng().next_u64()); - - let c = circ.clone(); - let (pk, vk) = Groth16::::setup(c, &mut rng).map_err(|_| GevulotError::Groth16SetupError)?; - let pvk = prepare_verifying_key::(&vk); - - let proof = Groth16::::prove(&pk, circ, &mut rng).unwrap(); - println!(" proof {:?}", &proof); - - let mut proof_bytes = Vec::new(); - proof - .serialize_uncompressed(&mut proof_bytes) - .map_err(|_| GevulotError::CanonicalSerializeError)?; - let mut pvk_bytes = Vec::new(); - - pvk.serialize_uncompressed(&mut pvk_bytes) - .map_err(|_| GevulotError::CanonicalSerializeError)?; - - let proof_encoded = general_purpose::STANDARD_NO_PAD.encode(&proof_bytes); - let pvk_encoded = general_purpose::STANDARD_NO_PAD.encode(&pvk_bytes); - println!(" proof {:?}", &proof); - println!(" proof_encoded len {}", proof_encoded.len()); - println!(" pvk_encoded len {}", pvk_encoded.len()); - - let proof_info = ProofInfo { - algorithm: "groth16".to_owned(), - proof: proof_encoded, - vk: pvk_encoded, - }; - println!(" do_prove took {} ms", get_millis() - start); - Ok(ProverResponse { - header: ResponseHeader { - success: true, - message: PROVER_SUCCESS.to_string(), - }, - proof_info: Some(proof_info), - }) -} - -/// Groth16 Rust verification -pub fn do_verify( - proof_bytes: &Vec, - index_vk_bytes: &Vec, - inputs: &Inputs, -) -> Result { - println!("do_verify"); - let start = get_millis(); - - let proof = Proof::::deserialize_uncompressed(proof_bytes.as_slice()) - .map_err(|_| GevulotError::CanonicalSerializeError)?; - - let pvk = PreparedVerifyingKey::::deserialize_uncompressed(index_vk_bytes.as_slice()) - .map_err(|_| GevulotError::CanonicalSerializeError)?; - - let success = Groth16::::verify_with_processed_vk(&pvk, inputs.as_slice(), &proof) - .map_err(|_| GevulotError::Groth16VerifyError)?; - - println!(" do_verify: success = {}", success); - println!(" do_verify took {} ms", get_millis() - start); - - let message = if success { - VERIFICATION_SUCCESS.to_string() - } else { - VERIFICATION_FAIL.to_string() - }; - Ok(VerifyResponse { - header: ResponseHeader { success, message }, - }) -} - -fn bigint256_to_fr(b: &BigInteger256) -> E::ScalarField { - E::ScalarField::from_le_bytes_mod_order(b.to_owned().to_bytes_le().as_slice()) -} - -fn r1cs_field_element_to_fr(fe: &FieldElement<32>) -> E::ScalarField { - E::ScalarField::from_le_bytes_mod_order(fe.to_owned().to_vec().as_slice()) -} - -fn wtns_field_element_to_fr(fe: &WtnsFE<32>) -> E::ScalarField { - E::ScalarField::from_le_bytes_mod_order(fe.to_owned().to_vec().as_slice()) -} - -/// exported for Rust calling -pub fn verify(verify_inputs: VerifyInputs) -> Result { - println!("inputs {:?}", verify_inputs.inputs); - let proof: Vec = general_purpose::STANDARD_NO_PAD - .decode(verify_inputs.proof_info.proof) - .map_err(|_| GevulotError::Base64DecodeError)?; - let vk: Vec = general_purpose::STANDARD_NO_PAD - .decode(verify_inputs.proof_info.vk) - .map_err(|_| GevulotError::Base64DecodeError)?; - let inputs = verify_inputs.inputs; - - println!(" proof len {}", proof.len()); - println!(" vk len {}", vk.len()); - println!(" inputs len {}", inputs.len()); - let mut fr_inputs: Vec = Vec::new(); - for input in inputs { - let fr = bigint256_to_fr::(&BigInteger256::new([input, 0, 0, 0])); - fr_inputs.push(fr); - } - do_verify::(&proof, &vk, &fr_inputs) -} - -#[cfg(test)] -mod test { - use super::*; - - fn circuit_test() { - let data = std::fs::read("../test-data/sudoku.r1cs") - .expect("could not read ../test-data/sudoku.r1cs"); - let r1cs = general_purpose::STANDARD_NO_PAD.encode(&data); - let data = std::fs::read("../test-data/sudoku.wtns") - .expect("could not read ../test-data/sudoku.wtns"); - let wtns = general_purpose::STANDARD_NO_PAD.encode(&data); - - let prover_inputs = ProverInputs { r1cs, wtns }; - - let prove_response = do_prove::(prover_inputs).unwrap(); - let proof_info = prove_response - .proof_info - .expect("proof_info is not present"); - let proof_bytes: Vec = general_purpose::STANDARD_NO_PAD - .decode(proof_info.proof) - .expect("could not proof r1cs data from base64 string"); - - let pvk_bytes: Vec = general_purpose::STANDARD_NO_PAD - .decode(proof_info.vk) - .expect("could not decode pvk data from base64 string"); - - let mut correct: Vec = Vec::new(); - for r in TEST_SUDOKU_CORRECT { - let fr = bigint256_to_fr::(&BigInteger256::new([r, 0, 0, 0])); - correct.push(fr); - } - - let mut wrong: Vec = Vec::new(); - for r in TEST_SUDOKU_WRONG { - let fr = bigint256_to_fr::(&BigInteger256::new([r, 0, 0, 0])); - wrong.push(fr); - } - - let verify_response = do_verify::(&proof_bytes, &pvk_bytes, &correct).unwrap(); - assert!(verify_response.header.success); - assert!(verify_response.header.message.eq(VERIFICATION_SUCCESS)); - - let verify_response = do_verify::(&proof_bytes, &pvk_bytes, &wrong).unwrap(); - assert!(!verify_response.header.success); - assert!(verify_response.header.message.eq(VERIFICATION_FAIL)); - } - - fn bad_verification_input() { - let data = std::fs::read("../test-data/sudoku.r1cs") - .expect("could not read ../test-data/sudoku.r1cs"); - let r1cs = general_purpose::STANDARD_NO_PAD.encode(&data); - let data = std::fs::read("../test-data/sudoku.wtns") - .expect("could not read ../test-data/sudoku.wtns"); - let wtns = general_purpose::STANDARD_NO_PAD.encode(&data); - - let prover_inputs = ProverInputs { r1cs, wtns }; - - let prove_response = do_prove::(prover_inputs).unwrap(); - let proof_info = prove_response - .proof_info - .expect("proof_info is not present"); - let proof_bytes: Vec = general_purpose::STANDARD_NO_PAD - .decode(proof_info.proof) - .expect("could not decode proof data from base64 string"); - - let mut bad_proof_bytes = proof_bytes.clone(); - bad_proof_bytes[0] = 252; - bad_proof_bytes[1] = 253; - bad_proof_bytes[2] = 254; - bad_proof_bytes[3] = 255; - - let pvk_bytes: Vec = general_purpose::STANDARD_NO_PAD - .decode(proof_info.vk) - .expect("could not decode pvk data from base64 string"); - let mut bad_pvk_bytes = pvk_bytes.clone(); - bad_pvk_bytes[0] = 252; - bad_pvk_bytes[1] = 253; - bad_pvk_bytes[2] = 254; - bad_pvk_bytes[3] = 255; - - let mut inputs: Vec = Vec::new(); - for r in TEST_SUDOKU_CORRECT { - let fr = bigint256_to_fr::(&BigInteger256::new([r, 0, 0, 0])); - inputs.push(fr); - } - - let result = do_verify::(&bad_proof_bytes, &pvk_bytes, &inputs); - assert!(matches!(result, Err(GevulotError::CanonicalSerializeError))); - - let result = do_verify::(&proof_bytes, &bad_pvk_bytes, &inputs); - assert!(matches!(result, Err(GevulotError::CanonicalSerializeError))); - } - - #[test] - fn test_circom() { - circuit_test::(); - } - - #[test] - fn test_bad_prover_input() { - // swap r1cs with wtns - let data = std::fs::read("../test-data/sudoku.r1cs") - .expect("could not read ../test-data/sudoku.r1cs"); - let r1cs = general_purpose::STANDARD_NO_PAD.encode(&data); - let data = std::fs::read("../test-data/sudoku.wtns") - .expect("could not read ../test-data/sudoku.wtns"); - let wtns = general_purpose::STANDARD_NO_PAD.encode(&data); - - // send bad r1cs data - let prover_inputs = ProverInputs { - r1cs: wtns.clone(), - wtns: wtns.clone(), - }; - let result = do_prove::(prover_inputs).map_err(|e| e); - println!("bad result: {:?}", result); - assert!(matches!(result, Err(GevulotError::R1csParseError))); - - // send bad wtns data - let prover_inputs = ProverInputs { - r1cs: r1cs.clone(), - wtns: r1cs.clone(), - }; - let result = do_prove::(prover_inputs); - assert!(matches!(result, Err(GevulotError::WtnsParseError))); - } - - #[test] - fn test_bad_verification_input() { - bad_verification_input::(); - } - - #[test] - #[ignore] - fn test_ed25519_prover() { - println!("test_ed25519_prover"); - let start = get_millis(); - let data = std::fs::read("../test-data/ed25519.r1cs") - .expect("could not read ../test-data/ed25519.r1cs"); - let r1cs = general_purpose::STANDARD_NO_PAD.encode(&data); - let data = std::fs::read("../test-data/ed25519.wtns") - .expect("could not read ../test-data/ed25519.wtns"); - let wtns = general_purpose::STANDARD_NO_PAD.encode(&data); - - // send bad r1cs data - let prover_inputs = ProverInputs { r1cs, wtns }; - - let prover_response = do_prove::(prover_inputs).unwrap(); - let proof_info = prover_response - .proof_info - .expect("proof_info is not present"); - let proof_bytes: Vec = general_purpose::STANDARD_NO_PAD - .decode(proof_info.proof) - .expect("could not decode proof data from base64 string"); - let index_vk_bytes: Vec = general_purpose::STANDARD_NO_PAD - .decode(proof_info.vk) - .expect("could not decode index vk data from base64 string"); - - println!(" proof len {}", proof_bytes.len()); - println!(" vk len {}", index_vk_bytes.len()); - let fr_inputs: Vec = Vec::new(); - - let verify_response = do_verify::(&proof_bytes, &index_vk_bytes, &fr_inputs); - println!("verify_response: {:?}", verify_response); - println!(" test_ed25519_prover took {} ms", get_millis() - start); - } -} diff --git a/prover/groth16/src/constraints.rs b/prover/groth16/src/constraints.rs deleted file mode 100644 index 11fe33b7..00000000 --- a/prover/groth16/src/constraints.rs +++ /dev/null @@ -1,551 +0,0 @@ -use crate::{ - r1cs_to_qap::{LibsnarkReduction, R1CSToQAP}, - Groth16, PreparedVerifyingKey, Proof, VerifyingKey, -}; -use ark_crypto_primitives::snark::{ - constraints::{CircuitSpecificSetupSNARKGadget, SNARKGadget}, - BooleanInputVar, SNARK, -}; -use ark_ec::{pairing::Pairing, AffineRepr, CurveGroup}; -use ark_ff::Field; -use ark_r1cs_std::{ - alloc::{AllocVar, AllocationMode}, - bits::{boolean::Boolean, uint8::UInt8}, - eq::EqGadget, - groups::CurveVar, - pairing::PairingVar, - ToBitsGadget, ToBytesGadget, -}; -use ark_relations::r1cs::{Namespace, SynthesisError}; -use ark_std::{borrow::Borrow, marker::PhantomData, vec::Vec}; - -type BasePrimeField = <<::G1 as CurveGroup>::BaseField as Field>::BasePrimeField; - -/// The proof variable for the Groth16 construction -#[derive(Derivative)] -#[derivative(Clone(bound = "P::G1Var: Clone, P::G2Var: Clone"))] -pub struct ProofVar>> { - /// The `A` element in `G1`. - pub a: P::G1Var, - /// The `B` element in `G2`. - pub b: P::G2Var, - /// The `C` element in `G1`. - pub c: P::G1Var, -} - -/// A variable representing the Groth16 verifying key in the constraint system. -#[derive(Derivative)] -#[derivative( - Clone(bound = "P::G1Var: Clone, P::GTVar: Clone, P::G1PreparedVar: Clone, \ - P::G2PreparedVar: Clone, ") -)] -pub struct VerifyingKeyVar>> { - #[doc(hidden)] - pub alpha_g1: P::G1Var, - #[doc(hidden)] - pub beta_g2: P::G2Var, - #[doc(hidden)] - pub gamma_g2: P::G2Var, - #[doc(hidden)] - pub delta_g2: P::G2Var, - #[doc(hidden)] - pub gamma_abc_g1: Vec, -} - -impl>> VerifyingKeyVar { - /// Prepare `self` for use in proof verification. - pub fn prepare(&self) -> Result, SynthesisError> { - let alpha_g1_pc = P::prepare_g1(&self.alpha_g1)?; - let beta_g2_pc = P::prepare_g2(&self.beta_g2)?; - - let alpha_g1_beta_g2 = P::pairing(alpha_g1_pc, beta_g2_pc)?; - let gamma_g2_neg_pc = P::prepare_g2(&self.gamma_g2.negate()?)?; - let delta_g2_neg_pc = P::prepare_g2(&self.delta_g2.negate()?)?; - - Ok(PreparedVerifyingKeyVar { - alpha_g1_beta_g2, - gamma_g2_neg_pc, - delta_g2_neg_pc, - gamma_abc_g1: self.gamma_abc_g1.clone(), - }) - } -} - -/// Preprocessed verification key parameters variable for the Groth16 -/// construction -#[derive(Derivative)] -#[derivative( - Clone(bound = "P::G1Var: Clone, P::GTVar: Clone, P::G1PreparedVar: Clone, \ - P::G2PreparedVar: Clone, ") -)] -pub struct PreparedVerifyingKeyVar>> { - #[doc(hidden)] - pub alpha_g1_beta_g2: P::GTVar, - #[doc(hidden)] - pub gamma_g2_neg_pc: P::G2PreparedVar, - #[doc(hidden)] - pub delta_g2_neg_pc: P::G2PreparedVar, - #[doc(hidden)] - pub gamma_abc_g1: Vec, -} - -/// Constraints for the verifier of the SNARK of [[Groth16]](https://eprint.iacr.org/2016/260.pdf). -pub struct Groth16VerifierGadget -where - E: Pairing, - P: PairingVar>, - QAP: R1CSToQAP, -{ - _pairing_engine: PhantomData, - _pairing_gadget: PhantomData

, - _qap: PhantomData, -} - -impl SNARKGadget, Groth16> - for Groth16VerifierGadget -where - E: Pairing, - QAP: R1CSToQAP, - P: PairingVar>, -{ - type ProcessedVerifyingKeyVar = PreparedVerifyingKeyVar; - type VerifyingKeyVar = VerifyingKeyVar; - type InputVar = BooleanInputVar>; - type ProofVar = ProofVar; - - type VerifierSize = usize; - - fn verifier_size( - circuit_vk: & as SNARK>::VerifyingKey, - ) -> Self::VerifierSize { - circuit_vk.gamma_abc_g1.len() - } - - /// Allocates `N::Proof` in `cs` without performing - /// subgroup checks. - #[tracing::instrument(target = "r1cs", skip(cs, f))] - fn new_proof_unchecked>>( - cs: impl Into>>, - f: impl FnOnce() -> Result, - mode: AllocationMode, - ) -> Result { - let ns = cs.into(); - let cs = ns.cs(); - f().and_then(|proof| { - let proof = proof.borrow(); - let a = CurveVar::new_variable_omit_prime_order_check( - ark_relations::ns!(cs, "Proof.a"), - || Ok(proof.a.into_group()), - mode, - )?; - let b = CurveVar::new_variable_omit_prime_order_check( - ark_relations::ns!(cs, "Proof.b"), - || Ok(proof.b.into_group()), - mode, - )?; - let c = CurveVar::new_variable_omit_prime_order_check( - ark_relations::ns!(cs, "Proof.c"), - || Ok(proof.c.into_group()), - mode, - )?; - Ok(ProofVar { a, b, c }) - }) - } - - /// Allocates `N::Proof` in `cs` without performing - /// subgroup checks. - #[tracing::instrument(target = "r1cs", skip(cs, f))] - fn new_verification_key_unchecked>>( - cs: impl Into>>, - f: impl FnOnce() -> Result, - mode: AllocationMode, - ) -> Result { - let ns = cs.into(); - let cs = ns.cs(); - f().and_then(|vk| { - let vk = vk.borrow(); - let alpha_g1 = P::G1Var::new_variable_omit_prime_order_check( - ark_relations::ns!(cs, "alpha_g1"), - || Ok(vk.alpha_g1.into_group()), - mode, - )?; - let beta_g2 = P::G2Var::new_variable_omit_prime_order_check( - ark_relations::ns!(cs, "beta_g2"), - || Ok(vk.beta_g2.into_group()), - mode, - )?; - let gamma_g2 = P::G2Var::new_variable_omit_prime_order_check( - ark_relations::ns!(cs, "gamma_g2"), - || Ok(vk.gamma_g2.into_group()), - mode, - )?; - let delta_g2 = P::G2Var::new_variable_omit_prime_order_check( - ark_relations::ns!(cs, "delta_g2"), - || Ok(vk.delta_g2.into_group()), - mode, - )?; - let gamma_abc_g1 = vk - .gamma_abc_g1 - .iter() - .map(|g| { - P::G1Var::new_variable_omit_prime_order_check( - ark_relations::ns!(cs, "gamma_abc_g1"), - || Ok(g.into_group()), - mode, - ) - }) - .collect::, _>>()?; - - Ok(VerifyingKeyVar { - alpha_g1, - beta_g2, - gamma_g2, - delta_g2, - gamma_abc_g1, - }) - }) - } - - #[tracing::instrument(target = "r1cs", skip(circuit_pvk, x, proof))] - fn verify_with_processed_vk( - circuit_pvk: &Self::ProcessedVerifyingKeyVar, - x: &Self::InputVar, - proof: &Self::ProofVar, - ) -> Result>, SynthesisError> { - let circuit_pvk = circuit_pvk.clone(); - - let g_ic = { - let mut g_ic: P::G1Var = circuit_pvk.gamma_abc_g1[0].clone(); - let mut input_len = 1; - let mut public_inputs = x.clone().into_iter(); - for (input, b) in public_inputs - .by_ref() - .zip(circuit_pvk.gamma_abc_g1.iter().skip(1)) - { - let encoded_input_i: P::G1Var = b.scalar_mul_le(input.to_bits_le()?.iter())?; - g_ic += encoded_input_i; - input_len += 1; - } - // Check that the input and the query in the verification are of the - // same length. - assert!(input_len == circuit_pvk.gamma_abc_g1.len() && public_inputs.next().is_none()); - g_ic - }; - - let test_exp = { - let proof_a_prep = P::prepare_g1(&proof.a)?; - let proof_b_prep = P::prepare_g2(&proof.b)?; - let proof_c_prep = P::prepare_g1(&proof.c)?; - - let g_ic_prep = P::prepare_g1(&g_ic)?; - - P::miller_loop( - &[proof_a_prep, g_ic_prep, proof_c_prep], - &[ - proof_b_prep, - circuit_pvk.gamma_g2_neg_pc.clone(), - circuit_pvk.delta_g2_neg_pc.clone(), - ], - )? - }; - - let test = P::final_exponentiation(&test_exp)?; - test.is_eq(&circuit_pvk.alpha_g1_beta_g2) - } - - #[tracing::instrument(target = "r1cs", skip(circuit_vk, x, proof))] - fn verify( - circuit_vk: &Self::VerifyingKeyVar, - x: &Self::InputVar, - proof: &Self::ProofVar, - ) -> Result>, SynthesisError> { - let pvk = circuit_vk.prepare()?; - Self::verify_with_processed_vk(&pvk, x, proof) - } -} - -impl - CircuitSpecificSetupSNARKGadget, Groth16> - for Groth16VerifierGadget -where - E: Pairing, - P: PairingVar>, - QAP: R1CSToQAP, -{ -} - -impl AllocVar, BasePrimeField> for PreparedVerifyingKeyVar -where - E: Pairing, - P: PairingVar>, -{ - #[tracing::instrument(target = "r1cs", skip(cs, f))] - fn new_variable>>( - cs: impl Into>>, - f: impl FnOnce() -> Result, - mode: AllocationMode, - ) -> Result { - let ns = cs.into(); - let cs = ns.cs(); - - f().and_then(|pvk| { - let pvk = pvk.borrow(); - let alpha_g1_beta_g2 = P::GTVar::new_variable( - ark_relations::ns!(cs, "alpha_g1_beta_g2"), - || Ok(pvk.alpha_g1_beta_g2.clone()), - mode, - )?; - - let gamma_g2_neg_pc = P::G2PreparedVar::new_variable( - ark_relations::ns!(cs, "gamma_g2_neg_pc"), - || Ok(pvk.gamma_g2_neg_pc.clone()), - mode, - )?; - - let delta_g2_neg_pc = P::G2PreparedVar::new_variable( - ark_relations::ns!(cs, "delta_g2_neg_pc"), - || Ok(pvk.delta_g2_neg_pc.clone()), - mode, - )?; - - let gamma_abc_g1 = Vec::new_variable( - ark_relations::ns!(cs, "gamma_abc_g1"), - || Ok(pvk.vk.gamma_abc_g1.clone()), - mode, - )?; - - Ok(Self { - alpha_g1_beta_g2, - gamma_g2_neg_pc, - delta_g2_neg_pc, - gamma_abc_g1, - }) - }) - } -} - -impl AllocVar, BasePrimeField> for VerifyingKeyVar -where - E: Pairing, - P: PairingVar>, -{ - #[tracing::instrument(target = "r1cs", skip(cs, f))] - fn new_variable>>( - cs: impl Into>>, - f: impl FnOnce() -> Result, - mode: AllocationMode, - ) -> Result { - let ns = cs.into(); - let cs = ns.cs(); - - f().and_then(|vk| { - let VerifyingKey { - alpha_g1, - beta_g2, - gamma_g2, - delta_g2, - gamma_abc_g1, - } = vk.borrow().clone(); - let alpha_g1 = - P::G1Var::new_variable(ark_relations::ns!(cs, "alpha_g1"), || Ok(alpha_g1), mode)?; - let beta_g2 = - P::G2Var::new_variable(ark_relations::ns!(cs, "beta_g2"), || Ok(beta_g2), mode)?; - let gamma_g2 = - P::G2Var::new_variable(ark_relations::ns!(cs, "gamma_g2"), || Ok(gamma_g2), mode)?; - let delta_g2 = - P::G2Var::new_variable(ark_relations::ns!(cs, "delta_g2"), || Ok(delta_g2), mode)?; - - let gamma_abc_g1 = Vec::new_variable(cs.clone(), || Ok(gamma_abc_g1), mode)?; - Ok(Self { - alpha_g1, - beta_g2, - gamma_g2, - delta_g2, - gamma_abc_g1, - }) - }) - } -} - -impl AllocVar, BasePrimeField> for ProofVar -where - E: Pairing, - P: PairingVar>, -{ - #[tracing::instrument(target = "r1cs", skip(cs, f))] - fn new_variable>>( - cs: impl Into>>, - f: impl FnOnce() -> Result, - mode: AllocationMode, - ) -> Result { - let ns = cs.into(); - let cs = ns.cs(); - - f().and_then(|proof| { - let Proof { a, b, c } = proof.borrow().clone(); - let a = P::G1Var::new_variable(ark_relations::ns!(cs, "a"), || Ok(a), mode)?; - let b = P::G2Var::new_variable(ark_relations::ns!(cs, "b"), || Ok(b), mode)?; - let c = P::G1Var::new_variable(ark_relations::ns!(cs, "c"), || Ok(c), mode)?; - Ok(Self { a, b, c }) - }) - } -} - -impl ToBytesGadget> for VerifyingKeyVar -where - E: Pairing, - P: PairingVar>, -{ - #[inline] - #[tracing::instrument(target = "r1cs", skip(self))] - fn to_bytes(&self) -> Result>>, SynthesisError> { - let mut bytes = Vec::new(); - bytes.extend_from_slice(&self.alpha_g1.to_bytes()?); - bytes.extend_from_slice(&self.beta_g2.to_bytes()?); - bytes.extend_from_slice(&self.gamma_g2.to_bytes()?); - bytes.extend_from_slice(&self.delta_g2.to_bytes()?); - for g in &self.gamma_abc_g1 { - bytes.extend_from_slice(&g.to_bytes()?); - } - Ok(bytes) - } -} - -#[cfg(test)] -mod test { - use crate::{constraints::Groth16VerifierGadget, Groth16}; - use ark_crypto_primitives::snark::{constraints::SNARKGadget, SNARK}; - use ark_ec::pairing::Pairing; - use ark_ff::{Field, UniformRand}; - use ark_mnt4_298::{constraints::PairingVar as MNT4PairingVar, Fr as MNT4Fr, MNT4_298 as MNT4}; - use ark_mnt6_298::Fr as MNT6Fr; - use ark_r1cs_std::{alloc::AllocVar, bits::boolean::Boolean, eq::EqGadget}; - use ark_relations::{ - lc, ns, - r1cs::{ConstraintSynthesizer, ConstraintSystem, ConstraintSystemRef, SynthesisError}, - }; - use ark_std::{ - ops::MulAssign, - rand::{RngCore, SeedableRng}, - test_rng, - }; - - #[derive(Copy, Clone)] - struct Circuit { - a: Option, - b: Option, - num_constraints: usize, - num_variables: usize, - } - - impl ConstraintSynthesizer for Circuit { - fn generate_constraints( - self, - cs: ConstraintSystemRef, - ) -> Result<(), SynthesisError> { - let a = cs.new_witness_variable(|| self.a.ok_or(SynthesisError::AssignmentMissing))?; - let b = cs.new_witness_variable(|| self.b.ok_or(SynthesisError::AssignmentMissing))?; - let c = cs.new_input_variable(|| { - let mut a = self.a.ok_or(SynthesisError::AssignmentMissing)?; - let b = self.b.ok_or(SynthesisError::AssignmentMissing)?; - - a.mul_assign(&b); - Ok(a) - })?; - - for _ in 0..(self.num_variables - 3) { - cs.new_witness_variable(|| self.a.ok_or(SynthesisError::AssignmentMissing))?; - } - - for _ in 0..self.num_constraints { - cs.enforce_constraint(lc!() + a, lc!() + b, lc!() + c) - .unwrap(); - } - Ok(()) - } - } - - type TestSNARK = Groth16; - type TestSNARKGadget = Groth16VerifierGadget; - - #[test] - fn groth16_snark_test() { - let mut rng = ark_std::rand::rngs::StdRng::seed_from_u64(test_rng().next_u64()); - let a = MNT4Fr::rand(&mut rng); - let b = MNT4Fr::rand(&mut rng); - let mut c = a; - c.mul_assign(&b); - - let circ = Circuit { - a: Some(a.clone()), - b: Some(b.clone()), - num_constraints: 100, - num_variables: 25, - }; - - let (pk, vk) = TestSNARK::circuit_specific_setup(circ, &mut rng).unwrap(); - - let proof = TestSNARK::prove(&pk, circ.clone(), &mut rng).unwrap(); - - assert!( - TestSNARK::verify(&vk, &vec![c], &proof).unwrap(), - "The native verification check fails." - ); - - let cs_sys = ConstraintSystem::::new(); - let cs = ConstraintSystemRef::new(cs_sys); - - let input_gadget = ::ScalarField, - ::BaseField, - TestSNARK, - >>::InputVar::new_input(ns!(cs, "new_input"), || Ok(vec![c])) - .unwrap(); - let proof_gadget = ::ScalarField, - ::BaseField, - TestSNARK, - >>::ProofVar::new_witness(ns!(cs, "alloc_proof"), || Ok(proof)) - .unwrap(); - let vk_gadget = ::ScalarField, - ::BaseField, - TestSNARK, - >>::VerifyingKeyVar::new_constant(ns!(cs, "alloc_vk"), vk.clone()) - .unwrap(); - ::ScalarField, - ::BaseField, - TestSNARK, - >>::verify(&vk_gadget, &input_gadget, &proof_gadget) - .unwrap() - .enforce_equal(&Boolean::constant(true)) - .unwrap(); - - assert!( - cs.is_satisfied().unwrap(), - "Constraints not satisfied: {}", - cs.which_is_unsatisfied().unwrap().unwrap_or_default() - ); - - let pvk = TestSNARK::process_vk(&vk).unwrap(); - let pvk_gadget = ::ScalarField, - ::BaseField, - TestSNARK, - >>::ProcessedVerifyingKeyVar::new_constant( - ns!(cs, "alloc_pvk"), pvk.clone() - ) - .unwrap(); - TestSNARKGadget::verify_with_processed_vk(&pvk_gadget, &input_gadget, &proof_gadget) - .unwrap() - .enforce_equal(&Boolean::constant(true)) - .unwrap(); - - assert!( - cs.is_satisfied().unwrap(), - "Constraints not satisfied: {}", - cs.which_is_unsatisfied().unwrap().unwrap_or_default() - ); - } -} diff --git a/prover/groth16/src/data_structures.rs b/prover/groth16/src/data_structures.rs deleted file mode 100644 index eb74823a..00000000 --- a/prover/groth16/src/data_structures.rs +++ /dev/null @@ -1,114 +0,0 @@ -use ark_ec::pairing::Pairing; -use ark_serialize::*; -use ark_std::vec::Vec; - -/// A proof in the Groth16 SNARK. -#[derive(Clone, Debug, PartialEq, CanonicalSerialize, CanonicalDeserialize)] -pub struct Proof { - /// The `A` element in `G1`. - pub a: E::G1Affine, - /// The `B` element in `G2`. - pub b: E::G2Affine, - /// The `C` element in `G1`. - pub c: E::G1Affine, -} - -impl Default for Proof { - fn default() -> Self { - Self { - a: E::G1Affine::default(), - b: E::G2Affine::default(), - c: E::G1Affine::default(), - } - } -} - -//////////////////////////////////////////////////////////////////////////////// - -/// A verification key in the Groth16 SNARK. -#[derive(Clone, Debug, PartialEq, CanonicalSerialize, CanonicalDeserialize)] -pub struct VerifyingKey { - /// The `alpha * G`, where `G` is the generator of `E::G1`. - pub alpha_g1: E::G1Affine, - /// The `alpha * H`, where `H` is the generator of `E::G2`. - pub beta_g2: E::G2Affine, - /// The `gamma * H`, where `H` is the generator of `E::G2`. - pub gamma_g2: E::G2Affine, - /// The `delta * H`, where `H` is the generator of `E::G2`. - pub delta_g2: E::G2Affine, - /// The `gamma^{-1} * (beta * a_i + alpha * b_i + c_i) * H`, where `H` is - /// the generator of `E::G1`. - pub gamma_abc_g1: Vec, -} - -impl Default for VerifyingKey { - fn default() -> Self { - Self { - alpha_g1: E::G1Affine::default(), - beta_g2: E::G2Affine::default(), - gamma_g2: E::G2Affine::default(), - delta_g2: E::G2Affine::default(), - gamma_abc_g1: Vec::new(), - } - } -} - -/// Preprocessed verification key parameters that enable faster verification -/// at the expense of larger size in memory. -#[derive(Clone, Debug, PartialEq, CanonicalSerialize, CanonicalDeserialize)] -pub struct PreparedVerifyingKey { - /// The unprepared verification key. - pub vk: VerifyingKey, - /// The element `e(alpha * G, beta * H)` in `E::GT`. - pub alpha_g1_beta_g2: E::TargetField, - /// The element `- gamma * H` in `E::G2`, prepared for use in pairings. - pub gamma_g2_neg_pc: E::G2Prepared, - /// The element `- delta * H` in `E::G2`, prepared for use in pairings. - pub delta_g2_neg_pc: E::G2Prepared, -} - -impl From> for VerifyingKey { - fn from(other: PreparedVerifyingKey) -> Self { - other.vk - } -} - -impl From> for PreparedVerifyingKey { - fn from(other: VerifyingKey) -> Self { - crate::prepare_verifying_key(&other) - } -} - -impl Default for PreparedVerifyingKey { - fn default() -> Self { - Self { - vk: VerifyingKey::default(), - alpha_g1_beta_g2: E::TargetField::default(), - gamma_g2_neg_pc: E::G2Prepared::default(), - delta_g2_neg_pc: E::G2Prepared::default(), - } - } -} - -//////////////////////////////////////////////////////////////////////////////// - -/// The prover key for for the Groth16 zkSNARK. -#[derive(Clone, Debug, PartialEq, CanonicalSerialize, CanonicalDeserialize)] -pub struct ProvingKey { - /// The underlying verification key. - pub vk: VerifyingKey, - /// The element `beta * G` in `E::G1`. - pub beta_g1: E::G1Affine, - /// The element `delta * G` in `E::G1`. - pub delta_g1: E::G1Affine, - /// The elements `a_i * G` in `E::G1`. - pub a_query: Vec, - /// The elements `b_i * G` in `E::G1`. - pub b_g1_query: Vec, - /// The elements `b_i * H` in `E::G2`. - pub b_g2_query: Vec, - /// The elements `h_i * G` in `E::G1`. - pub h_query: Vec, - /// The elements `l_i * G` in `E::G1`. - pub l_query: Vec, -} diff --git a/prover/groth16/src/generator.rs b/prover/groth16/src/generator.rs deleted file mode 100644 index fae12690..00000000 --- a/prover/groth16/src/generator.rs +++ /dev/null @@ -1,227 +0,0 @@ -use crate::{r1cs_to_qap::R1CSToQAP, Groth16, ProvingKey, Vec, VerifyingKey}; -use ark_ec::{pairing::Pairing, scalar_mul::fixed_base::FixedBase, CurveGroup, Group}; -use ark_ff::{Field, PrimeField, UniformRand, Zero}; -use ark_poly::{EvaluationDomain, GeneralEvaluationDomain}; -use ark_relations::r1cs::{ - ConstraintSynthesizer, ConstraintSystem, OptimizationGoal, Result as R1CSResult, - SynthesisError, SynthesisMode, -}; -use ark_std::{cfg_into_iter, cfg_iter, rand::Rng}; - -#[cfg(feature = "parallel")] -use rayon::prelude::*; - -impl Groth16 { - /// Generates a random common reference string for - /// a circuit using the provided R1CS-to-QAP reduction. - #[inline] - pub fn generate_random_parameters_with_reduction( - circuit: C, - rng: &mut impl Rng, - ) -> R1CSResult> - where - C: ConstraintSynthesizer, - { - let alpha = E::ScalarField::rand(rng); - let beta = E::ScalarField::rand(rng); - let gamma = E::ScalarField::rand(rng); - let delta = E::ScalarField::rand(rng); - - let g1_generator = E::G1::rand(rng); - let g2_generator = E::G2::rand(rng); - - let dummy = Self::generate_parameters_with_qap( - circuit, - alpha, - beta, - gamma, - delta, - g1_generator, - g2_generator, - rng, - ); - dummy - } - - /// Create parameters for a circuit, given some toxic waste, R1CS to QAP - /// calculator and group generators - #[allow(clippy::too_many_arguments)] - pub fn generate_parameters_with_qap( - circuit: C, - alpha: E::ScalarField, - beta: E::ScalarField, - gamma: E::ScalarField, - delta: E::ScalarField, - g1_generator: E::G1, - g2_generator: E::G2, - rng: &mut impl Rng, - ) -> R1CSResult> - where - C: ConstraintSynthesizer, - { - type D = GeneralEvaluationDomain; - - let setup_time = start_timer!(|| "Groth16::Generator"); - let cs = ConstraintSystem::new_ref(); - cs.set_optimization_goal(OptimizationGoal::Constraints); - cs.set_mode(SynthesisMode::Setup); - - // Synthesize the circuit. - let synthesis_time = start_timer!(|| "Constraint synthesis"); - circuit.generate_constraints(cs.clone())?; - end_timer!(synthesis_time); - - let lc_time = start_timer!(|| "Inlining LCs"); - cs.finalize(); - end_timer!(lc_time); - - // Following is the mapping of symbols from the Groth16 paper to this - // implementation l -> num_instance_variables - // m -> qap_num_variables - // x -> t - // t(x) - zt - // u_i(x) -> a - // v_i(x) -> b - // w_i(x) -> c - - /////////////////////////////////////////////////////////////////////////// - let domain_time = start_timer!(|| "Constructing evaluation domain"); - - let domain_size = cs.num_constraints() + cs.num_instance_variables(); - let domain = D::new(domain_size).ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - let t = domain.sample_element_outside_domain(rng); - - end_timer!(domain_time); - /////////////////////////////////////////////////////////////////////////// - - let reduction_time = start_timer!(|| "R1CS to QAP Instance Map with Evaluation"); - let num_instance_variables = cs.num_instance_variables(); - let (a, b, c, zt, qap_num_variables, m_raw) = - QAP::instance_map_with_evaluation::>(cs, &t)?; - end_timer!(reduction_time); - - // Compute query densities - let non_zero_a: usize = cfg_into_iter!(0..qap_num_variables) - .map(|i| usize::from(!a[i].is_zero())) - .sum(); - - let non_zero_b: usize = cfg_into_iter!(0..qap_num_variables) - .map(|i| usize::from(!b[i].is_zero())) - .sum(); - - let scalar_bits = E::ScalarField::MODULUS_BIT_SIZE as usize; - - let gamma_inverse = gamma.inverse().ok_or(SynthesisError::UnexpectedIdentity)?; - let delta_inverse = delta.inverse().ok_or(SynthesisError::UnexpectedIdentity)?; - - let gamma_abc = cfg_iter!(a[..num_instance_variables]) - .zip(&b[..num_instance_variables]) - .zip(&c[..num_instance_variables]) - .map(|((a, b), c)| (beta * a + &(alpha * b) + c) * &gamma_inverse) - .collect::>(); - - let l = cfg_iter!(a[num_instance_variables..]) - .zip(&b[num_instance_variables..]) - .zip(&c[num_instance_variables..]) - .map(|((a, b), c)| (beta * a + &(alpha * b) + c) * &delta_inverse) - .collect::>(); - - drop(c); - - // Compute B window table - let g2_time = start_timer!(|| "Compute G2 table"); - let g2_window = FixedBase::get_mul_window_size(non_zero_b); - let g2_table = FixedBase::get_window_table::(scalar_bits, g2_window, g2_generator); - end_timer!(g2_time); - - // Compute the B-query in G2 - // let b_g2_time = start_timer!(|| "Calculate B G2"); - let b_g2_query = FixedBase::msm::(scalar_bits, g2_window, &g2_table, &b); - drop(g2_table); - // end_timer!(b_g2_time); - - // Compute G window table - let g1_window_time = start_timer!(|| "Compute G1 window table"); - let g1_window = - FixedBase::get_mul_window_size(non_zero_a + non_zero_b + qap_num_variables + m_raw + 1); - let g1_table = FixedBase::get_window_table::(scalar_bits, g1_window, g1_generator); - end_timer!(g1_window_time); - - // Generate the R1CS proving key - let proving_key_time = start_timer!(|| "Generate the R1CS proving key"); - - let alpha_g1 = g1_generator.mul_bigint(&alpha.into_bigint()); - let beta_g1 = g1_generator.mul_bigint(&beta.into_bigint()); - let beta_g2 = g2_generator.mul_bigint(&beta.into_bigint()); - let delta_g1 = g1_generator.mul_bigint(&delta.into_bigint()); - let delta_g2 = g2_generator.mul_bigint(&delta.into_bigint()); - - // Compute the A-query - let a_time = start_timer!(|| "Calculate A"); - let a_query = FixedBase::msm::(scalar_bits, g1_window, &g1_table, &a); - drop(a); - end_timer!(a_time); - - // Compute the B-query in G1 - let b_g1_time = start_timer!(|| "Calculate B G1"); - let b_g1_query = FixedBase::msm::(scalar_bits, g1_window, &g1_table, &b); - drop(b); - end_timer!(b_g1_time); - - // Compute the H-query - let h_time = start_timer!(|| "Calculate H"); - let h_query = FixedBase::msm::( - scalar_bits, - g1_window, - &g1_table, - &QAP::h_query_scalars::<_, D>(m_raw - 1, t, zt, delta_inverse)?, - ); - - end_timer!(h_time); - - // Compute the L-query - let l_time = start_timer!(|| "Calculate L"); - let l_query = FixedBase::msm::(scalar_bits, g1_window, &g1_table, &l); - drop(l); - end_timer!(l_time); - - end_timer!(proving_key_time); - - // Generate R1CS verification key - let verifying_key_time = start_timer!(|| "Generate the R1CS verification key"); - let gamma_g2 = g2_generator.mul_bigint(&gamma.into_bigint()); - let gamma_abc_g1 = FixedBase::msm::(scalar_bits, g1_window, &g1_table, &gamma_abc); - - drop(g1_table); - - end_timer!(verifying_key_time); - - let vk = VerifyingKey:: { - alpha_g1: alpha_g1.into_affine(), - beta_g2: beta_g2.into_affine(), - gamma_g2: gamma_g2.into_affine(), - delta_g2: delta_g2.into_affine(), - gamma_abc_g1: E::G1::normalize_batch(&gamma_abc_g1), - }; - - let batch_normalization_time = start_timer!(|| "Convert proving key elements to affine"); - let a_query = E::G1::normalize_batch(&a_query); - let b_g1_query = E::G1::normalize_batch(&b_g1_query); - let b_g2_query = E::G2::normalize_batch(&b_g2_query); - let h_query = E::G1::normalize_batch(&h_query); - let l_query = E::G1::normalize_batch(&l_query); - end_timer!(batch_normalization_time); - end_timer!(setup_time); - - Ok(ProvingKey { - vk, - beta_g1: beta_g1.into_affine(), - delta_g1: delta_g1.into_affine(), - a_query, - b_g1_query, - b_g2_query, - h_query, - l_query, - }) - } -} diff --git a/prover/groth16/src/lib.rs b/prover/groth16/src/lib.rs deleted file mode 100644 index 217622ad..00000000 --- a/prover/groth16/src/lib.rs +++ /dev/null @@ -1,100 +0,0 @@ -//! An implementation of the [`Groth16`] zkSNARK. -//! -//! [`Groth16`]: https://eprint.iacr.org/2016/260.pdf -#![cfg_attr(not(feature = "std"), no_std)] -#![warn( - unused, - future_incompatible, - nonstandard_style, - rust_2018_idioms, - missing_docs -)] -#![allow(clippy::many_single_char_names, clippy::op_ref)] -// #![forbid(unsafe_code)] - -#[macro_use] -extern crate ark_std; - -#[cfg(feature = "r1cs")] -#[macro_use] -extern crate derivative; - -/// Reduce an R1CS instance to a *Quadratic Arithmetic Program* instance. -pub mod r1cs_to_qap; - -/// Data structures used by the prover, verifier, and generator. -pub mod data_structures; - -/// Generate public parameters for the Groth16 zkSNARK construction. -pub mod generator; - -/// Create proofs for the Groth16 zkSNARK construction. -pub mod prover; - -/// Verify proofs for the Groth16 zkSNARK construction. -pub mod verifier; - -/// Public calls -pub mod api; - -/// Constraints for the Groth16 verifier. -#[cfg(feature = "r1cs")] -pub mod constraints; - -#[cfg(test)] -mod test; - -pub use self::{data_structures::*, generator::*, prover::*, verifier::*}; - -use ark_crypto_primitives::snark::*; -use ark_ec::pairing::Pairing; -use ark_relations::r1cs::{ConstraintSynthesizer, SynthesisError}; -use ark_std::{marker::PhantomData, rand::RngCore, vec::Vec}; -use r1cs_to_qap::{LibsnarkReduction, R1CSToQAP}; - -/// The SNARK of [[Groth16]](https://eprint.iacr.org/2016/260.pdf). -pub struct Groth16 { - _p: PhantomData<(E, QAP)>, -} - -impl SNARK for Groth16 { - type ProvingKey = ProvingKey; - type VerifyingKey = VerifyingKey; - type Proof = Proof; - type ProcessedVerifyingKey = PreparedVerifyingKey; - type Error = SynthesisError; - - fn circuit_specific_setup, R: RngCore>( - circuit: C, - rng: &mut R, - ) -> Result<(Self::ProvingKey, Self::VerifyingKey), Self::Error> { - let pk = Self::generate_random_parameters_with_reduction(circuit, rng)?; - let vk = pk.vk.clone(); - Ok((pk, vk)) - } - - fn prove, R: RngCore>( - pk: &Self::ProvingKey, - circuit: C, - rng: &mut R, - ) -> Result { - println!("G16: prove"); - Self::create_random_proof_with_reduction(circuit, pk, rng) - } - - fn process_vk( - circuit_vk: &Self::VerifyingKey, - ) -> Result { - Ok(prepare_verifying_key(circuit_vk)) - } - - fn verify_with_processed_vk( - circuit_pvk: &Self::ProcessedVerifyingKey, - x: &[E::ScalarField], - proof: &Self::Proof, - ) -> Result { - Self::verify_proof(circuit_pvk, proof, x) - } -} - -impl CircuitSpecificSetupSNARK for Groth16 {} diff --git a/prover/groth16/src/prover.rs b/prover/groth16/src/prover.rs deleted file mode 100644 index 97a50785..00000000 --- a/prover/groth16/src/prover.rs +++ /dev/null @@ -1,277 +0,0 @@ -use crate::{r1cs_to_qap::R1CSToQAP, Groth16, Proof, ProvingKey, VerifyingKey}; -use ark_ec::{pairing::Pairing, AffineRepr, CurveGroup, Group, VariableBaseMSM}; -use ark_ff::{Field, PrimeField, UniformRand, Zero}; -use ark_poly::GeneralEvaluationDomain; -use ark_relations::r1cs::{ - ConstraintMatrices, ConstraintSynthesizer, ConstraintSystem, OptimizationGoal, - Result as R1CSResult, -}; -use ark_std::{ - cfg_into_iter, cfg_iter, - ops::{AddAssign, Mul}, - rand::Rng, - vec::Vec, -}; - -#[cfg(feature = "parallel")] -use rayon::prelude::*; - -type D = GeneralEvaluationDomain; - -impl Groth16 { - /// Create a Groth16 proof using randomness `r` and `s` and - /// the provided R1CS-to-QAP reduction, using the provided - /// R1CS constraint matrices. - #[inline] - pub fn create_proof_with_reduction_and_matrices( - pk: &ProvingKey, - r: E::ScalarField, - s: E::ScalarField, - matrices: &ConstraintMatrices, - num_inputs: usize, - num_constraints: usize, - full_assignment: &[E::ScalarField], - ) -> R1CSResult> { - let prover_time = start_timer!(|| "Groth16::Prover"); - let witness_map_time = start_timer!(|| "R1CS to QAP witness map"); - let h = QAP::witness_map_from_matrices::>( - matrices, - num_inputs, - num_constraints, - full_assignment, - )?; - end_timer!(witness_map_time); - let input_assignment = &full_assignment[1..num_inputs]; - let aux_assignment = &full_assignment[num_inputs..]; - let proof = - Self::create_proof_with_assignment(pk, r, s, &h, input_assignment, aux_assignment)?; - end_timer!(prover_time); - - Ok(proof) - } - - #[inline] - fn create_proof_with_assignment( - pk: &ProvingKey, - r: E::ScalarField, - s: E::ScalarField, - h: &[E::ScalarField], - input_assignment: &[E::ScalarField], - aux_assignment: &[E::ScalarField], - ) -> R1CSResult> { - let c_acc_time = start_timer!(|| "Compute C"); - let h_assignment = cfg_into_iter!(h) - .map(|s| s.into_bigint()) - .collect::>(); - let h_acc = E::G1::msm_bigint(&pk.h_query, &h_assignment); - drop(h_assignment); - - // Compute C - let aux_assignment = cfg_iter!(aux_assignment) - .map(|s| s.into_bigint()) - .collect::>(); - - let l_aux_acc = E::G1::msm_bigint(&pk.l_query, &aux_assignment); - - let r_s_delta_g1 = pk - .delta_g1 - .into_group() - .mul_bigint(&r.into_bigint()) - .mul_bigint(&s.into_bigint()); - - end_timer!(c_acc_time); - - let input_assignment = input_assignment - .iter() - .map(|s| s.into_bigint()) - .collect::>(); - - let assignment = [&input_assignment[..], &aux_assignment[..]].concat(); - drop(aux_assignment); - - // Compute A - let a_acc_time = start_timer!(|| "Compute A"); - let r_g1 = pk.delta_g1.mul(r); - - let g_a = Self::calculate_coeff(r_g1, &pk.a_query, pk.vk.alpha_g1, &assignment); - - let s_g_a = g_a.mul_bigint(&s.into_bigint()); - end_timer!(a_acc_time); - - // Compute B in G1 if needed - let g1_b = if !r.is_zero() { - let b_g1_acc_time = start_timer!(|| "Compute B in G1"); - let s_g1 = pk.delta_g1.mul(s); - let g1_b = Self::calculate_coeff(s_g1, &pk.b_g1_query, pk.beta_g1, &assignment); - - end_timer!(b_g1_acc_time); - - g1_b - } else { - E::G1::zero() - }; - - // Compute B in G2 - let b_g2_acc_time = start_timer!(|| "Compute B in G2"); - let s_g2 = pk.vk.delta_g2.mul(s); - let g2_b = Self::calculate_coeff(s_g2, &pk.b_g2_query, pk.vk.beta_g2, &assignment); - let r_g1_b = g1_b.mul_bigint(&r.into_bigint()); - drop(assignment); - - end_timer!(b_g2_acc_time); - - let c_time = start_timer!(|| "Finish C"); - let mut g_c = s_g_a; - g_c += &r_g1_b; - g_c -= &r_s_delta_g1; - g_c += &l_aux_acc; - g_c += &h_acc; - end_timer!(c_time); - - Ok(Proof { - a: g_a.into_affine(), - b: g2_b.into_affine(), - c: g_c.into_affine(), - }) - } - - /// Create a Groth16 proof that is zero-knowledge using the provided - /// R1CS-to-QAP reduction. - /// This method samples randomness for zero knowledges via `rng`. - #[inline] - pub fn create_random_proof_with_reduction( - circuit: C, - pk: &ProvingKey, - rng: &mut impl Rng, - ) -> R1CSResult> - where - C: ConstraintSynthesizer, - { - let r = E::ScalarField::rand(rng); - let s = E::ScalarField::rand(rng); - - Self::create_proof_with_reduction(circuit, pk, r, s) - } - - /// Create a Groth16 proof that is *not* zero-knowledge with the provided - /// R1CS-to-QAP reduction. - #[inline] - pub fn create_proof_with_reduction_no_zk( - circuit: C, - pk: &ProvingKey, - ) -> R1CSResult> - where - C: ConstraintSynthesizer, - { - Self::create_proof_with_reduction( - circuit, - pk, - E::ScalarField::zero(), - E::ScalarField::zero(), - ) - } - - /// Create a Groth16 proof using randomness `r` and `s` and the provided - /// R1CS-to-QAP reduction. - #[inline] - pub fn create_proof_with_reduction( - circuit: C, - pk: &ProvingKey, - r: E::ScalarField, - s: E::ScalarField, - ) -> R1CSResult> - where - E: Pairing, - C: ConstraintSynthesizer, - QAP: R1CSToQAP, - { - let prover_time = start_timer!(|| "Groth16::Prover"); - let cs = ConstraintSystem::new_ref(); - - // Set the optimization goal - cs.set_optimization_goal(OptimizationGoal::Constraints); - - // Synthesize the circuit. - let synthesis_time = start_timer!(|| "Constraint synthesis"); - circuit.generate_constraints(cs.clone())?; - - debug_assert!(cs.is_satisfied().unwrap()); - end_timer!(synthesis_time); - - let lc_time = start_timer!(|| "Inlining LCs"); - cs.finalize(); - end_timer!(lc_time); - - let witness_map_time = start_timer!(|| "R1CS to QAP witness map"); - let h = QAP::witness_map::>(cs.clone())?; - end_timer!(witness_map_time); - - let prover = cs.borrow().unwrap(); - let proof = Self::create_proof_with_assignment( - pk, - r, - s, - &h, - &prover.instance_assignment[1..], - &prover.witness_assignment, - )?; - - end_timer!(prover_time); - - Ok(proof) - } - - /// Given a Groth16 proof, returns a fresh proof of the same statement. For - /// a proof π of a statement S, the output of the non-deterministic - /// procedure `rerandomize_proof(π)` is statistically indistinguishable - /// from a fresh honest proof of S. For more info, see theorem 3 of [\[BKSV20\]](https://eprint.iacr.org/2020/811) - pub fn rerandomize_proof( - vk: &VerifyingKey, - proof: &Proof, - rng: &mut impl Rng, - ) -> Proof { - // These are our rerandomization factors. They must be nonzero and uniformly - // sampled. - let (mut r1, mut r2) = (E::ScalarField::zero(), E::ScalarField::zero()); - while r1.is_zero() || r2.is_zero() { - r1 = E::ScalarField::rand(rng); - r2 = E::ScalarField::rand(rng); - } - - // See figure 1 in the paper referenced above: - // A' = (1/r₁)A - // B' = r₁B + r₁r₂(δG₂) - // C' = C + r₂A - - // We can unwrap() this because r₁ is guaranteed to be nonzero - let new_a = proof.a.mul(r1.inverse().unwrap()); - let new_b = proof.b.mul(r1) + &vk.delta_g2.mul(r1 * &r2); - let new_c = proof.c + proof.a.mul(r2).into_affine(); - - Proof { - a: new_a.into_affine(), - b: new_b.into_affine(), - c: new_c.into_affine(), - } - } - - fn calculate_coeff( - initial: G::Group, - query: &[G], - vk_param: G, - assignment: &[::BigInt], - ) -> G::Group - where - G::Group: VariableBaseMSM, - { - let el = query[0]; - let acc = G::Group::msm_bigint(&query[1..], assignment); - - let mut res = initial; - res.add_assign(&el); - res += &acc; - res.add_assign(&vk_param); - - res - } -} diff --git a/prover/groth16/src/r1cs_to_qap.rs b/prover/groth16/src/r1cs_to_qap.rs deleted file mode 100644 index 0733a9f5..00000000 --- a/prover/groth16/src/r1cs_to_qap.rs +++ /dev/null @@ -1,230 +0,0 @@ -use ark_ff::{One, PrimeField, Zero}; -use ark_poly::EvaluationDomain; -use ark_std::{cfg_iter, cfg_iter_mut, vec}; - -use crate::Vec; -use ark_relations::r1cs::{ - ConstraintMatrices, ConstraintSystemRef, Result as R1CSResult, SynthesisError, -}; -use core::ops::{AddAssign, Deref}; - -#[cfg(feature = "parallel")] -use rayon::prelude::*; - -#[inline] -/// Computes the inner product of `terms` with `assignment`. -pub fn evaluate_constraint<'a, LHS, RHS, R>(terms: &'a [(LHS, usize)], assignment: &'a [RHS]) -> R -where - LHS: One + Send + Sync + PartialEq, - RHS: Send + Sync + core::ops::Mul<&'a LHS, Output = RHS> + Copy, - R: Zero + Send + Sync + AddAssign + core::iter::Sum, -{ - // Need to wrap in a closure when using Rayon - #[cfg(feature = "parallel")] - let zero = || R::zero(); - #[cfg(not(feature = "parallel"))] - let zero = R::zero(); - - let res = cfg_iter!(terms).fold(zero, |mut sum, (coeff, index)| { - let val = &assignment[*index]; - - if coeff.is_one() { - sum += *val; - } else { - sum += val.mul(coeff); - } - - sum - }); - - // Need to explicitly call `.sum()` when using Rayon - #[cfg(feature = "parallel")] - return res.sum(); - #[cfg(not(feature = "parallel"))] - return res; -} - -/// Computes instance and witness reductions from R1CS to -/// Quadratic Arithmetic Programs (QAPs). -pub trait R1CSToQAP { - /// Computes a QAP instance corresponding to the R1CS instance defined by - /// `cs`. - #[allow(clippy::type_complexity)] - fn instance_map_with_evaluation>( - cs: ConstraintSystemRef, - t: &F, - ) -> Result<(Vec, Vec, Vec, F, usize, usize), SynthesisError>; - - #[inline] - /// Computes a QAP witness corresponding to the R1CS witness defined by - /// `cs`. - fn witness_map>( - prover: ConstraintSystemRef, - ) -> Result, SynthesisError> { - let matrices = prover.to_matrices().unwrap(); - let num_inputs = prover.num_instance_variables(); - let num_constraints = prover.num_constraints(); - - let cs = prover.borrow().unwrap(); - let prover = cs.deref(); - - let full_assignment = [ - prover.instance_assignment.as_slice(), - prover.witness_assignment.as_slice(), - ] - .concat(); - - Self::witness_map_from_matrices::( - &matrices, - num_inputs, - num_constraints, - &full_assignment, - ) - } - - /// Computes a QAP witness corresponding to the R1CS witness defined by - /// `cs`. - fn witness_map_from_matrices>( - matrices: &ConstraintMatrices, - num_inputs: usize, - num_constraints: usize, - full_assignment: &[F], - ) -> R1CSResult>; - - /// Computes the exponents that the generator uses to calculate base - /// elements which the prover later uses to compute `h(x)t(x)/delta`. - fn h_query_scalars>( - max_power: usize, - t: F, - zt: F, - delta_inverse: F, - ) -> Result, SynthesisError>; -} - -/// Computes the R1CS-to-QAP reduction defined in [`libsnark`](https://github.com/scipr-lab/libsnark/blob/2af440246fa2c3d0b1b0a425fb6abd8cc8b9c54d/libsnark/reductions/r1cs_to_qap/r1cs_to_qap.tcc). -pub struct LibsnarkReduction; - -impl R1CSToQAP for LibsnarkReduction { - #[inline] - #[allow(clippy::type_complexity)] - fn instance_map_with_evaluation>( - cs: ConstraintSystemRef, - t: &F, - ) -> R1CSResult<(Vec, Vec, Vec, F, usize, usize)> { - let matrices = cs.to_matrices().unwrap(); - let domain_size = cs.num_constraints() + cs.num_instance_variables(); - let domain = D::new(domain_size).ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - let domain_size = domain.size(); - - let zt = domain.evaluate_vanishing_polynomial(*t); - - // Evaluate all Lagrange polynomials - let coefficients_time = start_timer!(|| "Evaluate Lagrange coefficients"); - let u = domain.evaluate_all_lagrange_coefficients(*t); - end_timer!(coefficients_time); - - let qap_num_variables = (cs.num_instance_variables() - 1) + cs.num_witness_variables(); - - let mut a = vec![F::zero(); qap_num_variables + 1]; - let mut b = vec![F::zero(); qap_num_variables + 1]; - let mut c = vec![F::zero(); qap_num_variables + 1]; - - { - let start = 0; - let end = cs.num_instance_variables(); - let num_constraints = cs.num_constraints(); - a[start..end].copy_from_slice(&u[(start + num_constraints)..(end + num_constraints)]); - } - - for (i, u_i) in u.iter().enumerate().take(cs.num_constraints()) { - for &(ref coeff, index) in &matrices.a[i] { - a[index] += &(*u_i * coeff); - } - for &(ref coeff, index) in &matrices.b[i] { - b[index] += &(*u_i * coeff); - } - for &(ref coeff, index) in &matrices.c[i] { - c[index] += &(*u_i * coeff); - } - } - - Ok((a, b, c, zt, qap_num_variables, domain_size)) - } - - fn witness_map_from_matrices>( - matrices: &ConstraintMatrices, - num_inputs: usize, - num_constraints: usize, - full_assignment: &[F], - ) -> R1CSResult> { - let domain = - D::new(num_constraints + num_inputs).ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - let domain_size = domain.size(); - let zero = F::zero(); - - let mut a = vec![zero; domain_size]; - let mut b = vec![zero; domain_size]; - - cfg_iter_mut!(a[..num_constraints]) - .zip(cfg_iter_mut!(b[..num_constraints])) - .zip(cfg_iter!(&matrices.a)) - .zip(cfg_iter!(&matrices.b)) - .for_each(|(((a, b), at_i), bt_i)| { - *a = evaluate_constraint(at_i, full_assignment); - *b = evaluate_constraint(bt_i, full_assignment); - }); - - { - let start = num_constraints; - let end = start + num_inputs; - a[start..end].clone_from_slice(&full_assignment[..num_inputs]); - } - - domain.ifft_in_place(&mut a); - domain.ifft_in_place(&mut b); - - let coset_domain = domain.get_coset(F::GENERATOR).unwrap(); - - coset_domain.fft_in_place(&mut a); - coset_domain.fft_in_place(&mut b); - - let mut ab = domain.mul_polynomials_in_evaluation_domain(&a, &b); - drop(a); - drop(b); - - let mut c = vec![zero; domain_size]; - cfg_iter_mut!(c[..num_constraints]) - .enumerate() - .for_each(|(i, c)| { - *c = evaluate_constraint(&matrices.c[i], full_assignment); - }); - - domain.ifft_in_place(&mut c); - coset_domain.fft_in_place(&mut c); - - let vanishing_polynomial_over_coset = domain - .evaluate_vanishing_polynomial(F::GENERATOR) - .inverse() - .unwrap(); - cfg_iter_mut!(ab).zip(c).for_each(|(ab_i, c_i)| { - *ab_i -= &c_i; - *ab_i *= &vanishing_polynomial_over_coset; - }); - - coset_domain.ifft_in_place(&mut ab); - - Ok(ab) - } - - fn h_query_scalars>( - max_power: usize, - t: F, - zt: F, - delta_inverse: F, - ) -> Result, SynthesisError> { - let scalars = cfg_into_iter!(0..max_power) - .map(|i| zt * &delta_inverse * &t.pow([i as u64])) - .collect::>(); - Ok(scalars) - } -} diff --git a/prover/groth16/src/test.rs b/prover/groth16/src/test.rs deleted file mode 100644 index e46eb56e..00000000 --- a/prover/groth16/src/test.rs +++ /dev/null @@ -1,149 +0,0 @@ -use crate::{prepare_verifying_key, Groth16}; -use ark_crypto_primitives::snark::{CircuitSpecificSetupSNARK, SNARK}; -use ark_ec::pairing::Pairing; -use ark_ff::Field; -use ark_relations::{ - lc, - r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}, -}; -use ark_std::{ - rand::{RngCore, SeedableRng}, - test_rng, UniformRand, -}; - -struct MySillyCircuit { - a: Option, - b: Option, -} - -impl ConstraintSynthesizer for MySillyCircuit { - fn generate_constraints( - self, - cs: ConstraintSystemRef, - ) -> Result<(), SynthesisError> { - let a = cs.new_witness_variable(|| self.a.ok_or(SynthesisError::AssignmentMissing))?; - let b = cs.new_witness_variable(|| self.b.ok_or(SynthesisError::AssignmentMissing))?; - let c = cs.new_input_variable(|| { - let mut a = self.a.ok_or(SynthesisError::AssignmentMissing)?; - let b = self.b.ok_or(SynthesisError::AssignmentMissing)?; - - a *= &b; - Ok(a) - })?; - - cs.enforce_constraint(lc!() + a, lc!() + b, lc!() + c)?; - cs.enforce_constraint(lc!() + a, lc!() + b, lc!() + c)?; - cs.enforce_constraint(lc!() + a, lc!() + b, lc!() + c)?; - cs.enforce_constraint(lc!() + a, lc!() + b, lc!() + c)?; - cs.enforce_constraint(lc!() + a, lc!() + b, lc!() + c)?; - cs.enforce_constraint(lc!() + a, lc!() + b, lc!() + c)?; - - Ok(()) - } -} - -fn test_prove_and_verify(n_iters: usize) -where - E: Pairing, -{ - let mut rng = ark_std::rand::rngs::StdRng::seed_from_u64(test_rng().next_u64()); - - let (pk, vk) = Groth16::::setup(MySillyCircuit { a: None, b: None }, &mut rng).unwrap(); - let pvk = prepare_verifying_key::(&vk); - - for _ in 0..n_iters { - let a = E::ScalarField::rand(&mut rng); - let b = E::ScalarField::rand(&mut rng); - let mut c = a; - c *= b; - - let proof = Groth16::::prove( - &pk, - MySillyCircuit { - a: Some(a), - b: Some(b), - }, - &mut rng, - ) - .unwrap(); - - assert!(Groth16::::verify_with_processed_vk(&pvk, &[c], &proof).unwrap()); - assert!(!Groth16::::verify_with_processed_vk(&pvk, &[a], &proof).unwrap()); - } -} - -fn test_rerandomize() -where - E: Pairing, -{ - let mut rng = ark_std::rand::rngs::StdRng::seed_from_u64(test_rng().next_u64()); - - let (pk, vk) = Groth16::::setup(MySillyCircuit { a: None, b: None }, &mut rng).unwrap(); - let pvk = prepare_verifying_key::(&vk); - - for _ in 0..10 { - let a = E::ScalarField::rand(&mut rng); - let b = E::ScalarField::rand(&mut rng); - let mut c = a; - c *= b; - - let proof1 = Groth16::::prove( - &pk, - MySillyCircuit { - a: Some(a), - b: Some(b), - }, - &mut rng, - ) - .unwrap(); - - // Rerandomize the proof, then rerandomize that - let proof2 = Groth16::::rerandomize_proof(&vk, &proof1, &mut rng); - let proof3 = Groth16::::rerandomize_proof(&vk, &proof2, &mut rng); - - // Check correctness: a rerandomized proof validates when the original validates - assert!(Groth16::::verify_with_processed_vk(&pvk, &[c], &proof1).unwrap()); - assert!(Groth16::::verify_with_processed_vk(&pvk, &[c], &proof2).unwrap()); - assert!(Groth16::::verify_with_processed_vk(&pvk, &[c], &proof3).unwrap()); - - assert!(!Groth16::::verify_with_processed_vk(&pvk, &[a], &proof1).unwrap()); - assert!(!Groth16::::verify_with_processed_vk(&pvk, &[a], &proof2).unwrap()); - assert!(!Groth16::::verify_with_processed_vk(&pvk, &[a], &proof3).unwrap()); - - // Check that the proofs are not equal as group elements - assert!(proof1 != proof2); - assert!(proof1 != proof3); - assert!(proof2 != proof3); - } -} - -mod bls12_377 { - use super::{test_prove_and_verify, test_rerandomize}; - use ark_bls12_377::Bls12_377; - - #[test] - fn prove_and_verify() { - test_prove_and_verify::(100); - } - - #[test] - fn rerandomize() { - test_rerandomize::(); - } -} - -mod cp6_782 { - use super::{test_prove_and_verify, test_rerandomize}; - - use ark_cp6_782::CP6_782; - - #[test] - fn prove_and_verify() { - test_prove_and_verify::(1); - } - - #[test] - fn rerandomize() { - test_rerandomize::(); - } -} diff --git a/prover/groth16/src/verifier.rs b/prover/groth16/src/verifier.rs deleted file mode 100644 index 94f23bbb..00000000 --- a/prover/groth16/src/verifier.rs +++ /dev/null @@ -1,78 +0,0 @@ -use ark_ec::{pairing::Pairing, AffineRepr, CurveGroup}; -use ark_ff::PrimeField; - -use crate::{r1cs_to_qap::R1CSToQAP, Groth16}; - -use super::{PreparedVerifyingKey, Proof, VerifyingKey}; - -use ark_relations::r1cs::{Result as R1CSResult, SynthesisError}; - -use core::ops::{AddAssign, Neg}; - -/// Prepare the verifying key `vk` for use in proof verification. -pub fn prepare_verifying_key(vk: &VerifyingKey) -> PreparedVerifyingKey { - PreparedVerifyingKey { - vk: vk.clone(), - alpha_g1_beta_g2: E::pairing(vk.alpha_g1, vk.beta_g2).0, - gamma_g2_neg_pc: vk.gamma_g2.into_group().neg().into_affine().into(), - delta_g2_neg_pc: vk.delta_g2.into_group().neg().into_affine().into(), - } -} - -impl Groth16 { - /// Prepare proof inputs for use with [`verify_proof_with_prepared_inputs`], - /// wrt the prepared verification key `pvk` and instance public inputs. - pub fn prepare_inputs( - pvk: &PreparedVerifyingKey, - public_inputs: &[E::ScalarField], - ) -> R1CSResult { - if (public_inputs.len() + 1) != pvk.vk.gamma_abc_g1.len() { - return Err(SynthesisError::MalformedVerifyingKey); - } - - let mut g_ic = pvk.vk.gamma_abc_g1[0].into_group(); - for (i, b) in public_inputs.iter().zip(pvk.vk.gamma_abc_g1.iter().skip(1)) { - g_ic.add_assign(&b.mul_bigint(i.into_bigint())); - } - - Ok(g_ic) - } - - /// Verify a Groth16 proof `proof` against the prepared verification key - /// `pvk` and prepared public inputs. This should be preferred over - /// [`verify_proof`] if the instance's public inputs are - /// known in advance. - pub fn verify_proof_with_prepared_inputs( - pvk: &PreparedVerifyingKey, - proof: &Proof, - prepared_inputs: &E::G1, - ) -> R1CSResult { - let qap = E::multi_miller_loop( - [ - >::into(proof.a), - prepared_inputs.into_affine().into(), - proof.c.into(), - ], - [ - proof.b.into(), - pvk.gamma_g2_neg_pc.clone(), - pvk.delta_g2_neg_pc.clone(), - ], - ); - - let test = E::final_exponentiation(qap).ok_or(SynthesisError::UnexpectedIdentity)?; - - Ok(test.0 == pvk.alpha_g1_beta_g2) - } - - /// Verify a Groth16 proof `proof` against the prepared verification key - /// `pvk`, with respect to the instance `public_inputs`. - pub fn verify_proof( - pvk: &PreparedVerifyingKey, - proof: &Proof, - public_inputs: &[E::ScalarField], - ) -> R1CSResult { - let prepared_inputs = Self::prepare_inputs(pvk, public_inputs)?; - Self::verify_proof_with_prepared_inputs(pvk, proof, &prepared_inputs) - } -} diff --git a/prover/groth16/tests/mimc.rs b/prover/groth16/tests/mimc.rs deleted file mode 100644 index dfd469dc..00000000 --- a/prover/groth16/tests/mimc.rs +++ /dev/null @@ -1,230 +0,0 @@ -#![warn(unused)] -#![deny( - trivial_casts, - trivial_numeric_casts, - variant_size_differences, - stable_features, - non_shorthand_field_patterns, - renamed_and_removed_lints, - private_in_public, - unsafe_code -)] - -use ark_crypto_primitives::snark::{CircuitSpecificSetupSNARK, SNARK}; -// For randomness (during paramgen and proof generation) -use ark_std::rand::{Rng, RngCore, SeedableRng}; - -// For benchmarking -use std::time::{Duration, Instant}; - -// Bring in some tools for using pairing-friendly curves -// We're going to use the BLS12-377 pairing-friendly elliptic curve. -use ark_bls12_377::{Bls12_377, Fr}; -use ark_ff::Field; -use ark_std::test_rng; - -// We'll use these interfaces to construct our circuit. -use ark_relations::{ - lc, ns, - r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError, Variable}, -}; - -const MIMC_ROUNDS: usize = 322; - -/// This is an implementation of MiMC, specifically a -/// variant named `LongsightF322p3` for BLS12-377. -/// See http://eprint.iacr.org/2016/492 for more -/// information about this construction. -/// -/// ``` -/// function LongsightF322p3(xL ⦂ Fp, xR ⦂ Fp) { -/// for i from 0 up to 321 { -/// xL, xR := xR + (xL + Ci)^3, xL -/// } -/// return xL -/// } -/// ``` -fn mimc(mut xl: F, mut xr: F, constants: &[F]) -> F { - assert_eq!(constants.len(), MIMC_ROUNDS); - - for i in 0..MIMC_ROUNDS { - let mut tmp1 = xl; - tmp1.add_assign(&constants[i]); - let mut tmp2 = tmp1; - tmp2.square_in_place(); - tmp2.mul_assign(&tmp1); - tmp2.add_assign(&xr); - xr = xl; - xl = tmp2; - } - - xl -} - -/// This is our demo circuit for proving knowledge of the -/// preimage of a MiMC hash invocation. -struct MiMCDemo<'a, F: Field> { - xl: Option, - xr: Option, - constants: &'a [F], -} - -/// Our demo circuit implements this `Circuit` trait which -/// is used during paramgen and proving in order to -/// synthesize the constraint system. -impl<'a, F: Field> ConstraintSynthesizer for MiMCDemo<'a, F> { - fn generate_constraints(self, cs: ConstraintSystemRef) -> Result<(), SynthesisError> { - assert_eq!(self.constants.len(), MIMC_ROUNDS); - - // Allocate the first component of the preimage. - let mut xl_value = self.xl; - let mut xl = - cs.new_witness_variable(|| xl_value.ok_or(SynthesisError::AssignmentMissing))?; - - // Allocate the second component of the preimage. - let mut xr_value = self.xr; - let mut xr = - cs.new_witness_variable(|| xr_value.ok_or(SynthesisError::AssignmentMissing))?; - - for i in 0..MIMC_ROUNDS { - // xL, xR := xR + (xL + Ci)^3, xL - let ns = ns!(cs, "round"); - let cs = ns.cs(); - - // tmp = (xL + Ci)^2 - let tmp_value = xl_value.map(|mut e| { - e.add_assign(&self.constants[i]); - e.square_in_place(); - e - }); - let tmp = - cs.new_witness_variable(|| tmp_value.ok_or(SynthesisError::AssignmentMissing))?; - - cs.enforce_constraint( - lc!() + xl + (self.constants[i], Variable::One), - lc!() + xl + (self.constants[i], Variable::One), - lc!() + tmp, - )?; - - // new_xL = xR + (xL + Ci)^3 - // new_xL = xR + tmp * (xL + Ci) - // new_xL - xR = tmp * (xL + Ci) - let new_xl_value = xl_value.map(|mut e| { - e.add_assign(&self.constants[i]); - e.mul_assign(&tmp_value.unwrap()); - e.add_assign(&xr_value.unwrap()); - e - }); - - let new_xl = if i == (MIMC_ROUNDS - 1) { - // This is the last round, xL is our image and so - // we allocate a public input. - cs.new_input_variable(|| new_xl_value.ok_or(SynthesisError::AssignmentMissing))? - } else { - cs.new_witness_variable(|| new_xl_value.ok_or(SynthesisError::AssignmentMissing))? - }; - - cs.enforce_constraint( - lc!() + tmp, - lc!() + xl + (self.constants[i], Variable::One), - lc!() + new_xl - xr, - )?; - - // xR = xL - xr = xl; - xr_value = xl_value; - - // xL = new_xL - xl = new_xl; - xl_value = new_xl_value; - } - - Ok(()) - } -} - -#[test] -fn test_mimc_groth16() { - // We're going to use the Groth16 proving system. - use ark_groth16::Groth16; - - // This may not be cryptographically safe, use - // `OsRng` (for example) in production software. - let mut rng = ark_std::rand::rngs::StdRng::seed_from_u64(test_rng().next_u64()); - - // Generate the MiMC round constants - let constants = (0..MIMC_ROUNDS).map(|_| rng.gen()).collect::>(); - - println!("Creating parameters..."); - - // Create parameters for our circuit - let (pk, vk) = { - let c = MiMCDemo:: { - xl: None, - xr: None, - constants: &constants, - }; - - Groth16::::setup(c, &mut rng).unwrap() - }; - - // Prepare the verification key (for proof verification) - let pvk = Groth16::::process_vk(&vk).unwrap(); - - println!("Creating proofs..."); - - // Let's benchmark stuff! - const SAMPLES: u32 = 50; - let mut total_proving = Duration::new(0, 0); - let mut total_verifying = Duration::new(0, 0); - - // Just a place to put the proof data, so we can - // benchmark deserialization. - // let mut proof_vec = vec![]; - - for _ in 0..SAMPLES { - // Generate a random preimage and compute the image - let xl = rng.gen(); - let xr = rng.gen(); - let image = mimc(xl, xr, &constants); - - // proof_vec.truncate(0); - - let start = Instant::now(); - { - // Create an instance of our circuit (with the - // witness) - let c = MiMCDemo { - xl: Some(xl), - xr: Some(xr), - constants: &constants, - }; - - // Create a groth16 proof with our parameters. - let proof = Groth16::::prove(&pk, c, &mut rng).unwrap(); - assert!( - Groth16::::verify_with_processed_vk(&pvk, &[image], &proof).unwrap() - ); - - // proof.write(&mut proof_vec).unwrap(); - } - - total_proving += start.elapsed(); - - let start = Instant::now(); - // let proof = Proof::read(&proof_vec[..]).unwrap(); - // Check the proof - - total_verifying += start.elapsed(); - } - let proving_avg = total_proving / SAMPLES; - let proving_avg = - proving_avg.subsec_nanos() as f64 / 1_000_000_000f64 + (proving_avg.as_secs() as f64); - - let verifying_avg = total_verifying / SAMPLES; - let verifying_avg = - verifying_avg.subsec_nanos() as f64 / 1_000_000_000f64 + (verifying_avg.as_secs() as f64); - - println!("Average proving time: {:?} seconds", proving_avg); - println!("Average verifying time: {:?} seconds", verifying_avg); -} diff --git a/prover/marlin/.gitignore b/prover/marlin/.gitignore deleted file mode 100644 index f4b939ed..00000000 --- a/prover/marlin/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -target -Cargo.lock -.DS_Store -.idea -*.iml -*.ipynb_checkpoints -*.pyc -*.sage.py -params -node/node_modules -*.txt \ No newline at end of file diff --git a/prover/marlin/AUTHORS b/prover/marlin/AUTHORS deleted file mode 100644 index 19afa37e..00000000 --- a/prover/marlin/AUTHORS +++ /dev/null @@ -1,6 +0,0 @@ -Alessandro Chiesa -Yuncong Hu -Mary Maller -Pratyush Mishra -Psi Vesely -Nicholas Ward diff --git a/prover/marlin/CHANGELOG.md b/prover/marlin/CHANGELOG.md deleted file mode 100644 index 05c79ae2..00000000 --- a/prover/marlin/CHANGELOG.md +++ /dev/null @@ -1,23 +0,0 @@ -# CHANGELOG - -## Pending - -### Breaking changes - -### Features - -### Improvements - -### Bug fixes - -## v0.3.0 - -- Change dependency to version `0.3.0` of other arkworks-rs crates. - -## v0.2.0 - -### Features - -- [\#47](https://github.com/arkworks-rs/marlin/pull/47) Automatically pad input to be of length 2^k, so constraint writers can have a public input of any size -- [\#51](https://github.com/arkworks-rs/marlin/pull/51) Implement CanonicalSerialize for Marlin's proofs. -- [\#54](https://github.com/arkworks-rs/marlin/pull/54) Implement CanonicalSerialize for Marlin's Index and Index Verification Key. diff --git a/prover/marlin/Cargo.toml b/prover/marlin/Cargo.toml deleted file mode 100644 index 1d565d11..00000000 --- a/prover/marlin/Cargo.toml +++ /dev/null @@ -1,114 +0,0 @@ -[package] -name = "ark-marlin" -version = "0.3.0" -authors = [ - "Alessandro Chiesa ", - "Mary Maller ", - "Yuncong Hu ", - "Pratyush Mishra ", - "Psi Vesely ", - "Nicholas Ward ", - "arkworks contributors", -] -description = "A library for the Marlin preprocessing zkSNARK" -repository = "https://github.com/arkworks-rs/marlin" -documentation = "https://docs.rs/ark-marlin/" -keywords = ["cryptography", "commitments", "zkSNARK"] -categories = ["cryptography"] -include = ["Cargo.toml", "src", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] -license = "MIT/Apache-2.0" -edition = "2018" - -[dependencies] -ark-serialize = { version = "^0.3.0", default-features = false, features = [ - "derive", -] } -ark-ff = { version = "^0.3.0", default-features = false } -ark-std = { version = "^0.3.0", default-features = false } -ark-poly = { version = "^0.3.0", default-features = false } -ark-relations = { version = "^0.3.0", default-features = false } -ark-poly-commit = { version = "^0.3.0", default-features = false } - -rand_chacha = { version = "0.3.0", default-features = false } -rayon = { version = "1", optional = true } -digest = { version = "0.9" } -derivative = { version = "2", features = ["use_core"] } -blake2 = { version = "0.9", default-features = false } -ark-bls12-381 = { version = "^0.3.0", default-features = false, features = [ - "curve", -] } -ark-mnt4-298 = { version = "^0.3.0", default-features = false, features = [ - "r1cs", - "curve", -] } -ark-mnt6-298 = { version = "^0.3.0", default-features = false, features = [ - "r1cs", -] } -ark-mnt4-753 = { version = "^0.3.0", default-features = false, features = [ - "r1cs", - "curve", -] } -ark-mnt6-753 = { version = "^0.3.0", default-features = false, features = [ - "r1cs", -] } -base64 = "0.21.2" -num-bigint = "0.4.3" -serde_json = "1.0.96" -serde = { version = "1.0", features = ["derive"] } -ark-bn254 = { version = "^0.3.0", default-features = false, features = [ - "curve", -] } -ark-crypto-primitives = { version = "0.4.0" } -ark-ec = { version = "0.4.1", default-features = false, features = [ - "parallel", -] } -r1cs-file = "0.3.0" -wtns-file = "0.1.5" -byteorder = "1.4.3" -gev-core = { path = "../gev-core" } - -[profile.release] -opt-level = 3 -lto = "thin" -incremental = true -debug = true -panic = 'abort' - -[profile.test] -opt-level = 3 -debug-assertions = true -incremental = true -debug = true - -[profile.dev] -opt-level = 0 -panic = 'abort' - -[features] -default = ["std", "parallel"] -std = [ - "ark-ff/std", - "ark-poly/std", - "ark-relations/std", - "ark-std/std", - "ark-serialize/std", - "ark-poly-commit/std", -] -print-trace = ["ark-std/print-trace"] -parallel = [ - "std", - "ark-ff/parallel", - "ark-poly/parallel", - "ark-std/parallel", - "ark-poly-commit/parallel", - "rayon", -] - -[[bench]] -name = "marlin-benches" -path = "benches/bench.rs" -harness = false -required-features = ["std"] - -[lib] -crate-type = ["cdylib", "rlib"] diff --git a/prover/marlin/LICENSE-APACHE b/prover/marlin/LICENSE-APACHE deleted file mode 100644 index 16fe87b0..00000000 --- a/prover/marlin/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -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. diff --git a/prover/marlin/LICENSE-MIT b/prover/marlin/LICENSE-MIT deleted file mode 100644 index 72dc60d8..00000000 --- a/prover/marlin/LICENSE-MIT +++ /dev/null @@ -1,19 +0,0 @@ -The MIT License (MIT) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/prover/marlin/README.md b/prover/marlin/README.md deleted file mode 100644 index 588e419c..00000000 --- a/prover/marlin/README.md +++ /dev/null @@ -1,113 +0,0 @@ -

Marlin

- -

- - -

- - -`marlin` is a Rust library that implements a -

-preprocessing zkSNARK for R1CS
-with
-universal and updatable SRS -

- -This library was initially developed as part of the [Marlin paper][marlin], and is released under the MIT License and the Apache v2 License (see [License](#license)). - -**WARNING:** This is an academic prototype, and in particular has not received careful code review. This implementation is NOT ready for production use. - -## Overview - -A zkSNARK with **preprocessing** achieves succinct verification for arbitrary computations, as opposed to only for structured computations. Informally, in an offline phase, one can preprocess the desired computation to produce a short summary of it; subsequently, in an online phase, this summary can be used to check any number of arguments relative to this computation. - -The preprocessing zkSNARKs in this library rely on a structured reference string (SRS), which contains system parameters required by the argument system to produce/validate arguments. The SRS in this library is **universal**, which means that it supports (deterministically) preprocessing any computation up to a given size bound. The SRS is also **updatable**, which means that anyone can contribute a fresh share of randomness to it, which facilitates deployments in the real world. - -The construction in this library follows the methodology introduced in the [Marlin paper][marlin], which obtains preprocessing zkSNARKs with universal and updatable SRS by combining two ingredients: - -* an **algebraic holographic proof** -* a **polynomial commitment scheme** - -The first ingredient is provided as part of this library, and is an efficient algebraic holographic proof for R1CS (a generalization of arithmetic circuit satisfiability supported by many argument systems). The second ingredient is imported from [`poly-commit`](https://github.com/arkworks-rs/poly-commit). See below for evaluation details. - -## Build guide - -The library compiles on the `stable` toolchain of the Rust compiler. To install the latest version of Rust, first install `rustup` by following the instructions [here](https://rustup.rs/), or via your platform's package manager. Once `rustup` is installed, install the Rust toolchain by invoking: -```bash -rustup install stable -``` - -After that, use `cargo` (the standard Rust build tool) to build the library: -```bash -git clone https://github.com/arkworks-rs/marlin.git -cd marlin -cargo build --release -``` - -This library comes with some unit and integration tests. Run these tests with: -```bash -cargo test -``` - -Lastly, this library is instrumented with profiling infrastructure that prints detailed traces of execution time. To enable this, compile with `cargo build --features print-trace`. - - -## Benchmarks - -All benchmarks below are performed over the BLS12-381 curve implemented in the [`ark-bls12-381`](https://github.com/arkworks-rs/curves/) library, with the `asm` feature activated. Benchmarks were run on a machine with an Intel Xeon 6136 CPU running at 3.0 GHz. - - -### Running time compared to Groth16 - -The graphs below compare the running time, in single-thread execution, of Marlin's indexer, prover, and verifier algorithms with the corresponding algorithms of [Groth16][groth16] (the state of the art in preprocessing zkSNARKs for R1CS with circuit-specific SRS) as implemented in [`groth16`](https://github.com/arkworks-rs/groth16). We evaluate Marlin's algorithms when instantiated with the PC scheme from [[CHMMVW20]][marlin] (denoted "M-AHP w/ PC of [[CHMMVW20]][marlin]"), and the PC scheme from [[MBKM19]][sonic] (denoted "M-AHP w/ PC of [[MBKM19]][sonic]"). - -

-Indexer -Prover -

-

-Verifier -

- -### Multi-threaded performance - -The following graphs compare the running time of Marlin's prover when instantiated with the PC scheme from [[CHMMVW20]][marlin] (left) and the PC scheme from [[MBKM19]][sonic] (right) when executed with a different number of threads. - -

-Multi-threaded scaling of Marlin AHP with the PC scheme from [CHMMVW20] -Multi-threaded scaling of Marlin AHP with the PC scheme from [MBKM19] -

- -### Proof size - -We compare the proof size of Marlin with that of [Groth16][groth16]. We instantiate the Marlin SNARK with the PC scheme from [[CHMMVW20]][marlin], and the PC scheme from [[MBKM19]][sonic]. - -| Scheme | Proof size in bytes | -|:------------------------------------------:|:---------------------:| -| Marlin AHP with PC of [[CHMMVW20]][marlin] | 880 | -| Marlin AHP with PC of [[MBKM19]][sonic] | 784 | -| [\[Groth16\]][groth16] | 192 | - - -## License - -This library is licensed under either of the following licenses, at your discretion. - - * [Apache License Version 2.0](LICENSE-APACHE) - * [MIT License](LICENSE-MIT) - -Unless you explicitly state otherwise, any contribution that you submit to this library shall be dual licensed as above (as defined in the Apache v2 License), without any additional terms or conditions. - -[marlin]: https://ia.cr/2019/1047 -[sonic]: https://ia.cr/2019/099 -[groth16]: https://ia.cr/2016/260 - -## Reference paper - -[Marlin: Preprocessing zkSNARKs with Universal and Updatable SRS][marlin] -Alessandro Chiesa, Yuncong Hu, Mary Maller, [Pratyush Mishra](https://www.github.com/pratyush), [Psi Vesely](https://github.com/psivesely), [Nicholas Ward](https://www.github.com/npwardberkeley) -EUROCRYPT 2020 - -## Acknowledgements - -This work was supported by: an Engineering and Physical Sciences Research Council grant; a Google Faculty Award; the RISELab at UC Berkeley; and donations from the Ethereum Foundation and the Interchain Foundation. diff --git a/prover/marlin/benches/bench.rs b/prover/marlin/benches/bench.rs deleted file mode 100644 index f0da95c0..00000000 --- a/prover/marlin/benches/bench.rs +++ /dev/null @@ -1,179 +0,0 @@ -// For benchmark, run: -// RAYON_NUM_THREADS=N cargo bench --no-default-features --features "std parallel" -- --nocapture -// where N is the number of threads you want to use (N = 1 for single-thread). - -use ark_bls12_381::{Bls12_381, Fr as BlsFr}; -use ark_ff::PrimeField; -use ark_marlin::Marlin; -use ark_mnt4_298::{Fr as MNT4Fr, MNT4_298}; -use ark_mnt4_753::{Fr as MNT4BigFr, MNT4_753}; -use ark_mnt6_298::{Fr as MNT6Fr, MNT6_298}; -use ark_mnt6_753::{Fr as MNT6BigFr, MNT6_753}; -use ark_poly::univariate::DensePolynomial; -use ark_poly_commit::marlin_pc::MarlinKZG10; -use ark_relations::{ - lc, - r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}, -}; -use ark_std::{ops::Mul, UniformRand}; -use blake2::Blake2s; - -const NUM_PROVE_REPEATITIONS: usize = 10; -const NUM_VERIFY_REPEATITIONS: usize = 50; - -#[derive(Copy)] -struct DummyCircuit { - pub a: Option, - pub b: Option, - pub num_variables: usize, - pub num_constraints: usize, -} - -impl Clone for DummyCircuit { - fn clone(&self) -> Self { - DummyCircuit { - a: self.a.clone(), - b: self.b.clone(), - num_variables: self.num_variables.clone(), - num_constraints: self.num_constraints.clone(), - } - } -} - -impl ConstraintSynthesizer for DummyCircuit { - fn generate_constraints(self, cs: ConstraintSystemRef) -> Result<(), SynthesisError> { - let a = cs.new_witness_variable(|| self.a.ok_or(SynthesisError::AssignmentMissing))?; - let b = cs.new_witness_variable(|| self.b.ok_or(SynthesisError::AssignmentMissing))?; - let c = cs.new_input_variable(|| { - let a = self.a.ok_or(SynthesisError::AssignmentMissing)?; - let b = self.b.ok_or(SynthesisError::AssignmentMissing)?; - - Ok(a * b) - })?; - - for _ in 0..(self.num_variables - 3) { - let _ = cs.new_witness_variable(|| self.a.ok_or(SynthesisError::AssignmentMissing))?; - } - - for _ in 0..self.num_constraints - 1 { - cs.enforce_constraint(lc!() + a, lc!() + b, lc!() + c)?; - } - - cs.enforce_constraint(lc!(), lc!(), lc!())?; - - Ok(()) - } -} - -macro_rules! marlin_prove_bench { - ($bench_name:ident, $bench_field:ty, $bench_pairing_engine:ty) => { - let rng = &mut ark_std::test_rng(); - let c = DummyCircuit::<$bench_field> { - a: Some(<$bench_field>::rand(rng)), - b: Some(<$bench_field>::rand(rng)), - num_variables: 10, - num_constraints: 65536, - }; - - let srs = Marlin::< - $bench_field, - MarlinKZG10<$bench_pairing_engine, DensePolynomial<$bench_field>>, - Blake2s, - >::universal_setup(65536, 65536, 65536, rng) - .unwrap(); - let (pk, _) = Marlin::< - $bench_field, - MarlinKZG10<$bench_pairing_engine, DensePolynomial<$bench_field>>, - Blake2s, - >::index(&srs, c) - .unwrap(); - - let start = ark_std::time::Instant::now(); - - for _ in 0..NUM_PROVE_REPEATITIONS { - let _ = Marlin::< - $bench_field, - MarlinKZG10<$bench_pairing_engine, DensePolynomial<$bench_field>>, - Blake2s, - >::prove(&pk, c.clone(), rng) - .unwrap(); - } - - println!( - "per-constraint proving time for {}: {} ns/constraint", - stringify!($bench_pairing_engine), - start.elapsed().as_nanos() / NUM_PROVE_REPEATITIONS as u128 / 65536u128 - ); - }; -} - -macro_rules! marlin_verify_bench { - ($bench_name:ident, $bench_field:ty, $bench_pairing_engine:ty) => { - let rng = &mut ark_std::test_rng(); - let c = DummyCircuit::<$bench_field> { - a: Some(<$bench_field>::rand(rng)), - b: Some(<$bench_field>::rand(rng)), - num_variables: 10, - num_constraints: 65536, - }; - - let srs = Marlin::< - $bench_field, - MarlinKZG10<$bench_pairing_engine, DensePolynomial<$bench_field>>, - Blake2s, - >::universal_setup(65536, 65536, 65536, rng) - .unwrap(); - let (pk, vk) = Marlin::< - $bench_field, - MarlinKZG10<$bench_pairing_engine, DensePolynomial<$bench_field>>, - Blake2s, - >::index(&srs, c) - .unwrap(); - let proof = Marlin::< - $bench_field, - MarlinKZG10<$bench_pairing_engine, DensePolynomial<$bench_field>>, - Blake2s, - >::prove(&pk, c.clone(), rng) - .unwrap(); - - let v = c.a.unwrap().mul(c.b.unwrap()); - - let start = ark_std::time::Instant::now(); - - for _ in 0..NUM_VERIFY_REPEATITIONS { - let _ = Marlin::< - $bench_field, - MarlinKZG10<$bench_pairing_engine, DensePolynomial<$bench_field>>, - Blake2s, - >::verify(&vk, &vec![v], &proof, rng) - .unwrap(); - } - - println!( - "verifying time for {}: {} ns", - stringify!($bench_pairing_engine), - start.elapsed().as_nanos() / NUM_VERIFY_REPEATITIONS as u128 - ); - }; -} - -fn bench_prove() { - marlin_prove_bench!(bls, BlsFr, Bls12_381); - marlin_prove_bench!(mnt4, MNT4Fr, MNT4_298); - marlin_prove_bench!(mnt6, MNT6Fr, MNT6_298); - marlin_prove_bench!(mnt4big, MNT4BigFr, MNT4_753); - marlin_prove_bench!(mnt6big, MNT6BigFr, MNT6_753); -} - -fn bench_verify() { - marlin_verify_bench!(bls, BlsFr, Bls12_381); - marlin_verify_bench!(mnt4, MNT4Fr, MNT4_298); - marlin_verify_bench!(mnt6, MNT6Fr, MNT6_298); - marlin_verify_bench!(mnt4big, MNT4BigFr, MNT4_753); - marlin_verify_bench!(mnt6big, MNT6BigFr, MNT6_753); -} - -fn main() { - bench_prove(); - bench_verify(); -} diff --git a/prover/marlin/diagram/.gitignore b/prover/marlin/diagram/.gitignore deleted file mode 100644 index 834c4a22..00000000 --- a/prover/marlin/diagram/.gitignore +++ /dev/null @@ -1 +0,0 @@ -latex.out diff --git a/prover/marlin/diagram/diagram.pdf b/prover/marlin/diagram/diagram.pdf deleted file mode 100644 index ffee934c..00000000 Binary files a/prover/marlin/diagram/diagram.pdf and /dev/null differ diff --git a/prover/marlin/diagram/diagram.tex b/prover/marlin/diagram/diagram.tex deleted file mode 100644 index 30599367..00000000 --- a/prover/marlin/diagram/diagram.tex +++ /dev/null @@ -1,269 +0,0 @@ -\documentclass{article} -\usepackage[utf8]{inputenc} -\usepackage{amsmath} -\usepackage{amsfonts} - -\title{Marlin Diagram} -\date{July 2020} - -\usepackage[x11names]{xcolor} -\usepackage[b4paper,margin=1.2in]{geometry} -\usepackage{tikz} -\usepackage{afterpage} - -\newenvironment{rcases} - {\left.\begin{aligned}} - {\end{aligned}\right\rbrace} - -\begin{document} - -\newcommand{\cm}[1]{\ensuremath{\mathsf{cm}_{#1}}} -\newcommand{\vcm}[1]{\ensuremath{\mathsf{vcm}_{#1}}} -\newcommand{\s}{\ensuremath{\hat{s}}} -\newcommand{\w}{\ensuremath{\hat{w}}} -\newcommand{\x}{\ensuremath{\hat{x}}} -\newcommand{\z}{\ensuremath{\hat{z}}} -\newcommand{\za}{\ensuremath{\hat{z}_A}} -\newcommand{\zb}{\ensuremath{\hat{z}_B}} -\newcommand{\zc}{\ensuremath{\hat{z}_C -}} -\newcommand{\zm}{\ensuremath{\hat{z}_M}} - -\newcommand{\val}{\ensuremath{\mathsf{val}}} -\newcommand{\row}{\ensuremath{\mathsf{row}}} -\newcommand{\col}{\ensuremath{\mathsf{col}}} -\newcommand{\rowcol}{\ensuremath{\mathsf{rowcol}}} - -\newcommand{\hval}{\ensuremath{\widehat{\val}}} -\newcommand{\hrow}{\ensuremath{\widehat{\row}}} -\newcommand{\hcol}{\ensuremath{\widehat{\col}}} -\newcommand{\hrowcol}{\ensuremath{\widehat{\rowcol}}} - -\newcommand{\bb}{\ensuremath{\mathsf{b}}} -\newcommand{\denom}{\ensuremath{\mathsf{denom}}} - -\newcommand{\sumcheckinner}{\mathsf{sumcheck} -_{\mathsf{inner}}} -\newcommand{\sumcheckouter}{\mathsf{sumcheck}_{\mathsf{outer}}} - -\newcommand{\Prover}{\mathcal{P}} -\newcommand{\Verifier}{\mathcal{V}} - -\newcommand{\F}{\mathbb{F}} - -\newcommand{\DomainA}{H} -\newcommand{\DomainB}{K} - -\newcommand{\vPoly}[1]{\ensuremath{v_{#1}}} - - -This diagram (on the following page) shows the interaction of the Marlin prover and verifier. It is similar to the diagrams in the paper (Figure 5 in Section 5 and Figure 7 in Appendix E, in the latest ePrint version), but with two changes: it shows not just the AHP but also the use of the polynomial commitments (the cryptography layer); and it aims to be fully up-to-date with the recent optimizations to the codebase. This diagram, together with the diagrams in the paper, can act as a ``bridge" between the codebase and the theory that the paper describes. - -\section{Glossary of notation} -\begin{table*}[htbp] - \centering - \begin{tabular}{c|c} - $\F$ & the finite field over which the R1CS instance is defined \\ - \hline - $x$ & public input \\ - \hline - $w$ & secret witness \\ - \hline - $\DomainA$ & variable domain \\ - \hline - $\DomainB$ & matrix domain \\ - \hline - $X$ & domain sized for input (not including witness) \\ - \hline - $v_D(X)$ & vanishing polynomial over domain $D$ \\ - \hline - $u_D(X, Y)$ & bivariate derivative of vanishing polynomials over domain $D$\\ - \hline - $A, B, C$ & R1CS instance matrices \\ - \hline - $A^*, B^*, C^*$ & - \begin{tabular}{@{}c@{}}shifted transpose of $A,B,C$ matries given by $M^*_{a,b} := M_{b,a} \cdot u_\DomainA(b,b) \; \forall a,b \in \DomainA$ \\ (optimization from Fractal, explained in Claim 6.7 of that paper) \end{tabular} \\ - \hline - $\{\hval, \hrow, \hcol\}_{\{A^*,B^*,C^*\}}$ & - \begin{tabular}{@{}c@{}} preprocessed polynomials from $A^*, B^*, C^*$ matrices containing LDEs of (respectively) \\ row positions, column positions, and values of non-zero matrix elements \end{tabular} \\ - \hline - $\hrowcol_{\{A^*, B^*, C^*\}}$ & - \begin{tabular}{@{}c@{}} the product polynomial of $\hrow$ and $\hcol$, given separately for efficiency (namely \\ to allow this product to be part of a \textit{linear} combination) \end{tabular} \\ - \hline - $\Prover$ & prover \\ - \hline - $\Verifier$ & verifier \\ - \hline - $\Verifier^{p}$ & - \begin{tabular}{@{}c@{}} $\Verifier$ with ``oracle" access to polynomial $p$ (via commitments provided \\ by the indexer, later opened as necessary by $\Prover$) \end{tabular}\\ - \hline - $\bb$ & bound on the number of queries \\ - \hline - $r_M(X, Y)$ & an intermediate polynomial defined by $r_M(X, Y) = M^*(Y,X)$\\ - \hline - \end{tabular} -\end{table*} - -\afterpage{% -\newgeometry{margin=0.5in} - -\section{Diagram} - -\centering -\begin{tikzpicture}[scale=0.9, every node/.style={scale=0.9}] - -\tikzstyle{lalign} = [minimum width=3cm,align=left,anchor=west] -\tikzstyle{ralign} = [minimum width=3cm,align=right,anchor=east] - -\node[lalign] (prover) at (-3,27.3) {% -$\Prover(\F, \DomainA, \DomainB, A, B, C, x, w)$ -}; - -\node[ralign] (verifier) at (16.2,27.3) {% -$\Verifier^{\{\hval, \hrow, \hcol, \hrowcol\}_{\{A^*, B^*, C^*\}}}(\F, \DomainA, \DomainB, x)$ -}; - -\draw [line width=1.0pt] (-3,27.0) -- (16,27.0); - -\node[lalign] (prover1) at (-3,26.1) {% -$z := (x, w), z_A := Az, z_B := Bz$ \\ -sample $\w(X) \in \F^{<|w|+\bb}[X]$ and $\za(X), \zb(X) \in \F^{<|\DomainA|+\bb}[X]$ \\ -sample mask poly $\s(X) \in \F^{<3|\DomainA|+2\bb-2}[X]$ such that $\sum_{\kappa \in \DomainA}\s(\kappa) = 0$ -}; - -\draw [->] (-2,24.8) -- node[midway,fill=white] {commitments $\cm{\w}, \cm{\za}, \cm{\zb}, \cm{\s}$} (15,24.8); - -\node[ralign] (verifier1) at (16,24.0) {% -$\eta_A, \eta_B, \eta_C \gets \F$ \\ -$\alpha \gets \F \setminus \DomainA$ -}; - -\draw [->] (15,23.3) -- node[midway,fill=white] {$\eta_A, \eta_B, \eta_C, \alpha \in \F$} (-2,23.3); - -\node[lalign] (prover2) at (-3,22.5) {% -compute $t(X) := \sum_M \eta_M r_M(\alpha, X)$ -}; - -\draw (-2.9,22.0) rectangle (15.9,4.8); - -\node (sc1label) at (6.5,21.7) {% -\textbf{sumcheck for} $\s(X) + u_H(\alpha, X) \left(\sum_M \eta_M \zm(X)\right) - t(X)\z(X)$ \textbf{ over } $\DomainA$ -}; - -\node[lalign] (prover3) at (-2,20.7) {% -let $\zc(X) := \za(X) \cdot \zb(X)$ \\ -find $g_1(X) \in \F^{|\DomainA|-1}[X]$ and $h_1(X)$ such that \\ -$s(X)+u_H(\alpha, X)(\sum_M \eta_M \zm(X)) - t(X)\z(X) = h_1(X)\vPoly{\DomainA}(X) + Xg_1(X)$ \hspace{0.3cm} $(*)$ -}; - -\draw [->] (-1,19.5) -- node[midway,fill=white] {commitments $\cm{t}, \cm{g_1}, \cm{h_1}$} (14,19.5); - -\node[ralign] (verifier2) at (15.4,19.1) {% -$\beta \gets \F \setminus \DomainA$ -}; - -\draw [->] (14,18.7) -- node[midway,fill=white] {$\beta \in \F$} (-1,18.7); - -\draw (-0.85,18.2) rectangle (13.85,8.4); - -\node (sc2label) at (6.5,17.6) {% -\textbf{sumcheck for } $\sum\limits_{M \in \{A, B, C\}} \eta_M \frac{\vPoly{\DomainA}(\beta) \vPoly{\DomainA}(\alpha)\hval_{M^*}(X)}{\color{purple}(\beta-\hrow_{M^*}(X))(\alpha-\hcol_{M^*}(X))} $ \textbf{ over } $\DomainB$ -}; - -\node[align=center] (mid1) at (6.5, 16.3) {% -$\begin{aligned} -\text{for } M \in \{A, B, C\} \text{, let } {\color{purple} M_\denom(X)} &:= (\beta - \hrow_{M^*}(X)) (\alpha - \hcol_{M^*}(X)) \\ -&= {\color{gray}\alpha\beta} - {\color{gray}\alpha}\hrow_{M^*}(X) - {\color{gray}\beta}\hcol_{M^*}(X) + \hrowcol_{M^*}(X) -\end{aligned}$ -}; - -\node[align=center] (mid2) at (6.5, 15.0) {% -let ${\color{orange} a(X)} := \sum\limits_{M \in \{A, B, C\}} {\color{gray} \eta_M \vPoly{\DomainA}(\beta) \vPoly{\DomainA}(\alpha)} \hval_{M^*}(X) \prod_{N \neq M} {\color{purple} N_\denom(X)}$ -}; - -\node[align=center] (mid3) at (6.5, 14.1) {% -let ${\color{Green4} b(X)} := \prod\limits_{M \in \{A, B, C\}} {\color{purple} M_\denom(X)}$ -}; - -\node[lalign] (prover4) at (-0.75,13.2) {% -find $g_2(X) \in \F^{|\DomainB|-1}[X]$ and $h_2(X)$ s.t. \\ -$h_2(X)\vPoly{\DomainB}(X) = {\color{orange} a(X)} - {\color{Green4} b(X)} (Xg_2(X)+t(\beta)/|\DomainB|)$ \hspace{0.3cm} $(**)$ -}; - -\draw [->] (0,12.2) -- node[midway,fill=white] {commitments $\cm{g_2}, \cm{h_2}$} (13,12.2); - -\draw [->] (13,11.5) -- node[midway,fill=white] {$\gamma \in \F$} (0,11.5); - -\node[ralign] (verifier3) at (14.5, 11.9) {% -$\gamma \gets \F$ -}; - -\draw[dashed] (1.5,11.0) rectangle (11.5,8.8); - -\node[align=center] (mid4) at (6.5, 9.9) {% -To verify $(**)$, $\Verifier$ will need to check the following: \\[10pt] -$ \underbrace{{\color{orange} a({\color{black} \gamma})} - {\color{Green4} b({\color{black} \gamma})} {\color{gray} (\gamma g_2(\gamma) + t(\beta) / |\DomainB|) - \vPoly{\DomainB}(\gamma)} h_2(\gamma)}_{\sumcheckinner(\gamma)} \stackrel{?}{=} 0 $ -}; - -\node[ralign] (verifier3) at (15.4, 7.9) {% -Compute $\x(X) \in \F^{<|x|}[X]$ from input $x$ -}; - -\draw[dashed] (-2.7,7.4) rectangle (15.7,5.2); - -\node[align=center] (mid5) at (6.5, 6.3) {% -To verify $(*)$, $\Verifier$ will need to check the following: \\[10pt] -$ \underbrace{s(\beta) + {\color{gray} v_H(\alpha, \beta)} ({\color{gray} \eta_A} \za(\beta) + {\color{gray} \eta_C\zb(\beta)} \za(\beta) + {\color{gray} \eta_B\zb(\beta)}) - {\color{gray} t(\beta) \vPoly{X}(\beta)} \w(\beta) - {\color{gray} t(\beta) \x(\beta)} - {\color{gray} \vPoly{\DomainA}(\beta)} h_1(\beta) - {\color{gray} \beta g_1(\beta)}}_{\sumcheckouter(\beta)} \stackrel{?}{=} 0 $ -}; - -\node[lalign] (prover5) at (-3,3.9) {% -$v_{g_2} := g_2(\gamma), v_{A_\denom} := A_\denom(\gamma), v_{B_\denom} := B_\denom(\gamma), v_{C_\denom} := C_\denom(\gamma)$ \\[3pt] -$v_{g_1} := g_1(\beta), v_{\zb} := \zb(\beta), v_{t} := t(\beta)$ -}; - -\draw [->] (-2,2.9) -- node[midway,fill=white] {$v_{g_2}, v_{A_\denom}, v_{B_\denom}, v_{C_\denom}, v_{g_1}, v_{\zb}, v_{t}$} (15,2.9); - -\node[align=center] (mid6) at (6.5,1.9) {% -use index commitments $\hrow, \hcol, \hrowcol$ to construct virtual commitments $\vcm{\{A_\denom, B_\denom, C_\denom\}}$ -}; - -\node[align=center] (mid7) at (6.5,0.8) {% -use index commitments $\hval$, commitments $\vcm{A_\denom}$, $\vcm{B_\denom}, \vcm{C_\denom}, \cm{h_2}$, {\color{gray} and evaluations $g_2(\gamma),t(\beta)$} \\ -to construct virtual commitment $\vcm{\sumcheckinner}$ -}; - -\node[align=center] (mid8) at (6.5,-0.5) {% -use commitments $\cm{\s}, \cm{\za}, \cm{\w}, \cm{h_1}$ {\color{gray} and evaluations $\zb(\beta), t(\beta), g_1(\beta)$} \\ -to construct virtual commitment $\vcm{\sumcheckouter}$ -}; - -\node[ralign] (verifier4) at (16,-1.5) {% -$\xi_1, \dots, \xi_5 \gets \F$ -}; - -\draw [->] (15,-2.1) -- node[midway,fill=white] {$\xi_1, \dots, \xi_5$} (-2,-2.1); - -\node[lalign] (prover6) at (-3,-3.6) {% -use $\mathsf{PC}.\mathsf{Prove}$ with randomness $\xi_1, \dots, \xi_5$ to \\ -construct a batch opening proof $\pi$ of the following: \\ -$(\cm{g_2}, \cm{A_\denom}, \cm{B_\denom}, \cm{C_\denom}, {\color{red} \vcm{\sumcheckinner}})$ at $\gamma$ evaluate to $(v_{g_2}, v_{A_\denom}, v_{B_\denom}, v_{C_\denom}, {\color{red} 0})$ \hspace{0.3cm} ${\color{red} (**)}$ \\ -$(\cm{g_1}, \cm{\zb}, \cm{t}, {\color{red} \vcm{\sumcheckouter}})$ at $\beta$ evaluate to $(v_{g_1}, v_{\zb}, v_{t}, {\color{red} 0})$ \hspace{0.3cm} ${\color{red} (*)}$ \\ -}; - -\draw [->] (-2,-4.7) -- node[midway,fill=white] {$\pi$} (15,-4.7); - -\node[ralign] (verifier5) at (16,-6.0) {% -verify $\pi$ with $\mathsf{PC}.\mathsf{Verify}$, using randomness $\xi_1, \dots, \xi_5$, \\ -evaluations $v_{g_2}, v_{A_\denom}, v_{B_\denom}, v_{C_\denom}, v_{g_1}, v_{\zb}, v_{t}$, and \\ -commitments $\cm{g_2}, \cm{A_\denom}, \cm{B_\denom}, \cm{C_\denom},$ \\ -$\vcm{\sumcheckinner}, \cm{g_1}, \cm{\zb}, \cm{t}, \vcm{\sumcheckinner}$ -}; - -\end{tikzpicture} - -\clearpage -\restoregeometry -} - - -\end{document} diff --git a/prover/marlin/scripts/linkify_changelog.py b/prover/marlin/scripts/linkify_changelog.py deleted file mode 100644 index 867ae14d..00000000 --- a/prover/marlin/scripts/linkify_changelog.py +++ /dev/null @@ -1,31 +0,0 @@ -import re -import sys -import fileinput -import os - -# Set this to the name of the repo, if you don't want it to be read from the filesystem. -# It assumes the changelog file is in the root of the repo. -repo_name = "" - -# This script goes through the provided file, and replaces any " \#", -# with the valid mark down formatted link to it. e.g. -# " [\#number](https://github.com/arkworks-rs/template/pull/) -# Note that if the number is for a an issue, github will auto-redirect you when you click the link. -# It is safe to run the script multiple times in succession. -# -# Example usage $ python3 linkify_changelog.py ../CHANGELOG.md -if len(sys.argv) < 2: - print("Must include path to changelog as the first argument to the script") - print("Example Usage: python3 linkify_changelog.py ../CHANGELOG.md") - exit() - -changelog_path = sys.argv[1] -if repo_name == "": - path = os.path.abspath(changelog_path) - components = path.split(os.path.sep) - repo_name = components[-2] - -for line in fileinput.input(inplace=True): - line = re.sub(r"\- #([0-9]*)", r"- [\\#\1](https://github.com/arkworks-rs/" + repo_name + r"/pull/\1)", line.rstrip()) - # edits the current file - print(line) \ No newline at end of file diff --git a/prover/marlin/src/ahp/constraint_systems.rs b/prover/marlin/src/ahp/constraint_systems.rs deleted file mode 100644 index 0ff714e6..00000000 --- a/prover/marlin/src/ahp/constraint_systems.rs +++ /dev/null @@ -1,302 +0,0 @@ -#![allow(non_snake_case)] - -use crate::ahp::indexer::Matrix; -use crate::ahp::*; -use crate::{BTreeMap, ToString}; -use ark_ff::{Field, PrimeField}; -use ark_poly::{EvaluationDomain, Evaluations as EvaluationsOnDomain, GeneralEvaluationDomain}; -use ark_relations::{ - lc, - r1cs::{ConstraintMatrices, ConstraintSystemRef}, -}; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError}; -use ark_std::{ - cfg_iter_mut, - io::{Read, Write}, -}; -use derivative::Derivative; - -/* ************************************************************************* */ -/* ************************************************************************* */ -/* ************************************************************************* */ - -pub(crate) fn balance_matrices(a_matrix: &mut Matrix, b_matrix: &mut Matrix) { - let mut a_density: usize = a_matrix.iter().map(|row| row.len()).sum(); - let mut b_density: usize = b_matrix.iter().map(|row| row.len()).sum(); - let mut max_density = core::cmp::max(a_density, b_density); - let mut a_is_denser = a_density == max_density; - for (a_row, b_row) in a_matrix.iter_mut().zip(b_matrix) { - if a_is_denser { - let a_row_size = a_row.len(); - let b_row_size = b_row.len(); - core::mem::swap(a_row, b_row); - a_density = a_density - a_row_size + b_row_size; - b_density = b_density - b_row_size + a_row_size; - max_density = core::cmp::max(a_density, b_density); - a_is_denser = a_density == max_density; - } - } -} - -pub(crate) fn num_non_zero(matrices: &ConstraintMatrices) -> usize { - *[ - matrices.a_num_non_zero, - matrices.b_num_non_zero, - matrices.c_num_non_zero, - ] - .iter() - .max() - .unwrap() -} - -pub(crate) fn make_matrices_square_for_indexer(cs: ConstraintSystemRef) { - let num_variables = cs.num_instance_variables() + cs.num_witness_variables(); - let matrix_dim = padded_matrix_dim(num_variables, cs.num_constraints()); - make_matrices_square(cs.clone(), num_variables); - assert_eq!( - cs.num_instance_variables() + cs.num_witness_variables(), - cs.num_constraints(), - "padding failed!" - ); - assert_eq!( - cs.num_instance_variables() + cs.num_witness_variables(), - matrix_dim, - "padding does not result in expected matrix size!" - ); -} - -/// This must *always* be in sync with `make_matrices_square`. -pub(crate) fn padded_matrix_dim(num_formatted_variables: usize, num_constraints: usize) -> usize { - core::cmp::max(num_formatted_variables, num_constraints) -} - -pub(crate) fn pad_input_for_indexer_and_prover(cs: ConstraintSystemRef) { - let formatted_input_size = cs.num_instance_variables(); - - let domain_x = GeneralEvaluationDomain::::new(formatted_input_size); - assert!(domain_x.is_some()); - - let padded_size = domain_x.unwrap().size(); - - if padded_size > formatted_input_size { - for _ in 0..(padded_size - formatted_input_size) { - cs.new_input_variable(|| Ok(F::zero())).unwrap(); - } - } -} - -pub(crate) fn make_matrices_square( - cs: ConstraintSystemRef, - num_formatted_variables: usize, -) { - let num_constraints = cs.num_constraints(); - let matrix_padding = ((num_formatted_variables as isize) - (num_constraints as isize)).abs(); - - if num_formatted_variables > num_constraints { - // Add dummy constraints of the form 0 * 0 == 0 - for _ in 0..matrix_padding { - cs.enforce_constraint(lc!(), lc!(), lc!()) - .expect("enforce 0 * 0 == 0 failed"); - } - } else { - // Add dummy unconstrained variables - for _ in 0..matrix_padding { - let _ = cs - .new_witness_variable(|| Ok(F::one())) - .expect("alloc failed"); - } - } -} - -#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)] -#[derivative(Clone(bound = "F: PrimeField"))] -pub struct MatrixEvals { - /// Evaluations of the LDE of row. - pub row: EvaluationsOnDomain, - /// Evaluations of the LDE of col. - pub col: EvaluationsOnDomain, - /// Evaluations of the LDE of val. - pub val: EvaluationsOnDomain, -} - -/// Contains information about the arithmetization of the matrix M^*. -/// Here `M^*(i, j) := M(j, i) * u_H(j, j)`. For more details, see [COS19]. -#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)] -#[derivative(Clone(bound = "F: PrimeField"))] -pub struct MatrixArithmetization { - /// LDE of the row indices of M^*. - pub row: LabeledPolynomial, - /// LDE of the column indices of M^*. - pub col: LabeledPolynomial, - /// LDE of the non-zero entries of M^*. - pub val: LabeledPolynomial, - /// LDE of the vector containing entry-wise products of `row` and `col`, - /// where `row` and `col` are as above. - pub row_col: LabeledPolynomial, - - /// Evaluation of `self.row`, `self.col`, and `self.val` on the domain `K`. - pub evals_on_K: MatrixEvals, - - /// Evaluation of `self.row`, `self.col`, and, `self.val` on - /// an extended domain B (of size > `3K`). - // TODO: rename B everywhere. - pub evals_on_B: MatrixEvals, - - /// Evaluation of `self.row_col` on an extended domain B (of size > `3K`). - pub row_col_evals_on_B: EvaluationsOnDomain, -} - -// TODO for debugging: add test that checks result of arithmetize_matrix(M). -pub(crate) fn arithmetize_matrix( - matrix_name: &str, - matrix: &mut Matrix, - interpolation_domain: GeneralEvaluationDomain, - output_domain: GeneralEvaluationDomain, - input_domain: GeneralEvaluationDomain, - expanded_domain: GeneralEvaluationDomain, -) -> MatrixArithmetization { - let matrix_time = start_timer!(|| "Computing row, col, and val LDEs"); - - let elems: Vec<_> = output_domain.elements().collect(); - - let mut row_vec = Vec::new(); - let mut col_vec = Vec::new(); - let mut val_vec = Vec::new(); - - let eq_poly_vals_time = start_timer!(|| "Precomputing eq_poly_vals"); - let eq_poly_vals: BTreeMap = output_domain - .elements() - .zip(output_domain.batch_eval_unnormalized_bivariate_lagrange_poly_with_same_inputs()) - .collect(); - end_timer!(eq_poly_vals_time); - - let lde_evals_time = start_timer!(|| "Computing row, col and val evals"); - let mut inverses = Vec::new(); - - let mut count = 0; - - // Recall that we are computing the arithmetization of M^*, - // where `M^*(i, j) := M(j, i) * u_H(j, j)`. - for (r, row) in matrix.iter_mut().enumerate() { - if !is_in_ascending_order(row, |(_, a), (_, b)| a < b) { - row.sort_by(|(_, a), (_, b)| a.cmp(b)); - }; - - for &mut (val, i) in row { - let row_val = elems[r]; - let col_val = elems[output_domain.reindex_by_subdomain(input_domain, i)]; - - // We are dealing with the transpose of M - row_vec.push(col_val); - col_vec.push(row_val); - val_vec.push(val); - inverses.push(eq_poly_vals[&col_val]); - - count += 1; - } - } - ark_ff::batch_inversion::(&mut inverses); - - cfg_iter_mut!(val_vec) - .zip(inverses) - .for_each(|(v, inv)| *v *= &inv); - end_timer!(lde_evals_time); - - for _ in 0..(interpolation_domain.size() - count) { - col_vec.push(elems[0]); - row_vec.push(elems[0]); - val_vec.push(F::zero()); - } - let row_col_vec: Vec<_> = row_vec - .iter() - .zip(&col_vec) - .map(|(row, col)| *row * col) - .collect(); - - let interpolate_time = start_timer!(|| "Interpolating on K and B"); - let row_evals_on_K = EvaluationsOnDomain::from_vec_and_domain(row_vec, interpolation_domain); - let col_evals_on_K = EvaluationsOnDomain::from_vec_and_domain(col_vec, interpolation_domain); - let val_evals_on_K = EvaluationsOnDomain::from_vec_and_domain(val_vec, interpolation_domain); - let row_col_evals_on_K = - EvaluationsOnDomain::from_vec_and_domain(row_col_vec, interpolation_domain); - - let row = row_evals_on_K.clone().interpolate(); - let col = col_evals_on_K.clone().interpolate(); - let val = val_evals_on_K.clone().interpolate(); - let row_col = row_col_evals_on_K.interpolate(); - - let row_evals_on_B = - EvaluationsOnDomain::from_vec_and_domain(expanded_domain.fft(&row), expanded_domain); - let col_evals_on_B = - EvaluationsOnDomain::from_vec_and_domain(expanded_domain.fft(&col), expanded_domain); - let val_evals_on_B = - EvaluationsOnDomain::from_vec_and_domain(expanded_domain.fft(&val), expanded_domain); - let row_col_evals_on_B = - EvaluationsOnDomain::from_vec_and_domain(expanded_domain.fft(&row_col), expanded_domain); - end_timer!(interpolate_time); - - end_timer!(matrix_time); - let evals_on_K = MatrixEvals { - row: row_evals_on_K, - col: col_evals_on_K, - val: val_evals_on_K, - }; - let evals_on_B = MatrixEvals { - row: row_evals_on_B, - col: col_evals_on_B, - val: val_evals_on_B, - }; - - let m_name = matrix_name.to_string(); - MatrixArithmetization { - row: LabeledPolynomial::new(m_name.clone() + "_row", row, None, None), - col: LabeledPolynomial::new(m_name.clone() + "_col", col, None, None), - val: LabeledPolynomial::new(m_name.clone() + "_val", val, None, None), - row_col: LabeledPolynomial::new(m_name + "_row_col", row_col, None, None), - evals_on_K, - evals_on_B, - row_col_evals_on_B, - } -} - -fn is_in_ascending_order(x_s: &[T], is_less_than: impl Fn(&T, &T) -> bool) -> bool { - if x_s.is_empty() { - true - } else { - let mut i = 0; - let mut is_sorted = true; - while i < (x_s.len() - 1) { - is_sorted &= is_less_than(&x_s[i], &x_s[i + 1]); - i += 1; - } - is_sorted - } -} - -/* ************************************************************************* */ -/* ************************************************************************* */ -/* ************************************************************************* */ - -/// Formats the public input according to the requirements of the constraint -/// system -pub(crate) fn format_public_input(public_input: &[F]) -> Vec { - let mut input = vec![F::one()]; - input.extend_from_slice(public_input); - input -} - -/// Takes in a previously formatted public input and removes the formatting -/// imposed by the constraint system. -pub(crate) fn unformat_public_input(input: &[F]) -> Vec { - input[1..].to_vec() -} - -pub(crate) fn make_matrices_square_for_prover(cs: ConstraintSystemRef) { - let num_variables = cs.num_instance_variables() + cs.num_witness_variables(); - make_matrices_square(cs.clone(), num_variables); - assert_eq!( - cs.num_instance_variables() + cs.num_witness_variables(), - cs.num_constraints(), - "padding failed!" - ); -} diff --git a/prover/marlin/src/ahp/indexer.rs b/prover/marlin/src/ahp/indexer.rs deleted file mode 100644 index 442db91f..00000000 --- a/prover/marlin/src/ahp/indexer.rs +++ /dev/null @@ -1,209 +0,0 @@ -#![allow(non_snake_case)] - -use crate::ahp::{ - constraint_systems::{arithmetize_matrix, MatrixArithmetization}, - AHPForR1CS, Error, LabeledPolynomial, -}; -use crate::Vec; -use ark_ff::PrimeField; -use ark_poly::{EvaluationDomain, GeneralEvaluationDomain}; -use ark_relations::r1cs::{ - ConstraintSynthesizer, ConstraintSystem, OptimizationGoal, SynthesisError, SynthesisMode, -}; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError}; -use ark_std::{ - io::{Read, Write}, - marker::PhantomData, -}; -use derivative::Derivative; - -use crate::ahp::constraint_systems::{ - balance_matrices, make_matrices_square_for_indexer, num_non_zero, - pad_input_for_indexer_and_prover, -}; - -/// Information about the index, including the field of definition, the number of -/// variables, the number of constraints, and the maximum number of non-zero -/// entries in any of the constraint matrices. -#[derive(Derivative, CanonicalSerialize, CanonicalDeserialize)] -#[derivative(Clone(bound = ""), Copy(bound = ""))] -pub struct IndexInfo { - /// The total number of variables in the constraint system. - pub num_variables: usize, - /// The number of constraints. - pub num_constraints: usize, - /// The maximum number of non-zero entries in any constraint matrix. - pub num_non_zero: usize, - /// The number of input elements. - pub num_instance_variables: usize, - - #[doc(hidden)] - f: PhantomData, -} - -impl ark_ff::ToBytes for IndexInfo { - fn write(&self, mut w: W) -> ark_std::io::Result<()> { - (self.num_variables as u64).write(&mut w)?; - (self.num_constraints as u64).write(&mut w)?; - (self.num_non_zero as u64).write(&mut w) - } -} - -impl IndexInfo { - /// The maximum degree of polynomial required to represent this index in the - /// the AHP. - pub fn max_degree(&self) -> usize { - AHPForR1CS::::max_degree(self.num_constraints, self.num_variables, self.num_non_zero) - .unwrap() - } -} - -/// Represents a matrix. -pub type Matrix = Vec>; - -#[derive(Derivative)] -#[derivative(Clone(bound = "F: PrimeField"))] -/// The indexed version of the constraint system. -/// This struct contains three kinds of objects: -/// 1) `index_info` is information about the index, such as the size of the -/// public input -/// 2) `{a,b,c}` are the matrices defining the R1CS instance -/// 3) `{a,b,c}_star_arith` are structs containing information about A^*, B^*, and C^*, -/// which are matrices defined as `M^*(i, j) = M(j, i) * u_H(j, j)`. -#[derive(CanonicalSerialize, CanonicalDeserialize)] -pub struct Index { - /// Information about the index. - pub index_info: IndexInfo, - - /// The A matrix for the R1CS instance - pub a: Matrix, - /// The B matrix for the R1CS instance - pub b: Matrix, - /// The C matrix for the R1CS instance - pub c: Matrix, - - /// Arithmetization of the A* matrix. - pub a_star_arith: MatrixArithmetization, - /// Arithmetization of the B* matrix. - pub b_star_arith: MatrixArithmetization, - /// Arithmetization of the C* matrix. - pub c_star_arith: MatrixArithmetization, -} - -impl Index { - /// The maximum degree required to represent polynomials of this index. - pub fn max_degree(&self) -> usize { - self.index_info.max_degree() - } - - /// Iterate over the indexed polynomials. - pub fn iter(&self) -> impl Iterator> { - ark_std::vec![ - &self.a_star_arith.row, - &self.a_star_arith.col, - &self.a_star_arith.val, - &self.a_star_arith.row_col, - &self.b_star_arith.row, - &self.b_star_arith.col, - &self.b_star_arith.val, - &self.b_star_arith.row_col, - &self.c_star_arith.row, - &self.c_star_arith.col, - &self.c_star_arith.val, - &self.c_star_arith.row_col, - ] - .into_iter() - } -} - -impl AHPForR1CS { - /// Generate the index for this constraint system. - pub fn index>(c: C) -> Result, Error> { - let index_time = start_timer!(|| "AHP::Index"); - - let constraint_time = start_timer!(|| "Generating constraints"); - let ics = ConstraintSystem::new_ref(); - ics.set_optimization_goal(OptimizationGoal::Weight); - ics.set_mode(SynthesisMode::Setup); - c.generate_constraints(ics.clone())?; - end_timer!(constraint_time); - - let padding_time = start_timer!(|| "Padding matrices to make them square"); - pad_input_for_indexer_and_prover(ics.clone()); - end_timer!(padding_time); - let matrix_processing_time = start_timer!(|| "Processing matrices"); - ics.finalize(); - make_matrices_square_for_indexer(ics.clone()); - let matrices = ics.to_matrices().expect("should not be `None`"); - let num_non_zero_val = num_non_zero::(&matrices); - let (mut a, mut b, mut c) = (matrices.a, matrices.b, matrices.c); - balance_matrices(&mut a, &mut b); - end_timer!(matrix_processing_time); - - let (num_formatted_input_variables, num_witness_variables, num_constraints, num_non_zero) = ( - ics.num_instance_variables(), - ics.num_witness_variables(), - ics.num_constraints(), - num_non_zero_val, - ); - let num_variables = num_formatted_input_variables + num_witness_variables; - - if num_constraints != num_formatted_input_variables + num_witness_variables { - eprintln!( - "number of (formatted) input_variables: {}", - num_formatted_input_variables - ); - eprintln!("number of witness_variables: {}", num_witness_variables); - eprintln!("number of num_constraints: {}", num_constraints); - eprintln!("number of num_non_zero: {}", num_non_zero); - return Err(Error::NonSquareMatrix); - } - - if !Self::num_formatted_public_inputs_is_admissible(num_formatted_input_variables) { - return Err(Error::InvalidPublicInputLength); - } - - let index_info = IndexInfo { - num_variables, - num_constraints, - num_non_zero, - num_instance_variables: num_formatted_input_variables, - - f: PhantomData, - }; - - let domain_h = GeneralEvaluationDomain::new(num_constraints) - .ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - let domain_k = GeneralEvaluationDomain::new(num_non_zero) - .ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - let x_domain = GeneralEvaluationDomain::::new(num_formatted_input_variables) - .ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - let b_domain = GeneralEvaluationDomain::::new(3 * domain_k.size() - 3) - .ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - - let a_arithmetization_time = start_timer!(|| "Arithmetizing A"); - let a_star_arith = arithmetize_matrix("a", &mut a, domain_k, domain_h, x_domain, b_domain); - end_timer!(a_arithmetization_time); - - let b_arithmetization_time = start_timer!(|| "Arithmetizing B"); - let b_star_arith = arithmetize_matrix("b", &mut b, domain_k, domain_h, x_domain, b_domain); - end_timer!(b_arithmetization_time); - - let c_arithmetization_time = start_timer!(|| "Arithmetizing C"); - let c_star_arith = arithmetize_matrix("c", &mut c, domain_k, domain_h, x_domain, b_domain); - end_timer!(c_arithmetization_time); - - end_timer!(index_time); - Ok(Index { - index_info, - - a, - b, - c, - - a_star_arith, - b_star_arith, - c_star_arith, - }) - } -} diff --git a/prover/marlin/src/ahp/mod.rs b/prover/marlin/src/ahp/mod.rs deleted file mode 100644 index 81acce35..00000000 --- a/prover/marlin/src/ahp/mod.rs +++ /dev/null @@ -1,492 +0,0 @@ -use crate::{String, ToString, Vec}; -use ark_ff::{Field, PrimeField}; -use ark_poly::univariate::DensePolynomial; -use ark_poly::{EvaluationDomain, GeneralEvaluationDomain}; -use ark_poly_commit::{LCTerm, LinearCombination}; -use ark_relations::r1cs::SynthesisError; -use ark_std::{borrow::Borrow, cfg_iter_mut, format, marker::PhantomData, vec}; - -#[cfg(feature = "parallel")] -use rayon::prelude::*; - -pub(crate) mod constraint_systems; -/// Describes data structures and the algorithms used by the AHP indexer. -pub mod indexer; -/// Describes data structures and the algorithms used by the AHP prover. -pub mod prover; -/// Describes data structures and the algorithms used by the AHP verifier. -pub mod verifier; - -/// A labeled DensePolynomial with coefficients over `F` -pub type LabeledPolynomial = ark_poly_commit::LabeledPolynomial>; - -/// The algebraic holographic proof defined in [CHMMVW19](https://eprint.iacr.org/2019/1047). -/// Currently, this AHP only supports inputs of size one -/// less than a power of 2 (i.e., of the form 2^n - 1). -pub struct AHPForR1CS { - field: PhantomData, -} - -impl AHPForR1CS { - /// The labels for the polynomials output by the AHP indexer. - #[rustfmt::skip] - pub const INDEXER_POLYNOMIALS: [&'static str; 12] = [ - // Polynomials for A - "a_row", "a_col", "a_val", "a_row_col", - // Polynomials for B - "b_row", "b_col", "b_val", "b_row_col", - // Polynomials for C - "c_row", "c_col", "c_val", "c_row_col", - ]; - - /// The labels for the polynomials output by the AHP prover. - #[rustfmt::skip] - pub const PROVER_POLYNOMIALS: [&'static str; 9] = [ - // First sumcheck - "w", "z_a", "z_b", "mask_poly", "t", "g_1", "h_1", - // Second sumcheck - "g_2", "h_2", - ]; - - /// THe linear combinations that are statically known to evaluate to zero. - pub const LC_WITH_ZERO_EVAL: [&'static str; 2] = ["inner_sumcheck", "outer_sumcheck"]; - - pub(crate) fn polynomial_labels() -> impl Iterator { - Self::INDEXER_POLYNOMIALS - .iter() - .chain(&Self::PROVER_POLYNOMIALS) - .map(|s| s.to_string()) - } - - /// Check that the (formatted) public input is of the form 2^n for some integer n. - pub fn num_formatted_public_inputs_is_admissible(num_inputs: usize) -> bool { - num_inputs.count_ones() == 1 - } - - /// Check that the (formatted) public input is of the form 2^n for some integer n. - pub fn formatted_public_input_is_admissible(input: &[F]) -> bool { - Self::num_formatted_public_inputs_is_admissible(input.len()) - } - - /// The maximum degree of polynomials produced by the indexer and prover - /// of this protocol. - /// The number of the variables must include the "one" variable. That is, it - /// must be with respect to the number of formatted public inputs. - pub fn max_degree( - num_constraints: usize, - num_variables: usize, - num_non_zero: usize, - ) -> Result { - let padded_matrix_dim = - constraint_systems::padded_matrix_dim(num_variables, num_constraints); - let zk_bound = 1; - let domain_h_size = GeneralEvaluationDomain::::compute_size_of_domain(padded_matrix_dim) - .ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - let domain_k_size = GeneralEvaluationDomain::::compute_size_of_domain(num_non_zero) - .ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - Ok(*[ - 2 * domain_h_size + zk_bound - 2, - 3 * domain_h_size + 2 * zk_bound - 3, // mask_poly - domain_h_size, - domain_h_size, - 3 * domain_k_size - 3, - ] - .iter() - .max() - .unwrap()) - } - - /// Get all the strict degree bounds enforced in the AHP. - pub fn get_degree_bounds(info: &indexer::IndexInfo) -> [usize; 2] { - let mut degree_bounds = [0usize; 2]; - let num_constraints = info.num_constraints; - let num_non_zero = info.num_non_zero; - let h_size = GeneralEvaluationDomain::::compute_size_of_domain(num_constraints).unwrap(); - let k_size = GeneralEvaluationDomain::::compute_size_of_domain(num_non_zero).unwrap(); - - degree_bounds[0] = h_size - 2; - degree_bounds[1] = k_size - 2; - degree_bounds - } - - /// Construct the linear combinations that are checked by the AHP. - #[allow(non_snake_case)] - pub fn construct_linear_combinations( - public_input: &[F], - evals: &E, - state: &verifier::VerifierState, - ) -> Result>, Error> - where - E: EvaluationsProvider, - { - let domain_h = state.domain_h; - let domain_k = state.domain_k; - let k_size = domain_k.size_as_field_element(); - - let public_input = constraint_systems::format_public_input(public_input); - if !Self::formatted_public_input_is_admissible(&public_input) { - return Err(Error::InvalidPublicInputLength); - } - let x_domain = GeneralEvaluationDomain::new(public_input.len()) - .ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - - let first_round_msg = state.first_round_msg.unwrap(); - let alpha = first_round_msg.alpha; - let eta_a = first_round_msg.eta_a; - let eta_b = first_round_msg.eta_b; - let eta_c = first_round_msg.eta_c; - - let beta = state.second_round_msg.unwrap().beta; - let gamma = state.gamma.unwrap(); - - let mut linear_combinations = Vec::new(); - - // Outer sumcheck: - let z_b = LinearCombination::new("z_b", vec![(F::one(), "z_b")]); - let g_1 = LinearCombination::new("g_1", vec![(F::one(), "g_1")]); - let t = LinearCombination::new("t", vec![(F::one(), "t")]); - - let r_alpha_at_beta = domain_h.eval_unnormalized_bivariate_lagrange_poly(alpha, beta); - let v_H_at_alpha = domain_h.evaluate_vanishing_polynomial(alpha); - let v_H_at_beta = domain_h.evaluate_vanishing_polynomial(beta); - let v_X_at_beta = x_domain.evaluate_vanishing_polynomial(beta); - - let z_b_at_beta = evals.get_lc_eval(&z_b, beta)?; - let t_at_beta = evals.get_lc_eval(&t, beta)?; - let g_1_at_beta = evals.get_lc_eval(&g_1, beta)?; - - let x_at_beta = x_domain - .evaluate_all_lagrange_coefficients(beta) - .into_iter() - .zip(public_input) - .map(|(l, x)| l * x) - .fold(F::zero(), |x, y| x + y); - - #[rustfmt::skip] - let outer_sumcheck = LinearCombination::new( - "outer_sumcheck", - vec![ - (F::one(), "mask_poly".into()), - - (r_alpha_at_beta * (eta_a + eta_c * z_b_at_beta), "z_a".into()), - (r_alpha_at_beta * eta_b * z_b_at_beta, LCTerm::One), - - (-t_at_beta * v_X_at_beta, "w".into()), - (-t_at_beta * x_at_beta, LCTerm::One), - - (-v_H_at_beta, "h_1".into()), - (-beta * g_1_at_beta, LCTerm::One), - ], - ); - let res = evals.get_lc_eval(&outer_sumcheck, beta).unwrap(); - debug_assert!(res.is_zero()); - - linear_combinations.push(z_b); - linear_combinations.push(g_1); - linear_combinations.push(t); - linear_combinations.push(outer_sumcheck); - - // Inner sumcheck: - let beta_alpha = beta * alpha; - let g_2 = LinearCombination::new("g_2", vec![(F::one(), "g_2")]); - - let a_denom = LinearCombination::new( - "a_denom", - vec![ - (beta_alpha, LCTerm::One), - (-alpha, "a_row".into()), - (-beta, "a_col".into()), - (F::one(), "a_row_col".into()), - ], - ); - - let b_denom = LinearCombination::new( - "b_denom", - vec![ - (beta_alpha, LCTerm::One), - (-alpha, "b_row".into()), - (-beta, "b_col".into()), - (F::one(), "b_row_col".into()), - ], - ); - - let c_denom = LinearCombination::new( - "c_denom", - vec![ - (beta_alpha, LCTerm::One), - (-alpha, "c_row".into()), - (-beta, "c_col".into()), - (F::one(), "c_row_col".into()), - ], - ); - - let a_denom_at_gamma = evals.get_lc_eval(&a_denom, gamma)?; - let b_denom_at_gamma = evals.get_lc_eval(&b_denom, gamma)?; - let c_denom_at_gamma = evals.get_lc_eval(&c_denom, gamma)?; - let g_2_at_gamma = evals.get_lc_eval(&g_2, gamma)?; - - let v_K_at_gamma = domain_k.evaluate_vanishing_polynomial(gamma); - - let mut a = LinearCombination::new( - "a_poly", - vec![ - (eta_a * b_denom_at_gamma * c_denom_at_gamma, "a_val"), - (eta_b * a_denom_at_gamma * c_denom_at_gamma, "b_val"), - (eta_c * b_denom_at_gamma * a_denom_at_gamma, "c_val"), - ], - ); - - a *= v_H_at_alpha * v_H_at_beta; - let b_at_gamma = a_denom_at_gamma * b_denom_at_gamma * c_denom_at_gamma; - let b_expr_at_gamma = b_at_gamma * (gamma * g_2_at_gamma + (t_at_beta / k_size)); - - a -= &LinearCombination::new("b_expr", vec![(b_expr_at_gamma, LCTerm::One)]); - a -= &LinearCombination::new("h_2", vec![(v_K_at_gamma, "h_2")]); - - a.label = "inner_sumcheck".into(); - let inner_sumcheck = a; - debug_assert!(evals.get_lc_eval(&inner_sumcheck, gamma)?.is_zero()); - - linear_combinations.push(g_2); - linear_combinations.push(a_denom); - linear_combinations.push(b_denom); - linear_combinations.push(c_denom); - linear_combinations.push(inner_sumcheck); - - linear_combinations.sort_by(|a, b| a.label.cmp(&b.label)); - Ok(linear_combinations) - } -} - -/// Abstraction that provides evaluations of (linear combinations of) polynomials -/// -/// Intended to provide a common interface for both the prover and the verifier -/// when constructing linear combinations via `AHPForR1CS::construct_linear_combinations`. -pub trait EvaluationsProvider { - /// Get the evaluation of linear combination `lc` at `point`. - fn get_lc_eval(&self, lc: &LinearCombination, point: F) -> Result; -} - -impl EvaluationsProvider for ark_poly_commit::Evaluations { - fn get_lc_eval(&self, lc: &LinearCombination, point: F) -> Result { - let key = (lc.label.clone(), point); - self.get(&key) - .copied() - .ok_or(Error::MissingEval(lc.label.clone())) - } -} - -impl>> EvaluationsProvider for Vec { - fn get_lc_eval(&self, lc: &LinearCombination, point: F) -> Result { - let mut eval = F::zero(); - for (coeff, term) in lc.iter() { - let value = if let LCTerm::PolyLabel(label) = term { - self.iter() - .find(|p| { - let p: &LabeledPolynomial = (*p).borrow(); - p.label() == label - }) - .ok_or(Error::MissingEval(format!( - "Missing {} for {}", - label, lc.label - )))? - .borrow() - .evaluate(&point) - } else { - assert!(term.is_one()); - F::one() - }; - eval += *coeff * value - } - Ok(eval) - } -} - -/// Describes the failure modes of the AHP scheme. -#[derive(Debug)] -pub enum Error { - /// During verification, a required evaluation is missing - MissingEval(String), - /// The number of public inputs is incorrect. - InvalidPublicInputLength, - /// The instance generated during proving does not match that in the index. - InstanceDoesNotMatchIndex, - /// Currently we only support square constraint matrices. - NonSquareMatrix, - /// An error occurred during constraint generation. - ConstraintSystemError(SynthesisError), -} - -impl From for Error { - fn from(other: SynthesisError) -> Self { - Error::ConstraintSystemError(other) - } -} - -/// The derivative of the vanishing polynomial -pub trait UnnormalizedBivariateLagrangePoly { - /// Evaluate the polynomial - fn eval_unnormalized_bivariate_lagrange_poly(&self, x: F, y: F) -> F; - - /// Evaluate over a batch of inputs - fn batch_eval_unnormalized_bivariate_lagrange_poly_with_diff_inputs(&self, x: F) -> Vec; - - /// Evaluate the magic polynomial over `self` - fn batch_eval_unnormalized_bivariate_lagrange_poly_with_same_inputs(&self) -> Vec; -} - -impl UnnormalizedBivariateLagrangePoly for GeneralEvaluationDomain { - fn eval_unnormalized_bivariate_lagrange_poly(&self, x: F, y: F) -> F { - if x != y { - (self.evaluate_vanishing_polynomial(x) - self.evaluate_vanishing_polynomial(y)) - / (x - y) - } else { - self.size_as_field_element() * x.pow([(self.size() - 1) as u64]) - } - } - - fn batch_eval_unnormalized_bivariate_lagrange_poly_with_diff_inputs(&self, x: F) -> Vec { - let vanish_x = self.evaluate_vanishing_polynomial(x); - let mut inverses: Vec = self.elements().map(|y| x - y).collect(); - ark_ff::batch_inversion(&mut inverses); - - cfg_iter_mut!(inverses).for_each(|denominator| *denominator *= vanish_x); - inverses - } - - fn batch_eval_unnormalized_bivariate_lagrange_poly_with_same_inputs(&self) -> Vec { - let mut elems: Vec = self - .elements() - .map(|e| e * self.size_as_field_element()) - .collect(); - elems[1..].reverse(); - elems - } -} - -#[cfg(test)] -mod tests { - use super::*; - use ark_bn254::Fr; - use ark_ff::{One, UniformRand, Zero}; - use ark_poly::{ - univariate::{DenseOrSparsePolynomial, DensePolynomial}, - Polynomial, UVPolynomial, - }; - - #[test] - fn domain_unnormalized_bivariate_lagrange_poly() { - for domain_size in 1..10 { - let domain = GeneralEvaluationDomain::::new(1 << domain_size).unwrap(); - let manual: Vec<_> = domain - .elements() - .map(|elem| domain.eval_unnormalized_bivariate_lagrange_poly(elem, elem)) - .collect(); - let fast = domain.batch_eval_unnormalized_bivariate_lagrange_poly_with_same_inputs(); - assert_eq!(fast, manual); - } - } - - #[test] - fn domain_unnormalized_bivariate_lagrange_poly_diff_inputs() { - let rng = &mut ark_std::test_rng(); - for domain_size in 1..10 { - let domain = GeneralEvaluationDomain::::new(1 << domain_size).unwrap(); - let x = Fr::rand(rng); - let manual: Vec<_> = domain - .elements() - .map(|y| domain.eval_unnormalized_bivariate_lagrange_poly(x, y)) - .collect(); - let fast = domain.batch_eval_unnormalized_bivariate_lagrange_poly_with_diff_inputs(x); - assert_eq!(fast, manual); - } - } - - #[test] - fn test_summation() { - let rng = &mut ark_std::test_rng(); - let size = 1 << 4; - let domain = GeneralEvaluationDomain::::new(1 << 4).unwrap(); - let size_as_fe = domain.size_as_field_element(); - let poly = DensePolynomial::rand(size, rng); - - let mut sum: Fr = Fr::zero(); - for eval in domain.elements().map(|e| poly.evaluate(&e)) { - sum += eval; - } - let first = poly.coeffs[0] * size_as_fe; - let last = *poly.coeffs.last().unwrap() * size_as_fe; - assert_eq!(sum, first + last); - } - - #[test] - fn test_alternator_polynomial() { - use ark_poly::Evaluations; - let domain_k = GeneralEvaluationDomain::::new(1 << 4).unwrap(); - let domain_h = GeneralEvaluationDomain::::new(1 << 3).unwrap(); - let domain_h_elems = domain_h - .elements() - .collect::>(); - let alternator_poly_evals = domain_k - .elements() - .map(|e| { - if domain_h_elems.contains(&e) { - Fr::one() - } else { - Fr::zero() - } - }) - .collect(); - let v_k: DenseOrSparsePolynomial<_> = domain_k.vanishing_polynomial().into(); - let v_h: DenseOrSparsePolynomial<_> = domain_h.vanishing_polynomial().into(); - let (divisor, remainder) = v_k.divide_with_q_and_r(&v_h).unwrap(); - assert!(remainder.is_zero()); - println!("Divisor: {:?}", divisor); - println!( - "{:#?}", - divisor - .coeffs - .iter() - .filter_map(|f| if !f.is_zero() { - Some(f.into_repr()) - } else { - None - }) - .collect::>() - ); - - for e in domain_h.elements() { - println!("{:?}", divisor.evaluate(&e)); - } - // Let p = v_K / v_H; - // The alternator polynomial is p * t, where t is defined as - // the LDE of p(h)^{-1} for all h in H. - // - // Because for each h in H, p(h) equals a constant c, we have that t - // is the constant polynomial c^{-1}. - // - // Q: what is the constant c? Why is p(h) constant? What is the easiest - // way to calculate c? - let alternator_poly = - Evaluations::from_vec_and_domain(alternator_poly_evals, domain_k).interpolate(); - let (quotient, remainder) = DenseOrSparsePolynomial::from(alternator_poly.clone()) - .divide_with_q_and_r(&DenseOrSparsePolynomial::from(divisor)) - .unwrap(); - assert!(remainder.is_zero()); - println!("quotient: {:?}", quotient); - println!( - "{:#?}", - quotient - .coeffs - .iter() - .filter_map(|f| if !f.is_zero() { - Some(f.into_repr()) - } else { - None - }) - .collect::>() - ); - - println!("{:?}", alternator_poly); - } -} diff --git a/prover/marlin/src/ahp/prover.rs b/prover/marlin/src/ahp/prover.rs deleted file mode 100644 index 401a32f7..00000000 --- a/prover/marlin/src/ahp/prover.rs +++ /dev/null @@ -1,733 +0,0 @@ -#![allow(non_snake_case)] - -use crate::ahp::indexer::*; -use crate::ahp::verifier::*; -use crate::ahp::*; - -use crate::ahp::constraint_systems::{ - make_matrices_square_for_prover, pad_input_for_indexer_and_prover, unformat_public_input, -}; -use crate::{ToString, Vec}; -use ark_ff::{Field, PrimeField, Zero}; -use ark_poly::{ - univariate::DensePolynomial, EvaluationDomain, Evaluations as EvaluationsOnDomain, - GeneralEvaluationDomain, Polynomial, UVPolynomial, -}; -use ark_relations::r1cs::{ - ConstraintSynthesizer, ConstraintSystem, OptimizationGoal, SynthesisError, -}; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError}; -use ark_std::rand::RngCore; -use ark_std::{ - cfg_into_iter, cfg_iter, cfg_iter_mut, - io::{Read, Write}, -}; - -/// State for the AHP prover. -pub struct ProverState<'a, F: PrimeField> { - formatted_input_assignment: Vec, - witness_assignment: Vec, - /// Az - z_a: Option>, - /// Bz - z_b: Option>, - /// query bound b - zk_bound: usize, - - w_poly: Option>, - mz_polys: Option<(LabeledPolynomial, LabeledPolynomial)>, - - index: &'a Index, - - /// the random values sent by the verifier in the first round - verifier_first_msg: Option>, - - /// the blinding polynomial for the first round - mask_poly: Option>, - - /// domain X, sized for the public input - domain_x: GeneralEvaluationDomain, - - /// domain H, sized for constraints - domain_h: GeneralEvaluationDomain, - - /// domain K, sized for matrix nonzero elements - domain_k: GeneralEvaluationDomain, -} - -impl<'a, F: PrimeField> ProverState<'a, F> { - /// Get the public input. - pub fn public_input(&self) -> Vec { - unformat_public_input(&self.formatted_input_assignment) - } -} - -/// Each prover message that is not a list of oracles is a list of field elements. -#[derive(Clone)] -pub enum ProverMsg { - /// Some rounds, the prover sends only oracles. (This is actually the case for all - /// rounds in Marlin.) - EmptyMessage, - /// Otherwise, it's one or more field elements. - FieldElements(Vec), -} - -impl ark_ff::ToBytes for ProverMsg { - fn write(&self, w: W) -> ark_std::io::Result<()> { - match self { - ProverMsg::EmptyMessage => Ok(()), - ProverMsg::FieldElements(field_elems) => field_elems.write(w), - } - } -} - -impl CanonicalSerialize for ProverMsg { - fn serialize(&self, mut writer: W) -> Result<(), SerializationError> { - let res: Option> = match self { - ProverMsg::EmptyMessage => None, - ProverMsg::FieldElements(v) => Some(v.clone()), - }; - res.serialize(&mut writer) - } - - fn serialized_size(&self) -> usize { - let res: Option> = match self { - ProverMsg::EmptyMessage => None, - ProverMsg::FieldElements(v) => Some(v.clone()), - }; - res.serialized_size() - } - - fn serialize_unchecked(&self, mut writer: W) -> Result<(), SerializationError> { - let res: Option> = match self { - ProverMsg::EmptyMessage => None, - ProverMsg::FieldElements(v) => Some(v.clone()), - }; - res.serialize_unchecked(&mut writer) - } - - fn serialize_uncompressed(&self, mut writer: W) -> Result<(), SerializationError> { - let res: Option> = match self { - ProverMsg::EmptyMessage => None, - ProverMsg::FieldElements(v) => Some(v.clone()), - }; - res.serialize_uncompressed(&mut writer) - } - - fn uncompressed_size(&self) -> usize { - let res: Option> = match self { - ProverMsg::EmptyMessage => None, - ProverMsg::FieldElements(v) => Some(v.clone()), - }; - res.uncompressed_size() - } -} - -impl CanonicalDeserialize for ProverMsg { - fn deserialize(mut reader: R) -> Result { - let res = Option::>::deserialize(&mut reader)?; - - if let Some(res) = res { - Ok(ProverMsg::FieldElements(res)) - } else { - Ok(ProverMsg::EmptyMessage) - } - } - - fn deserialize_unchecked(mut reader: R) -> Result { - let res = Option::>::deserialize_unchecked(&mut reader)?; - - if let Some(res) = res { - Ok(ProverMsg::FieldElements(res)) - } else { - Ok(ProverMsg::EmptyMessage) - } - } - - fn deserialize_uncompressed(mut reader: R) -> Result { - let res = Option::>::deserialize_uncompressed(&mut reader)?; - - if let Some(res) = res { - Ok(ProverMsg::FieldElements(res)) - } else { - Ok(ProverMsg::EmptyMessage) - } - } -} - -/// The first set of prover oracles. -pub struct ProverFirstOracles { - /// The LDE of `w`. - pub w: LabeledPolynomial, - /// The LDE of `Az`. - pub z_a: LabeledPolynomial, - /// The LDE of `Bz`. - pub z_b: LabeledPolynomial, - /// The sum-check hiding polynomial. - pub mask_poly: LabeledPolynomial, -} - -impl ProverFirstOracles { - /// Iterate over the polynomials output by the prover in the first round. - pub fn iter(&self) -> impl Iterator> { - vec![&self.w, &self.z_a, &self.z_b, &self.mask_poly].into_iter() - } -} - -/// The second set of prover oracles. -pub struct ProverSecondOracles { - /// The polynomial `t` that is produced in the first round. - pub t: LabeledPolynomial, - /// The polynomial `g` resulting from the first sumcheck. - pub g_1: LabeledPolynomial, - /// The polynomial `h` resulting from the first sumcheck. - pub h_1: LabeledPolynomial, -} - -impl ProverSecondOracles { - /// Iterate over the polynomials output by the prover in the second round. - pub fn iter(&self) -> impl Iterator> { - vec![&self.t, &self.g_1, &self.h_1].into_iter() - } -} - -/// The third set of prover oracles. -pub struct ProverThirdOracles { - /// The polynomial `g` resulting from the second sumcheck. - pub g_2: LabeledPolynomial, - /// The polynomial `h` resulting from the second sumcheck. - pub h_2: LabeledPolynomial, -} - -impl ProverThirdOracles { - /// Iterate over the polynomials output by the prover in the third round. - pub fn iter(&self) -> impl Iterator> { - vec![&self.g_2, &self.h_2].into_iter() - } -} - -impl AHPForR1CS { - /// Initialize the AHP prover. - pub fn prover_init>( - index: &Index, - c: C, - ) -> Result, Error> { - let init_time = start_timer!(|| "AHP::Prover::Init"); - - let constraint_time = start_timer!(|| "Generating constraints and witnesses"); - let pcs = ConstraintSystem::new_ref(); - pcs.set_optimization_goal(OptimizationGoal::Weight); - pcs.set_mode(ark_relations::r1cs::SynthesisMode::Prove { - construct_matrices: true, - }); - c.generate_constraints(pcs.clone())?; - let result = pcs.is_satisfied().unwrap(); - assert!(result); - end_timer!(constraint_time); - - let padding_time = start_timer!(|| "Padding matrices to make them square"); - pad_input_for_indexer_and_prover(pcs.clone()); - pcs.finalize(); - make_matrices_square_for_prover(pcs.clone()); - end_timer!(padding_time); - - let num_non_zero = index.index_info.num_non_zero; - - let (formatted_input_assignment, witness_assignment, num_constraints) = { - let pcs = pcs.borrow().unwrap(); - ( - pcs.instance_assignment.as_slice().to_vec(), - pcs.witness_assignment.as_slice().to_vec(), - pcs.num_constraints, - ) - }; - - let num_input_variables = formatted_input_assignment.len(); - let num_witness_variables = witness_assignment.len(); - if index.index_info.num_constraints != num_constraints - || num_input_variables + num_witness_variables != index.index_info.num_variables - { - return Err(Error::InstanceDoesNotMatchIndex); - } - - if !Self::formatted_public_input_is_admissible(&formatted_input_assignment) { - return Err(Error::InvalidPublicInputLength); - } - - // Perform matrix multiplications - let inner_prod_fn = |row: &[(F, usize)]| { - let mut acc = F::zero(); - for &(ref coeff, i) in row { - let tmp = if i < num_input_variables { - formatted_input_assignment[i] - } else { - witness_assignment[i - num_input_variables] - }; - - acc += &(if coeff.is_one() { tmp } else { tmp * coeff }); - } - acc - }; - - let eval_z_a_time = start_timer!(|| "Evaluating z_A"); - let z_a = index.a.iter().map(|row| inner_prod_fn(row)).collect(); - end_timer!(eval_z_a_time); - - let eval_z_b_time = start_timer!(|| "Evaluating z_B"); - let z_b = index.b.iter().map(|row| inner_prod_fn(row)).collect(); - end_timer!(eval_z_b_time); - - let zk_bound = 1; // One query is sufficient for our desired soundness - - let domain_h = GeneralEvaluationDomain::new(num_constraints) - .ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - - let domain_k = GeneralEvaluationDomain::new(num_non_zero) - .ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - - let domain_x = GeneralEvaluationDomain::new(num_input_variables) - .ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - - end_timer!(init_time); - - Ok(ProverState { - formatted_input_assignment, - witness_assignment, - z_a: Some(z_a), - z_b: Some(z_b), - w_poly: None, - mz_polys: None, - zk_bound, - index, - verifier_first_msg: None, - mask_poly: None, - domain_h, - domain_k, - domain_x, - }) - } - - /// Output the first round message and the next state. - #[allow(clippy::type_complexity)] - pub fn prover_first_round<'a, R: RngCore>( - mut state: ProverState<'a, F>, - rng: &mut R, - ) -> Result<(ProverMsg, ProverFirstOracles, ProverState<'a, F>), Error> { - let round_time = start_timer!(|| "AHP::Prover::FirstRound"); - let domain_h = state.domain_h; - let zk_bound = state.zk_bound; - - let v_H = domain_h.vanishing_polynomial().into(); - - let x_time = start_timer!(|| "Computing x polynomial and evals"); - let domain_x = state.domain_x; - let x_poly = EvaluationsOnDomain::from_vec_and_domain( - state.formatted_input_assignment.clone(), - domain_x, - ) - .interpolate(); - let x_evals = domain_h.fft(&x_poly); - end_timer!(x_time); - - let ratio = domain_h.size() / domain_x.size(); - - let mut w_extended = state.witness_assignment.clone(); - w_extended.extend(vec![ - F::zero(); - domain_h.size() - - domain_x.size() - - state.witness_assignment.len() - ]); - - let w_poly_time = start_timer!(|| "Computing w polynomial"); - let w_poly_evals = cfg_into_iter!(0..domain_h.size()) - .map(|k| { - if k % ratio == 0 { - F::zero() - } else { - w_extended[k - (k / ratio) - 1] - x_evals[k] - } - }) - .collect(); - - let w_poly = &EvaluationsOnDomain::from_vec_and_domain(w_poly_evals, domain_h) - .interpolate() - + &(&DensePolynomial::from_coefficients_slice(&[F::rand(rng)]) * &v_H); - let (w_poly, remainder) = w_poly.divide_by_vanishing_poly(domain_x).unwrap(); - assert!(remainder.is_zero()); - end_timer!(w_poly_time); - - let z_a_poly_time = start_timer!(|| "Computing z_A polynomial"); - let z_a = state.z_a.clone().unwrap(); - let z_a_poly = &EvaluationsOnDomain::from_vec_and_domain(z_a, domain_h).interpolate() - + &(&DensePolynomial::from_coefficients_slice(&[F::rand(rng)]) * &v_H); - end_timer!(z_a_poly_time); - - let z_b_poly_time = start_timer!(|| "Computing z_B polynomial"); - let z_b = state.z_b.clone().unwrap(); - let z_b_poly = &EvaluationsOnDomain::from_vec_and_domain(z_b, domain_h).interpolate() - + &(&DensePolynomial::from_coefficients_slice(&[F::rand(rng)]) * &v_H); - end_timer!(z_b_poly_time); - - let mask_poly_time = start_timer!(|| "Computing mask polynomial"); - let mask_poly_degree = 3 * domain_h.size() + 2 * zk_bound - 3; - let mut mask_poly = DensePolynomial::rand(mask_poly_degree, rng); - let scaled_sigma_1 = (mask_poly.divide_by_vanishing_poly(domain_h).unwrap().1)[0]; - mask_poly[0] -= &scaled_sigma_1; - end_timer!(mask_poly_time); - - let msg = ProverMsg::EmptyMessage; - - assert!(w_poly.degree() < domain_h.size() - domain_x.size() + zk_bound); - assert!(z_a_poly.degree() < domain_h.size() + zk_bound); - assert!(z_b_poly.degree() < domain_h.size() + zk_bound); - assert!(mask_poly.degree() <= 3 * domain_h.size() + 2 * zk_bound - 3); - - let w = LabeledPolynomial::new("w".to_string(), w_poly, None, Some(1)); - let z_a = LabeledPolynomial::new("z_a".to_string(), z_a_poly, None, Some(1)); - let z_b = LabeledPolynomial::new("z_b".to_string(), z_b_poly, None, Some(1)); - let mask_poly = - LabeledPolynomial::new("mask_poly".to_string(), mask_poly.clone(), None, None); - - let oracles = ProverFirstOracles { - w: w.clone(), - z_a: z_a.clone(), - z_b: z_b.clone(), - mask_poly: mask_poly.clone(), - }; - - state.w_poly = Some(w); - state.mz_polys = Some((z_a, z_b)); - state.mask_poly = Some(mask_poly); - end_timer!(round_time); - - Ok((msg, oracles, state)) - } - - fn calculate_t<'a>( - matrices: impl Iterator>, - matrix_randomizers: &[F], - input_domain: GeneralEvaluationDomain, - domain_h: GeneralEvaluationDomain, - r_alpha_x_on_h: Vec, - ) -> DensePolynomial { - let mut t_evals_on_h = vec![F::zero(); domain_h.size()]; - for (matrix, eta) in matrices.zip(matrix_randomizers) { - for (r, row) in matrix.iter().enumerate() { - for (coeff, c) in row.iter() { - let index = domain_h.reindex_by_subdomain(input_domain, *c); - t_evals_on_h[index] += *eta * coeff * r_alpha_x_on_h[r]; - } - } - } - EvaluationsOnDomain::from_vec_and_domain(t_evals_on_h, domain_h).interpolate() - } - - /// Output the number of oracles sent by the prover in the first round. - pub fn prover_num_first_round_oracles() -> usize { - 4 - } - - /// Output the degree bounds of oracles in the first round. - pub fn prover_first_round_degree_bounds( - _info: &IndexInfo, - ) -> impl Iterator> { - vec![None; 4].into_iter() - } - - /// Output the second round message and the next state. - pub fn prover_second_round<'a, R: RngCore>( - ver_message: &VerifierFirstMsg, - mut state: ProverState<'a, F>, - _r: &mut R, - ) -> (ProverMsg, ProverSecondOracles, ProverState<'a, F>) { - let round_time = start_timer!(|| "AHP::Prover::SecondRound"); - - let domain_h = state.domain_h; - let zk_bound = state.zk_bound; - - let mask_poly = state - .mask_poly - .as_ref() - .expect("ProverState should include mask_poly when prover_second_round is called"); - - let VerifierFirstMsg { - alpha, - eta_a, - eta_b, - eta_c, - } = *ver_message; - - let summed_z_m_poly_time = start_timer!(|| "Compute z_m poly"); - let (z_a_poly, z_b_poly) = state.mz_polys.as_ref().unwrap(); - let z_c_poly = z_a_poly.polynomial() * z_b_poly.polynomial(); - - let mut summed_z_m_coeffs = z_c_poly.coeffs; - // Note: Can't combine these two loops, because z_c_poly has 2x the degree - // of z_a_poly and z_b_poly, so the second loop gets truncated due to - // the `zip`s. - cfg_iter_mut!(summed_z_m_coeffs).for_each(|c| *c *= &eta_c); - cfg_iter_mut!(summed_z_m_coeffs) - .zip(&z_a_poly.polynomial().coeffs) - .zip(&z_b_poly.polynomial().coeffs) - .for_each(|((c, a), b)| *c += &(eta_a * a + (eta_b * b))); - - let summed_z_m = DensePolynomial::from_coefficients_vec(summed_z_m_coeffs); - end_timer!(summed_z_m_poly_time); - - let r_alpha_x_evals_time = start_timer!(|| "Compute r_alpha_x evals"); - let r_alpha_x_evals = - domain_h.batch_eval_unnormalized_bivariate_lagrange_poly_with_diff_inputs(alpha); - end_timer!(r_alpha_x_evals_time); - - let r_alpha_poly_time = start_timer!(|| "Compute r_alpha_x poly"); - let r_alpha_poly = DensePolynomial::from_coefficients_vec(domain_h.ifft(&r_alpha_x_evals)); - end_timer!(r_alpha_poly_time); - - let t_poly_time = start_timer!(|| "Compute t poly"); - let t_poly = Self::calculate_t( - vec![&state.index.a, &state.index.b, &state.index.c].into_iter(), - &[eta_a, eta_b, eta_c], - state.domain_x, - state.domain_h, - r_alpha_x_evals.to_vec(), - ); - end_timer!(t_poly_time); - - let z_poly_time = start_timer!(|| "Compute z poly"); - - let domain_x = GeneralEvaluationDomain::new(state.formatted_input_assignment.len()) - .ok_or(SynthesisError::PolynomialDegreeTooLarge) - .unwrap(); - let x_poly = EvaluationsOnDomain::from_vec_and_domain( - state.formatted_input_assignment.clone(), - domain_x, - ) - .interpolate(); - let w_poly = state.w_poly.as_ref().unwrap(); - let mut z_poly = w_poly.polynomial().mul_by_vanishing_poly(domain_x); - cfg_iter_mut!(z_poly.coeffs) - .zip(&x_poly.coeffs) - .for_each(|(z, x)| *z += x); - assert!(z_poly.degree() < domain_h.size() + zk_bound); - - end_timer!(z_poly_time); - - let q_1_time = start_timer!(|| "Compute q_1 poly"); - - let mul_domain_size = *[ - mask_poly.len(), - r_alpha_poly.coeffs.len() + summed_z_m.coeffs.len(), - t_poly.coeffs.len() + z_poly.len(), - ] - .iter() - .max() - .unwrap(); - let mul_domain = GeneralEvaluationDomain::new(mul_domain_size) - .expect("field is not smooth enough to construct domain"); - let mut r_alpha_evals = r_alpha_poly.evaluate_over_domain_by_ref(mul_domain); - let summed_z_m_evals = summed_z_m.evaluate_over_domain_by_ref(mul_domain); - let z_poly_evals = z_poly.evaluate_over_domain_by_ref(mul_domain); - let t_poly_m_evals = t_poly.evaluate_over_domain_by_ref(mul_domain); - - cfg_iter_mut!(r_alpha_evals.evals) - .zip(&summed_z_m_evals.evals) - .zip(&z_poly_evals.evals) - .zip(&t_poly_m_evals.evals) - .for_each(|(((a, b), &c), d)| { - *a *= b; - *a -= c * d; - }); - let rhs = r_alpha_evals.interpolate(); - let q_1 = mask_poly.polynomial() + &rhs; - end_timer!(q_1_time); - - let sumcheck_time = start_timer!(|| "Compute sumcheck h and g polys"); - let (h_1, x_g_1) = q_1.divide_by_vanishing_poly(domain_h).unwrap(); - let g_1 = DensePolynomial::from_coefficients_slice(&x_g_1.coeffs[1..]); - end_timer!(sumcheck_time); - - let msg = ProverMsg::EmptyMessage; - - assert!(g_1.degree() <= domain_h.size() - 2); - assert!(h_1.degree() <= 2 * domain_h.size() + 2 * zk_bound - 2); - - let oracles = ProverSecondOracles { - t: LabeledPolynomial::new("t".into(), t_poly, None, None), - g_1: LabeledPolynomial::new("g_1".into(), g_1, Some(domain_h.size() - 2), Some(1)), - h_1: LabeledPolynomial::new("h_1".into(), h_1, None, None), - }; - - state.w_poly = None; - state.verifier_first_msg = Some(*ver_message); - end_timer!(round_time); - - (msg, oracles, state) - } - - /// Output the number of oracles sent by the prover in the second round. - pub fn prover_num_second_round_oracles() -> usize { - 3 - } - - /// Output the degree bounds of oracles in the second round. - pub fn prover_second_round_degree_bounds( - info: &IndexInfo, - ) -> impl Iterator> { - let h_domain_size = - GeneralEvaluationDomain::::compute_size_of_domain(info.num_constraints).unwrap(); - - vec![None, Some(h_domain_size - 2), None].into_iter() - } - - /// Output the third round message and the next state. - pub fn prover_third_round( - ver_message: &VerifierSecondMsg, - prover_state: ProverState<'_, F>, - _r: &mut R, - ) -> Result<(ProverMsg, ProverThirdOracles), Error> { - let round_time = start_timer!(|| "AHP::Prover::ThirdRound"); - - let ProverState { - index, - verifier_first_msg, - domain_h, - domain_k, - .. - } = prover_state; - - let VerifierFirstMsg { - eta_a, - eta_b, - eta_c, - alpha, - } = verifier_first_msg.expect( - "ProverState should include verifier_first_msg when prover_third_round is called", - ); - - let beta = ver_message.beta; - - let v_H_at_alpha = domain_h.evaluate_vanishing_polynomial(alpha); - let v_H_at_beta = domain_h.evaluate_vanishing_polynomial(beta); - - let (a_star, b_star, c_star) = ( - &index.a_star_arith, - &index.b_star_arith, - &index.c_star_arith, - ); - - let f_evals_time = start_timer!(|| "Computing f evals on K"); - let mut f_vals_on_K = Vec::with_capacity(domain_k.size()); - let mut inverses_a = Vec::with_capacity(domain_k.size()); - let mut inverses_b = Vec::with_capacity(domain_k.size()); - let mut inverses_c = Vec::with_capacity(domain_k.size()); - - for i in 0..domain_k.size() { - inverses_a.push((beta - a_star.evals_on_K.row[i]) * (alpha - a_star.evals_on_K.col[i])); - inverses_b.push((beta - b_star.evals_on_K.row[i]) * (alpha - b_star.evals_on_K.col[i])); - inverses_c.push((beta - c_star.evals_on_K.row[i]) * (alpha - c_star.evals_on_K.col[i])); - } - ark_ff::batch_inversion(&mut inverses_a); - ark_ff::batch_inversion(&mut inverses_b); - ark_ff::batch_inversion(&mut inverses_c); - - for i in 0..domain_k.size() { - let t = eta_a * a_star.evals_on_K.val[i] * inverses_a[i] - + eta_b * b_star.evals_on_K.val[i] * inverses_b[i] - + eta_c * c_star.evals_on_K.val[i] * inverses_c[i]; - let f_at_kappa = v_H_at_beta * v_H_at_alpha * t; - f_vals_on_K.push(f_at_kappa); - } - end_timer!(f_evals_time); - - let f_poly_time = start_timer!(|| "Computing f poly"); - let f = EvaluationsOnDomain::from_vec_and_domain(f_vals_on_K, domain_k).interpolate(); - end_timer!(f_poly_time); - - let g_2 = DensePolynomial::from_coefficients_slice(&f.coeffs[1..]); - - let domain_b = GeneralEvaluationDomain::::new(3 * domain_k.size() - 3) - .ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - - let denom_eval_time = start_timer!(|| "Computing denominator evals on B"); - let a_denom: Vec<_> = cfg_iter!(a_star.evals_on_B.row.evals) - .zip(&a_star.evals_on_B.col.evals) - .zip(&a_star.row_col_evals_on_B.evals) - .map(|((&r, c), r_c)| beta * alpha - (r * alpha) - (beta * c) + r_c) - .collect(); - - let b_denom: Vec<_> = cfg_iter!(b_star.evals_on_B.row.evals) - .zip(&b_star.evals_on_B.col.evals) - .zip(&b_star.row_col_evals_on_B.evals) - .map(|((&r, c), r_c)| beta * alpha - (r * alpha) - (beta * c) + r_c) - .collect(); - - let c_denom: Vec<_> = cfg_iter!(c_star.evals_on_B.row.evals) - .zip(&c_star.evals_on_B.col.evals) - .zip(&c_star.row_col_evals_on_B.evals) - .map(|((&r, c), r_c)| beta * alpha - (r * alpha) - (beta * c) + r_c) - .collect(); - end_timer!(denom_eval_time); - - let a_evals_time = start_timer!(|| "Computing a evals on B"); - let a_star_evals_on_B = &a_star.evals_on_B; - let b_star_evals_on_B = &b_star.evals_on_B; - let c_star_evals_on_B = &c_star.evals_on_B; - let a_poly_on_B = cfg_into_iter!(0..domain_b.size()) - .map(|i| { - let t = eta_a * a_star_evals_on_B.val.evals[i] * b_denom[i] * c_denom[i] - + eta_b * b_star_evals_on_B.val.evals[i] * a_denom[i] * c_denom[i] - + eta_c * c_star_evals_on_B.val.evals[i] * a_denom[i] * b_denom[i]; - v_H_at_beta * v_H_at_alpha * t - }) - .collect(); - end_timer!(a_evals_time); - - let a_poly_time = start_timer!(|| "Computing a poly"); - let a_poly = EvaluationsOnDomain::from_vec_and_domain(a_poly_on_B, domain_b).interpolate(); - end_timer!(a_poly_time); - - let b_evals_time = start_timer!(|| "Computing b evals on B"); - let b_poly_on_B = cfg_into_iter!(0..domain_b.size()) - .map(|i| a_denom[i] * b_denom[i] * c_denom[i]) - .collect(); - end_timer!(b_evals_time); - - let b_poly_time = start_timer!(|| "Computing b poly"); - let b_poly = EvaluationsOnDomain::from_vec_and_domain(b_poly_on_B, domain_b).interpolate(); - end_timer!(b_poly_time); - - let h_2_poly_time = start_timer!(|| "Computing sumcheck h poly"); - let h_2 = (&a_poly - &(&b_poly * &f)) - .divide_by_vanishing_poly(domain_k) - .unwrap() - .0; - end_timer!(h_2_poly_time); - - let msg = ProverMsg::EmptyMessage; - - assert!(g_2.degree() <= domain_k.size() - 2); - let oracles = ProverThirdOracles { - g_2: LabeledPolynomial::new("g_2".to_string(), g_2, Some(domain_k.size() - 2), None), - h_2: LabeledPolynomial::new("h_2".to_string(), h_2, None, None), - }; - end_timer!(round_time); - - Ok((msg, oracles)) - } - - /// Output the number of oracles sent by the prover in the third round. - pub fn prover_num_third_round_oracles() -> usize { - 3 - } - - /// Output the degree bounds of oracles in the third round. - pub fn prover_third_round_degree_bounds( - info: &IndexInfo, - ) -> impl Iterator> { - let num_non_zero = info.num_non_zero; - let k_size = GeneralEvaluationDomain::::compute_size_of_domain(num_non_zero).unwrap(); - - vec![Some(k_size - 2), None].into_iter() - } -} diff --git a/prover/marlin/src/ahp/verifier.rs b/prover/marlin/src/ahp/verifier.rs deleted file mode 100644 index ea437709..00000000 --- a/prover/marlin/src/ahp/verifier.rs +++ /dev/null @@ -1,210 +0,0 @@ -#![allow(non_snake_case)] - -use crate::ahp::indexer::IndexInfo; -use crate::ahp::*; -use ark_std::rand::RngCore; - -use ark_ff::PrimeField; -use ark_poly::{EvaluationDomain, GeneralEvaluationDomain}; -use ark_poly_commit::QuerySet; - -/// State of the AHP verifier -pub struct VerifierState { - pub(crate) domain_h: GeneralEvaluationDomain, - pub(crate) domain_k: GeneralEvaluationDomain, - - pub(crate) first_round_msg: Option>, - pub(crate) second_round_msg: Option>, - - pub(crate) gamma: Option, -} - -/// First message of the verifier. -#[derive(Copy, Clone)] -pub struct VerifierFirstMsg { - /// Query for the random polynomial. - pub alpha: F, - /// Randomizer for the lincheck for `A`. - pub eta_a: F, - /// Randomizer for the lincheck for `B`. - pub eta_b: F, - /// Randomizer for the lincheck for `C`. - pub eta_c: F, -} - -/// Second verifier message. -#[derive(Copy, Clone)] -pub struct VerifierSecondMsg { - /// Query for the second round of polynomials. - pub beta: F, -} - -impl AHPForR1CS { - /// Output the first message and next round state. - pub fn verifier_first_round( - index_info: IndexInfo, - rng: &mut R, - ) -> Result<(VerifierFirstMsg, VerifierState), Error> { - if index_info.num_constraints != index_info.num_variables { - return Err(Error::NonSquareMatrix); - } - - let domain_h = GeneralEvaluationDomain::new(index_info.num_constraints) - .ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - - let domain_k = GeneralEvaluationDomain::new(index_info.num_non_zero) - .ok_or(SynthesisError::PolynomialDegreeTooLarge)?; - - let alpha = domain_h.sample_element_outside_domain(rng); - let eta_a = F::rand(rng); - let eta_b = F::rand(rng); - let eta_c = F::rand(rng); - - let msg = VerifierFirstMsg { - alpha, - eta_a, - eta_b, - eta_c, - }; - - let new_state = VerifierState { - domain_h, - domain_k, - first_round_msg: Some(msg), - second_round_msg: None, - gamma: None, - }; - - Ok((msg, new_state)) - } - - /// Output the second message and next round state. - pub fn verifier_second_round( - mut state: VerifierState, - rng: &mut R, - ) -> (VerifierSecondMsg, VerifierState) { - let beta = state.domain_h.sample_element_outside_domain(rng); - let msg = VerifierSecondMsg { beta }; - state.second_round_msg = Some(msg); - - (msg, state) - } - - /// Output the third message and next round state. - pub fn verifier_third_round( - mut state: VerifierState, - rng: &mut R, - ) -> VerifierState { - state.gamma = Some(F::rand(rng)); - state - } - - /// Output the query state and next round state. - pub fn verifier_query_set( - state: VerifierState, - _: &mut R, - ) -> (QuerySet, VerifierState) { - let beta = state.second_round_msg.unwrap().beta; - - let gamma = state.gamma.unwrap(); - - let mut query_set = QuerySet::new(); - // For the first linear combination - // Outer sumcheck test: - // s(beta) + r(alpha, beta) * (sum_M eta_M z_M(beta)) - t(beta) * z(beta) - // = h_1(beta) * v_H(beta) + beta * g_1(beta) - // - // Note that z is the interpolation of x || w, so it equals x + v_X * w - // We also use an optimization: instead of explicitly calculating z_c, we - // use the "virtual oracle" z_b * z_c - // - // LinearCombination::new( - // outer_sumcheck - // vec![ - // (F::one(), "mask_poly".into()), - // - // (r_alpha_at_beta * (eta_a + eta_c * z_b_at_beta), "z_a".into()), - // (r_alpha_at_beta * eta_b * z_b_at_beta, LCTerm::One), - // - // (-t_at_beta * v_X_at_beta, "w".into()), - // (-t_at_beta * x_at_beta, LCTerm::One), - // - // (-v_H_at_beta, "h_1".into()), - // (-beta * g_1_at_beta, LCTerm::One), - // ], - // ) - // LinearCombination::new("z_b", vec![(F::one(), z_b)]) - // LinearCombination::new("g_1", vec![(F::one(), g_1)], rhs::new(g_1_at_beta)) - // LinearCombination::new("t", vec![(F::one(), t)]) - query_set.insert(("g_1".into(), ("beta".into(), beta))); - query_set.insert(("z_b".into(), ("beta".into(), beta))); - query_set.insert(("t".into(), ("beta".into(), beta))); - query_set.insert(("outer_sumcheck".into(), ("beta".into(), beta))); - - // For the second linear combination - // Inner sumcheck test: - // h_2(gamma) * v_K(gamma) - // = a(gamma) - b(gamma) * (gamma g_2(gamma) + t(beta) / |K|) - // - // where - // a(X) := sum_M (eta_M v_H(beta) v_H(alpha) val_M(X) prod_N (beta - row_N(X)) (alpha - col_N(X))) - // b(X) := prod_M (beta - row_M(X)) (alpha - col_M(X)) - // - // We define "n_denom" := prod_N (beta - row_N(X)) (alpha - col_N(X))) - // - // LinearCombination::new("g_2", vec![(F::one(), g_2)]); - // - // LinearCombination::new( - // "a_denom".into(), - // vec![ - // (alpha * beta, LCTerm::One), - // (-alpha, "a_row"), - // (-beta, "a_col"), - // (F::one(), "a_row_col"), - // ]); - // LinearCombination::new( - // "b_denom".into(), - // vec![ - // (alpha * beta, LCTerm::One), - // (-alpha, "b_row"), - // (-beta, "b_col"), - // (F::one(), "b_row_col"), - // ]); - // LinearCombination::new( - // "c_denom".into(), - // vec![ - // (alpha * beta, LCTerm::one()), - // (-alpha, "c_row"), - // (-beta, "c_col"), - // (F::one(), "c_row_col"), - // ]); - // - // LinearCombination::new( - // "a_poly".into(), - // vec![ - // (eta_a * b_denom_at_gamma * c_denom_at_gamma, "a_val".into()), - // (eta_b * a_denom_at_gamma * c_denom_at_gamma, "b_val".into()), - // (eta_c * b_denom_at_gamma * a_denom_at_gamma, "c_val".into()), - // ], - // ) - // - // let v_H_at_alpha = domain_h.evaluate_vanishing_polynomial(alpha); - // let v_H_at_beta = domain_h.evaluate_vanishing_polynomial(beta); - // let v_K_at_gamma = domain_k.evaluate_vanishing_polynomial(gamma); - // - // let a_poly_lc *= v_H_at_alpha * v_H_at_beta; - // let b_lc = LinearCombination::new("b_poly", vec![(a_denom_at_gamma * b_denom_at_gamma * c_denom_at_gamma, "one")]); - // let h_lc = LinearCombination::new("b_poly", vec![(v_K_at_gamma, "h_2")]); - // - // // This LC is the only one that is evaluated: - // let inner_sumcheck = a_poly_lc - (b_lc * (gamma * &g_2_at_gamma + &(t_at_beta / &k_size))) - h_lc - // main_lc.set_label("inner_sumcheck"); - query_set.insert(("g_2".into(), ("gamma".into(), gamma))); - query_set.insert(("a_denom".into(), ("gamma".into(), gamma))); - query_set.insert(("b_denom".into(), ("gamma".into(), gamma))); - query_set.insert(("c_denom".into(), ("gamma".into(), gamma))); - query_set.insert(("inner_sumcheck".into(), ("gamma".into(), gamma))); - - (query_set, state) - } -} diff --git a/prover/marlin/src/api.rs b/prover/marlin/src/api.rs deleted file mode 100644 index 366e73af..00000000 --- a/prover/marlin/src/api.rs +++ /dev/null @@ -1,411 +0,0 @@ -use crate::IndexVerifierKey; -use crate::Marlin; -use crate::Proof; -use ark_bn254::{Bn254, Fr}; -use ark_ff::{Field, FromBytes}; -use ark_poly::univariate::DensePolynomial; -use ark_poly_commit::marlin_pc::MarlinKZG10; -use ark_relations::r1cs::{ - ConstraintSynthesizer, ConstraintSystemRef, LinearCombination, SynthesisError, Variable, -}; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_std::{io::Read, vec::Vec}; -use base64::{engine::general_purpose, Engine as _}; -use blake2::Blake2s; -use r1cs_file::{FieldElement, R1csFile}; -use wtns_file::{FieldElement as WtnsFE, WtnsFile}; -type MultiPC = MarlinKZG10>; -type MarlinInst = Marlin; -type Inputs = Vec; -type ConstraintVec = Vec<(usize, Fr)>; -type Constraints = (ConstraintVec, ConstraintVec, ConstraintVec); -use ark_ff::{BigInteger, BigInteger256}; -use gev_core::*; - -#[derive(Clone)] -struct Circuit { - pub(crate) num_inputs: usize, - pub(crate) num_outputs: usize, - pub(crate) num_wires: usize, - pub(crate) constraints: Vec, - pub(crate) witness: Vec, -} - -impl ConstraintSynthesizer for Circuit { - fn generate_constraints(self, cs: ConstraintSystemRef) -> Result<(), SynthesisError> { - let w = &self.witness; - - let input_start = 1 + self.num_outputs; - let input_end = input_start + self.num_inputs; - - // the inputs are after ONE (constant, index 0) and the outputs (if any) - for i in 0..self.num_inputs { - cs.new_input_variable(|| Ok(w[i + input_start]))?; - } - // If any outputs, they start at index 1 - for wval in w.iter().take(self.num_outputs + 1) { - cs.new_witness_variable(|| Ok(*wval))?; - } - // the rest of the witness variables - for i in 0..self.num_wires - 1 - self.num_outputs { - cs.new_witness_variable(|| Ok(w[i + input_end]))?; - } - - let make_index = |index| { - if index < input_start { - Variable::Witness(index) - } else if index < input_end { - Variable::Instance(index - input_start + 1) - } else { - Variable::Witness(index - self.num_inputs) - } - }; - let make_lc = |lc_data: &[(usize, Fr)]| { - lc_data.iter().fold( - LinearCombination::::zero(), - |lc: LinearCombination, (index, coeff)| lc + (*coeff, make_index(*index)), - ) - }; - - for constraint in &self.constraints { - cs.enforce_constraint( - make_lc(&constraint.0), - make_lc(&constraint.1), - make_lc(&constraint.2), - )?; - } - - Ok(()) - } -} - -fn create_circuit(prover_inputs: ProverInputs) -> Result, GevulotError> { - let r1cs_bytes: Vec = general_purpose::STANDARD_NO_PAD - .decode(prover_inputs.r1cs) - .expect("could not decode r1cs data from base64 string"); - let wtns_bytes: Vec = general_purpose::STANDARD_NO_PAD - .decode(prover_inputs.wtns) - .expect("could not decode wtns data from base64 string"); - - let r1cs_file = - R1csFile::<32>::read(r1cs_bytes.as_slice()).map_err(|_| GevulotError::R1csParseError)?; - - let wtns_file = - WtnsFile::<32>::read(wtns_bytes.as_slice()).map_err(|_| GevulotError::R1csParseError)?; - - let mut witness: Vec = Vec::new(); - for fe in &wtns_file.witness.0 { - let fr = wtns_field_element_to_fr(fe); - witness.push(fr); - } - - let mut constraints: Vec = Vec::new(); - - println!(" create_circuit"); - println!(" witness len: {}", witness.len()); - println!(" constraints len: {}", r1cs_file.constraints.0.len()); - for c in &r1cs_file.constraints.0 { - let mut c0: Vec<(usize, Fr)> = Vec::new(); - for n in 0..c.0.len() { - let i = c.0[n].1 as usize; - let fr = r1cs_field_element_to_fr(&c.0[n].0); - c0.push((i, fr)); - } - let mut c1: Vec<(usize, Fr)> = Vec::new(); - for n in 0..c.1.len() { - let i = c.1[n].1 as usize; - let fr = r1cs_field_element_to_fr(&c.1[n].0); - c1.push((i, fr)); - } - let mut c2: Vec<(usize, Fr)> = Vec::new(); - for n in 0..c.2.len() { - let i = c.2[n].1 as usize; - let fr = r1cs_field_element_to_fr(&c.2[n].0); - c2.push((i, fr)); - } - - let constraint: Constraints = (c0, c1, c2); - constraints.push(constraint); - } - - let num_inputs = r1cs_file.header.n_pub_in as usize; - let num_wires = r1cs_file.header.n_wires as usize - num_inputs; - let num_outputs = r1cs_file.header.n_pub_out as usize; - println!(" num_inputs: {:?}", num_inputs); - println!(" num_outputs: {:?}", num_outputs); - println!(" num_wires: {:?}", num_wires); - - Ok(Circuit { - num_inputs, - num_outputs, - num_wires, - constraints, - witness, - }) -} - -/// This is our Rust prover function -pub fn do_prove(inputs: ProverInputs) -> Result { - let rng = &mut ark_std::test_rng(); - // TODO: get num constraints - println!("marlin::do_prove"); - let start = get_millis(); - - let circ = create_circuit(inputs)?; - - // let num_constraints = circ.constraints.len(); - // let num_variables = circ.num_wires; - // let num_non_zero = circ.num_wires * 2; - let num_constraints = 10000; - let num_variables = 10000; - let num_non_zero = 10000; - - let universal_srs = - MarlinInst::universal_setup(num_constraints, num_variables, num_non_zero, rng).unwrap(); - - let (index_pk, index_vk) = MarlinInst::index(&universal_srs, circ.clone()).unwrap(); - - let proof = match MarlinInst::prove(&index_pk, circ, rng) { - Ok(pi) => pi, - Err(error) => { - panic!("MarlinInst::prove error: {:?}", error); - } - }; - - let mut proof_bytes = Vec::new(); - proof - .serialize_uncompressed(&mut proof_bytes) - .map_err(|_| GevulotError::CanonicalSerializeError)?; - - let mut index_vk_bytes = Vec::new(); - index_vk - .serialize_uncompressed(&mut index_vk_bytes) - .map_err(|_| GevulotError::CanonicalSerializeError)?; - - println!(" proof_bytes len {:?}", proof_bytes.len()); - println!(" index_vk_bytes len {:?}", index_vk_bytes.len()); - - let proof_encoded = general_purpose::STANDARD_NO_PAD.encode(&proof_bytes); - let index_vk_encoded = general_purpose::STANDARD_NO_PAD.encode(&index_vk_bytes); - let proof_info = ProofInfo { - algorithm: "marlin".to_owned(), - proof: proof_encoded, - vk: index_vk_encoded, - }; - - println!(" do_prove took {} ms", get_millis() - start); - Ok(ProverResponse { - header: ResponseHeader { - success: true, - message: "Prover succeeded".to_owned(), - }, - proof_info: Some(proof_info), - }) -} - -pub fn do_verify( - proof_bytes: &Vec, - index_vk_bytes: &Vec, - inputs: &Inputs, -) -> Result { - println!("marlin::do_verify"); - let rng = &mut ark_std::test_rng(); - let start = get_millis(); - - type ProofType = Proof; - let proof = ProofType::deserialize_uncompressed(proof_bytes.as_slice()) - .map_err(|_| GevulotError::CanonicalSerializeError)?; - - type IndexVkType = IndexVerifierKey; - let index_vk = IndexVkType::deserialize_uncompressed(index_vk_bytes.as_slice()) - .map_err(|_| GevulotError::CanonicalSerializeError)?; - - let success = MarlinInst::verify(&index_vk, inputs, &proof, rng) - .map_err(|_| GevulotError::MarlinVerifyError)?; - - println!(" do_verify: success = {}", success); - - let message = if success { - VERIFICATION_SUCCESS.to_string() - } else { - VERIFICATION_FAIL.to_string() - }; - println!(" do_verify took {} ms", get_millis() - start); - - Ok(VerifyResponse { - header: ResponseHeader { success, message }, - }) -} - -fn read_field_element(reader: R) -> Fr { - Fr::read(reader).expect("could not read field element") -} - -fn bigint256_to_fr(b: &BigInteger256) -> Fr { - read_field_element(b.to_owned().to_bytes_le().as_slice()) -} -fn r1cs_field_element_to_fr(fe: &FieldElement<32>) -> Fr { - read_field_element(fe.to_owned().to_vec().as_slice()) -} - -fn wtns_field_element_to_fr(fe: &WtnsFE<32>) -> Fr { - read_field_element(fe.to_owned().to_vec().as_slice()) -} - -// fn unpack_and_prove(jproverinputs: String) -> Result { -// let prover_inputs: ProverInputs = -// serde_json::from_str(&jproverinputs).map_err(|_| GevulotError::JsonDeserializeError)?; -// println!(" r1cs len {:?}", prover_inputs.r1cs.len()); -// println!(" wtns len {:?}", prover_inputs.wtns.len()); - -// do_prove(prover_inputs) -// } - -// fn unpack_and_verify(jverifyinputs: String) -> Result { -// let verify_inputs: VerifyInputs = -// serde_json::from_str(&jverifyinputs).map_err(|_| GevulotError::JsonDeserializeError)?; -// verify(verify_inputs) -// } - -pub fn verify(verify_inputs: VerifyInputs) -> Result { - println!("inputs {:?}", verify_inputs.inputs); - let proof: Vec = general_purpose::STANDARD_NO_PAD - .decode(verify_inputs.proof_info.proof) - .map_err(|_| GevulotError::Base64DecodeError)?; - let vk: Vec = general_purpose::STANDARD_NO_PAD - .decode(verify_inputs.proof_info.vk) - .map_err(|_| GevulotError::Base64DecodeError)?; - let inputs = verify_inputs.inputs; - - println!(" proof len {}", proof.len()); - println!(" vk len {}", vk.len()); - println!(" inputs len {}", inputs.len()); - let mut fr_inputs: Vec = Vec::new(); - for input in inputs { - let fr = bigint256_to_fr(&BigInteger256::new([input, 0, 0, 0])); - fr_inputs.push(fr); - } - do_verify(&proof, &vk, &fr_inputs) -} - -#[test] -fn test_circom() { - let data = - std::fs::read("../test-data/sudoku.r1cs").expect("could not read ../test-data/sudoku.r1cs"); - let r1cs = general_purpose::STANDARD_NO_PAD.encode(&data); - let data = - std::fs::read("../test-data/sudoku.wtns").expect("could not read ../test-data/sudoku.wtns"); - let wtns = general_purpose::STANDARD_NO_PAD.encode(&data); - - let prover_inputs = ProverInputs { r1cs, wtns }; - - let prove_response = do_prove(prover_inputs).unwrap(); - let proof_info = prove_response - .proof_info - .expect("proof_info is not present"); - let proof_bytes: Vec = general_purpose::STANDARD_NO_PAD - .decode(proof_info.proof) - .expect("could not decode proof data from base64 string"); - - let vk_bytes: Vec = general_purpose::STANDARD_NO_PAD - .decode(proof_info.vk) - .expect("could not decode vk data from base64 string"); - - type ProofType = Proof; - assert!(ProofType::deserialize_uncompressed(proof_bytes.as_slice()).is_ok()); - type IndexVkType = IndexVerifierKey; - assert!(IndexVkType::deserialize_uncompressed(vk_bytes.as_slice()).is_ok()); - - let mut correct: Vec = Vec::new(); - for r in TEST_SUDOKU_CORRECT { - let fr = bigint256_to_fr(&BigInteger256([r, 0, 0, 0])); - correct.push(fr); - } - - let mut wrong: Vec = Vec::new(); - for r in TEST_SUDOKU_WRONG { - let fr = bigint256_to_fr(&BigInteger256([r, 0, 0, 0])); - wrong.push(fr); - } - - let verify_response = do_verify(&proof_bytes, &vk_bytes, &correct); - println!("correct data: {:?}", verify_response); - - let verify_response = do_verify(&proof_bytes, &vk_bytes, &wrong); - println!("wrong data: {:?}", verify_response); -} - -#[test] -fn test_bad_prover_input() { - // swap r1cs with wtns - let data = std::fs::read("../test-data/sudoku.r1cs") - .expect("could not read file ../test-data/sudoku.r1cs"); - let r1cs = general_purpose::STANDARD_NO_PAD.encode(&data); - let data = std::fs::read("../test-data/sudoku.wtns") - .expect("could not read file ../test-data/sudoku.wtns"); - let wtns = general_purpose::STANDARD_NO_PAD.encode(&data); - - // send bad r1cs data - let prover_inputs = ProverInputs { - r1cs: wtns.clone(), - wtns: wtns.clone(), - }; - - let result = do_prove(prover_inputs); - assert!(matches!(result, Err(GevulotError::R1csParseError))); - - // send bad wtns data - let prover_inputs = ProverInputs { - r1cs: r1cs.clone(), - wtns: r1cs.clone(), - }; - - let result = do_prove(prover_inputs); - assert!(matches!(result, Err(GevulotError::R1csParseError))); -} - -#[test] -fn test_bad_verification_input() { - let data = std::fs::read("../test-data/sudoku.r1cs") - .expect("could not read file ../test-data/sudoku.r1cs"); - let r1cs = general_purpose::STANDARD_NO_PAD.encode(&data); - let data = std::fs::read("../test-data/sudoku.wtns") - .expect("could not read file ../test-data/sudoku.wtns"); - let wtns = general_purpose::STANDARD_NO_PAD.encode(&data); - - let prover_inputs = ProverInputs { r1cs, wtns }; - - let prove_response = do_prove(prover_inputs).unwrap(); - let proof_info = prove_response - .proof_info - .expect("proof_info is not present"); - let proof_bytes: Vec = general_purpose::STANDARD_NO_PAD - .decode(proof_info.proof) - .expect("could not decode proof data from base64 string"); - let mut bad_proof_bytes = proof_bytes.clone(); - bad_proof_bytes[0] = 252; - bad_proof_bytes[1] = 253; - bad_proof_bytes[2] = 254; - bad_proof_bytes[3] = 255; - - let pvk_bytes: Vec = general_purpose::STANDARD_NO_PAD - .decode(proof_info.vk) - .expect("could not decode pvk data from base64 string"); - let mut bad_pvk_bytes = pvk_bytes.clone(); - bad_pvk_bytes[0] = 252; - bad_pvk_bytes[1] = 253; - bad_pvk_bytes[2] = 254; - bad_pvk_bytes[3] = 255; - - let mut inputs: Vec = Vec::new(); - for r in TEST_SUDOKU_CORRECT { - let fr = bigint256_to_fr(&BigInteger256::new([r, 0, 0, 0])); - inputs.push(fr); - } - - let result = do_verify(&bad_proof_bytes, &pvk_bytes, &inputs); - assert!(matches!(result, Err(GevulotError::CanonicalSerializeError))); - - let result = do_verify(&proof_bytes, &bad_pvk_bytes, &inputs); - assert!(matches!(result, Err(GevulotError::MarlinVerifyError))); -} diff --git a/prover/marlin/src/data_structures.rs b/prover/marlin/src/data_structures.rs deleted file mode 100644 index a433119d..00000000 --- a/prover/marlin/src/data_structures.rs +++ /dev/null @@ -1,196 +0,0 @@ -use crate::ahp::indexer::*; -use crate::ahp::prover::ProverMsg; -use crate::Vec; -use ark_ff::PrimeField; -use ark_poly::univariate::DensePolynomial; -use ark_poly_commit::{BatchLCProof, PolynomialCommitment}; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError}; -use ark_std::{ - format, - io::{Read, Write}, -}; - -/* ************************************************************************* */ -/* ************************************************************************* */ -/* ************************************************************************* */ - -/// The universal public parameters for the argument system. -pub type UniversalSRS = >>::UniversalParams; - -/* ************************************************************************* */ -/* ************************************************************************* */ -/* ************************************************************************* */ - -/// Verification key for a specific index (i.e., R1CS matrices). -#[derive(CanonicalSerialize, CanonicalDeserialize)] -pub struct IndexVerifierKey>> { - /// Stores information about the size of the index, as well as its field of - /// definition. - pub index_info: IndexInfo, - /// Commitments to the indexed polynomials. - pub index_comms: Vec, - /// The verifier key for this index, trimmed from the universal SRS. - pub verifier_key: PC::VerifierKey, -} - -impl>> ark_ff::ToBytes - for IndexVerifierKey -{ - fn write(&self, mut w: W) -> ark_std::io::Result<()> { - self.index_info.write(&mut w)?; - self.index_comms.write(&mut w) - } -} - -impl>> Clone - for IndexVerifierKey -{ - fn clone(&self) -> Self { - Self { - index_comms: self.index_comms.clone(), - index_info: self.index_info, - verifier_key: self.verifier_key.clone(), - } - } -} - -impl>> IndexVerifierKey { - /// Iterate over the commitments to indexed polynomials in `self`. - pub fn iter(&self) -> impl Iterator { - self.index_comms.iter() - } -} - -/* ************************************************************************* */ -/* ************************************************************************* */ -/* ************************************************************************* */ - -/// Proving key for a specific index (i.e., R1CS matrices). -#[derive(CanonicalSerialize, CanonicalDeserialize)] -pub struct IndexProverKey>> { - /// The index verifier key. - pub index_vk: IndexVerifierKey, - /// The randomness for the index polynomial commitments. - pub index_comm_rands: Vec, - /// The index itself. - pub index: Index, - /// The committer key for this index, trimmed from the universal SRS. - pub committer_key: PC::CommitterKey, -} - -impl>> Clone for IndexProverKey -where - PC::Commitment: Clone, -{ - fn clone(&self) -> Self { - Self { - index_vk: self.index_vk.clone(), - index_comm_rands: self.index_comm_rands.clone(), - index: self.index.clone(), - committer_key: self.committer_key.clone(), - } - } -} - -/* ************************************************************************* */ -/* ************************************************************************* */ -/* ************************************************************************* */ - -/// A zkSNARK proof. -#[derive(CanonicalSerialize, CanonicalDeserialize)] -pub struct Proof>> { - /// Commitments to the polynomials produced by the AHP prover. - pub commitments: Vec>, - /// Evaluations of these polynomials. - pub evaluations: Vec, - /// The field elements sent by the prover. - pub prover_messages: Vec>, - /// An evaluation proof from the polynomial commitment. - pub pc_proof: BatchLCProof, PC>, -} - -impl>> Proof { - /// Construct a new proof. - pub fn new( - commitments: Vec>, - evaluations: Vec, - prover_messages: Vec>, - pc_proof: BatchLCProof, PC>, - ) -> Self { - Self { - commitments, - evaluations, - prover_messages, - pc_proof, - } - } - - /// Prints information about the size of the proof. - pub fn print_size_info(&self) { - use ark_poly_commit::{PCCommitment, PCProof}; - - let size_of_fe_in_bytes = F::zero().into_repr().as_ref().len() * 8; - let mut num_comms_without_degree_bounds = 0; - let mut num_comms_with_degree_bounds = 0; - let mut size_bytes_comms_without_degree_bounds = 0; - let mut size_bytes_comms_with_degree_bounds = 0; - let mut size_bytes_proofs = 0; - for c in self.commitments.iter().flatten() { - if !c.has_degree_bound() { - num_comms_without_degree_bounds += 1; - size_bytes_comms_without_degree_bounds += c.size_in_bytes(); - } else { - num_comms_with_degree_bounds += 1; - size_bytes_comms_with_degree_bounds += c.size_in_bytes(); - } - } - - let proofs: Vec = self.pc_proof.proof.clone().into(); - let num_proofs = proofs.len(); - for proof in &proofs { - size_bytes_proofs += proof.size_in_bytes(); - } - - let num_evals = self.evaluations.len(); - let evals_size_in_bytes = num_evals * size_of_fe_in_bytes; - let num_prover_messages: usize = self - .prover_messages - .iter() - .map(|v| match v { - ProverMsg::EmptyMessage => 0, - ProverMsg::FieldElements(elems) => elems.len(), - }) - .sum(); - let prover_msg_size_in_bytes = num_prover_messages * size_of_fe_in_bytes; - let arg_size = size_bytes_comms_with_degree_bounds - + size_bytes_comms_without_degree_bounds - + size_bytes_proofs - + prover_msg_size_in_bytes - + evals_size_in_bytes; - let stats = format!( - "Argument size in bytes: {}\n\n\ - Number of commitments without degree bounds: {}\n\ - Size (in bytes) of commitments without degree bounds: {}\n\ - Number of commitments with degree bounds: {}\n\ - Size (in bytes) of commitments with degree bounds: {}\n\n\ - Number of evaluation proofs: {}\n\ - Size (in bytes) of evaluation proofs: {}\n\n\ - Number of evaluations: {}\n\ - Size (in bytes) of evaluations: {}\n\n\ - Number of field elements in prover messages: {}\n\ - Size (in bytes) of prover message: {}\n", - arg_size, - num_comms_without_degree_bounds, - size_bytes_comms_without_degree_bounds, - num_comms_with_degree_bounds, - size_bytes_comms_with_degree_bounds, - num_proofs, - size_bytes_proofs, - num_evals, - evals_size_in_bytes, - num_prover_messages, - prover_msg_size_in_bytes, - ); - add_to_trace!(|| "Statistics about proof", || stats); - } -} diff --git a/prover/marlin/src/error.rs b/prover/marlin/src/error.rs deleted file mode 100644 index 07f1b344..00000000 --- a/prover/marlin/src/error.rs +++ /dev/null @@ -1,26 +0,0 @@ -use crate::ahp::Error as AHPError; - -/// A `enum` specifying the possible failure modes of the `SNARK`. -#[derive(Debug)] -pub enum Error { - /// The index is too large for the universal public parameters. - IndexTooLarge, - /// There was an error in the underlying holographic IOP. - AHPError(AHPError), - /// There was an error in the underlying polynomial commitment. - PolynomialCommitmentError(E), -} - -impl From for Error { - fn from(err: AHPError) -> Self { - Error::AHPError(err) - } -} - -impl Error { - /// Convert an error in the underlying polynomial commitment scheme - /// to a `Error`. - pub fn from_pc_err(err: E) -> Self { - Error::PolynomialCommitmentError(err) - } -} diff --git a/prover/marlin/src/lib.rs b/prover/marlin/src/lib.rs deleted file mode 100644 index e5d5a8e9..00000000 --- a/prover/marlin/src/lib.rs +++ /dev/null @@ -1,440 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] -//! A crate for the Marlin preprocessing zkSNARK for R1CS. -//! -//! # Note -//! -//! Currently, Marlin only supports R1CS instances where the number of inputs -//! is the same as the number of constraints (i.e., where the constraint -//! matrices are square). Furthermore, Marlin only supports instances where the -//! public inputs are of size one less than a power of 2 (i.e., 2^n - 1). -#![deny(unused_import_braces, unused_qualifications, trivial_casts)] -#![deny(private_in_public)] -#![deny(stable_features, unreachable_pub, non_shorthand_field_patterns)] -#![deny(unused_attributes, unused_mut)] -#![deny(renamed_and_removed_lints, stable_features, unused_allocation)] -#![deny(unused_comparisons, bare_trait_objects, unused_must_use)] - -#[macro_use] -extern crate ark_std; - -use ark_ff::{to_bytes, PrimeField, UniformRand}; -use ark_poly::{univariate::DensePolynomial, EvaluationDomain, GeneralEvaluationDomain}; -use ark_poly_commit::Evaluations; -use ark_poly_commit::{LabeledCommitment, PCUniversalParams, PolynomialCommitment}; -use ark_relations::r1cs::ConstraintSynthesizer; -use ark_std::rand::RngCore; -use digest::Digest; - -use ark_std::{ - collections::BTreeMap, - format, - marker::PhantomData, - string::{String, ToString}, - vec, - vec::Vec, -}; - -#[cfg(not(feature = "std"))] -macro_rules! eprintln { - () => {}; - ($($arg: tt)*) => {}; -} - -/// Implements a Fiat-Shamir based Rng that allows one to incrementally update -/// the seed based on new messages in the proof transcript. -pub mod rng; -use rng::FiatShamirRng; - -mod error; -pub use error::*; - -mod data_structures; -pub use data_structures::*; - -/// Implements an Algebraic Holographic Proof (AHP) for the R1CS indexed relation. -pub mod ahp; -pub mod api; -pub use ahp::AHPForR1CS; -use ahp::EvaluationsProvider; - -#[cfg(test)] -mod test; - -/// The compiled argument system. -pub struct Marlin>, D: Digest>( - #[doc(hidden)] PhantomData, - #[doc(hidden)] PhantomData, - #[doc(hidden)] PhantomData, -); - -impl>, D: Digest> Marlin { - /// The personalization string for this protocol. Used to personalize the - /// Fiat-Shamir rng. - pub const PROTOCOL_NAME: &'static [u8] = b"MARLIN-2019"; - - /// Generate the universal prover and verifier keys for the - /// argument system. - pub fn universal_setup( - num_constraints: usize, - num_variables: usize, - num_non_zero: usize, - rng: &mut R, - ) -> Result, Error> { - println!("------------------num_constraints {}", num_constraints); - println!("------------------num_variables {}", num_variables); - println!("------------------num_non_zero {}", num_non_zero); - let max_degree = AHPForR1CS::::max_degree(num_constraints, num_variables, num_non_zero)?; - println!("------------------max_degree {}", max_degree); - let setup_time = start_timer!(|| { - format!( - "Marlin::UniversalSetup with max_degree {}, computed for a maximum of {} constraints, {} vars, {} non_zero", - max_degree, num_constraints, num_variables, num_non_zero, - ) - }); - - let srs = PC::setup(max_degree, None, rng).map_err(Error::from_pc_err); - end_timer!(setup_time); - srs - } - - /// Generate the index-specific (i.e., circuit-specific) prover and verifier - /// keys. This is a deterministic algorithm that anyone can rerun. - #[allow(clippy::type_complexity)] - pub fn index>( - srs: &UniversalSRS, - c: C, - ) -> Result<(IndexProverKey, IndexVerifierKey), Error> { - let index_time = start_timer!(|| "Marlin::Index"); - - // TODO: Add check that c is in the correct mode. - let index = AHPForR1CS::index(c)?; - println!("srs.max_degree() {}", srs.max_degree()); - println!("index.max_degree() {}", index.max_degree()); - if srs.max_degree() < index.max_degree() { - Err(Error::IndexTooLarge)?; - } - - let coeff_support = AHPForR1CS::get_degree_bounds(&index.index_info); - // Marlin only needs degree 2 random polynomials - let supported_hiding_bound = 1; - let (committer_key, verifier_key) = PC::trim( - srs, - index.max_degree(), - supported_hiding_bound, - Some(&coeff_support), - ) - .map_err(Error::from_pc_err)?; - - let commit_time = start_timer!(|| "Commit to index polynomials"); - let (index_comms, index_comm_rands): (_, _) = - PC::commit(&committer_key, index.iter(), None).map_err(Error::from_pc_err)?; - end_timer!(commit_time); - - let index_comms = index_comms - .into_iter() - .map(|c| c.commitment().clone()) - .collect(); - let index_vk = IndexVerifierKey { - index_info: index.index_info, - index_comms, - verifier_key, - }; - - let index_pk = IndexProverKey { - index, - index_comm_rands, - index_vk: index_vk.clone(), - committer_key, - }; - - end_timer!(index_time); - - Ok((index_pk, index_vk)) - } - - /// Create a zkSNARK asserting that the constraint system is satisfied. - pub fn prove, R: RngCore>( - index_pk: &IndexProverKey, - c: C, - zk_rng: &mut R, - ) -> Result, Error> { - let prover_time = start_timer!(|| "Marlin::Prover"); - // Add check that c is in the correct mode. - - let prover_init_state = AHPForR1CS::prover_init(&index_pk.index, c)?; - let public_input = prover_init_state.public_input(); - let mut fs_rng = FiatShamirRng::::from_seed( - &to_bytes![&Self::PROTOCOL_NAME, &index_pk.index_vk, &public_input].unwrap(), - ); - - // -------------------------------------------------------------------- - // First round - - let (prover_first_msg, prover_first_oracles, prover_state) = - AHPForR1CS::prover_first_round(prover_init_state, zk_rng)?; - - let first_round_comm_time = start_timer!(|| "Committing to first round polys"); - let (first_comms, first_comm_rands) = PC::commit( - &index_pk.committer_key, - prover_first_oracles.iter(), - Some(zk_rng), - ) - .map_err(Error::from_pc_err)?; - end_timer!(first_round_comm_time); - - fs_rng.absorb(&to_bytes![first_comms, prover_first_msg].unwrap()); - - let (verifier_first_msg, verifier_state) = - AHPForR1CS::verifier_first_round(index_pk.index_vk.index_info, &mut fs_rng)?; - // -------------------------------------------------------------------- - - // -------------------------------------------------------------------- - // Second round - - let (prover_second_msg, prover_second_oracles, prover_state) = - AHPForR1CS::prover_second_round(&verifier_first_msg, prover_state, zk_rng); - - let second_round_comm_time = start_timer!(|| "Committing to second round polys"); - let (second_comms, second_comm_rands) = PC::commit( - &index_pk.committer_key, - prover_second_oracles.iter(), - Some(zk_rng), - ) - .map_err(Error::from_pc_err)?; - end_timer!(second_round_comm_time); - - fs_rng.absorb(&to_bytes![second_comms, prover_second_msg].unwrap()); - - let (verifier_second_msg, verifier_state) = - AHPForR1CS::verifier_second_round(verifier_state, &mut fs_rng); - // -------------------------------------------------------------------- - - // -------------------------------------------------------------------- - // Third round - let (prover_third_msg, prover_third_oracles) = - AHPForR1CS::prover_third_round(&verifier_second_msg, prover_state, zk_rng)?; - - let third_round_comm_time = start_timer!(|| "Committing to third round polys"); - let (third_comms, third_comm_rands) = PC::commit( - &index_pk.committer_key, - prover_third_oracles.iter(), - Some(zk_rng), - ) - .map_err(Error::from_pc_err)?; - end_timer!(third_round_comm_time); - - fs_rng.absorb(&to_bytes![third_comms, prover_third_msg].unwrap()); - - let verifier_state = AHPForR1CS::verifier_third_round(verifier_state, &mut fs_rng); - // -------------------------------------------------------------------- - - // Gather prover polynomials in one vector. - let polynomials: Vec<_> = index_pk - .index - .iter() - .chain(prover_first_oracles.iter()) - .chain(prover_second_oracles.iter()) - .chain(prover_third_oracles.iter()) - .collect(); - - // Gather commitments in one vector. - #[rustfmt::skip] - let commitments = vec![ - first_comms.iter().map(|p| p.commitment().clone()).collect(), - second_comms.iter().map(|p| p.commitment().clone()).collect(), - third_comms.iter().map(|p| p.commitment().clone()).collect(), - ]; - let labeled_comms: Vec<_> = index_pk - .index_vk - .iter() - .cloned() - .zip(&AHPForR1CS::::INDEXER_POLYNOMIALS) - .map(|(c, l)| LabeledCommitment::new(l.to_string(), c, None)) - .chain(first_comms.iter().cloned()) - .chain(second_comms.iter().cloned()) - .chain(third_comms.iter().cloned()) - .collect(); - - // Gather commitment randomness together. - let comm_rands: Vec = index_pk - .index_comm_rands - .clone() - .into_iter() - .chain(first_comm_rands) - .chain(second_comm_rands) - .chain(third_comm_rands) - .collect(); - - // Compute the AHP verifier's query set. - let (query_set, verifier_state) = - AHPForR1CS::verifier_query_set(verifier_state, &mut fs_rng); - let lc_s = AHPForR1CS::construct_linear_combinations( - &public_input, - &polynomials, - &verifier_state, - )?; - - let eval_time = start_timer!(|| "Evaluating linear combinations over query set"); - let mut evaluations = Vec::new(); - for (label, (_, point)) in &query_set { - let lc = lc_s - .iter() - .find(|lc| &lc.label == label) - .ok_or(ahp::Error::MissingEval(label.to_string()))?; - let eval = polynomials.get_lc_eval(lc, *point)?; - if !AHPForR1CS::::LC_WITH_ZERO_EVAL.contains(&lc.label.as_ref()) { - evaluations.push((label.to_string(), eval)); - } - } - - evaluations.sort_by(|a, b| a.0.cmp(&b.0)); - let evaluations = evaluations.into_iter().map(|x| x.1).collect::>(); - end_timer!(eval_time); - - fs_rng.absorb(&evaluations); - let opening_challenge: F = u128::rand(&mut fs_rng).into(); - - let pc_proof = PC::open_combinations( - &index_pk.committer_key, - &lc_s, - polynomials, - &labeled_comms, - &query_set, - opening_challenge, - &comm_rands, - Some(zk_rng), - ) - .map_err(Error::from_pc_err)?; - - // Gather prover messages together. - let prover_messages = vec![prover_first_msg, prover_second_msg, prover_third_msg]; - - let proof = Proof::new(commitments, evaluations, prover_messages, pc_proof); - proof.print_size_info(); - end_timer!(prover_time); - Ok(proof) - } - - /// Verify that a proof for the constrain system defined by `C` asserts that - /// all constraints are satisfied. - pub fn verify( - index_vk: &IndexVerifierKey, - public_input: &[F], - proof: &Proof, - rng: &mut R, - ) -> Result> { - let verifier_time = start_timer!(|| "Marlin::Verify"); - - let public_input = { - let domain_x = GeneralEvaluationDomain::::new(public_input.len() + 1).unwrap(); - - let mut unpadded_input = public_input.to_vec(); - unpadded_input.resize( - core::cmp::max(public_input.len(), domain_x.size() - 1), - F::zero(), - ); - - unpadded_input - }; - - let mut fs_rng = FiatShamirRng::::from_seed( - &to_bytes![&Self::PROTOCOL_NAME, &index_vk, &public_input].unwrap(), - ); - - // -------------------------------------------------------------------- - // First round - - let first_comms = &proof.commitments[0]; - fs_rng.absorb(&to_bytes![first_comms, proof.prover_messages[0]].unwrap()); - - let (_, verifier_state) = - AHPForR1CS::verifier_first_round(index_vk.index_info, &mut fs_rng)?; - // -------------------------------------------------------------------- - - // -------------------------------------------------------------------- - // Second round - let second_comms = &proof.commitments[1]; - fs_rng.absorb(&to_bytes![second_comms, proof.prover_messages[1]].unwrap()); - - let (_, verifier_state) = AHPForR1CS::verifier_second_round(verifier_state, &mut fs_rng); - // -------------------------------------------------------------------- - - // -------------------------------------------------------------------- - // Third round - let third_comms = &proof.commitments[2]; - fs_rng.absorb(&to_bytes![third_comms, proof.prover_messages[2]].unwrap()); - - let verifier_state = AHPForR1CS::verifier_third_round(verifier_state, &mut fs_rng); - // -------------------------------------------------------------------- - - // Collect degree bounds for commitments. Indexed polynomials have *no* - // degree bounds because we know the committed index polynomial has the - // correct degree. - let index_info = index_vk.index_info; - let degree_bounds = vec![None; index_vk.index_comms.len()] - .into_iter() - .chain(AHPForR1CS::prover_first_round_degree_bounds(&index_info)) - .chain(AHPForR1CS::prover_second_round_degree_bounds(&index_info)) - .chain(AHPForR1CS::prover_third_round_degree_bounds(&index_info)) - .collect::>(); - - // Gather commitments in one vector. - let commitments: Vec<_> = index_vk - .iter() - .chain(first_comms) - .chain(second_comms) - .chain(third_comms) - .cloned() - .zip(AHPForR1CS::::polynomial_labels()) - .zip(degree_bounds) - .map(|((c, l), d)| LabeledCommitment::new(l, c, d)) - .collect(); - - let (query_set, verifier_state) = - AHPForR1CS::verifier_query_set(verifier_state, &mut fs_rng); - - fs_rng.absorb(&proof.evaluations); - let opening_challenge: F = u128::rand(&mut fs_rng).into(); - - let mut evaluations = Evaluations::new(); - let mut evaluation_labels = Vec::new(); - for (poly_label, (_, point)) in query_set.iter().cloned() { - if AHPForR1CS::::LC_WITH_ZERO_EVAL.contains(&poly_label.as_ref()) { - evaluations.insert((poly_label, point), F::zero()); - } else { - evaluation_labels.push((poly_label, point)); - } - } - evaluation_labels.sort_by(|a, b| a.0.cmp(&b.0)); - for (q, eval) in evaluation_labels.into_iter().zip(&proof.evaluations) { - evaluations.insert(q, *eval); - } - - let lc_s = AHPForR1CS::construct_linear_combinations( - &public_input, - &evaluations, - &verifier_state, - )?; - - let evaluations_are_correct = PC::check_combinations( - &index_vk.verifier_key, - &lc_s, - &commitments, - &query_set, - &evaluations, - &proof.pc_proof, - opening_challenge, - rng, - ) - .map_err(Error::from_pc_err)?; - - if !evaluations_are_correct { - //eprintln!("PC::Check failed"); - } - end_timer!(verifier_time, || format!( - " PC::Check for AHP Verifier linear equations: {}", - evaluations_are_correct - )); - Ok(evaluations_are_correct) - } -} diff --git a/prover/marlin/src/rng.rs b/prover/marlin/src/rng.rs deleted file mode 100644 index 077cd4fd..00000000 --- a/prover/marlin/src/rng.rs +++ /dev/null @@ -1,69 +0,0 @@ -use crate::Vec; -use ark_ff::{FromBytes, ToBytes}; -use ark_std::marker::PhantomData; -use ark_std::rand::{RngCore, SeedableRng}; -use digest::{generic_array::GenericArray, Digest}; -use rand_chacha::ChaChaRng; - -/// A `SeedableRng` that refreshes its seed by hashing together the previous seed -/// and the new seed material. -// TODO: later: re-evaluate decision about ChaChaRng -pub struct FiatShamirRng { - r: ChaChaRng, - seed: GenericArray, - #[doc(hidden)] - digest: PhantomData, -} - -impl RngCore for FiatShamirRng { - #[inline] - fn next_u32(&mut self) -> u32 { - self.r.next_u32() - } - - #[inline] - fn next_u64(&mut self) -> u64 { - self.r.next_u64() - } - - #[inline] - fn fill_bytes(&mut self, dest: &mut [u8]) { - self.r.fill_bytes(dest); - } - - #[inline] - fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), ark_std::rand::Error> { - self.r.fill_bytes(dest); - Ok(()) - } -} - -impl FiatShamirRng { - /// Create a new `Self` by initializing with a fresh seed. - /// `self.seed = H(self.seed || new_seed)`. - #[inline] - pub fn from_seed<'a, T: 'a + ToBytes>(seed: &'a T) -> Self { - let mut bytes = Vec::new(); - seed.write(&mut bytes).expect("failed to convert to bytes"); - let seed = D::digest(&bytes); - let r_seed: [u8; 32] = FromBytes::read(seed.as_ref()).expect("failed to get [u32; 8]"); - let r = ChaChaRng::from_seed(r_seed); - Self { - r, - seed, - digest: PhantomData, - } - } - - /// Refresh `self.seed` with new material. Achieved by setting - /// `self.seed = H(self.seed || new_seed)`. - #[inline] - pub fn absorb<'a, T: 'a + ToBytes>(&mut self, seed: &'a T) { - let mut bytes = Vec::new(); - seed.write(&mut bytes).expect("failed to convert to bytes"); - bytes.extend_from_slice(&self.seed); - self.seed = D::digest(&bytes); - let seed: [u8; 32] = FromBytes::read(self.seed.as_ref()).expect("failed to get [u32; 8]"); - self.r = ChaChaRng::from_seed(seed); - } -} diff --git a/prover/marlin/src/test.rs b/prover/marlin/src/test.rs deleted file mode 100644 index 0a4f7515..00000000 --- a/prover/marlin/src/test.rs +++ /dev/null @@ -1,227 +0,0 @@ -use ark_ff::Field; -use ark_relations::{ - lc, - r1cs::{ConstraintSynthesizer, ConstraintSystemRef, SynthesisError}, -}; -use ark_std::marker::PhantomData; - -#[derive(Copy, Clone)] -struct Circuit { - a: Option, - b: Option, - num_constraints: usize, - num_variables: usize, -} - -impl ConstraintSynthesizer for Circuit { - fn generate_constraints( - self, - cs: ConstraintSystemRef, - ) -> Result<(), SynthesisError> { - let a = cs.new_witness_variable(|| self.a.ok_or(SynthesisError::AssignmentMissing))?; - let b = cs.new_witness_variable(|| self.b.ok_or(SynthesisError::AssignmentMissing))?; - let c = cs.new_input_variable(|| { - let mut a = self.a.ok_or(SynthesisError::AssignmentMissing)?; - let b = self.b.ok_or(SynthesisError::AssignmentMissing)?; - - a.mul_assign(&b); - Ok(a) - })?; - let d = cs.new_input_variable(|| { - let mut a = self.a.ok_or(SynthesisError::AssignmentMissing)?; - let b = self.b.ok_or(SynthesisError::AssignmentMissing)?; - - a.mul_assign(&b); - a.mul_assign(&b); - Ok(a) - })?; - - for _ in 0..(self.num_variables - 3) { - let _ = cs.new_witness_variable(|| self.a.ok_or(SynthesisError::AssignmentMissing))?; - } - - for _ in 0..(self.num_constraints - 1) { - cs.enforce_constraint(lc!() + a, lc!() + b, lc!() + c)?; - } - cs.enforce_constraint(lc!() + c, lc!() + b, lc!() + d)?; - - Ok(()) - } -} - -#[derive(Clone)] -/// Define a constraint system that would trigger outlining. -struct OutlineTestCircuit { - field_phantom: PhantomData, -} - -impl ConstraintSynthesizer for OutlineTestCircuit { - fn generate_constraints(self, cs: ConstraintSystemRef) -> Result<(), SynthesisError> { - // This program checks if the input elements are between 0 and 9. - // - // Note that this constraint system is neither the most intuitive way nor - // the most efficient way for such a task. It is for testing purposes, - // as we want to trigger the outlining. - // - let mut inputs = Vec::new(); - for i in 0..5 { - inputs.push(cs.new_input_variable(|| Ok(F::from(i as u128)))?); - } - - for i in 0..5 { - let mut total_count_for_this_input = cs.new_lc(lc!()).unwrap(); - - for bucket in 0..10 { - let count_increment_for_this_bucket = - cs.new_witness_variable(|| Ok(F::from(i == bucket)))?; - - total_count_for_this_input = cs - .new_lc( - lc!() - + (F::one(), total_count_for_this_input) - + (F::one(), count_increment_for_this_bucket.clone()), - ) - .unwrap(); - - // Only when `input[i]` equals `bucket` can `count_increment_for_this_bucket` be nonzero. - // - // A malicious prover can make `count_increment_for_this_bucket` neither 0 nor 1. - // But the constraint on `total_count_for_this_input` will reject such case. - // - // At a high level, only one of the `count_increment_for_this_bucket` among all the buckets - // could be nonzero, which equals `total_count_for_this_input`. Thus, by checking whether - // `total_count_for_this_input` is 1, we know this input number is in the range. - // - cs.enforce_constraint( - lc!() + (F::one(), inputs[i].clone()) - - (F::from(bucket as u128), ark_relations::r1cs::Variable::One), - lc!() + (F::one(), count_increment_for_this_bucket), - lc!(), - )?; - } - - // Enforce `total_count_for_this_input` to be one. - cs.enforce_constraint( - lc!(), - lc!(), - lc!() + (F::one(), total_count_for_this_input.clone()) - - (F::one(), ark_relations::r1cs::Variable::One), - )?; - } - - Ok(()) - } -} - -mod marlin { - use super::*; - use crate::Marlin; - - use ark_bn254::{Bn254, Fr}; - use ark_ff::BigInteger256; - use ark_poly::univariate::DensePolynomial; - use ark_poly_commit::marlin_pc::MarlinKZG10; - use ark_std::ops::MulAssign; - use blake2::Blake2s; - - type MultiPC = MarlinKZG10>; - type MarlinInst = Marlin; - - fn test_circuit(num_constraints: usize, num_variables: usize) { - let rng = &mut ark_std::test_rng(); - - let universal_srs = MarlinInst::universal_setup(100, 25, 300, rng).unwrap(); - - // for _ in 0..6 { - // let a = Fr::rand(rng); - // let b = Fr::rand(rng); - let a = Fr::new(BigInteger256([3, 0, 0, 0])); - let b = Fr::new(BigInteger256([4, 0, 0, 0])); - let mut c = a; - c.mul_assign(&b); - let mut d = c; - d.mul_assign(&b); - - let circ = Circuit { - a: Some(a), - b: Some(b), - num_constraints, - num_variables, - }; - - let (index_pk, index_vk) = MarlinInst::index(&universal_srs, circ.clone()).unwrap(); - println!("Called index"); - - let proof = MarlinInst::prove(&index_pk, circ, rng).unwrap(); - println!("Called prover"); - - assert!(MarlinInst::verify(&index_vk, &[c, d], &proof, rng).unwrap()); - println!("Called verifier"); - } - - #[test] - fn prove_and_verify_with_tall_matrix_big() { - let num_constraints = 100; - let num_variables = 25; - - test_circuit(num_constraints, num_variables); - } - - #[test] - fn prove_and_verify_with_tall_matrix_small() { - let num_constraints = 26; - let num_variables = 25; - - test_circuit(num_constraints, num_variables); - } - - #[test] - fn prove_and_verify_with_squat_matrix_big() { - let num_constraints = 25; - let num_variables = 100; - - test_circuit(num_constraints, num_variables); - } - - #[test] - fn prove_and_verify_with_squat_matrix_small() { - let num_constraints = 25; - let num_variables = 26; - - test_circuit(num_constraints, num_variables); - } - - #[test] - fn prove_and_verify_with_square_matrix() { - let num_constraints = 25; - let num_variables = 25; - - test_circuit(num_constraints, num_variables); - } - - #[test] - /// Test on a constraint system that will trigger outlining. - fn prove_and_test_outlining() { - let rng = &mut ark_std::test_rng(); - - let universal_srs = MarlinInst::universal_setup(150, 150, 150, rng).unwrap(); - - let circ = OutlineTestCircuit { - field_phantom: PhantomData, - }; - - let (index_pk, index_vk) = MarlinInst::index(&universal_srs, circ.clone()).unwrap(); - println!("Called index"); - - let proof = MarlinInst::prove(&index_pk, circ, rng).unwrap(); - println!("Called prover"); - - let mut inputs = Vec::new(); - for i in 0..5 { - inputs.push(Fr::from(i as u128)); - } - - assert!(MarlinInst::verify(&index_vk, &inputs, &proof, rng).unwrap()); - println!("Called verifier"); - } -} diff --git a/prover/rust-fil-proofs/CHANGELOG.md b/prover/rust-fil-proofs/CHANGELOG.md deleted file mode 100644 index 2c771507..00000000 --- a/prover/rust-fil-proofs/CHANGELOG.md +++ /dev/null @@ -1,444 +0,0 @@ -# Changelog - -All notable changes to rust-fil-proofs will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://book.async.rs/overview/stability-guarantees.html). - -## Unreleased - -## [15.0.0] - 2023-06-30 - -- Add SyntheticPoRep audit results to repo [#1710](https://github.com/filecoin-project/rust-fil-proofs/pull/1710) -- Remove DRG PoRep (historical code; unused on mainnet) [#1684](https://github.com/filecoin-project/rust-fil-proofs/pull/1684) -- Document the TreeRLast tree generation [#1699](https://github.com/filecoin-project/rust-fil-proofs/pull/1699) -- Optimize add_piece method [#1707](https://github.com/filecoin-project/rust-fil-proofs/pull/1707) -- Refactor replicate_phase2 arguments [#1700](https://github.com/filecoin-project/rust-fil-proofs/pull/1700) -- Add public API to generate tree_r_last and tree_c [#1705](https://github.com/filecoin-project/rust-fil-proofs/pull/1705) -- Add method to decode a range from an updated sector [#1704](https://github.com/filecoin-project/rust-fil-proofs/pull/1704) -- Clarify h and h_select usage [#1696](https://github.com/filecoin-project/rust-fil-proofs/pull/1696) -- Add new from trait for PoseidonDomain [#1703](https://github.com/filecoin-project/rust-fil-proofs/pull/1703) -- Ensure that number of layers matches column arity [#1702](https://github.com/filecoin-project/rust-fil-proofs/pull/1702) -- Clean up some code and mutability usage [#1698](https://github.com/filecoin-project/rust-fil-proofs/pull/1698) -- Remove superfluous API generic [#1695](https://github.com/filecoin-project/rust-fil-proofs/pull/1695) -- copy_parents_data optimization using base parents only [#1660](https://github.com/filecoin-project/rust-fil-proofs/pull/1660) -- Update to the newest version of ff dependency [#1691](https://github.com/filecoin-project/rust-fil-proofs/pull/1691) -- Replace heim dep with sysinfo [#1694](https://github.com/filecoin-project/rust-fil-proofs/pull/1694) -- rustix dependency update [#1693](https://github.com/filecoin-project/rust-fil-proofs/pull/1693) -- TreeD size and rows to discard calculation fix [#1692](https://github.com/filecoin-project/rust-fil-proofs/pull/1692) -- Benchy fix for output results without git info [#1688](https://github.com/filecoin-project/rust-fil-proofs/pull/1688) -- Add parallel tasks to WindowPoSt bench [#1686](https://github.com/filecoin-project/rust-fil-proofs/pull/1686) -- Return last layer from Labels [#1685](https://github.com/filecoin-project/rust-fil-proofs/pull/1685) -- Support optional API features for ranges of API versions [#1683](https://github.com/filecoin-project/rust-fil-proofs/pull/1683) - -## [14.0.0] - 2023-03-17 - -- Allow PC1 unreplicated data to be /dev/zero [#1681](https://github.com/filecoin-project/rust-fil-proofs/pull/1681) -- Add additional tests for faulty sector reporting [#1680](https://github.com/filecoin-project/rust-fil-proofs/pull/1680) -- Make builds on stable and aarch64 possible [#1679](https://github.com/filecoin-project/rust-fil-proofs/pull/1679) -- Fix the open grindability issue [#1661](https://github.com/filecoin-project/rust-fil-proofs/pull/1661) -- Add the v13 Cargo.lock file [#1673](https://github.com/filecoin-project/rust-fil-proofs/pull/1673) - -## [13.0.0] - 2023-03-06 - -- Disable broken coverage job CI coverage job [#1669](https://github.com/filecoin-project/rust-fil-proofs/pull/1669) -- Update rust-toolchain to 1.67.1 [#1668](https://github.com/filecoin-project/rust-fil-proofs/pull/1668) -- Clean up tree definitions [#1655](https://github.com/filecoin-project/rust-fil-proofs/pull/1655) -- Introduce PoRepConfig::new_groth16() [#1635](https://github.com/filecoin-project/rust-fil-proofs/pull/1635) -- Fix broken links in README.md [#1649](https://github.com/filecoin-project/rust-fil-proofs/pull/1649) -- Update ec-gpu-gen [#1638](https://github.com/filecoin-project/rust-fil-proofs/pull/1638) -- Use current process binding to limit thread cores [#1633](https://github.com/filecoin-project/rust-fil-proofs/pull/1633) -- Ensure that WindowPoSt works on read-only files [#1630](https://github.com/filecoin-project/rust-fil-proofs/pull/1630) -- Added Tarpaulin Coverage [#1628](https://github.com/filecoin-project/rust-fil-proofs/pull/1628) -- Use memmap2 instead of mapr [#1624](https://github.com/filecoin-project/rust-fil-proofs/pull/1624) -- Update CircleCI to xcode 13.4.1 [#1625](https://github.com/filecoin-project/rust-fil-proofs/pull/1625) -- Update rust-toolchain to 1.62.0 [#1623](https://github.com/filecoin-project/rust-fil-proofs/pull/1623) - -## [12.0.0] - 2022-08-04 - -- Add additional sector logging [#1610](https://github.com/filecoin-project/rust-fil-proofs/pull/1610) -- Make it possible bind to cores using multicore SDR if units > groups [#1588](https://github.com/filecoin-project/rust-fil-proofs/pull/1588) -- Update repo dependencies and forward port v11.x release updates [#1615](https://github.com/filecoin-project/rust-fil-proofs/pull/1615) -- Update rust-toolchain to 1.59.0 [#1607](https://github.com/filecoin-project/rust-fil-proofs/pull/1607) -- Correct comment in SDR code [#1603](https://github.com/filecoin-project/rust-fil-proofs/pull/1603) -- Remove unused dependencies [#1600](https://github.com/filecoin-project/rust-fil-proofs/pull/1600) -- CI: run storage-proofs-update tests [#1599](https://github.com/filecoin-project/rust-fil-proofs/pull/1599) -- CI: split GPU tree building test runs [#1594](https://github.com/filecoin-project/rust-fil-proofs/pull/1594) -- CI: improve tests on MacOS [#1597](https://github.com/filecoin-project/rust-fil-proofs/pull/1597) -- Remove unused dependencies from storage-proofs-update [#1593](https://github.com/filecoin-project/rust-fil-proofs/pull/1593) -- Add SectorUpdate Compount tests to ignored [#1592](https://github.com/filecoin-project/rust-fil-proofs/pull/1592) -- Update fil_logger due to failures [#1591](https://github.com/filecoin-project/rust-fil-proofs/pull/1591) -- Update CLI to properly use default values [#1590](https://github.com/filecoin-project/rust-fil-proofs/pull/1590) -- CI: run most tests on specified rust-toolchain [#1587](https://github.com/filecoin-project/rust-fil-proofs/pull/1587) -- CI: run no GPU tests in release mode [#1586](https://github.com/filecoin-project/rust-fil-proofs/pull/1586) -- CI: remove redundant test [#1585](https://github.com/filecoin-project/rust-fil-proofs/pull/1585) -- Update repo dependencies and cleanups [#1584](https://github.com/filecoin-project/rust-fil-proofs/pull/1584) -- Increase parallelism in Window PoSt [#1580](https://github.com/filecoin-project/rust-fil-proofs/pull/1580) -- CI: Use parameter cache on MacOS [#1583](https://github.com/filecoin-project/rust-fil-proofs/pull/1583) -- CI: Resolve timeout due to ipget issue [#1582](https://github.com/filecoin-project/rust-fil-proofs/pull/1582) -- Update rust-toolchain to 1.56.0 [#1576](https://github.com/filecoin-project/rust-fil-proofs/pull/1576) -- Extend winning_post bench to allow fake sealing [#1571](https://github.com/filecoin-project/rust-fil-proofs/pull/1571) -- Update byte-unit version [#1574](https://github.com/filecoin-project/rust-fil-proofs/pull/1574) -- Fix incorrect sector size in README [#1566](https://github.com/filecoin-project/rust-fil-proofs/pull/1566) -- Re-use method for parameter verification [#1567](https://github.com/filecoin-project/rust-fil-proofs/pull/1567) - -## [11.1.1] - 2022-06-15 - -- Lock versions to the correct minor number [#1614](https://github.com/filecoin-project/rust-fil-proofs/pull/1614) - -## [11.1.0] - 2022-06-13 - -- Updates for aggregate proof versioning support [#1612](https://github.com/filecoin-project/rust-fil-proofs/pull/1612) - -## [11.0.2] - 2022-02-09 - -- Fix cache clearing by resetting the cache path first [#1563](https://github.com/filecoin-project/rust-fil-proofs/pull/1563) -- Test updates and clean-ups [#1562](https://github.com/filecoin-project/rust-fil-proofs/pull/1562) - -## [11.0.1] - 2022-02-03 - -- NOTE: This release contains the SnapDeals related API and funtionality. The parameters referenced in the parameters.json are now mainnet ready. -- Update SnapDeal Production Parameters [#1559](https://github.com/filecoin-project/rust-fil-proofs/pull/1559) -- Add Poseidon version of SnapDeals (concept, not full impl) [#1547](https://github.com/filecoin-project/rust-fil-proofs/pull/1547) -- Fix empty sector update proof priority and add debugging [#1558](https://github.com/filecoin-project/rust-fil-proofs/pull/1558) -- Correctly set the cache path for empty sector update proofs [#1557](https://github.com/filecoin-project/rust-fil-proofs/pull/1557) -- Update project codeowners file [#1555](https://github.com/filecoin-project/rust-fil-proofs/pull/1555) -- Add releases dir with Cargo.lock files for future releases [#1554](https://github.com/filecoin-project/rust-fil-proofs/pull/1554) -- Make paramcache arguments mututally exclusive [#1552](https://github.com/filecoin-project/rust-fil-proofs/pull/1552) - -## [11.0.0] - 2022-01-10 - -- NOTE: This release contains the SnapDeals related API and funtionality, however the parameters referenced in the parameters.json are NOT -mainnet ready and will be replaced in a future version. This release is intended for testing SnapDeals only. -- Update paramcache to properly generate .meta files for Empty Sector Update parameters [#1551](https://github.com/filecoin-project/rust-fil-proofs/pull/1551) -- Add support for Empty Sector Update proofs (SnapDeal) [#1519](https://github.com/filecoin-project/rust-fil-proofs/pull/1519) -- Expose multicore sdr feature explicitly [#1510](https://github.com/filecoin-project/rust-fil-proofs/pull/1510) -- Reset multicore sdr consumer [#1535](https://github.com/filecoin-project/rust-fil-proofs/pull/1535) -- Update heim dep to current master branch [#1539](https://github.com/filecoin-project/rust-fil-proofs/pull/1539) - -## [10.1.0] - 2021-10-25 - -- Allow window post proving on a single partition basis [#1526](https://github.com/filecoin-project/rust-fil-proofs/pull/1526) -- Update bellperson, neptune, and rust-toolchain [#1529](https://github.com/filecoin-project/rust-fil-proofs/pull/1529) -- Reduce verbose info logging [#1530](https://github.com/filecoin-project/rust-fil-proofs/pull/1530) -- Improve benchy by printing help when no command is given [#1527](https://github.com/filecoin-project/rust-fil-proofs/pull/1527) -- Fall back to CPU if GPU is not available [#1517](https://github.com/filecoin-project/rust-fil-proofs/pull/1517) -- remove FIL_PROOFS_CUDA_NVCC_ARGS env var [#1520](https://github.com/filecoin-project/rust-fil-proofs/pull/1520) -- Split GPU Tree builder CI jobs [#1518](https://github.com/filecoin-project/rust-fil-proofs/pull/1518) -- Use GPU Tree builder only for Poseidon hashes [#1515](https://github.com/filecoin-project/rust-fil-proofs/pull/1515) -- Run GPU Tree building tests on all CI tests [#1514](https://github.com/filecoin-project/rust-fil-proofs/pull/1514) - -## [10.0.0] - 2021-09-30 - -- Integrate a variety of zk-SNARK proving related performance improvements. For details see [#220](https://github.com/filecoin-project/bellperson#220) -- Properly implement and document the CUDA feature [#1507](https://github.com/filecoin-project/rust-fil-proofs/pull/1507) -- Remove pairing dependency for circuit [#1509](https://github.com/filecoin-project/rust-fil-proofs/pull/1509) -- Warm up cache for window post verify bench [#1508](https://github.com/filecoin-project/rust-fil-proofs/pull/1508) -- Upgrade to dependencies supporting CUDA [#1504](https://github.com/filecoin-project/rust-fil-proofs/pull/1504) -- Use upstream group, ff and pairing dependencies [#1488](https://github.com/filecoin-project/rust-fil-proofs/pull/1488) - -## [9.0.2] - 2021-09-07 - -- Use sync channels in PC2 [#1500](https://github.com/filecoin-project/rust-fil-proofs/pull/1500) -- Return error verifiying empty proof bytes [#1498](https://github.com/filecoin-project/rust-fil-proofs/pull/1498) -- Serialize parent's cache generation and access [#1496](https://github.com/filecoin-project/rust-fil-proofs/pull/1496) - -## [9.0.1] - 2021-08-16 - -- Flush mutable mmap after data updates [#1493](https://github.com/filecoin-project/rust-fil-proofs/pull/1493) -- Revert usage of bitmask in multicore sdr [#1492](https://github.com/filecoin-project/rust-fil-proofs/pull/1492) - -## [9.0.0] - 2021-08-12 - -- Correct usage of bitmask in multicore sdr (authored by @qy3u) [#1477](https://github.com/filecoin-project/rust-fil-proofs/pull/1477) -- Switch to yastl threadpool from rayon [#1483](https://github.com/filecoin-project/rust-fil-proofs/pull/1483) -- Swap out default bls-381 backend from pairing to blst [#1482](https://github.com/filecoin-project/rust-fil-proofs/pull/1482) -- Improve multicore sdr logging [#1485](https://github.com/filecoin-project/rust-fil-proofs/pull/1485) - -## [8.0.3] - 2021-07-26 - -- Avoid duplicate generation of srs key caches [#1481](https://github.com/filecoin-project/rust-fil-proofs/pull/1481) -- Add an srs key loading bench and re-factor some tests [#1474](https://github.com/filecoin-project/rust-fil-proofs/pull/1474) - -## [8.0.2] - 2021-06-17 - -- Use correct aggregate proof serialization format [#1475](https://github.com/filecoin-project/rust-fil-proofs/pull/1475) - -## [8.0.1] - 2021-06-09 - -- Required SnarkPack Audit updates [#1470](https://github.com/filecoin-project/rust-fil-proofs/pull/1470) -- Allow hwloc to be optional, but enabled by default [#1468](https://github.com/filecoin-project/rust-fil-proofs/pull/1468) -- Improve Clippy on CI [#1465](https://github.com/filecoin-project/rust-fil-proofs/pull/1465) - -## [8.0.0] - 2021-06-01 - -- Add an API for Proof Aggregation [#1395](https://github.com/filecoin-project/rust-fil-proofs/pull/1395) -- Enforce serde for PublicInputs [#1458](https://github.com/filecoin-project/rust-fil-proofs/pull/1458) - -## [7.0.1] - 2021-05-06 - -- Added Apple M1 asm support via updated sha2 dependency [#1457](https://github.com/filecoin-project/rust-fil-proofs/pull/1457) -- Remove additional build warnings and update CI nightly toolchain [#1456](https://github.com/filecoin-project/rust-fil-proofs/pull/1456) -- Fix aarch64/Linux build regression [#1455](https://github.com/filecoin-project/rust-fil-proofs/pull/1455) -- Fix changelog errors and typos [#1451](https://github.com/filecoin-project/rust-fil-proofs/pull/1451) -- Fix initial value for cache_count [#1454](https://github.com/filecoin-project/rust-fil-proofs/pull/1454) - -## [7.0.0] - 2021-04-28 - -- Split up non-gpu tests for improved CI [#1448](https://github.com/filecoin-project/rust-fil-proofs/pull/1448) -- Use latest version of dialoguer [#1447](https://github.com/filecoin-project/rust-fil-proofs/pull/1447) -- Fix circuitinfo's binary name [#1443](https://github.com/filecoin-project/rust-fil-proofs/pull/1443) -- Remove deprecated calls and clean-up warnings; add parallelization [#1436](https://github.com/filecoin-project/rust-fil-proofs/pull/1436) -- Migrate gpu2 to default gpu code; Update rust toolchain to 1.51.0 [#1441](https://github.com/filecoin-project/rust-fil-proofs/pull/1441) -- Improve unsealing memory performance [#1401](https://github.com/filecoin-project/rust-fil-proofs/pull/1401) -- Update codeowners to current [#1432](https://github.com/filecoin-project/rust-fil-proofs/pull/1432) -- Update config.json for the benches [#1431](https://github.com/filecoin-project/rust-fil-proofs/pull/1431) - -## [6.1.0] - 2021-03-09 - -- Update bellperson to the latest version [#1430](https://github.com/filecoin-project/rust-fil-proofs/pull/1430) -- Remove unused metrics capture CI job [#1428](https://github.com/filecoin-project/rust-fil-proofs/pull/1428) -- Split up pc1/pc2 in the Window PoSt bench [#1427](https://github.com/filecoin-project/rust-fil-proofs/pull/1427) -- Use `compress,asm` features of sha2 for aarch64 [#1404](https://github.com/filecoin-project/rust-fil-proofs/pull/1404) -- Add gpu2, an optional feature that uses `neptune`'s opencl backend [#1397](https://github.com/filecoin-project/rust-fil-proofs/pull/1397) -- Clean-up imports and remove globs [#1394](https://github.com/filecoin-project/rust-fil-proofs/pull/1394) -- Remove `storage-proofs` sub-crate [#1393](https://github.com/filecoin-project/rust-fil-proofs/pull/1393) -- Re-factor parameter related binaries [#1392](https://github.com/filecoin-project/rust-fil-proofs/pull/1392) -- Fix merkle bench for poseidon hashing [#1389](https://github.com/filecoin-project/rust-fil-proofs/pull/1389) -- Move `phase2` code into its own crate [#1388](https://github.com/filecoin-project/rust-fil-proofs/pull/1388) -- Move `fr32` into its own crate [#1387](https://github.com/filecoin-project/rust-fil-proofs/pull/1387) -- Ensure that builds without gpu support work [#1386](https://github.com/filecoin-project/rust-fil-proofs/pull/1386) -- Increase parallelism in fallback PoSt [#1384](https://github.com/filecoin-project/rust-fil-proofs/pull/1384) -- Move checkout_cores test behing a single-threaded feature [#1383](https://github.com/filecoin-project/rust-fil-proofs/pull/1383) -- Improve the cache preservation in Window PoSt bench [#1382](https://github.com/filecoin-project/rust-fil-proofs/pull/1382) -- Correct some typos in the Changelog [#1381](https://github.com/filecoin-project/rust-fil-proofs/pull/1381) - -## [6.0.0] - 2020-12-01 - -- Add PoR gadget that does not add a public input [#1374](https://github.com/filecoin-project/rust-fil-proofs/pull/1374) -- Update README and fix some typos [#1377](https://github.com/filecoin-project/rust-fil-proofs/pull/1377) -- Update bellperson using new blstrs, which in turn now uses`blst@0.3.2` [#1376](https://github.com/filecoin-project/rust-fil-proofs/pull/1376) -- Fix tree_c and tree_r_last generation in GPU mode [#1375](https://github.com/filecoin-project/rust-fil-proofs/pull/1375) -- Add API version enum for determining runtime behaviour [#1362](https://github.com/filecoin-project/rust-fil-proofs/pull/1362) -- Parallelize CI test runs across packages [#1358](https://github.com/filecoin-project/rust-fil-proofs/pull/1358) -- Update paramcache run for metrics capture CI job [#1363](https://github.com/filecoin-project/rust-fil-proofs/pull/1363) -- Re-organize filecoin-proofs source [#1352](https://github.com/filecoin-project/rust-fil-proofs/pull/1352) -- Move hashers into `filecoin-hashers` crate [#1356](https://github.com/filecoin-project/rust-fil-proofs/pull/1356) -- Speed up Fr32Reader [#1341](https://github.com/filecoin-project/rust-fil-proofs/pull/1341) -- Serialize GPU tree building with GPU lock [#1335](https://github.com/filecoin-project/rust-fil-proofs/pull/1335) -- Disable `phase2` tests that require external files [#1342](https://github.com/filecoin-project/rust-fil-proofs/pull/1342) -- Move `phase2` into its own crate [#1340](https://github.com/filecoin-project/rust-fil-proofs/pull/1340) -- Raise soft fdlimit to max at runtime (OS X/Linux) [#1338](https://github.com/filecoin-project/rust-fil-proofs/pull/1338) -- Improve clippy lints (rust 2018 idioms) [#1337](https://github.com/filecoin-project/rust-fil-proofs/pull/1337) - -## [5.4.0] - 2020-11-02 - -- Fix graph generation [#1336](https://github.com/filecoin-project/rust-fil-proofs/pull/1336) - -## [5.3.0] - 2020-10-29 - -- Integrate blst backend and proof verification optimizations [#1332](https://github.com/filecoin-project/rust-fil-proofs/pull/1332) -- Remove unused pedersen hasher [#1331](https://github.com/filecoin-project/rust-fil-proofs/pull/1331) -- Sanity check commitments [#1330](https://github.com/filecoin-project/rust-fil-proofs/pull/1330) -- Install hwloc to fix metrics capture on CI [#1328](https://github.com/filecoin-project/rust-fil-proofs/pull/1328) -- Remove no longer used exports [#1315](https://github.com/filecoin-project/rust-fil-proofs/pull/1315) -- Add tests for resumable sealing [#1309](https://github.com/filecoin-project/rust-fil-proofs/pull/1309) -- Add circuitinfo CLI tool to count circuit constraints [#1325](https://github.com/filecoin-project/rust-fil-proofs/pull/1325) -- Remove mutex from settings access [#1321](https://github.com/filecoin-project/rust-fil-proofs/pull/1321) -- Add SECURITY.md [#1317](https://github.com/filecoin-project/rust-fil-proofs/pull/1317) -- Update hwloc dependency for CI [#1316](https://github.com/filecoin-project/rust-fil-proofs/pull/1316) - -## [5.2.3] - 2020-10-13 - -- Update neptune dependency version - -## [5.2.2] - 2020-10-13 - -- Add notes about param and cache verification [#1313](https://github.com/filecoin-project/rust-fil-proofs/pull/1313) -- Update incorrect log message [#1312](https://github.com/filecoin-project/rust-fil-proofs/pull/1312) -- Bind threads to cores in multicore SDR [#1305](https://github.com/filecoin-project/rust-fil-proofs/pull/1305) -- Add hwloc dependency to CI [#1307](https://github.com/filecoin-project/rust-fil-proofs/pull/1307) - -## [5.2.1] - 2020-10-01 - -- Pin neptune to version 1.2.x [#1302](https://github.com/filecoin-project/rust-fil-proofs/pull/1302) -- Add correct sizes for metrics capture CI [#1301](https://github.com/filecoin-project/rust-fil-proofs/pull/1301) -- Ensure all PoSt code paths are tested [#1299](https://github.com/filecoin-project/rust-fil-proofs/pull/1299) -- Add byte_unit dep for handling benchy input sizes [#1297](https://github.com/filecoin-project/rust-fil-proofs/pull/1297) -- Implement prefetch macro for aarch64 [#1294](https://github.com/filecoin-project/rust-fil-proofs/pull/1294) - -## [5.2.0] - 2020-09-28 - -- Add Seal resume by skipping existing layers [#1292](https://github.com/filecoin-project/rust-fil-proofs/pull/1292) -- Use two producers in all layers [#1296](https://github.com/filecoin-project/rust-fil-proofs/pull/1296) -- Re-export some methods that moved for api access [#1291](https://github.com/filecoin-project/rust-fil-proofs/pull/1291) -- Update rustc to 1.46.0 [#1290](https://github.com/filecoin-project/rust-fil-proofs/pull/1290) -- Optimize Phase 1 (Replication) [#1289](https://github.com/filecoin-project/rust-fil-proofs/pull/1289) -- Add Seal resume testing to the Window PoSt bench [#1288](https://github.com/filecoin-project/rust-fil-proofs/pull/1288) -- Add labeling test vectors [#1285](https://github.com/filecoin-project/rust-fil-proofs/pull/1285) -- Remove artificial requirement that sector count be 1 for single vanilla proof [#1283](https://github.com/filecoin-project/rust-fil-proofs/pull/1283) -- Add Parent Cache and parameter verification and settings to enable [#1265](https://github.com/filecoin-project/rust-fil-proofs/pull/1265) -- Improve SectorId logging [#1280](https://github.com/filecoin-project/rust-fil-proofs/pull/1280) -- Split up Window PoSt API into separate calls [#1278](https://github.com/filecoin-project/rust-fil-proofs/pull/1278) -- Destructure settings [#1273](https://github.com/filecoin-project/rust-fil-proofs/pull/1273) - -## [5.1.4] - 2020-09-08 - -- Add FaultySectors error to Fallback PoSt [#1274](https://github.com/filecoin-project/rust-fil-proofs/pull/1274) - -## [5.1.3] - 2020-09-07 - -- Make fil-blst usage in Window PoSt possible [#1272](https://github.com/filecoin-project/rust-fil-proofs/pull/1272) - -## [5.1.2] - 2020-09-03 - -- Accelerate SNARK verification [#1271](https://github.com/filecoin-project/rust-fil-proofs/pull/1271) -- Decompress proofs in parallel [#1268](https://github.com/filecoin-project/rust-fil-proofs/pull/1268) -- Eliminate wasteful public-input conversions [#1267](https://github.com/filecoin-project/rust-fil-proofs/pull/1267) -- Remove usage of unwrap [#1260](https://github.com/filecoin-project/rust-fil-proofs/pull/1260) -- Pin params to the filecoin collab cluster [#1263](https://github.com/filecoin-project/rust-fil-proofs/pull/1263) - -## [5.1.1] - 2020-08-12 - -- Only perform subgroup check on 'after' params [#1258](https://github.com/filecoin-project/rust-fil-proofs/pull/1258) - -## [5.1.0] - 2020-08-12 - -- Add Phase2 cli verify raw g1 point command [#1256](https://github.com/filecoin-project/rust-fil-proofs/pull/1256) - -## [5.0.0] - 2020-08-10 - -- Publish v28 parameters and update Changelog for release [#1254](https://github.com/filecoin-project/rust-fil-proofs/pull/1254) -- Fix benchmark examples in README [#1253](https://github.com/filecoin-project/rust-fil-proofs/pull/1253) -- Remove unused dependencies [#1124](https://github.com/filecoin-project/rust-fil-proofs/pull/1124) and [#1252](https://github.com/filecoin-project/rust-fil-proofs/pull/1252) -- Add script to validate parameter checksums in parameters.json [#1251](https://github.com/filecoin-project/rust-fil-proofs/pull/1251) -- phase2-cli force small-raw contributions [#1248](https://github.com/filecoin-project/rust-fil-proofs/pull/1248) -- phase2-cli parse command [#1247](https://github.com/filecoin-project/rust-fil-proofs/pull/1247) -- phase2-cli merge command [#1242](https://github.com/filecoin-project/rust-fil-proofs/pull/1242) -- phase2-cli paramgen and filename parsing [#1240](https://github.com/filecoin-project/rust-fil-proofs/pull/1240) -- Verify transitions from non-raw to raw parameters in phase2-cli [#1239](https://github.com/filecoin-project/rust-fil-proofs/pull/1239) -- Add a check parameter command that maps parameter files [#1238](https://github.com/filecoin-project/rust-fil-proofs/pull/1238) -- Add tool to split phase2 parameters [#1235](https://github.com/filecoin-project/rust-fil-proofs/pull/1235) - -## [4.0.5] - 2020-07-28 - -- Include proofs and snark security audit documents, with updated references [#1233](https://github.com/filecoin-project/rust-fil-proofs/pull/1233) -- Remove `stacked` benchmark from benchy (broken) [#1229](https://github.com/filecoin-project/rust-fil-proofs/pull/1229) -- Update range for feistel tests [#1228](https://github.com/filecoin-project/rust-fil-proofs/pull/1228) -- Allow for compilation on aarch64 [#1204](https://github.com/filecoin-project/rust-fil-proofs/pull/1204) -- Implement `fauxrep2`: a testable fake replication API [#1218](https://github.com/filecoin-project/rust-fil-proofs/pull/1218) -- Fix CI `metrics_capture` jobs from consistently failing [#1215](https://github.com/filecoin-project/rust-fil-proofs/pull/1215) -- Correct `rows_to_discard` value during post [#1220](https://github.com/filecoin-project/rust-fil-proofs/pull/1220) - -## [4.0.4] - 2020-07-15 - -- Default parent cache path to use FIL_PROOFS_CACHE_DIR if set [#1207](https://github.com/filecoin-project/rust-fil-proofs/pull/1207) -- Investigate CI metrics capture [#1212](https://github.com/filecoin-project/rust-fil-proofs/pull/1212) and [#1213](https://github.com/filecoin-project/rust-fil-proofs/pull/1213) -- Additional README updates and corrections [#1211](https://github.com/filecoin-project/rust-fil-proofs/pull/1211) -- Update README [#1208](https://github.com/filecoin-project/rust-fil-proofs/pull/1208) -- Swap buffers instead of memcpy in generate_labels [#1197](https://github.com/filecoin-project/rust-fil-proofs/pull/1197) -- Apply suggested security audit fixes [#1196](https://github.com/filecoin-project/rust-fil-proofs/pull/1196) -- Make pieces::Stack methods private [#1202](https://github.com/filecoin-project/rust-fil-proofs/pull/1202) -- Remove dead code [#1201](https://github.com/filecoin-project/rust-fil-proofs/pull/1201) -- Test feistel implementation is a valid permutation [#1193](https://github.com/filecoin-project/rust-fil-proofs/pull/1193) - -## [4.0.3] - 2020-07-01 - -- Add fauxrep to API for fake sealing [#1194](https://github.com/filecoin-project/rust-fil-proofs/pull/1194) -- Streaming phase2 contribution and fast I/O [#1188](https://github.com/filecoin-project/rust-fil-proofs/pull/1188) -- Add omitted changelog updates [#1190](https://github.com/filecoin-project/rust-fil-proofs/pull/1190) - -## [4.0.2] - 2020-06-25 - -- Allow parameters map to be accessible externally [#1186](https://github.com/filecoin-project/rust-fil-proofs/pull/1186) -- Extend update_tree_r_cache command with new features [#1175](https://github.com/filecoin-project/rust-fil-proofs/pull/1175) -- Add OpenCL to the build instructions [#1112](https://github.com/filecoin-project/rust-fil-proofs/pull/1112) -- Use file locking for cache generation [#1179](https://github.com/filecoin-project/rust-fil-proofs/pull/1179) -- Add logging to all public API functions [#1137](https://github.com/filecoin-project/rust-fil-proofs/pull/1137) -- Upgrade some dependencies [#1126](https://github.com/filecoin-project/rust-fil-proofs/pull/1126) -- Fix clippy warnings [#1147](https://github.com/filecoin-project/rust-fil-proofs/pull/1147) -- Partial caching for SDR [#1163](https://github.com/filecoin-project/rust-fil-proofs/pull/1163) -- Add tool to rebuild tree_r_last from a replica [#1170](https://github.com/filecoin-project/rust-fil-proofs/pull/1170) -- Verify consistent use of porep_id when sealing [#1167](https://github.com/filecoin-project/rust-fil-proofs/pull/1167) - -## [4.0.1] - 2020-06-22 - -- This release is a hotfix that pinned dependencies to avoid a build break [#1182](https://github.com/filecoin-project/rust-fil-proofs/pull/1182) - -## [4.0.0] - 2020-06-15 - -- Change default rows_to_discard for cached oct-trees [#1165](https://github.com/filecoin-project/rust-fil-proofs/pull/1165) -- Remove validate commit message [#1164](https://github.com/filecoin-project/rust-fil-proofs/pull/1164) -- Modularized window-post bench [#1162](https://github.com/filecoin-project/rust-fil-proofs/pull/1162) -- Updated reported PoSt constraints (in comments) [#1161](https://github.com/filecoin-project/rust-fil-proofs/pull/1161) - -## [3.0.0] - 2020-06-08 - -- Publish v27 parameters: [#1158](https://github.com/filecoin-project/rust-fil-proofs/pull/1158) -- Update toolchain to rust stable: [#1149](https://github.com/filecoin-project/rust-fil-proofs/pull/1149) -- Allow tree_r_last to be built on the GPU: [#1138](https://github.com/filecoin-project/rust-fil-proofs/pull/1138) - - Improve performance of building tree_c on the GPU - - Properly remove tree_c when no longer needed - - Update circuit test constraints -- Update neptune dependency version: [#1159](https://github.com/filecoin-project/rust-fil-proofs/pull/1159) -- Update total challenge count and increase partitions: [#1153](https://github.com/filecoin-project/rust-fil-proofs/pull/1153) -- Improve UX of paramcache: [#1152](https://github.com/filecoin-project/rust-fil-proofs/pull/1152) -- Add porep_id to construct replica_id and graph seeds: [#1144](https://github.com/filecoin-project/rust-fil-proofs/pull/1144) -- Include layer index before node when creating label preimage: [#1139](https://github.com/filecoin-project/rust-fil-proofs/pull/1139) -- Circuit optimizations for oct/quad insertion: [#1125](https://github.com/filecoin-project/rust-fil-proofs/pull/1125) - -## [2.0.0] - 2020-05-27 - -- Add a method 'unseal_range' to unseal a sector to a file descriptor -- Calculate required config count based on tree shape -- Update merkle tree cached tree usage (fixing an incorrect size usage) -- Replace merkle_light 'height' property usage with 'row_count' -- Update stacked bench usage of recent replica changes - -## [1.0.0] - 2020-05-19 - -- Initial stable release - -[Unreleased]: https://github.com/filecoin-project/rust-fil-proofs/compare/v15.0.0...HEAD -[15.0.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v15.0.0 -[14.0.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v14.0.0 -[13.0.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v13.0.0 -[12.0.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v12.0.0 -[11.1.1]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v11.1.1 -[11.1.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v11.1.0 -[11.0.2]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v11.0.2 -[11.0.1]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v11.0.1 -[11.0.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v11.0.0 -[10.1.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v10.1.0 -[10.0.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v10.0.0 -[9.0.2]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v9.0.2 -[9.0.1]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v9.0.1 -[9.0.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v9.0.0 -[8.0.3]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v8.0.3 -[8.0.2]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v8.0.2 -[8.0.1]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v8.0.1 -[8.0.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v8.0.0 -[7.0.1]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v7.0.1 -[7.0.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v7.0.0 -[6.1.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v6.1.0 -[6.0.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v6.0.0 -[5.4.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v5.4.0 -[5.3.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v5.3.0 -[5.2.3]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v5.2.3 -[5.2.2]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v5.2.2 -[5.2.1]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v5.2.1 -[5.2.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v5.2.0 -[5.1.4]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v5.1.4 -[5.1.3]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v5.1.3 -[5.1.2]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v5.1.2 -[5.1.1]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v5.1.1 -[5.1.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v5.1.0 -[5.0.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v5.0.0 -[4.0.5]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v4.0.5 -[4.0.4]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v4.0.4 -[4.0.3]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v4.0.3 -[4.0.2]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v4.0.2 -[4.0.1]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v4.0.0 -[3.0.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v3.0.0 -[2.0.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v2.0.0 -[1.0.0]: https://github.com/filecoin-project/rust-fil-proofs/tree/releases/v1.0.0 diff --git a/prover/rust-fil-proofs/CODEOWNERS b/prover/rust-fil-proofs/CODEOWNERS deleted file mode 100644 index a5a63c1f..00000000 --- a/prover/rust-fil-proofs/CODEOWNERS +++ /dev/null @@ -1,3 +0,0 @@ -# Global Owners -* @dignifiedquire @cryptonemo @DrPeterVanNostrand @vmx - diff --git a/prover/rust-fil-proofs/CONTRIBUTING.md b/prover/rust-fil-proofs/CONTRIBUTING.md deleted file mode 100644 index 18a54bfe..00000000 --- a/prover/rust-fil-proofs/CONTRIBUTING.md +++ /dev/null @@ -1,163 +0,0 @@ -# Contributing - -Welcome, it is great that you found your way here. In order to make the best of all our time, we have gathered some notes -below which we think can be helpful when contributing to this project. - -## Getting Started - -Please start by reviewing this file. - -## Coding Standards - -- No compiler warnings. -- No [clippy](https://github.com/rust-lang/rust-clippy) warnings. -- Minimize use of `unsafe` and justify usage in comments. -- Prefer `expect` with a good description to `unwrap`. -- Write unit tests in the same file. -- Format your code with `rustfmt` -- Code should compile on `stable` and `nightly`. If adding `nightly` only features they should be behind a flag. -- Write benchmarks for performance sensitive areas. We use [criterion.rs](https://github.com/japaric/criterion.rs). - - -## General Guidelines -- PRs require code owner approval to merge. -- Please scope PRs to areas in which you have expertise. This code is still close to research. -- Please follow our commit guideline described below. -- Welcome contribution areas might include: - - SNARKs - - Proof-of-replication - - Rust improvements - - Optimizations - - Documentation (expertise would require careful reading of the code) - - -## PR Merge Policy (Git topology) - -### Allowed (white list) - - Single fast-forward merge commit, with all internal commits squashed. - - Non-fast-forward merge commit, with all internal commits squashed -- rebased to branch from the previous commit to master. - - Non-fast-forward merge commit, with curated (as appropriate), linear, internal commits preserved -- rebased to branch from the previous commit to master. - -### Disallowed (black list) - - Non-rebased merge commits which branch from anywhere but the previous commit to master. - - Merge commits whose internal history contains merge commits (except in rare circumstances). - - Multiple fast-forward merge commits for a single PR. - - Internal junk commits — (e.g. strings of WIP). - -### In Practice - - In general, please rebase PRs before merging. - - To avoid having approvals dismissed by rebasing, authors may instead choose to: - - First use GitHub's 'resolve conflicts' button; - - Then merge with GitHub's 'squash and merge' button. - -If automated conflict resolution is not possible, you will need to rebase and seek re-approval. In any event, please note the guidelines and prefer either a single commit or a usefully curated set of commits. - -## Resources for learning Rust - -- Beginners - - [The Rust Book](https://doc.rust-lang.org/book/) - - [Rust Playground](https://play.rust-lang.org/) - - [Rust Docs](https://doc.rust-lang.org/) - - [Clippy](https://github.com/rust-lang/rust-clippy) - - [Rustfmt](https://github.com/rust-lang/rustfmt) -- Advanced - - What does the Rust compiler do with my code? [Godbolt compiler explorer](https://rust.godbolt.org/) - - How to safely write unsafe Rust: [The Rustonomicon](https://doc.rust-lang.org/nomicon/) - - Did someone say macros? [The Little Book of Rust Macros](https://danielkeep.github.io/tlborm/book/index.html) - - -## Commit Message Guidelines - -We have very precise rules over how our git commit messages can be formatted. This leads to **more -readable messages** that are easy to follow when looking through the **project history**. But also, -we use the git commit messages to **generate the change log programmatically**. - -### Commit Message Format - -Each commit message consists of a **header**, a **body** and a **footer**. The header has a special -format that includes a **type**, a **scope** and a **subject**: - -``` -(): - - - -