From 8889eff982a6a4b4c68edb0ae20d646e943d950d Mon Sep 17 00:00:00 2001 From: Wisdom Ogwu Date: Mon, 27 Mar 2023 08:09:13 +0100 Subject: [PATCH 1/7] fix trait implementation bug --- packages/rs-drive/src/drive/test_utils.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/rs-drive/src/drive/test_utils.rs b/packages/rs-drive/src/drive/test_utils.rs index 61240e3d254..d0180bb85f9 100644 --- a/packages/rs-drive/src/drive/test_utils.rs +++ b/packages/rs-drive/src/drive/test_utils.rs @@ -2,6 +2,7 @@ use std::cell::RefCell; use dpp::util::entropy_generator::EntropyGenerator; use rand::{rngs::SmallRng, Rng, SeedableRng}; +use dpp::dashcore::anyhow; pub(crate) struct TestEntropyGenerator { rng: RefCell, @@ -16,7 +17,7 @@ impl TestEntropyGenerator { } impl EntropyGenerator for TestEntropyGenerator { - fn generate(&self) -> [u8; 32] { - self.rng.borrow_mut().gen() + fn generate(&self) -> anyhow::Result<[u8; 32]> { + Ok(self.rng.borrow_mut().gen()) } } From d4cbd2c3ec0e5cf2eb74b121bf04a646a3894209 Mon Sep 17 00:00:00 2001 From: Wisdom Ogwu Date: Mon, 27 Mar 2023 08:33:11 +0100 Subject: [PATCH 2/7] expose necessary items for verification bindings --- Cargo.lock | 10 +++++----- packages/rs-dpp/src/lib.rs | 1 + packages/rs-drive/Cargo.toml | 7 ++++--- packages/rs-drive/src/drive/verify/mod.rs | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d1f194c5b7..4878ac9fce7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -566,7 +566,7 @@ checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "costs" version = "1.0.0" -source = "git+https://github.com/dashpay/grovedb?rev=3f07f53175d99e4a3eab7b53d8bd221f59ea9047#3f07f53175d99e4a3eab7b53d8bd221f59ea9047" +source = "git+https://github.com/dashpay/grovedb?branch=develop#12a1ddf3fc3c08851c244673b17683d7df2c1adb" dependencies = [ "integer-encoding", "intmap", @@ -1349,7 +1349,7 @@ dependencies = [ [[package]] name = "grovedb" version = "0.12.2" -source = "git+https://github.com/dashpay/grovedb?rev=3f07f53175d99e4a3eab7b53d8bd221f59ea9047#3f07f53175d99e4a3eab7b53d8bd221f59ea9047" +source = "git+https://github.com/dashpay/grovedb?branch=develop#12a1ddf3fc3c08851c244673b17683d7df2c1adb" dependencies = [ "bincode", "costs", @@ -1786,7 +1786,7 @@ dependencies = [ [[package]] name = "merk" version = "0.12.2" -source = "git+https://github.com/dashpay/grovedb?rev=3f07f53175d99e4a3eab7b53d8bd221f59ea9047#3f07f53175d99e4a3eab7b53d8bd221f59ea9047" +source = "git+https://github.com/dashpay/grovedb?branch=develop#12a1ddf3fc3c08851c244673b17683d7df2c1adb" dependencies = [ "blake3", "byteorder", @@ -2893,7 +2893,7 @@ dependencies = [ [[package]] name = "storage" version = "1.0.0" -source = "git+https://github.com/dashpay/grovedb?rev=3f07f53175d99e4a3eab7b53d8bd221f59ea9047#3f07f53175d99e4a3eab7b53d8bd221f59ea9047" +source = "git+https://github.com/dashpay/grovedb?branch=develop#12a1ddf3fc3c08851c244673b17683d7df2c1adb" dependencies = [ "blake3", "costs", @@ -3310,7 +3310,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "visualize" version = "0.1.0" -source = "git+https://github.com/dashpay/grovedb?rev=3f07f53175d99e4a3eab7b53d8bd221f59ea9047#3f07f53175d99e4a3eab7b53d8bd221f59ea9047" +source = "git+https://github.com/dashpay/grovedb?branch=develop#12a1ddf3fc3c08851c244673b17683d7df2c1adb" dependencies = [ "hex", "itertools", diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index 859638efb8d..4cabdfb7a78 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -55,6 +55,7 @@ pub mod prelude { pub use crate::identity::Identity; pub use crate::identity::IdentityPublicKey; pub use crate::validation::ValidationResult; + pub use crate::identity::state_transition::asset_lock_proof::AssetLockProof; pub use super::convertible::Convertible; pub type TimestampMillis = u64; diff --git a/packages/rs-drive/Cargo.toml b/packages/rs-drive/Cargo.toml index b24bb3b8373..455cf9a5914 100644 --- a/packages/rs-drive/Cargo.toml +++ b/packages/rs-drive/Cargo.toml @@ -37,17 +37,18 @@ mockall= { version ="0.11", optional = true } [dependencies.grovedb] git = "https://github.com/dashpay/grovedb" -rev = "3f07f53175d99e4a3eab7b53d8bd221f59ea9047" +branch = "develop" optional = true +default-features = false [dependencies.storage] git = "https://github.com/dashpay/grovedb" -rev = "3f07f53175d99e4a3eab7b53d8bd221f59ea9047" +branch = "develop" optional = true [dependencies.costs] git = "https://github.com/dashpay/grovedb" -rev = "3f07f53175d99e4a3eab7b53d8bd221f59ea9047" +branch = "develop" optional = true [dev-dependencies] diff --git a/packages/rs-drive/src/drive/verify/mod.rs b/packages/rs-drive/src/drive/verify/mod.rs index 38dcfa4f96c..5ddc9193d37 100644 --- a/packages/rs-drive/src/drive/verify/mod.rs +++ b/packages/rs-drive/src/drive/verify/mod.rs @@ -8,7 +8,7 @@ use crate::error::proof::ProofError; use crate::error::Error; use dpp::identifier::Identifier; use dpp::identity::{IdentityPublicKey, KeyID}; -use dpp::prelude::{Identity, Revision}; +pub use dpp::prelude::{Identity, Revision, AssetLockProof}; use crate::fee::credits::Credits; use grovedb::GroveDb; From 7da5a03af32d7980bef4154ce33c0dc2f80512df Mon Sep 17 00:00:00 2001 From: Wisdom Ogwu Date: Mon, 27 Mar 2023 09:07:45 +0100 Subject: [PATCH 3/7] add batch pause height --- Cargo.lock | 68 ++++++++++++++++++- Cargo.toml | 3 +- .../rs-drive/src/drive/grove_operations.rs | 4 +- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4878ac9fce7..8375b19b443 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -428,6 +428,25 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" +[[package]] +name = "cbindgen" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6358dedf60f4d9b8db43ad187391afe959746101346fe51bb978126bec61dfb" +dependencies = [ + "clap 3.2.23", + "heck", + "indexmap", + "log", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn", + "tempfile", + "toml", +] + [[package]] name = "cc" version = "1.0.79" @@ -516,10 +535,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "bitflags", - "textwrap", + "textwrap 0.11.0", "unicode-width", ] +[[package]] +name = "clap" +version = "3.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +dependencies = [ + "atty", + "bitflags", + "clap_lex", + "indexmap", + "strsim", + "termcolor", + "textwrap 0.16.0", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -590,7 +633,7 @@ checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" dependencies = [ "atty", "cast", - "clap", + "clap 2.34.0", "criterion-plot", "csv", "itertools", @@ -2141,6 +2184,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "os_str_bytes" +version = "6.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" + [[package]] name = "output_vt100" version = "0.1.3" @@ -2560,6 +2609,15 @@ dependencies = [ "librocksdb-sys", ] +[[package]] +name = "rs-drive-verify-c-binding" +version = "0.1.0" +dependencies = [ + "cbindgen", + "drive", + "hex", +] + [[package]] name = "rust_decimal" version = "1.28.1" @@ -3048,6 +3106,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" + [[package]] name = "thiserror" version = "1.0.38" diff --git a/Cargo.toml b/Cargo.toml index 0af5b8688a8..d24507e77fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,5 +12,6 @@ members = [ "packages/masternode-reward-shares-contract", "packages/feature-flags-contract", "packages/dpns-contract", - "packages/data-contracts" + "packages/data-contracts", + "packages/rs-drive-verify-c-binding" ] diff --git a/packages/rs-drive/src/drive/grove_operations.rs b/packages/rs-drive/src/drive/grove_operations.rs index f4abf06885d..66990aa2db1 100644 --- a/packages/rs-drive/src/drive/grove_operations.rs +++ b/packages/rs-drive/src/drive/grove_operations.rs @@ -1603,7 +1603,8 @@ impl Drive { allow_deleting_non_empty_trees: false, deleting_non_empty_trees_returns_error: true, disable_operation_consistency_check: false, - base_root_storage_is_free: true + base_root_storage_is_free: true, + batch_pause_height: None, }), |cost, old_flags, new_flags| { @@ -1726,6 +1727,7 @@ impl Drive { deleting_non_empty_trees_returns_error: true, disable_operation_consistency_check: false, base_root_storage_is_free: true, + batch_pause_height: None }), |_, _, _| Ok(false), |_, _, _| Err(GroveError::InternalError("not implemented")), From da8f1221cabf587a8a4b876495a88eaa89cdbbac Mon Sep 17 00:00:00 2001 From: Wisdom Ogwu Date: Mon, 27 Mar 2023 09:08:27 +0100 Subject: [PATCH 4/7] add bindings code as a package --- packages/rs-drive-verify-c-binding/.gitignore | 3 + packages/rs-drive-verify-c-binding/Cargo.toml | 20 + packages/rs-drive-verify-c-binding/build.rs | 12 + packages/rs-drive-verify-c-binding/c/main.c | 265 ++++++ packages/rs-drive-verify-c-binding/c/utils.c | 87 ++ .../rs-drive-verify-c-binding/cbindgen.toml | 0 packages/rs-drive-verify-c-binding/src/lib.rs | 782 ++++++++++++++++++ .../rs-drive-verify-c-binding/src/types.rs | 203 +++++ .../rs-drive-verify-c-binding/src/util.rs | 102 +++ 9 files changed, 1474 insertions(+) create mode 100644 packages/rs-drive-verify-c-binding/.gitignore create mode 100644 packages/rs-drive-verify-c-binding/Cargo.toml create mode 100644 packages/rs-drive-verify-c-binding/build.rs create mode 100644 packages/rs-drive-verify-c-binding/c/main.c create mode 100644 packages/rs-drive-verify-c-binding/c/utils.c create mode 100644 packages/rs-drive-verify-c-binding/cbindgen.toml create mode 100644 packages/rs-drive-verify-c-binding/src/lib.rs create mode 100644 packages/rs-drive-verify-c-binding/src/types.rs create mode 100644 packages/rs-drive-verify-c-binding/src/util.rs diff --git a/packages/rs-drive-verify-c-binding/.gitignore b/packages/rs-drive-verify-c-binding/.gitignore new file mode 100644 index 00000000000..178ab4f911c --- /dev/null +++ b/packages/rs-drive-verify-c-binding/.gitignore @@ -0,0 +1,3 @@ +/target +/Cargo.lock +a \ No newline at end of file diff --git a/packages/rs-drive-verify-c-binding/Cargo.toml b/packages/rs-drive-verify-c-binding/Cargo.toml new file mode 100644 index 00000000000..7736140b4b0 --- /dev/null +++ b/packages/rs-drive-verify-c-binding/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "rs-drive-verify-c-binding" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "drive" +crate-type = ["staticlib"] + +[build-dependencies] +cbindgen = "0.24.3" + +[dependencies] +hex = "0.4.3" + +[dependencies.drive] +path = "../rs-drive" +features = ["verify"] +default-features = false diff --git a/packages/rs-drive-verify-c-binding/build.rs b/packages/rs-drive-verify-c-binding/build.rs new file mode 100644 index 00000000000..f44a99b622d --- /dev/null +++ b/packages/rs-drive-verify-c-binding/build.rs @@ -0,0 +1,12 @@ +use cbindgen; + +use std::env; + +fn main() { + let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let mut config: cbindgen::Config = Default::default(); + config.language = cbindgen::Language::C; + cbindgen::generate_with_config(&crate_dir, config) + .unwrap() + .write_to_file("target/drive.h"); +} diff --git a/packages/rs-drive-verify-c-binding/c/main.c b/packages/rs-drive-verify-c-binding/c/main.c new file mode 100644 index 00000000000..a374f303c12 --- /dev/null +++ b/packages/rs-drive-verify-c-binding/c/main.c @@ -0,0 +1,265 @@ +#include +#include +#include "../target/drive.h" +#include "./utils.c" + +void test_verify_full_identity_by_public_key_hash() { + char *proof_hex = "06000100a603014a75cf3f535e81c4680f8137a2208dbcb2652ffd7e715bd4290cc5c560b2cc6102cfbe0535bd2defe586b863b9ccb92d0d66fb2b810d730e7ba2cb7e2fb302613b100401180018020114aee302720896bba837dcf3f2d674f546fd25496f00ca359aa1b2032e3158ae5e5c489f7d46722f29644a15e1cf7c3935b30606def61104012000240201203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200a0d5a4f6418663468515cd75189be3e1034bbfa9a1807eb81d964ba7442a0b1e100169931838564707dbf11e90a059fd7dd453cc7e68adb7d2c2375bae53566664e711025670752cc3d883200a7598b65cd74b41a760cc0be57cda5536f15f03c8783aa81001c33635136e502e9ac5244b15a20a757e0759ce0a90823cd37f893f6a49556d26040160002d0401203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2fd1cb12a5b2614000000fbbd3be097e7f07d5619dd69e7767884d116f95ae9a5fcdb651e71727902cc1e10011e0c1443d0925f781132f4c506747202dbffa3ca3ded4d2387d4b7e40e0303e311110201187f03144463a1a994d5040e69c090b6985d7af295bfd11a002300203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200029e6f2d33b1580030e3b6030e3c25016ab7253965682556059dcc243b75c7fa6d1001e09f88cd09cc595d524892b3e642b939f2827995605703c49c861f653001d5e1110101204d04203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200090201010201030000007fae89b888b23f4fbdaed2fb990a1f42727aef5bd2a8b91f8cb970570909ab3901203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a27f030100000b000800000000000000100004010100050201010100d651221796b5206a5b9678a4d9995d519d8b9e75e87d85e57effb91f82a23e8d1002bcf84a882c0f72dd0d520a6954b3e1887fa55b7dc67635b44516856b31fd20a8100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100001e001b0000010200144463a1a994d5040e69c090b6985d7af295bfd11a0000030101003a0037010002010030973988b291fd1bca86d906723e335bdf13d3ebbadfea31dd164b3c672c16da72af8e6edfc0bac44b92b8c536d708dc33000010030102002b00280200030000210360da79c58995e4ec88512af9a4440ca4f2d7bfe84240e17effc4dd8ce94033a20000110201604f04203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2000b03fd1cb12a5b261400000068f31829eaec02f7e5eddada129d4981a99bda0e5c0fd4eff3c23eafc2c79a02"; + char *pub_key_hex = "4463a1a994d5040e69c090b6985d7af295bfd11a"; + + unsigned char *proof_bin = hex2bin(proof_hex); + unsigned char *pub_key_bin = hex2bin(pub_key_hex); + + IdentityVerificationResult *result = verify_full_identity_by_public_key_hash(proof_bin, 1038, pub_key_bin); + assert(result->is_valid); + + uint8_t expected_root_hash[32] = {72,72,215,200,156,21,128,156,166,182,110,57,113,232,229,242,193,199,240,135,222,102,246,165,181,68,81,221,120,195,236,199}; + assert(is_array_equal(result->root_hash, expected_root_hash,32)); + + assert(result->has_identity); + + Identity *identity = result->identity; + assert(identity->protocol_version == 1); + + uint8_t id[32] = {62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162}; + assert(is_array_equal(*identity->id, id, 32)); + + // Confirm identity has 3 public keys + assert(identity->public_keys_count == 3); + + // Assert on the first public key + assert(identity->public_keys[0]->key == 0); + IdentityPublicKey *first = identity->public_keys[0]->public_key; + assert(first->id == 0); + assert(first->purpose == 0); + assert(first->security_level == 1); + assert(first->key_type == 2); + assert(first->read_only == false); + assert(first->has_disabled_at == false); + uint8_t first_public_key[20] = {68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182, 152, 93, 122, 242, 149, 191, 209, 26}; + assert(is_array_equal(first->data, first_public_key, first->data_length)); + + // Assert on the second public key + assert(identity->public_keys[1]->key == 1); + IdentityPublicKey *second = identity->public_keys[1]->public_key; + assert(second->id == 1); + assert(second->purpose == 0); + assert(second->security_level == 2); + assert(second->key_type == 1); + assert(second->read_only == false); + assert(second->has_disabled_at == false); + unsigned char second_public_key[50] = {151, 57, 136, 178, 145, 253, 27, 202, 134, 217, 6, 114, 62, 51, 91, 223, 19, 211, 235, 186, 223, 234, 49, 221, 22, 75, 60, 103, 44, 22, 218, 114, 175, 142, 110, 223, 192, 186, 196, 75, 146, 184, 197, 54, 215, 8, 220, 51}; + assert(is_array_equal(second->data,second_public_key, second->data_length)); + + // Assert on the third public key + assert(identity->public_keys[0]->key == 0); + IdentityPublicKey *third = identity->public_keys[2]->public_key; + assert(third->id == 2); + assert(third->purpose == 0); + assert(third->security_level == 3); + assert(third->key_type == 0); + assert(third->read_only == false); + assert(third->has_disabled_at == false); + unsigned char third_public_key[33] = {3, 96, 218, 121, 197, 137, 149, 228, 236, 136, 81, 42, 249, 164, 68, 12, 164, 242, 215, 191, 232, 66, 64, 225, 126, 255, 196, 221, 140, 233, 64, 51, 162}; + assert(is_array_equal(third->data,third_public_key, third->data_length)); + + assert(identity->balance == 11077485418638); + assert(identity->revision == 16); + assert(!identity->has_metadata); + assert(!identity->has_asset_lock_proof); + +} + +void test_verify_full_identities_by_public_key_hashes() { + char *multiple_identity_proof_hex = "06000100a603014a75cf3f535e81c4680f8137a2208dbcb2652ffd7e715bd4290cc5c560b2cc6102cfbe0535bd2defe586b863b9ccb92d0d66fb2b810d730e7ba2cb7e2fb302613b1004011800180201145e0e49d808ad21d01d07dd799a75bd1b472788a7008c10aa4c1d19e2e7e42fe0b1a7f6d93d4c0b6992ef63ea985c16447cada4629511040120002402012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000ba56cfb1d87ef47857f6b1cd7fb918406fd50f81966619777dd4c1b595a1a26e100169931838564707dbf11e90a059fd7dd453cc7e68adb7d2c2375bae53566664e711025670752cc3d883200a7598b65cd74b41a760cc0be57cda5536f15f03c8783aa81001c33635136e502e9ac5244b15a20a757e0759ce0a90823cd37f893f6a49556d26040160002d04012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30fdbafd6833aeb700000012b27f4a0a7cfd06e3387b33a5bca6682953512e21621ae9cf6d633d9041771910011e0c1443d0925f781132f4c506747202dbffa3ca3ded4d2387d4b7e40e0303e31111020118b3080132c9d35844d5ce2a8e0f377cee23c143a53396073dea86c494b86ba4c4af0b3903141f0815269afc012de44260ceb28a4496d3184184002300200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb00100168576e24521e03ba4b624912bb07833767c81102310b87d8ea1caf2795c68f921102e8b7eb376f0f7993badf93971f690be8a48f09db0711f052a2ed48471497b9d01003144463a1a994d5040e69c090b6985d7af295bfd11a002300203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a20002254bf0a990beb721c21f21e8dbab50e33cd9cf09618fc27c9f7450c673516aee1001c6adfe081809218ee07461f95f53ce6ce462ec379f97a71f1be40f7218cb50af111103145e0e49d808ad21d01d07dd799a75bd1b472788a70023002035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30001001a4b31998d47c30e390f4fa56f28f19c62f114f17a704d29c56e28b6fdb47f101031467892af390cd2b7653a918c7b692c85b87b44d3200230020399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80001001eb4da977338a3da4204eaaac0c8856bdfd51d9b25ceef04b40bb38eff79ab11011021f22102429dbe1bc0ca714847b08187d9a874cc43329aaa79647fb9aa0834d691003149a061f31734c5f5f0b119ab72d433c9af133d3a600230020e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330002644c601e67692188cf5a975c2207caba899d99f1bbd4b62e5fe856850b9d7286100314a54921bb29b67e31898efebc29f241b1aefa4dca002300207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e510010029e6f2d33b1580030e3b6030e3c25016ab7253965682556059dcc243b75c7fa6d0314b3bfce478de96fe30cd3713bf88ce7728687da8a00230020a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40001111110314bb3df025e32fd90d1feee7dca4b83321c683292d0023002003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3001001ee0847805b145b5fb500b139fe12767ee681fc310a21d6e9814619df5187470802a0de352fe6767da7bf4c33ba7d2da8db0440457835d3c2992473210e02b6312c1001e09f88cd09cc595d524892b3e642b939f2827995605703c49c861f653001d5e1029a563c983d202520c1a94f4c6ba99750373450aaf9dcb2a62ef50e9877646043100314ed738aaadd75d1677fefeccadd033f126cfee76a0023002097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000314fbd9daa5993de56a2e4346b7c72ff5585efffaab002300201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb0010111111110101208b06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d300090201010201030000006c4bfcf223cd4fe5c1cac82e1a9e2c73eb0e7f34cebabdd7630e24cb192f975804200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000902010102010300000080da62acb8c49f901d6bf84a2a2af15431e69e29069abf8d02f2c113c6099ba61004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000902010102010300000051a23049efbcde3a0e9c85ea7af05a28d4de31f90ae44a07c5fa18090128237011042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000090201010201030000002a390761b997897afe51540c39dfeb5c78d00781a547d2b83b1e72259894dea5100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f800009020101020103000000b3f28f9cc26df90ea49e13e3cd97c01d772e9d6609453e91d4369ef78e3880a004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200090201010201030000007fae89b888b23f4fbdaed2fb990a1f42727aef5bd2a8b91f8cb970570909ab391004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e5100090201010201030000001d64a3f9270bf8b8104305ba76829472f3aac2b6fff20b98ac10361ec5473fbb11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef0009020101020103000000adb76570d64f89650686df5819414e5e42cf7eedab24605aa63c4b8e26e90eda100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be400009020101020103000000a5a8530416d9462521b6fd932723d8971684b4620e4254caf09c75289e0e64700420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330009020101020103000000fa1d907f967c48292a5af3d4c3aad435c2ee9237119614d612aee3b4f52e3614111111012003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d37f030100000b0008000000000000003d000401010005020101010072cc451270c61384d358f7d41135b78788011830301a697b97a3714c203a36dc100214105bdf191491b67249d321f3d9bebdf82c9a3395fef336c60b3701af0593e7100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b000002030014bb3df025e32fd90d1feee7dca4b83321c683292d0000030101003a0037010001010030a5fd02c96d5f60eb54b15b043a84ed80a0af804eff4a2bfea1fc9fed323232c7ab12072368097e556439d08aa0a6866c000010030102003a003702000001003085ff00e6339367d3e31e27cbc33c13c3cd0c6e973a5b902e76668d7a6daf83c129257cc7f9cc35e1c0689a6df03a891d00001101200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb7f030100000b000800000000000000030004010100050201010100783a62676dbffd012f9343ef0af71c1b800cda19801689dfb7e2372cccc3ed9d10027f0e94e54c63ffdcd3d3d9017a63e82f9984ade5c4faa59d2479c11007932524100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df1102010178030100002b002800000200002103fe65fcdcfe242dc2e43d654274ec9ce1bbbc9dd5a1c88945eeef18cc93151f7f0000030101001e001b010001030014c94f46cf38b83862990f782c84acbc178d7b02da000010030102001e001b02000203001426d387d9884862f96160dd59ca596bdce82da74600001101201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb7f030100000b000800000000000000600004010100050201010100ca3a10eab3b889465bba51bc5354131aee1044e510d9ed4a7068d1181c7dbfcd10029626ec2b4e8861c675b20bc4456333d8c41fd0c0b9c9f0b78047c6634ebab8ef100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100001e001b000003020014fbd9daa5993de56a2e4346b7c72ff5585efffaab0000030101002b002801000300002103fdc9403eb6f005db700e7841627f4f92e7c65d167384cd57a4f4e46583c21afe000010030102002b002802000000002103703446f77c8db1fbac6f3422c8e045098adb662c0b620a15b8c4d9ecd2a3defa000011012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c307f030100000b000800000000000000420004010100050201010100d7f397a816f23f32e9a6cd2ab5b03d5b6d30742cf0b58517f276d9f75c1c4d611002bfd5686ae0d2a7684c2f6ed3a7419a436a5389afc9a84a1bb22a1decdfa7625d100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b0000020300145e0e49d808ad21d01d07dd799a75bd1b472788a70000030101003a003701000001003097c8d8102d216818c693dc46614ce9242b8e54e05a8ff1f520a3694b9481091d92906b13b9b2762b127ee4f07e91119e000010030102003a00370200030100308949c96dda849268044e176dbdba458fb5deac81e9918793bdb837f5afee0c2496a5930d46d1fe37ce536cbef8e95bb40000110120399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f807f030100000b0008000000000000000c0004010100050201010100a9403aa408af35d267980dfff1706d70a59b6dba867d0b568ca8c5b77560d67a100276cbfe822d7b9f6863f9a06b668097458e123ff385e31c29d830d03f1148973a100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100003a0037000000010030b79d4caa865f84207124c3d304430372f39d7c18a237df3a71e3c4fb7ba9ab9816439a809beb8606c3bb52d53a5364590000030101001e001b0100030200146406a5082b231340726d4cd0de2452bc73a33003000010030102001e001b0200010300144ac7b42f524e1d1b22098f85adfca752600ef9a000001101203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a27f030100000b000800000000000000100004010100050201010100d651221796b5206a5b9678a4d9995d519d8b9e75e87d85e57effb91f82a23e8d1002bcf84a882c0f72dd0d520a6954b3e1887fa55b7dc67635b44516856b31fd20a8100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100001e001b0000010200144463a1a994d5040e69c090b6985d7af295bfd11a0000030101003a0037010002010030973988b291fd1bca86d906723e335bdf13d3ebbadfea31dd164b3c672c16da72af8e6edfc0bac44b92b8c536d708dc33000010030102002b00280200030000210360da79c58995e4ec88512af9a4440ca4f2d7bfe84240e17effc4dd8ce94033a200001101207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e517f030100000b000800000000000000580004010100050201010100d95ff983db933edc675487a6f4e388fcf2db59313aeab5f45991a7f2471774471002355f98c38fd87ca5775e5e451243eb11300ed91fc950ea204c0a74b9a1991a25100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100003a0037000003010030b3423844bae8a591bbfb437b55566b5d61e54ee64f93351b0a3b9d4b731445d25ce367f7aedfcb32bd3cd14308a54cf50000030101003a0037010001010030a154c19082ac6b5fec72b81f6488550fec7149d52f66b4463915a61179c4f1f8507d366614b454dabf2c942235caad01000010030102001e001b0200030300140a8c14745c982f9fdc43aa985c02b1e5bff6c403000011012097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef7f030100000b000800000000000000620004010100050201010100412c1e7de2394dcd009223eb8c3a24e34b93a7c48df0bb86499160a31ea9dbdb1002180590eec33397034675f379cf17f62c0e77d17724a03238dcd3f216a4bc9509100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100003a0037000002010030afa4370aa5a48ab2f3ab510ccaba3b6d8cf51752304507e6a341c4e4ff6aa7c07610a503b42f479834b032d25dd160590000030101002b002801000300002103a9584c4580d165d2744ba49a70472653915bfdbec4bef471e26ce4c1c9e6c6ab000010030102001e001b02000102001445d04558a26b8ca04b486957c8abf5abf24ec76f0000110120a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be407f030100000b0008000000000000005d0004010100050201010100f140186a6bd413a50814db484b00398c2e7e6da9fbe2cb536728e880deb7506010027767f75fded47f94a6f81c671d448beddb6c2727f1f209ba015bf8de7331c13c100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100002b002800000000002102eebd2f91818a234e1879f8a55652f1e52419ad168b8f27b91be6b79958f7a5510000030101002b00280100020000210214a91dfcb36718209a5ee79c290029b849f1ce2feef6585a3b3fa37d04fb62b7000010030102001e001b0200030200144ee490084160fc8b1e73361d5a4c055beee77d8c0000110120e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4337f030100000b0008000000000000004f0004010100050201010100eb90b3c6d9a547e3b8a1111f621e0dbe5bfc68a8196371d497cb2912fa809d001002ab80ce7b6ca4875dbc7dc1f0d902551628c97b2383c27d04538d46a97d3cad43100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100001e001b0000020300149a061f31734c5f5f0b119ab72d433c9af133d3a60000030101003a003701000101003096e1fc631934a14acd313ff28ca29c9e9b43181b8df29386702b1a2d65a7cc823683f5733e296fb40c73648bc9cbf625000010030102001e001b02000102001474f185aa527f31202442d208cdb2905fa71403290000110201609f06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3000b03fda4d93a40301700000095840c6be056ed3d199dedf5265a5d3dafd195aa4cb54ca26943f7e092a5f06904200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000b03fd62132d410718000000b9dec92595e5eabb6de045782827bd98b60b9252287eec0f8e3450ea7c59619b1004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000b03fd8e29761d5405000000380d1a8cb3511b3ecf770a1d81f40c293182d29cf0574962db50c4cfb626fdb711042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30000b03fd62b9bfe135190000002eefa752386580c31084b54f2119973ccef6ac92fc38607e8609e896c9994c3e100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80000b03fdd0a1b7eee2140000002271b648a8925b8c717543453a59a3a20a3c52ce9b3e5fc793983c64f9f6fea004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2000b03fd1cb12a5b261400000068f31829eaec02f7e5eddada129d4981a99bda0e5c0fd4eff3c23eafc2c79a021004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e51000b03fd586ba25d1f1a0000005e3b38a6d9bede250ed0b612d01915a78182ee18d819d07d43ae925728b42d2d11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000b03fd120b51f4ea10000000be380b13cfd7149332e5ac818ae84d31e4be119bc0ebd717475630f6f38b6e90100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40000b03fd505d6c926f0d0000009500204c698cc12fc96774a34f77415c37376ff17b492838e414d774b5b7bec10420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae433000b03fd1e078984690800000064d995f4b5b62c480a04f1b8fb4c7a30b607f12da4abc357993ee7505be19b26111111"; + char *pub_key_hash_one_hex = "1f0815269afc012de44260ceb28a4496d3184184"; + char *pub_key_hash_two_hex = "4463a1a994d5040e69c090b6985d7af295bfd11a"; + char *pub_key_hash_three_hex = "5e0e49d808ad21d01d07dd799a75bd1b472788a7"; + + unsigned char *multiple_identity_proof_bin = hex2bin(multiple_identity_proof_hex); + unsigned char *pub_key_hashes[3] = { + hex2bin(pub_key_hash_one_hex), + hex2bin(pub_key_hash_two_hex), + hex2bin(pub_key_hash_three_hex), + }; + MultipleIdentityVerificationResult *multi_iden_result = verify_full_identities_by_public_key_hashes(multiple_identity_proof_bin, 6206, pub_key_hashes, 3); + assert(multi_iden_result->is_valid); + + uint8_t expected_root_hash[32] = {202, 84, 121, 98, 165, 168, 181, 237, 228, 130, 249, 5, 45, 10, 35, 77, 17, 60, 42, 121, 141, 6, 90, 21, 12, 231, 68, 33, 156, 219, 114, 132}; + assert(is_array_equal(expected_root_hash, *multi_iden_result->root_hash, 32)); + + assert(multi_iden_result->map_size == 3); + + uint8_t iden_one_pk_hash[20] = { 31, + 8, + 21, + 38, + 154, + 252, + 1, + 45, + 228, + 66, + 96, + 206, + 178, + 138, + 68, + 150, + 211, + 24, + 65, + 132}; + assert(is_array_equal(iden_one_pk_hash, multi_iden_result-> public_key_hash_identity_map[0]->public_key_hash, multi_iden_result->public_key_hash_identity_map[0]->public_key_hash_length)); + assert(multi_iden_result->public_key_hash_identity_map[0]->has_identity); + + uint8_t iden_two_pk_hash[20] = { 68, + 99, + 161, + 169, + 148, + 213, + 4, + 14, + 105, + 192, + 144, + 182, + 152, + 93, + 122, + 242, + 149, + 191, + 209, + 26}; + assert(is_array_equal(iden_two_pk_hash, multi_iden_result-> public_key_hash_identity_map[1]->public_key_hash, multi_iden_result->public_key_hash_identity_map[1]->public_key_hash_length)); + assert(multi_iden_result->public_key_hash_identity_map[1]->has_identity); + + uint8_t iden_three_pk_hash[20] = { 94, + 14, + 73, + 216, 8, + 173, + 33, + 208, + 29, + 7, + 221, + 121, + 154, + 117, + 189, + 27, + 71, + 39, + 136, + 167}; + assert(is_array_equal(iden_three_pk_hash, multi_iden_result-> public_key_hash_identity_map[2]->public_key_hash, multi_iden_result->public_key_hash_identity_map[2]->public_key_hash_length)); + assert(multi_iden_result->public_key_hash_identity_map[2]->has_identity); +} + +void test_verify_full_identity_by_identity_id() { + char *proof_hex = "06000100a603014a75cf3f535e81c4680f8137a2208dbcb2652ffd7e715bd4290cc5c560b2cc6102cfbe0535bd2defe586b863b9ccb92d0d66fb2b810d730e7ba2cb7e2fb302613b100401180018020114aee302720896bba837dcf3f2d674f546fd25496f00ca359aa1b2032e3158ae5e5c489f7d46722f29644a15e1cf7c3935b30606def61104012000240201203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200a0d5a4f6418663468515cd75189be3e1034bbfa9a1807eb81d964ba7442a0b1e100169931838564707dbf11e90a059fd7dd453cc7e68adb7d2c2375bae53566664e711025670752cc3d883200a7598b65cd74b41a760cc0be57cda5536f15f03c8783aa81001c33635136e502e9ac5244b15a20a757e0759ce0a90823cd37f893f6a49556d26040160002d0401203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2fd1cb12a5b2614000000fbbd3be097e7f07d5619dd69e7767884d116f95ae9a5fcdb651e71727902cc1e10011e0c1443d0925f781132f4c506747202dbffa3ca3ded4d2387d4b7e40e0303e311110201187f03144463a1a994d5040e69c090b6985d7af295bfd11a002300203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200029e6f2d33b1580030e3b6030e3c25016ab7253965682556059dcc243b75c7fa6d1001e09f88cd09cc595d524892b3e642b939f2827995605703c49c861f653001d5e1110101204d04203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200090201010201030000007fae89b888b23f4fbdaed2fb990a1f42727aef5bd2a8b91f8cb970570909ab3901203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a27f030100000b000800000000000000100004010100050201010100d651221796b5206a5b9678a4d9995d519d8b9e75e87d85e57effb91f82a23e8d1002bcf84a882c0f72dd0d520a6954b3e1887fa55b7dc67635b44516856b31fd20a8100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100001e001b0000010200144463a1a994d5040e69c090b6985d7af295bfd11a0000030101003a0037010002010030973988b291fd1bca86d906723e335bdf13d3ebbadfea31dd164b3c672c16da72af8e6edfc0bac44b92b8c536d708dc33000010030102002b00280200030000210360da79c58995e4ec88512af9a4440ca4f2d7bfe84240e17effc4dd8ce94033a20000110201604f04203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2000b03fd1cb12a5b261400000068f31829eaec02f7e5eddada129d4981a99bda0e5c0fd4eff3c23eafc2c79a02"; + char *identity_id_hex = "3eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2"; + + unsigned char *proof_bin = hex2bin(proof_hex); + unsigned char *identity_id_bin = hex2bin(identity_id_hex); + + IdentityVerificationResult *result = verify_full_identity_by_identity_id(proof_bin, 1038, true, identity_id_bin); + assert(result->is_valid); + + uint8_t expected_root_hash[32] = {72,72,215,200,156,21,128,156,166,182,110,57,113,232,229,242,193,199,240,135,222,102,246,165,181,68,81,221,120,195,236,199}; + assert(is_array_equal(result->root_hash, expected_root_hash,32)); + + assert(result->has_identity); +} + +void test_verify_identity_id_by_public_key_hash() { + char *multiple_identity_proof_hex = "06000100a603014a75cf3f535e81c4680f8137a2208dbcb2652ffd7e715bd4290cc5c560b2cc6102cfbe0535bd2defe586b863b9ccb92d0d66fb2b810d730e7ba2cb7e2fb302613b1004011800180201145e0e49d808ad21d01d07dd799a75bd1b472788a7008c10aa4c1d19e2e7e42fe0b1a7f6d93d4c0b6992ef63ea985c16447cada4629511040120002402012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000ba56cfb1d87ef47857f6b1cd7fb918406fd50f81966619777dd4c1b595a1a26e100169931838564707dbf11e90a059fd7dd453cc7e68adb7d2c2375bae53566664e711025670752cc3d883200a7598b65cd74b41a760cc0be57cda5536f15f03c8783aa81001c33635136e502e9ac5244b15a20a757e0759ce0a90823cd37f893f6a49556d26040160002d04012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30fdbafd6833aeb700000012b27f4a0a7cfd06e3387b33a5bca6682953512e21621ae9cf6d633d9041771910011e0c1443d0925f781132f4c506747202dbffa3ca3ded4d2387d4b7e40e0303e31111020118b3080132c9d35844d5ce2a8e0f377cee23c143a53396073dea86c494b86ba4c4af0b3903141f0815269afc012de44260ceb28a4496d3184184002300200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb00100168576e24521e03ba4b624912bb07833767c81102310b87d8ea1caf2795c68f921102e8b7eb376f0f7993badf93971f690be8a48f09db0711f052a2ed48471497b9d01003144463a1a994d5040e69c090b6985d7af295bfd11a002300203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a20002254bf0a990beb721c21f21e8dbab50e33cd9cf09618fc27c9f7450c673516aee1001c6adfe081809218ee07461f95f53ce6ce462ec379f97a71f1be40f7218cb50af111103145e0e49d808ad21d01d07dd799a75bd1b472788a70023002035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30001001a4b31998d47c30e390f4fa56f28f19c62f114f17a704d29c56e28b6fdb47f101031467892af390cd2b7653a918c7b692c85b87b44d3200230020399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80001001eb4da977338a3da4204eaaac0c8856bdfd51d9b25ceef04b40bb38eff79ab11011021f22102429dbe1bc0ca714847b08187d9a874cc43329aaa79647fb9aa0834d691003149a061f31734c5f5f0b119ab72d433c9af133d3a600230020e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330002644c601e67692188cf5a975c2207caba899d99f1bbd4b62e5fe856850b9d7286100314a54921bb29b67e31898efebc29f241b1aefa4dca002300207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e510010029e6f2d33b1580030e3b6030e3c25016ab7253965682556059dcc243b75c7fa6d0314b3bfce478de96fe30cd3713bf88ce7728687da8a00230020a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40001111110314bb3df025e32fd90d1feee7dca4b83321c683292d0023002003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3001001ee0847805b145b5fb500b139fe12767ee681fc310a21d6e9814619df5187470802a0de352fe6767da7bf4c33ba7d2da8db0440457835d3c2992473210e02b6312c1001e09f88cd09cc595d524892b3e642b939f2827995605703c49c861f653001d5e1029a563c983d202520c1a94f4c6ba99750373450aaf9dcb2a62ef50e9877646043100314ed738aaadd75d1677fefeccadd033f126cfee76a0023002097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000314fbd9daa5993de56a2e4346b7c72ff5585efffaab002300201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb0010111111110101208b06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d300090201010201030000006c4bfcf223cd4fe5c1cac82e1a9e2c73eb0e7f34cebabdd7630e24cb192f975804200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000902010102010300000080da62acb8c49f901d6bf84a2a2af15431e69e29069abf8d02f2c113c6099ba61004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000902010102010300000051a23049efbcde3a0e9c85ea7af05a28d4de31f90ae44a07c5fa18090128237011042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000090201010201030000002a390761b997897afe51540c39dfeb5c78d00781a547d2b83b1e72259894dea5100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f800009020101020103000000b3f28f9cc26df90ea49e13e3cd97c01d772e9d6609453e91d4369ef78e3880a004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200090201010201030000007fae89b888b23f4fbdaed2fb990a1f42727aef5bd2a8b91f8cb970570909ab391004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e5100090201010201030000001d64a3f9270bf8b8104305ba76829472f3aac2b6fff20b98ac10361ec5473fbb11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef0009020101020103000000adb76570d64f89650686df5819414e5e42cf7eedab24605aa63c4b8e26e90eda100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be400009020101020103000000a5a8530416d9462521b6fd932723d8971684b4620e4254caf09c75289e0e64700420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330009020101020103000000fa1d907f967c48292a5af3d4c3aad435c2ee9237119614d612aee3b4f52e3614111111012003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d37f030100000b0008000000000000003d000401010005020101010072cc451270c61384d358f7d41135b78788011830301a697b97a3714c203a36dc100214105bdf191491b67249d321f3d9bebdf82c9a3395fef336c60b3701af0593e7100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b000002030014bb3df025e32fd90d1feee7dca4b83321c683292d0000030101003a0037010001010030a5fd02c96d5f60eb54b15b043a84ed80a0af804eff4a2bfea1fc9fed323232c7ab12072368097e556439d08aa0a6866c000010030102003a003702000001003085ff00e6339367d3e31e27cbc33c13c3cd0c6e973a5b902e76668d7a6daf83c129257cc7f9cc35e1c0689a6df03a891d00001101200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb7f030100000b000800000000000000030004010100050201010100783a62676dbffd012f9343ef0af71c1b800cda19801689dfb7e2372cccc3ed9d10027f0e94e54c63ffdcd3d3d9017a63e82f9984ade5c4faa59d2479c11007932524100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df1102010178030100002b002800000200002103fe65fcdcfe242dc2e43d654274ec9ce1bbbc9dd5a1c88945eeef18cc93151f7f0000030101001e001b010001030014c94f46cf38b83862990f782c84acbc178d7b02da000010030102001e001b02000203001426d387d9884862f96160dd59ca596bdce82da74600001101201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb7f030100000b000800000000000000600004010100050201010100ca3a10eab3b889465bba51bc5354131aee1044e510d9ed4a7068d1181c7dbfcd10029626ec2b4e8861c675b20bc4456333d8c41fd0c0b9c9f0b78047c6634ebab8ef100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100001e001b000003020014fbd9daa5993de56a2e4346b7c72ff5585efffaab0000030101002b002801000300002103fdc9403eb6f005db700e7841627f4f92e7c65d167384cd57a4f4e46583c21afe000010030102002b002802000000002103703446f77c8db1fbac6f3422c8e045098adb662c0b620a15b8c4d9ecd2a3defa000011012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c307f030100000b000800000000000000420004010100050201010100d7f397a816f23f32e9a6cd2ab5b03d5b6d30742cf0b58517f276d9f75c1c4d611002bfd5686ae0d2a7684c2f6ed3a7419a436a5389afc9a84a1bb22a1decdfa7625d100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b0000020300145e0e49d808ad21d01d07dd799a75bd1b472788a70000030101003a003701000001003097c8d8102d216818c693dc46614ce9242b8e54e05a8ff1f520a3694b9481091d92906b13b9b2762b127ee4f07e91119e000010030102003a00370200030100308949c96dda849268044e176dbdba458fb5deac81e9918793bdb837f5afee0c2496a5930d46d1fe37ce536cbef8e95bb40000110120399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f807f030100000b0008000000000000000c0004010100050201010100a9403aa408af35d267980dfff1706d70a59b6dba867d0b568ca8c5b77560d67a100276cbfe822d7b9f6863f9a06b668097458e123ff385e31c29d830d03f1148973a100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100003a0037000000010030b79d4caa865f84207124c3d304430372f39d7c18a237df3a71e3c4fb7ba9ab9816439a809beb8606c3bb52d53a5364590000030101001e001b0100030200146406a5082b231340726d4cd0de2452bc73a33003000010030102001e001b0200010300144ac7b42f524e1d1b22098f85adfca752600ef9a000001101203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a27f030100000b000800000000000000100004010100050201010100d651221796b5206a5b9678a4d9995d519d8b9e75e87d85e57effb91f82a23e8d1002bcf84a882c0f72dd0d520a6954b3e1887fa55b7dc67635b44516856b31fd20a8100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100001e001b0000010200144463a1a994d5040e69c090b6985d7af295bfd11a0000030101003a0037010002010030973988b291fd1bca86d906723e335bdf13d3ebbadfea31dd164b3c672c16da72af8e6edfc0bac44b92b8c536d708dc33000010030102002b00280200030000210360da79c58995e4ec88512af9a4440ca4f2d7bfe84240e17effc4dd8ce94033a200001101207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e517f030100000b000800000000000000580004010100050201010100d95ff983db933edc675487a6f4e388fcf2db59313aeab5f45991a7f2471774471002355f98c38fd87ca5775e5e451243eb11300ed91fc950ea204c0a74b9a1991a25100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100003a0037000003010030b3423844bae8a591bbfb437b55566b5d61e54ee64f93351b0a3b9d4b731445d25ce367f7aedfcb32bd3cd14308a54cf50000030101003a0037010001010030a154c19082ac6b5fec72b81f6488550fec7149d52f66b4463915a61179c4f1f8507d366614b454dabf2c942235caad01000010030102001e001b0200030300140a8c14745c982f9fdc43aa985c02b1e5bff6c403000011012097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef7f030100000b000800000000000000620004010100050201010100412c1e7de2394dcd009223eb8c3a24e34b93a7c48df0bb86499160a31ea9dbdb1002180590eec33397034675f379cf17f62c0e77d17724a03238dcd3f216a4bc9509100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100003a0037000002010030afa4370aa5a48ab2f3ab510ccaba3b6d8cf51752304507e6a341c4e4ff6aa7c07610a503b42f479834b032d25dd160590000030101002b002801000300002103a9584c4580d165d2744ba49a70472653915bfdbec4bef471e26ce4c1c9e6c6ab000010030102001e001b02000102001445d04558a26b8ca04b486957c8abf5abf24ec76f0000110120a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be407f030100000b0008000000000000005d0004010100050201010100f140186a6bd413a50814db484b00398c2e7e6da9fbe2cb536728e880deb7506010027767f75fded47f94a6f81c671d448beddb6c2727f1f209ba015bf8de7331c13c100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100002b002800000000002102eebd2f91818a234e1879f8a55652f1e52419ad168b8f27b91be6b79958f7a5510000030101002b00280100020000210214a91dfcb36718209a5ee79c290029b849f1ce2feef6585a3b3fa37d04fb62b7000010030102001e001b0200030200144ee490084160fc8b1e73361d5a4c055beee77d8c0000110120e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4337f030100000b0008000000000000004f0004010100050201010100eb90b3c6d9a547e3b8a1111f621e0dbe5bfc68a8196371d497cb2912fa809d001002ab80ce7b6ca4875dbc7dc1f0d902551628c97b2383c27d04538d46a97d3cad43100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100001e001b0000020300149a061f31734c5f5f0b119ab72d433c9af133d3a60000030101003a003701000101003096e1fc631934a14acd313ff28ca29c9e9b43181b8df29386702b1a2d65a7cc823683f5733e296fb40c73648bc9cbf625000010030102001e001b02000102001474f185aa527f31202442d208cdb2905fa71403290000110201609f06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3000b03fda4d93a40301700000095840c6be056ed3d199dedf5265a5d3dafd195aa4cb54ca26943f7e092a5f06904200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000b03fd62132d410718000000b9dec92595e5eabb6de045782827bd98b60b9252287eec0f8e3450ea7c59619b1004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000b03fd8e29761d5405000000380d1a8cb3511b3ecf770a1d81f40c293182d29cf0574962db50c4cfb626fdb711042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30000b03fd62b9bfe135190000002eefa752386580c31084b54f2119973ccef6ac92fc38607e8609e896c9994c3e100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80000b03fdd0a1b7eee2140000002271b648a8925b8c717543453a59a3a20a3c52ce9b3e5fc793983c64f9f6fea004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2000b03fd1cb12a5b261400000068f31829eaec02f7e5eddada129d4981a99bda0e5c0fd4eff3c23eafc2c79a021004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e51000b03fd586ba25d1f1a0000005e3b38a6d9bede250ed0b612d01915a78182ee18d819d07d43ae925728b42d2d11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000b03fd120b51f4ea10000000be380b13cfd7149332e5ac818ae84d31e4be119bc0ebd717475630f6f38b6e90100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40000b03fd505d6c926f0d0000009500204c698cc12fc96774a34f77415c37376ff17b492838e414d774b5b7bec10420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae433000b03fd1e078984690800000064d995f4b5b62c480a04f1b8fb4c7a30b607f12da4abc357993ee7505be19b26111111"; + char *pub_key_hash_hex = "1f0815269afc012de44260ceb28a4496d3184184"; + + unsigned char *proof = hex2bin(multiple_identity_proof_hex); + unsigned char *pub_key_hash = hex2bin(pub_key_hash_hex); + + IdentityIdVerificationResult *result = verify_identity_id_by_public_key_hash(proof, 6206, true, pub_key_hash); + uint8_t expected_identity_id[32] = {15, 126, 159, 152, 150, 254, 206, 186, 180, 193, 157, 65, 233, 215, 241, 108, 23, 39, + 205, 99, 217, 219, 86, 244, 213, 176, 67, 34, 242, 146, 86, 203,}; + assert(result->is_valid); + assert(result->has_identity_id); + assert(result->id_size == 32); + assert(is_array_equal(expected_identity_id, result->identity_id, result->id_size)); +} + +void test_verify_identity_balances_by_identity_ids() { + char *multiple_identity_proof_hex = "06000100a603014a75cf3f535e81c4680f8137a2208dbcb2652ffd7e715bd4290cc5c560b2cc6102cfbe0535bd2defe586b863b9ccb92d0d66fb2b810d730e7ba2cb7e2fb302613b1004011800180201145e0e49d808ad21d01d07dd799a75bd1b472788a7008c10aa4c1d19e2e7e42fe0b1a7f6d93d4c0b6992ef63ea985c16447cada4629511040120002402012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000ba56cfb1d87ef47857f6b1cd7fb918406fd50f81966619777dd4c1b595a1a26e100169931838564707dbf11e90a059fd7dd453cc7e68adb7d2c2375bae53566664e711025670752cc3d883200a7598b65cd74b41a760cc0be57cda5536f15f03c8783aa81001c33635136e502e9ac5244b15a20a757e0759ce0a90823cd37f893f6a49556d26040160002d04012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30fdbafd6833aeb700000012b27f4a0a7cfd06e3387b33a5bca6682953512e21621ae9cf6d633d9041771910011e0c1443d0925f781132f4c506747202dbffa3ca3ded4d2387d4b7e40e0303e31111020118b3080132c9d35844d5ce2a8e0f377cee23c143a53396073dea86c494b86ba4c4af0b3903141f0815269afc012de44260ceb28a4496d3184184002300200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb00100168576e24521e03ba4b624912bb07833767c81102310b87d8ea1caf2795c68f921102e8b7eb376f0f7993badf93971f690be8a48f09db0711f052a2ed48471497b9d01003144463a1a994d5040e69c090b6985d7af295bfd11a002300203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a20002254bf0a990beb721c21f21e8dbab50e33cd9cf09618fc27c9f7450c673516aee1001c6adfe081809218ee07461f95f53ce6ce462ec379f97a71f1be40f7218cb50af111103145e0e49d808ad21d01d07dd799a75bd1b472788a70023002035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30001001a4b31998d47c30e390f4fa56f28f19c62f114f17a704d29c56e28b6fdb47f101031467892af390cd2b7653a918c7b692c85b87b44d3200230020399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80001001eb4da977338a3da4204eaaac0c8856bdfd51d9b25ceef04b40bb38eff79ab11011021f22102429dbe1bc0ca714847b08187d9a874cc43329aaa79647fb9aa0834d691003149a061f31734c5f5f0b119ab72d433c9af133d3a600230020e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330002644c601e67692188cf5a975c2207caba899d99f1bbd4b62e5fe856850b9d7286100314a54921bb29b67e31898efebc29f241b1aefa4dca002300207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e510010029e6f2d33b1580030e3b6030e3c25016ab7253965682556059dcc243b75c7fa6d0314b3bfce478de96fe30cd3713bf88ce7728687da8a00230020a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40001111110314bb3df025e32fd90d1feee7dca4b83321c683292d0023002003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3001001ee0847805b145b5fb500b139fe12767ee681fc310a21d6e9814619df5187470802a0de352fe6767da7bf4c33ba7d2da8db0440457835d3c2992473210e02b6312c1001e09f88cd09cc595d524892b3e642b939f2827995605703c49c861f653001d5e1029a563c983d202520c1a94f4c6ba99750373450aaf9dcb2a62ef50e9877646043100314ed738aaadd75d1677fefeccadd033f126cfee76a0023002097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000314fbd9daa5993de56a2e4346b7c72ff5585efffaab002300201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb0010111111110101208b06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d300090201010201030000006c4bfcf223cd4fe5c1cac82e1a9e2c73eb0e7f34cebabdd7630e24cb192f975804200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000902010102010300000080da62acb8c49f901d6bf84a2a2af15431e69e29069abf8d02f2c113c6099ba61004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000902010102010300000051a23049efbcde3a0e9c85ea7af05a28d4de31f90ae44a07c5fa18090128237011042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000090201010201030000002a390761b997897afe51540c39dfeb5c78d00781a547d2b83b1e72259894dea5100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f800009020101020103000000b3f28f9cc26df90ea49e13e3cd97c01d772e9d6609453e91d4369ef78e3880a004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200090201010201030000007fae89b888b23f4fbdaed2fb990a1f42727aef5bd2a8b91f8cb970570909ab391004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e5100090201010201030000001d64a3f9270bf8b8104305ba76829472f3aac2b6fff20b98ac10361ec5473fbb11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef0009020101020103000000adb76570d64f89650686df5819414e5e42cf7eedab24605aa63c4b8e26e90eda100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be400009020101020103000000a5a8530416d9462521b6fd932723d8971684b4620e4254caf09c75289e0e64700420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330009020101020103000000fa1d907f967c48292a5af3d4c3aad435c2ee9237119614d612aee3b4f52e3614111111012003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d37f030100000b0008000000000000003d000401010005020101010072cc451270c61384d358f7d41135b78788011830301a697b97a3714c203a36dc100214105bdf191491b67249d321f3d9bebdf82c9a3395fef336c60b3701af0593e7100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b000002030014bb3df025e32fd90d1feee7dca4b83321c683292d0000030101003a0037010001010030a5fd02c96d5f60eb54b15b043a84ed80a0af804eff4a2bfea1fc9fed323232c7ab12072368097e556439d08aa0a6866c000010030102003a003702000001003085ff00e6339367d3e31e27cbc33c13c3cd0c6e973a5b902e76668d7a6daf83c129257cc7f9cc35e1c0689a6df03a891d00001101200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb7f030100000b000800000000000000030004010100050201010100783a62676dbffd012f9343ef0af71c1b800cda19801689dfb7e2372cccc3ed9d10027f0e94e54c63ffdcd3d3d9017a63e82f9984ade5c4faa59d2479c11007932524100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df1102010178030100002b002800000200002103fe65fcdcfe242dc2e43d654274ec9ce1bbbc9dd5a1c88945eeef18cc93151f7f0000030101001e001b010001030014c94f46cf38b83862990f782c84acbc178d7b02da000010030102001e001b02000203001426d387d9884862f96160dd59ca596bdce82da74600001101201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb7f030100000b000800000000000000600004010100050201010100ca3a10eab3b889465bba51bc5354131aee1044e510d9ed4a7068d1181c7dbfcd10029626ec2b4e8861c675b20bc4456333d8c41fd0c0b9c9f0b78047c6634ebab8ef100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100001e001b000003020014fbd9daa5993de56a2e4346b7c72ff5585efffaab0000030101002b002801000300002103fdc9403eb6f005db700e7841627f4f92e7c65d167384cd57a4f4e46583c21afe000010030102002b002802000000002103703446f77c8db1fbac6f3422c8e045098adb662c0b620a15b8c4d9ecd2a3defa000011012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c307f030100000b000800000000000000420004010100050201010100d7f397a816f23f32e9a6cd2ab5b03d5b6d30742cf0b58517f276d9f75c1c4d611002bfd5686ae0d2a7684c2f6ed3a7419a436a5389afc9a84a1bb22a1decdfa7625d100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b0000020300145e0e49d808ad21d01d07dd799a75bd1b472788a70000030101003a003701000001003097c8d8102d216818c693dc46614ce9242b8e54e05a8ff1f520a3694b9481091d92906b13b9b2762b127ee4f07e91119e000010030102003a00370200030100308949c96dda849268044e176dbdba458fb5deac81e9918793bdb837f5afee0c2496a5930d46d1fe37ce536cbef8e95bb40000110120399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f807f030100000b0008000000000000000c0004010100050201010100a9403aa408af35d267980dfff1706d70a59b6dba867d0b568ca8c5b77560d67a100276cbfe822d7b9f6863f9a06b668097458e123ff385e31c29d830d03f1148973a100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100003a0037000000010030b79d4caa865f84207124c3d304430372f39d7c18a237df3a71e3c4fb7ba9ab9816439a809beb8606c3bb52d53a5364590000030101001e001b0100030200146406a5082b231340726d4cd0de2452bc73a33003000010030102001e001b0200010300144ac7b42f524e1d1b22098f85adfca752600ef9a000001101203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a27f030100000b000800000000000000100004010100050201010100d651221796b5206a5b9678a4d9995d519d8b9e75e87d85e57effb91f82a23e8d1002bcf84a882c0f72dd0d520a6954b3e1887fa55b7dc67635b44516856b31fd20a8100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100001e001b0000010200144463a1a994d5040e69c090b6985d7af295bfd11a0000030101003a0037010002010030973988b291fd1bca86d906723e335bdf13d3ebbadfea31dd164b3c672c16da72af8e6edfc0bac44b92b8c536d708dc33000010030102002b00280200030000210360da79c58995e4ec88512af9a4440ca4f2d7bfe84240e17effc4dd8ce94033a200001101207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e517f030100000b000800000000000000580004010100050201010100d95ff983db933edc675487a6f4e388fcf2db59313aeab5f45991a7f2471774471002355f98c38fd87ca5775e5e451243eb11300ed91fc950ea204c0a74b9a1991a25100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100003a0037000003010030b3423844bae8a591bbfb437b55566b5d61e54ee64f93351b0a3b9d4b731445d25ce367f7aedfcb32bd3cd14308a54cf50000030101003a0037010001010030a154c19082ac6b5fec72b81f6488550fec7149d52f66b4463915a61179c4f1f8507d366614b454dabf2c942235caad01000010030102001e001b0200030300140a8c14745c982f9fdc43aa985c02b1e5bff6c403000011012097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef7f030100000b000800000000000000620004010100050201010100412c1e7de2394dcd009223eb8c3a24e34b93a7c48df0bb86499160a31ea9dbdb1002180590eec33397034675f379cf17f62c0e77d17724a03238dcd3f216a4bc9509100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100003a0037000002010030afa4370aa5a48ab2f3ab510ccaba3b6d8cf51752304507e6a341c4e4ff6aa7c07610a503b42f479834b032d25dd160590000030101002b002801000300002103a9584c4580d165d2744ba49a70472653915bfdbec4bef471e26ce4c1c9e6c6ab000010030102001e001b02000102001445d04558a26b8ca04b486957c8abf5abf24ec76f0000110120a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be407f030100000b0008000000000000005d0004010100050201010100f140186a6bd413a50814db484b00398c2e7e6da9fbe2cb536728e880deb7506010027767f75fded47f94a6f81c671d448beddb6c2727f1f209ba015bf8de7331c13c100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100002b002800000000002102eebd2f91818a234e1879f8a55652f1e52419ad168b8f27b91be6b79958f7a5510000030101002b00280100020000210214a91dfcb36718209a5ee79c290029b849f1ce2feef6585a3b3fa37d04fb62b7000010030102001e001b0200030200144ee490084160fc8b1e73361d5a4c055beee77d8c0000110120e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4337f030100000b0008000000000000004f0004010100050201010100eb90b3c6d9a547e3b8a1111f621e0dbe5bfc68a8196371d497cb2912fa809d001002ab80ce7b6ca4875dbc7dc1f0d902551628c97b2383c27d04538d46a97d3cad43100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100001e001b0000020300149a061f31734c5f5f0b119ab72d433c9af133d3a60000030101003a003701000101003096e1fc631934a14acd313ff28ca29c9e9b43181b8df29386702b1a2d65a7cc823683f5733e296fb40c73648bc9cbf625000010030102001e001b02000102001474f185aa527f31202442d208cdb2905fa71403290000110201609f06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3000b03fda4d93a40301700000095840c6be056ed3d199dedf5265a5d3dafd195aa4cb54ca26943f7e092a5f06904200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000b03fd62132d410718000000b9dec92595e5eabb6de045782827bd98b60b9252287eec0f8e3450ea7c59619b1004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000b03fd8e29761d5405000000380d1a8cb3511b3ecf770a1d81f40c293182d29cf0574962db50c4cfb626fdb711042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30000b03fd62b9bfe135190000002eefa752386580c31084b54f2119973ccef6ac92fc38607e8609e896c9994c3e100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80000b03fdd0a1b7eee2140000002271b648a8925b8c717543453a59a3a20a3c52ce9b3e5fc793983c64f9f6fea004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2000b03fd1cb12a5b261400000068f31829eaec02f7e5eddada129d4981a99bda0e5c0fd4eff3c23eafc2c79a021004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e51000b03fd586ba25d1f1a0000005e3b38a6d9bede250ed0b612d01915a78182ee18d819d07d43ae925728b42d2d11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000b03fd120b51f4ea10000000be380b13cfd7149332e5ac818ae84d31e4be119bc0ebd717475630f6f38b6e90100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40000b03fd505d6c926f0d0000009500204c698cc12fc96774a34f77415c37376ff17b492838e414d774b5b7bec10420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae433000b03fd1e078984690800000064d995f4b5b62c480a04f1b8fb4c7a30b607f12da4abc357993ee7505be19b26111111"; + char *iden_one_hex = "3eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2"; + char *iden_two_hex = "97ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef"; + + unsigned char *proof = hex2bin(multiple_identity_proof_hex); + unsigned char *iden_ids[2] = { + hex2bin(iden_one_hex), + hex2bin(iden_two_hex), + }; + MultipleIdentityBalanceVerificationResult *result = verify_identity_balances_by_identity_ids(proof, 6206, true, iden_ids, 2); + assert(result->is_valid); + assert(result->map_size == 2); + assert(result->identity_id_balance_map[0]->has_balance); + assert(result->identity_id_balance_map[0]->balance == 11077485418638); + uint8_t expected_iden_one_bin[32] = {62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, + 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162}; + assert(is_array_equal(expected_iden_one_bin, result->identity_id_balance_map[0]->identity_id, result->identity_id_balance_map[0]->id_size)); + + assert(result->identity_id_balance_map[1]->has_balance); + assert(result->identity_id_balance_map[1]->balance == 9300653671817); + uint8_t expected_iden_two_bin[32] = {151, 172, 124, 81, 243, 147, 225, 5, 188, 204, 9, 152, 150, 127, 129, 13, 246, 19, + 141, 93, 239, 8, 214, 194, 123, 127, 177, 23, 144, 211, 189, 239,}; + assert(is_array_equal(expected_iden_two_bin, result->identity_id_balance_map[1]->identity_id, result->identity_id_balance_map[1]->id_size)); +} + +void test_verify_identity_ids_by_public_key_hashes() { + char *multiple_identity_proof_hex = "06000100a603014a75cf3f535e81c4680f8137a2208dbcb2652ffd7e715bd4290cc5c560b2cc6102cfbe0535bd2defe586b863b9ccb92d0d66fb2b810d730e7ba2cb7e2fb302613b1004011800180201145e0e49d808ad21d01d07dd799a75bd1b472788a7008c10aa4c1d19e2e7e42fe0b1a7f6d93d4c0b6992ef63ea985c16447cada4629511040120002402012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000ba56cfb1d87ef47857f6b1cd7fb918406fd50f81966619777dd4c1b595a1a26e100169931838564707dbf11e90a059fd7dd453cc7e68adb7d2c2375bae53566664e711025670752cc3d883200a7598b65cd74b41a760cc0be57cda5536f15f03c8783aa81001c33635136e502e9ac5244b15a20a757e0759ce0a90823cd37f893f6a49556d26040160002d04012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30fdbafd6833aeb700000012b27f4a0a7cfd06e3387b33a5bca6682953512e21621ae9cf6d633d9041771910011e0c1443d0925f781132f4c506747202dbffa3ca3ded4d2387d4b7e40e0303e31111020118b3080132c9d35844d5ce2a8e0f377cee23c143a53396073dea86c494b86ba4c4af0b3903141f0815269afc012de44260ceb28a4496d3184184002300200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb00100168576e24521e03ba4b624912bb07833767c81102310b87d8ea1caf2795c68f921102e8b7eb376f0f7993badf93971f690be8a48f09db0711f052a2ed48471497b9d01003144463a1a994d5040e69c090b6985d7af295bfd11a002300203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a20002254bf0a990beb721c21f21e8dbab50e33cd9cf09618fc27c9f7450c673516aee1001c6adfe081809218ee07461f95f53ce6ce462ec379f97a71f1be40f7218cb50af111103145e0e49d808ad21d01d07dd799a75bd1b472788a70023002035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30001001a4b31998d47c30e390f4fa56f28f19c62f114f17a704d29c56e28b6fdb47f101031467892af390cd2b7653a918c7b692c85b87b44d3200230020399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80001001eb4da977338a3da4204eaaac0c8856bdfd51d9b25ceef04b40bb38eff79ab11011021f22102429dbe1bc0ca714847b08187d9a874cc43329aaa79647fb9aa0834d691003149a061f31734c5f5f0b119ab72d433c9af133d3a600230020e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330002644c601e67692188cf5a975c2207caba899d99f1bbd4b62e5fe856850b9d7286100314a54921bb29b67e31898efebc29f241b1aefa4dca002300207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e510010029e6f2d33b1580030e3b6030e3c25016ab7253965682556059dcc243b75c7fa6d0314b3bfce478de96fe30cd3713bf88ce7728687da8a00230020a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40001111110314bb3df025e32fd90d1feee7dca4b83321c683292d0023002003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3001001ee0847805b145b5fb500b139fe12767ee681fc310a21d6e9814619df5187470802a0de352fe6767da7bf4c33ba7d2da8db0440457835d3c2992473210e02b6312c1001e09f88cd09cc595d524892b3e642b939f2827995605703c49c861f653001d5e1029a563c983d202520c1a94f4c6ba99750373450aaf9dcb2a62ef50e9877646043100314ed738aaadd75d1677fefeccadd033f126cfee76a0023002097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000314fbd9daa5993de56a2e4346b7c72ff5585efffaab002300201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb0010111111110101208b06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d300090201010201030000006c4bfcf223cd4fe5c1cac82e1a9e2c73eb0e7f34cebabdd7630e24cb192f975804200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000902010102010300000080da62acb8c49f901d6bf84a2a2af15431e69e29069abf8d02f2c113c6099ba61004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000902010102010300000051a23049efbcde3a0e9c85ea7af05a28d4de31f90ae44a07c5fa18090128237011042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c3000090201010201030000002a390761b997897afe51540c39dfeb5c78d00781a547d2b83b1e72259894dea5100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f800009020101020103000000b3f28f9cc26df90ea49e13e3cd97c01d772e9d6609453e91d4369ef78e3880a004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a200090201010201030000007fae89b888b23f4fbdaed2fb990a1f42727aef5bd2a8b91f8cb970570909ab391004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e5100090201010201030000001d64a3f9270bf8b8104305ba76829472f3aac2b6fff20b98ac10361ec5473fbb11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef0009020101020103000000adb76570d64f89650686df5819414e5e42cf7eedab24605aa63c4b8e26e90eda100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be400009020101020103000000a5a8530416d9462521b6fd932723d8971684b4620e4254caf09c75289e0e64700420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4330009020101020103000000fa1d907f967c48292a5af3d4c3aad435c2ee9237119614d612aee3b4f52e3614111111012003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d37f030100000b0008000000000000003d000401010005020101010072cc451270c61384d358f7d41135b78788011830301a697b97a3714c203a36dc100214105bdf191491b67249d321f3d9bebdf82c9a3395fef336c60b3701af0593e7100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b000002030014bb3df025e32fd90d1feee7dca4b83321c683292d0000030101003a0037010001010030a5fd02c96d5f60eb54b15b043a84ed80a0af804eff4a2bfea1fc9fed323232c7ab12072368097e556439d08aa0a6866c000010030102003a003702000001003085ff00e6339367d3e31e27cbc33c13c3cd0c6e973a5b902e76668d7a6daf83c129257cc7f9cc35e1c0689a6df03a891d00001101200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb7f030100000b000800000000000000030004010100050201010100783a62676dbffd012f9343ef0af71c1b800cda19801689dfb7e2372cccc3ed9d10027f0e94e54c63ffdcd3d3d9017a63e82f9984ade5c4faa59d2479c11007932524100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df1102010178030100002b002800000200002103fe65fcdcfe242dc2e43d654274ec9ce1bbbc9dd5a1c88945eeef18cc93151f7f0000030101001e001b010001030014c94f46cf38b83862990f782c84acbc178d7b02da000010030102001e001b02000203001426d387d9884862f96160dd59ca596bdce82da74600001101201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb7f030100000b000800000000000000600004010100050201010100ca3a10eab3b889465bba51bc5354131aee1044e510d9ed4a7068d1181c7dbfcd10029626ec2b4e8861c675b20bc4456333d8c41fd0c0b9c9f0b78047c6634ebab8ef100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100001e001b000003020014fbd9daa5993de56a2e4346b7c72ff5585efffaab0000030101002b002801000300002103fdc9403eb6f005db700e7841627f4f92e7c65d167384cd57a4f4e46583c21afe000010030102002b002802000000002103703446f77c8db1fbac6f3422c8e045098adb662c0b620a15b8c4d9ecd2a3defa000011012035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c307f030100000b000800000000000000420004010100050201010100d7f397a816f23f32e9a6cd2ab5b03d5b6d30742cf0b58517f276d9f75c1c4d611002bfd5686ae0d2a7684c2f6ed3a7419a436a5389afc9a84a1bb22a1decdfa7625d100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100001e001b0000020300145e0e49d808ad21d01d07dd799a75bd1b472788a70000030101003a003701000001003097c8d8102d216818c693dc46614ce9242b8e54e05a8ff1f520a3694b9481091d92906b13b9b2762b127ee4f07e91119e000010030102003a00370200030100308949c96dda849268044e176dbdba458fb5deac81e9918793bdb837f5afee0c2496a5930d46d1fe37ce536cbef8e95bb40000110120399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f807f030100000b0008000000000000000c0004010100050201010100a9403aa408af35d267980dfff1706d70a59b6dba867d0b568ca8c5b77560d67a100276cbfe822d7b9f6863f9a06b668097458e123ff385e31c29d830d03f1148973a100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100003a0037000000010030b79d4caa865f84207124c3d304430372f39d7c18a237df3a71e3c4fb7ba9ab9816439a809beb8606c3bb52d53a5364590000030101001e001b0100030200146406a5082b231340726d4cd0de2452bc73a33003000010030102001e001b0200010300144ac7b42f524e1d1b22098f85adfca752600ef9a000001101203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a27f030100000b000800000000000000100004010100050201010100d651221796b5206a5b9678a4d9995d519d8b9e75e87d85e57effb91f82a23e8d1002bcf84a882c0f72dd0d520a6954b3e1887fa55b7dc67635b44516856b31fd20a8100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100001e001b0000010200144463a1a994d5040e69c090b6985d7af295bfd11a0000030101003a0037010002010030973988b291fd1bca86d906723e335bdf13d3ebbadfea31dd164b3c672c16da72af8e6edfc0bac44b92b8c536d708dc33000010030102002b00280200030000210360da79c58995e4ec88512af9a4440ca4f2d7bfe84240e17effc4dd8ce94033a200001101207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e517f030100000b000800000000000000580004010100050201010100d95ff983db933edc675487a6f4e388fcf2db59313aeab5f45991a7f2471774471002355f98c38fd87ca5775e5e451243eb11300ed91fc950ea204c0a74b9a1991a25100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df11020101a301030100003a0037000003010030b3423844bae8a591bbfb437b55566b5d61e54ee64f93351b0a3b9d4b731445d25ce367f7aedfcb32bd3cd14308a54cf50000030101003a0037010001010030a154c19082ac6b5fec72b81f6488550fec7149d52f66b4463915a61179c4f1f8507d366614b454dabf2c942235caad01000010030102001e001b0200030300140a8c14745c982f9fdc43aa985c02b1e5bff6c403000011012097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef7f030100000b000800000000000000620004010100050201010100412c1e7de2394dcd009223eb8c3a24e34b93a7c48df0bb86499160a31ea9dbdb1002180590eec33397034675f379cf17f62c0e77d17724a03238dcd3f216a4bc9509100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201019401030100003a0037000002010030afa4370aa5a48ab2f3ab510ccaba3b6d8cf51752304507e6a341c4e4ff6aa7c07610a503b42f479834b032d25dd160590000030101002b002801000300002103a9584c4580d165d2744ba49a70472653915bfdbec4bef471e26ce4c1c9e6c6ab000010030102001e001b02000102001445d04558a26b8ca04b486957c8abf5abf24ec76f0000110120a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be407f030100000b0008000000000000005d0004010100050201010100f140186a6bd413a50814db484b00398c2e7e6da9fbe2cb536728e880deb7506010027767f75fded47f94a6f81c671d448beddb6c2727f1f209ba015bf8de7331c13c100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018501030100002b002800000000002102eebd2f91818a234e1879f8a55652f1e52419ad168b8f27b91be6b79958f7a5510000030101002b00280100020000210214a91dfcb36718209a5ee79c290029b849f1ce2feef6585a3b3fa37d04fb62b7000010030102001e001b0200030200144ee490084160fc8b1e73361d5a4c055beee77d8c0000110120e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae4337f030100000b0008000000000000004f0004010100050201010100eb90b3c6d9a547e3b8a1111f621e0dbe5bfc68a8196371d497cb2912fa809d001002ab80ce7b6ca4875dbc7dc1f0d902551628c97b2383c27d04538d46a97d3cad43100146197ba2d1d89ae65f0e38b4207166d2b6d52014cc704c567082bf1dbd65f9df110201018701030100001e001b0000020300149a061f31734c5f5f0b119ab72d433c9af133d3a60000030101003a003701000101003096e1fc631934a14acd313ff28ca29c9e9b43181b8df29386702b1a2d65a7cc823683f5733e296fb40c73648bc9cbf625000010030102001e001b02000102001474f185aa527f31202442d208cdb2905fa71403290000110201609f06042003c1211aa9d26239c6dca1e6cb1dbb8266fe2b9500f8699c84aa90d623f7b1d3000b03fda4d93a40301700000095840c6be056ed3d199dedf5265a5d3dafd195aa4cb54ca26943f7e092a5f06904200f7e9f9896fecebab4c19d41e9d7f16c1727cd63d9db56f4d5b04322f29256cb000b03fd62132d410718000000b9dec92595e5eabb6de045782827bd98b60b9252287eec0f8e3450ea7c59619b1004201b240fcb4e632e7856bff58b784dcebc19398c734ec600c465fde95a2366dbeb000b03fd8e29761d5405000000380d1a8cb3511b3ecf770a1d81f40c293182d29cf0574962db50c4cfb626fdb711042035a8dd6a65ed429912d2db054462c7e8c011965aa76a76356a69b4c881808c30000b03fd62b9bfe135190000002eefa752386580c31084b54f2119973ccef6ac92fc38607e8609e896c9994c3e100420399474f653ba6b7b3839a43ed0fa35ffcddd5efa1d0e7082941bd6240c219f80000b03fdd0a1b7eee2140000002271b648a8925b8c717543453a59a3a20a3c52ce9b3e5fc793983c64f9f6fea004203eab8233e9132dbfc2b700abb64d5d46d843162f27199c92236c638522bbf3a2000b03fd1cb12a5b261400000068f31829eaec02f7e5eddada129d4981a99bda0e5c0fd4eff3c23eafc2c79a021004207f3dfd2ccb054f410ee77eb02ee7b4ea960795d89746cdc226ddd899e6ac4e51000b03fd586ba25d1f1a0000005e3b38a6d9bede250ed0b612d01915a78182ee18d819d07d43ae925728b42d2d11042097ac7c51f393e105bccc0998967f810df6138d5def08d6c27b7fb11790d3bdef000b03fd120b51f4ea10000000be380b13cfd7149332e5ac818ae84d31e4be119bc0ebd717475630f6f38b6e90100420a89ba1a7b2bd5b99fc1beee05aca5587ae3cfb4628d2a0358f208252b7e8be40000b03fd505d6c926f0d0000009500204c698cc12fc96774a34f77415c37376ff17b492838e414d774b5b7bec10420e8f1eaea303ab85c0a20dc6e80ba551e3fab2b85702319a122e550a8734ae433000b03fd1e078984690800000064d995f4b5b62c480a04f1b8fb4c7a30b607f12da4abc357993ee7505be19b26111111"; + char *pub_key_hash_one_hex = "1f0815269afc012de44260ceb28a4496d3184184"; + char *pub_key_hash_two_hex = "4463a1a994d5040e69c090b6985d7af295bfd11a"; + char *pub_key_hash_three_hex = "5e0e49d808ad21d01d07dd799a75bd1b472788a7"; + + unsigned char *multiple_identity_proof_bin = hex2bin(multiple_identity_proof_hex); + unsigned char *pub_key_hashes[3] = { + hex2bin(pub_key_hash_one_hex), + hex2bin(pub_key_hash_two_hex), + hex2bin(pub_key_hash_three_hex), + }; + MultipleIdentityIdVerificationResult *result = verify_identity_ids_by_public_key_hashes(multiple_identity_proof_bin, 6206, true, pub_key_hashes, 3); + assert(result->is_valid); + assert(result->map_size == 3); + + assert(result->public_key_hash_identity_id_map[0]->has_identity_id); + assert(result->public_key_hash_identity_id_map[0]->id_size == 32); + uint8_t expected_id_one[32] = {15, 126, 159, 152, 150, 254, 206, 186, 180, 193, 157, 65, 233, 215, 241, 108, 23, + 39, 205, 99, 217, 219, 86, 244, 213, 176, 67, 34, 242, 146, 86, 203}; + assert(is_array_equal(expected_id_one, result->public_key_hash_identity_id_map[0]->identity_id, result->public_key_hash_identity_id_map[0]->id_size)); + + assert(result->public_key_hash_identity_id_map[1]->has_identity_id); + assert(result->public_key_hash_identity_id_map[1]->id_size == 32); + uint8_t expected_id_two[32] = {62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, + 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162}; + assert(is_array_equal(expected_id_two, result->public_key_hash_identity_id_map[1]->identity_id, result->public_key_hash_identity_id_map[0]->id_size)); + + assert(result->public_key_hash_identity_id_map[2]->has_identity_id); + assert(result->public_key_hash_identity_id_map[2]->id_size == 32); + uint8_t expected_id_three[32] = {53, 168, 221, 106, 101, 237, 66, 153, 18, 210, 219, 5, 68, 98, 199, 232, 192, 17, + 150, 90, 167, 106, 118, 53, 106, 105, 180, 200, 129, 128, 140, 48,}; + assert(is_array_equal(expected_id_three, result->public_key_hash_identity_id_map[2]->identity_id, result->public_key_hash_identity_id_map[2]->id_size)); +} + + +int main() { + test_verify_full_identity_by_public_key_hash(); + test_verify_full_identities_by_public_key_hashes(); + test_verify_full_identity_by_identity_id(); + test_verify_identity_id_by_public_key_hash(); + test_verify_identity_balances_by_identity_ids(); + test_verify_identity_ids_by_public_key_hashes(); + + printf("All assertions passed!!"); +} diff --git a/packages/rs-drive-verify-c-binding/c/utils.c b/packages/rs-drive-verify-c-binding/c/utils.c new file mode 100644 index 00000000000..db766ffb833 --- /dev/null +++ b/packages/rs-drive-verify-c-binding/c/utils.c @@ -0,0 +1,87 @@ +// +// Created by anton on 05.10.2021. +// + +#include + +char *bin2hex(unsigned char *p, int len) +{ + char *hex = malloc(((2*len) + 1)); + char *r = hex; + + while(len && p) + { + (*r) = ((*p) & 0xF0) >> 4; + (*r) = ((*r) <= 9 ? '0' + (*r) : 'a' - 10 + (*r)); + r++; + (*r) = ((*p) & 0x0F); + (*r) = ((*r) <= 9 ? '0' + (*r) : 'a' - 10 + (*r)); + r++; + p++; + len--; + } + *r = '\0'; + + return hex; +} + +unsigned char *hex2bin(const char *str) +{ + int len, h; + unsigned char *result, *err, *p, c; + + err = malloc(1); + *err = 0; + + if (!str) + return err; + + if (!*str) + return err; + + len = 0; + p = (unsigned char*) str; + while (*p++) + len++; + + result = malloc((len/2)+1); + h = !(len%2) * 4; + p = result; + *p = 0; + + c = *str; + while(c) + { + if(('0' <= c) && (c <= '9')) + *p += (c - '0') << h; + else if(('A' <= c) && (c <= 'F')) + *p += (c - 'A' + 10) << h; + else if(('a' <= c) && (c <= 'f')) + *p += (c - 'a' + 10) << h; + else + return err; + + str++; + c = *str; + + if (h) + h = 0; + else + { + h = 4; + p++; + *p = 0; + } + } + + return result; +} + +bool is_array_equal(uint8_t a[], uint8_t b[], int size) { + for (int i = 0; i < size; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; +} diff --git a/packages/rs-drive-verify-c-binding/cbindgen.toml b/packages/rs-drive-verify-c-binding/cbindgen.toml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/rs-drive-verify-c-binding/src/lib.rs b/packages/rs-drive-verify-c-binding/src/lib.rs new file mode 100644 index 00000000000..61adefc109c --- /dev/null +++ b/packages/rs-drive-verify-c-binding/src/lib.rs @@ -0,0 +1,782 @@ +mod types; +mod util; + +use crate::types::{ + IdentityIdBalanceMap, IdentityIdVerificationResult, IdentityVerificationResult, + MultipleIdentityBalanceVerificationResult, MultipleIdentityIdVerificationResult, + MultipleIdentityVerificationResult, PublicKeyHash, PublicKeyHashIdentityIdMap, + PublicKeyHashIdentityMap, +}; +use crate::util::{build_c_identity_struct, extract_vector_from_pointer, vec_to_pointer}; +use drive::drive::verify::Identity as DppIdentity; +use drive::drive::verify::{AssetLockProof as DppAssetLockProof, RootHash}; +use drive::drive::Drive; +use std::collections::BTreeMap; +use std::{mem, slice}; + +#[no_mangle] +pub extern "C" fn verify_full_identity_by_public_key_hash( + proof_array: *const u8, + proof_len: usize, + public_key_hash: *const PublicKeyHash, +) -> *const IdentityVerificationResult { + let proof = unsafe { slice::from_raw_parts(proof_array, proof_len) }; + let public_key_hash = unsafe { std::ptr::read(public_key_hash) }; + + let verification_result = + Drive::verify_full_identity_by_public_key_hash(proof, public_key_hash); + + match verification_result { + Ok((root_hash, maybe_identity)) => Box::into_raw(Box::from(IdentityVerificationResult { + root_hash: Box::into_raw(Box::from(root_hash)), + is_valid: true, + has_identity: maybe_identity.is_some(), + identity: build_c_identity_struct(maybe_identity), + })), + Err(..) => Box::into_raw(Box::from(IdentityVerificationResult::default())), + } +} + +#[no_mangle] +pub extern "C" fn verify_full_identities_by_public_key_hashes( + proof_array: *const u8, + proof_len: usize, + public_key_hashes_c: *const *const u8, + public_key_hash_count: usize, +) -> *const MultipleIdentityVerificationResult { + let proof = unsafe { slice::from_raw_parts(proof_array, proof_len) }; + let public_key_hashes = + extract_vector_from_pointer::<[u8; 20]>(public_key_hashes_c, public_key_hash_count); + + let verification_result = Drive::verify_full_identities_by_public_key_hashes::< + BTreeMap>, + >(proof, &public_key_hashes); + + match verification_result { + Ok((root_hash, hash_identity_map)) => { + let mut pkhash_identity_map_as_vec: Vec<*const PublicKeyHashIdentityMap> = Vec::new(); + for (public_key_hash, maybe_identity) in hash_identity_map { + pkhash_identity_map_as_vec.push(Box::into_raw(Box::from( + PublicKeyHashIdentityMap { + public_key_hash: vec_to_pointer(public_key_hash.to_vec()), + public_key_hash_length: public_key_hash.len(), + has_identity: maybe_identity.is_some(), + identity: build_c_identity_struct(maybe_identity), + }, + ))); + } + + Box::into_raw(Box::from(MultipleIdentityVerificationResult { + is_valid: true, + root_hash: Box::into_raw(Box::from(root_hash)), + map_size: pkhash_identity_map_as_vec.len(), + public_key_hash_identity_map: vec_to_pointer(pkhash_identity_map_as_vec), + })) + } + Err(..) => Box::into_raw(Box::from(MultipleIdentityVerificationResult::default())), + } +} + +#[no_mangle] +pub extern "C" fn verify_full_identity_by_identity_id( + proof_array: *const u8, + proof_len: usize, + is_proof_subset: bool, + identity_id: *const [u8; 32], +) -> *const IdentityVerificationResult { + let proof = unsafe { slice::from_raw_parts(proof_array, proof_len) }; + let identity_id: [u8; 32] = unsafe { std::ptr::read(identity_id) }; + let verification_result = + Drive::verify_full_identity_by_identity_id(proof, is_proof_subset, identity_id); + match verification_result { + Ok((root_hash, maybe_identity)) => Box::into_raw(Box::from(IdentityVerificationResult { + root_hash: Box::into_raw(Box::from(root_hash)), + is_valid: true, + has_identity: maybe_identity.is_some(), + identity: build_c_identity_struct(maybe_identity), + })), + Err(..) => Box::into_raw(Box::from(IdentityVerificationResult::default())), + } +} + +#[no_mangle] +pub extern "C" fn verify_identity_id_by_public_key_hash( + proof_array: *const u8, + proof_len: usize, + is_proof_subset: bool, + public_key_hash: *const PublicKeyHash, +) -> *const IdentityIdVerificationResult { + let proof = unsafe { slice::from_raw_parts(proof_array, proof_len) }; + let public_key_hash = unsafe { std::ptr::read(public_key_hash) }; + + let verification_result = + Drive::verify_identity_id_by_public_key_hash(proof, is_proof_subset, public_key_hash); + + match verification_result { + Ok((root_hash, maybe_identity_id)) => { + Box::into_raw(Box::from(IdentityIdVerificationResult { + root_hash: Box::into_raw(Box::from(root_hash)), + is_valid: true, + has_identity_id: maybe_identity_id.is_some(), + identity_id: maybe_identity_id + .map(|id| vec_to_pointer(id.to_vec())) + .unwrap_or(std::ptr::null()), + id_size: maybe_identity_id.map(|id| id.len()).unwrap_or(0), + })) + } + Err(..) => Box::into_raw(Box::from(IdentityIdVerificationResult::default())), + } +} + +#[no_mangle] +pub extern "C" fn verify_identity_balances_by_identity_ids( + proof_array: *const u8, + proof_len: usize, + is_proof_subset: bool, + identity_ids: *const *const u8, + id_size: usize, +) -> *const MultipleIdentityBalanceVerificationResult { + let proof = unsafe { slice::from_raw_parts(proof_array, proof_len) }; + let identity_ids = extract_vector_from_pointer::<[u8; 32]>(identity_ids, id_size); + + let verification_result = Drive::verify_identity_balances_for_identity_ids::< + Vec<([u8; 32], Option)>, + >(proof, is_proof_subset, identity_ids.as_slice()); + + match verification_result { + Ok((root_hash, identity_id_balance_map)) => { + let mut identity_id_balance_map_as_vec: Vec<*const IdentityIdBalanceMap> = Vec::new(); + for (identity_id, maybe_balance) in identity_id_balance_map { + identity_id_balance_map_as_vec.push(Box::into_raw(Box::from( + IdentityIdBalanceMap { + identity_id: vec_to_pointer(identity_id.to_vec()), + id_size: 32, + has_balance: maybe_balance.is_some(), + balance: maybe_balance.map(|b| b).unwrap_or(0), + }, + ))); + } + Box::into_raw(Box::from(MultipleIdentityBalanceVerificationResult { + is_valid: true, + root_hash: Box::into_raw(Box::from(root_hash)), + map_size: identity_id_balance_map_as_vec.len(), + identity_id_balance_map: vec_to_pointer(identity_id_balance_map_as_vec), + })) + } + Err(..) => Box::into_raw(Box::from( + MultipleIdentityBalanceVerificationResult::default(), + )), + } +} + +#[no_mangle] +pub extern "C" fn verify_identity_ids_by_public_key_hashes( + proof_array: *const u8, + proof_len: usize, + is_proof_subset: bool, + public_key_hashes_c: *const *const u8, + public_key_hash_count: usize, +) -> *const MultipleIdentityIdVerificationResult { + let proof = unsafe { slice::from_raw_parts(proof_array, proof_len) }; + let public_key_hashes = + extract_vector_from_pointer::<[u8; 20]>(public_key_hashes_c, public_key_hash_count); + + let verification_result = Drive::verify_identity_ids_by_public_key_hashes::< + Vec<(PublicKeyHash, Option<[u8; 32]>)>, + >(proof, is_proof_subset, public_key_hashes.as_slice()); + + match verification_result { + Ok((root_hash, public_key_hash_identity_id_map)) => { + let mut pkhash_identity_id_map_as_vec: Vec<*const PublicKeyHashIdentityIdMap> = + Vec::new(); + for (public_key_hash, maybe_identity_id) in &public_key_hash_identity_id_map { + pkhash_identity_id_map_as_vec.push(Box::into_raw(Box::from( + PublicKeyHashIdentityIdMap { + public_key_hash: vec_to_pointer(public_key_hash.to_vec()), + public_key_hash_size: public_key_hash.len(), + has_identity_id: maybe_identity_id.is_some(), + identity_id: maybe_identity_id + .map(|id| vec_to_pointer(id.to_vec())) + .unwrap_or(std::ptr::null()), + id_size: maybe_identity_id.map(|id| id.len()).unwrap_or(0), + }, + ))) + } + Box::into_raw(Box::from(MultipleIdentityIdVerificationResult { + is_valid: true, + root_hash: Box::into_raw(Box::from(root_hash)), + map_size: public_key_hash_identity_id_map.len(), + public_key_hash_identity_id_map: vec_to_pointer(pkhash_identity_id_map_as_vec), + })) + } + Err(..) => Box::into_raw(Box::from(MultipleIdentityIdVerificationResult::default())), + } +} + +// TODO: handle memory deallocation + +#[cfg(test)] +mod tests { + use super::*; + use drive::drive::Drive; + use std::collections::BTreeMap; + + fn single_identity_proof() -> &'static [u8] { + &[ + 6, 0, 1, 0, 166, 3, 1, 74, 117, 207, 63, 83, 94, 129, 196, 104, 15, 129, 55, 162, 32, + 141, 188, 178, 101, 47, 253, 126, 113, 91, 212, 41, 12, 197, 197, 96, 178, 204, 97, 2, + 207, 190, 5, 53, 189, 45, 239, 229, 134, 184, 99, 185, 204, 185, 45, 13, 102, 251, 43, + 129, 13, 115, 14, 123, 162, 203, 126, 47, 179, 2, 97, 59, 16, 4, 1, 24, 0, 24, 2, 1, + 20, 174, 227, 2, 114, 8, 150, 187, 168, 55, 220, 243, 242, 214, 116, 245, 70, 253, 37, + 73, 111, 0, 202, 53, 154, 161, 178, 3, 46, 49, 88, 174, 94, 92, 72, 159, 125, 70, 114, + 47, 41, 100, 74, 21, 225, 207, 124, 57, 53, 179, 6, 6, 222, 246, 17, 4, 1, 32, 0, 36, + 2, 1, 32, 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, + 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, 0, 160, 213, 164, + 246, 65, 134, 99, 70, 133, 21, 205, 117, 24, 155, 227, 225, 3, 75, 191, 169, 161, 128, + 126, 184, 29, 150, 75, 167, 68, 42, 11, 30, 16, 1, 105, 147, 24, 56, 86, 71, 7, 219, + 241, 30, 144, 160, 89, 253, 125, 212, 83, 204, 126, 104, 173, 183, 210, 194, 55, 91, + 174, 83, 86, 102, 100, 231, 17, 2, 86, 112, 117, 44, 195, 216, 131, 32, 10, 117, 152, + 182, 92, 215, 75, 65, 167, 96, 204, 11, 229, 124, 218, 85, 54, 241, 95, 3, 200, 120, + 58, 168, 16, 1, 195, 54, 53, 19, 110, 80, 46, 154, 197, 36, 75, 21, 162, 10, 117, 126, + 7, 89, 206, 10, 144, 130, 60, 211, 127, 137, 63, 106, 73, 85, 109, 38, 4, 1, 96, 0, 45, + 4, 1, 32, 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, + 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, 253, 28, 177, 42, + 91, 38, 20, 0, 0, 0, 251, 189, 59, 224, 151, 231, 240, 125, 86, 25, 221, 105, 231, 118, + 120, 132, 209, 22, 249, 90, 233, 165, 252, 219, 101, 30, 113, 114, 121, 2, 204, 30, 16, + 1, 30, 12, 20, 67, 208, 146, 95, 120, 17, 50, 244, 197, 6, 116, 114, 2, 219, 255, 163, + 202, 61, 237, 77, 35, 135, 212, 183, 228, 14, 3, 3, 227, 17, 17, 2, 1, 24, 127, 3, 20, + 68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182, 152, 93, 122, 242, 149, 191, + 209, 26, 0, 35, 0, 32, 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, + 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, 0, 2, + 158, 111, 45, 51, 177, 88, 0, 48, 227, 182, 3, 14, 60, 37, 1, 106, 183, 37, 57, 101, + 104, 37, 86, 5, 157, 204, 36, 59, 117, 199, 250, 109, 16, 1, 224, 159, 136, 205, 9, + 204, 89, 93, 82, 72, 146, 179, 230, 66, 185, 57, 242, 130, 121, 149, 96, 87, 3, 196, + 156, 134, 31, 101, 48, 1, 213, 225, 17, 1, 1, 32, 77, 4, 32, 62, 171, 130, 51, 233, 19, + 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108, + 99, 133, 34, 187, 243, 162, 0, 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 127, 174, 137, 184, 136, + 178, 63, 79, 189, 174, 210, 251, 153, 10, 31, 66, 114, 122, 239, 91, 210, 168, 185, 31, + 140, 185, 112, 87, 9, 9, 171, 57, 1, 32, 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, + 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, + 243, 162, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, 1, 1, 0, 5, 2, 1, + 1, 1, 0, 214, 81, 34, 23, 150, 181, 32, 106, 91, 150, 120, 164, 217, 153, 93, 81, 157, + 139, 158, 117, 232, 125, 133, 229, 126, 255, 185, 31, 130, 162, 62, 141, 16, 2, 188, + 248, 74, 136, 44, 15, 114, 221, 13, 82, 10, 105, 84, 179, 225, 136, 127, 165, 91, 125, + 198, 118, 53, 180, 69, 22, 133, 107, 49, 253, 32, 168, 16, 1, 70, 25, 123, 162, 209, + 216, 154, 230, 95, 14, 56, 180, 32, 113, 102, 210, 182, 213, 32, 20, 204, 112, 76, 86, + 112, 130, 191, 29, 189, 101, 249, 223, 17, 2, 1, 1, 148, 1, 3, 1, 0, 0, 30, 0, 27, 0, + 0, 1, 2, 0, 20, 68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182, 152, 93, 122, + 242, 149, 191, 209, 26, 0, 0, 3, 1, 1, 0, 58, 0, 55, 1, 0, 2, 1, 0, 48, 151, 57, 136, + 178, 145, 253, 27, 202, 134, 217, 6, 114, 62, 51, 91, 223, 19, 211, 235, 186, 223, 234, + 49, 221, 22, 75, 60, 103, 44, 22, 218, 114, 175, 142, 110, 223, 192, 186, 196, 75, 146, + 184, 197, 54, 215, 8, 220, 51, 0, 0, 16, 3, 1, 2, 0, 43, 0, 40, 2, 0, 3, 0, 0, 33, 3, + 96, 218, 121, 197, 137, 149, 228, 236, 136, 81, 42, 249, 164, 68, 12, 164, 242, 215, + 191, 232, 66, 64, 225, 126, 255, 196, 221, 140, 233, 64, 51, 162, 0, 0, 17, 2, 1, 96, + 79, 4, 32, 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, + 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, 0, 11, 3, 253, 28, + 177, 42, 91, 38, 20, 0, 0, 0, 104, 243, 24, 41, 234, 236, 2, 247, 229, 237, 218, 218, + 18, 157, 73, 129, 169, 155, 218, 14, 92, 15, 212, 239, 243, 194, 62, 175, 194, 199, + 154, 2, + ] + } + + fn multiple_identity_proof() -> &'static [u8] { + &[ + 6, 0, 1, 0, 166, 3, 1, 74, 117, 207, 63, 83, 94, 129, 196, 104, 15, 129, 55, 162, 32, + 141, 188, 178, 101, 47, 253, 126, 113, 91, 212, 41, 12, 197, 197, 96, 178, 204, 97, 2, + 207, 190, 5, 53, 189, 45, 239, 229, 134, 184, 99, 185, 204, 185, 45, 13, 102, 251, 43, + 129, 13, 115, 14, 123, 162, 203, 126, 47, 179, 2, 97, 59, 16, 4, 1, 24, 0, 24, 2, 1, + 20, 94, 14, 73, 216, 8, 173, 33, 208, 29, 7, 221, 121, 154, 117, 189, 27, 71, 39, 136, + 167, 0, 140, 16, 170, 76, 29, 25, 226, 231, 228, 47, 224, 177, 167, 246, 217, 61, 76, + 11, 105, 146, 239, 99, 234, 152, 92, 22, 68, 124, 173, 164, 98, 149, 17, 4, 1, 32, 0, + 36, 2, 1, 32, 53, 168, 221, 106, 101, 237, 66, 153, 18, 210, 219, 5, 68, 98, 199, 232, + 192, 17, 150, 90, 167, 106, 118, 53, 106, 105, 180, 200, 129, 128, 140, 48, 0, 186, 86, + 207, 177, 216, 126, 244, 120, 87, 246, 177, 205, 127, 185, 24, 64, 111, 213, 15, 129, + 150, 102, 25, 119, 125, 212, 193, 181, 149, 161, 162, 110, 16, 1, 105, 147, 24, 56, 86, + 71, 7, 219, 241, 30, 144, 160, 89, 253, 125, 212, 83, 204, 126, 104, 173, 183, 210, + 194, 55, 91, 174, 83, 86, 102, 100, 231, 17, 2, 86, 112, 117, 44, 195, 216, 131, 32, + 10, 117, 152, 182, 92, 215, 75, 65, 167, 96, 204, 11, 229, 124, 218, 85, 54, 241, 95, + 3, 200, 120, 58, 168, 16, 1, 195, 54, 53, 19, 110, 80, 46, 154, 197, 36, 75, 21, 162, + 10, 117, 126, 7, 89, 206, 10, 144, 130, 60, 211, 127, 137, 63, 106, 73, 85, 109, 38, 4, + 1, 96, 0, 45, 4, 1, 32, 53, 168, 221, 106, 101, 237, 66, 153, 18, 210, 219, 5, 68, 98, + 199, 232, 192, 17, 150, 90, 167, 106, 118, 53, 106, 105, 180, 200, 129, 128, 140, 48, + 253, 186, 253, 104, 51, 174, 183, 0, 0, 0, 18, 178, 127, 74, 10, 124, 253, 6, 227, 56, + 123, 51, 165, 188, 166, 104, 41, 83, 81, 46, 33, 98, 26, 233, 207, 109, 99, 61, 144, + 65, 119, 25, 16, 1, 30, 12, 20, 67, 208, 146, 95, 120, 17, 50, 244, 197, 6, 116, 114, + 2, 219, 255, 163, 202, 61, 237, 77, 35, 135, 212, 183, 228, 14, 3, 3, 227, 17, 17, 2, + 1, 24, 179, 8, 1, 50, 201, 211, 88, 68, 213, 206, 42, 142, 15, 55, 124, 238, 35, 193, + 67, 165, 51, 150, 7, 61, 234, 134, 196, 148, 184, 107, 164, 196, 175, 11, 57, 3, 20, + 31, 8, 21, 38, 154, 252, 1, 45, 228, 66, 96, 206, 178, 138, 68, 150, 211, 24, 65, 132, + 0, 35, 0, 32, 15, 126, 159, 152, 150, 254, 206, 186, 180, 193, 157, 65, 233, 215, 241, + 108, 23, 39, 205, 99, 217, 219, 86, 244, 213, 176, 67, 34, 242, 146, 86, 203, 0, 16, 1, + 104, 87, 110, 36, 82, 30, 3, 186, 75, 98, 73, 18, 187, 7, 131, 55, 103, 200, 17, 2, 49, + 11, 135, 216, 234, 28, 175, 39, 149, 198, 143, 146, 17, 2, 232, 183, 235, 55, 111, 15, + 121, 147, 186, 223, 147, 151, 31, 105, 11, 232, 164, 143, 9, 219, 7, 17, 240, 82, 162, + 237, 72, 71, 20, 151, 185, 208, 16, 3, 20, 68, 99, 161, 169, 148, 213, 4, 14, 105, 192, + 144, 182, 152, 93, 122, 242, 149, 191, 209, 26, 0, 35, 0, 32, 62, 171, 130, 51, 233, + 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, + 108, 99, 133, 34, 187, 243, 162, 0, 2, 37, 75, 240, 169, 144, 190, 183, 33, 194, 31, + 33, 232, 219, 171, 80, 227, 60, 217, 207, 9, 97, 143, 194, 124, 159, 116, 80, 198, 115, + 81, 106, 238, 16, 1, 198, 173, 254, 8, 24, 9, 33, 142, 224, 116, 97, 249, 95, 83, 206, + 108, 228, 98, 236, 55, 159, 151, 167, 31, 27, 228, 15, 114, 24, 203, 80, 175, 17, 17, + 3, 20, 94, 14, 73, 216, 8, 173, 33, 208, 29, 7, 221, 121, 154, 117, 189, 27, 71, 39, + 136, 167, 0, 35, 0, 32, 53, 168, 221, 106, 101, 237, 66, 153, 18, 210, 219, 5, 68, 98, + 199, 232, 192, 17, 150, 90, 167, 106, 118, 53, 106, 105, 180, 200, 129, 128, 140, 48, + 0, 16, 1, 164, 179, 25, 152, 212, 124, 48, 227, 144, 244, 250, 86, 242, 143, 25, 198, + 47, 17, 79, 23, 167, 4, 210, 156, 86, 226, 139, 111, 219, 71, 241, 1, 3, 20, 103, 137, + 42, 243, 144, 205, 43, 118, 83, 169, 24, 199, 182, 146, 200, 91, 135, 180, 77, 50, 0, + 35, 0, 32, 57, 148, 116, 246, 83, 186, 107, 123, 56, 57, 164, 62, 208, 250, 53, 255, + 205, 221, 94, 250, 29, 14, 112, 130, 148, 27, 214, 36, 12, 33, 159, 128, 0, 16, 1, 235, + 77, 169, 119, 51, 138, 61, 164, 32, 78, 170, 172, 12, 136, 86, 189, 253, 81, 217, 178, + 92, 238, 240, 75, 64, 187, 56, 239, 247, 154, 177, 16, 17, 2, 31, 34, 16, 36, 41, 219, + 225, 188, 12, 167, 20, 132, 123, 8, 24, 125, 154, 135, 76, 196, 51, 41, 170, 167, 150, + 71, 251, 154, 160, 131, 77, 105, 16, 3, 20, 154, 6, 31, 49, 115, 76, 95, 95, 11, 17, + 154, 183, 45, 67, 60, 154, 241, 51, 211, 166, 0, 35, 0, 32, 232, 241, 234, 234, 48, 58, + 184, 92, 10, 32, 220, 110, 128, 186, 85, 30, 63, 171, 43, 133, 112, 35, 25, 161, 34, + 229, 80, 168, 115, 74, 228, 51, 0, 2, 100, 76, 96, 30, 103, 105, 33, 136, 207, 90, 151, + 92, 34, 7, 202, 186, 137, 157, 153, 241, 187, 212, 182, 46, 95, 232, 86, 133, 11, 157, + 114, 134, 16, 3, 20, 165, 73, 33, 187, 41, 182, 126, 49, 137, 142, 254, 188, 41, 242, + 65, 177, 174, 250, 77, 202, 0, 35, 0, 32, 127, 61, 253, 44, 203, 5, 79, 65, 14, 231, + 126, 176, 46, 231, 180, 234, 150, 7, 149, 216, 151, 70, 205, 194, 38, 221, 216, 153, + 230, 172, 78, 81, 0, 16, 2, 158, 111, 45, 51, 177, 88, 0, 48, 227, 182, 3, 14, 60, 37, + 1, 106, 183, 37, 57, 101, 104, 37, 86, 5, 157, 204, 36, 59, 117, 199, 250, 109, 3, 20, + 179, 191, 206, 71, 141, 233, 111, 227, 12, 211, 113, 59, 248, 140, 231, 114, 134, 135, + 218, 138, 0, 35, 0, 32, 168, 155, 161, 167, 178, 189, 91, 153, 252, 27, 238, 224, 90, + 202, 85, 135, 174, 60, 251, 70, 40, 210, 160, 53, 143, 32, 130, 82, 183, 232, 190, 64, + 0, 17, 17, 17, 3, 20, 187, 61, 240, 37, 227, 47, 217, 13, 31, 238, 231, 220, 164, 184, + 51, 33, 198, 131, 41, 45, 0, 35, 0, 32, 3, 193, 33, 26, 169, 210, 98, 57, 198, 220, + 161, 230, 203, 29, 187, 130, 102, 254, 43, 149, 0, 248, 105, 156, 132, 170, 144, 214, + 35, 247, 177, 211, 0, 16, 1, 238, 8, 71, 128, 91, 20, 91, 95, 181, 0, 177, 57, 254, 18, + 118, 126, 230, 129, 252, 49, 10, 33, 214, 233, 129, 70, 25, 223, 81, 135, 71, 8, 2, + 160, 222, 53, 47, 230, 118, 125, 167, 191, 76, 51, 186, 125, 45, 168, 219, 4, 64, 69, + 120, 53, 211, 194, 153, 36, 115, 33, 14, 2, 182, 49, 44, 16, 1, 224, 159, 136, 205, 9, + 204, 89, 93, 82, 72, 146, 179, 230, 66, 185, 57, 242, 130, 121, 149, 96, 87, 3, 196, + 156, 134, 31, 101, 48, 1, 213, 225, 2, 154, 86, 60, 152, 61, 32, 37, 32, 193, 169, 79, + 76, 107, 169, 151, 80, 55, 52, 80, 170, 249, 220, 178, 166, 46, 245, 14, 152, 119, 100, + 96, 67, 16, 3, 20, 237, 115, 138, 170, 221, 117, 209, 103, 127, 239, 236, 202, 221, 3, + 63, 18, 108, 254, 231, 106, 0, 35, 0, 32, 151, 172, 124, 81, 243, 147, 225, 5, 188, + 204, 9, 152, 150, 127, 129, 13, 246, 19, 141, 93, 239, 8, 214, 194, 123, 127, 177, 23, + 144, 211, 189, 239, 0, 3, 20, 251, 217, 218, 165, 153, 61, 229, 106, 46, 67, 70, 183, + 199, 47, 245, 88, 94, 255, 250, 171, 0, 35, 0, 32, 27, 36, 15, 203, 78, 99, 46, 120, + 86, 191, 245, 139, 120, 77, 206, 188, 25, 57, 140, 115, 78, 198, 0, 196, 101, 253, 233, + 90, 35, 102, 219, 235, 0, 16, 17, 17, 17, 17, 1, 1, 32, 139, 6, 4, 32, 3, 193, 33, 26, + 169, 210, 98, 57, 198, 220, 161, 230, 203, 29, 187, 130, 102, 254, 43, 149, 0, 248, + 105, 156, 132, 170, 144, 214, 35, 247, 177, 211, 0, 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 108, + 75, 252, 242, 35, 205, 79, 229, 193, 202, 200, 46, 26, 158, 44, 115, 235, 14, 127, 52, + 206, 186, 189, 215, 99, 14, 36, 203, 25, 47, 151, 88, 4, 32, 15, 126, 159, 152, 150, + 254, 206, 186, 180, 193, 157, 65, 233, 215, 241, 108, 23, 39, 205, 99, 217, 219, 86, + 244, 213, 176, 67, 34, 242, 146, 86, 203, 0, 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 128, 218, + 98, 172, 184, 196, 159, 144, 29, 107, 248, 74, 42, 42, 241, 84, 49, 230, 158, 41, 6, + 154, 191, 141, 2, 242, 193, 19, 198, 9, 155, 166, 16, 4, 32, 27, 36, 15, 203, 78, 99, + 46, 120, 86, 191, 245, 139, 120, 77, 206, 188, 25, 57, 140, 115, 78, 198, 0, 196, 101, + 253, 233, 90, 35, 102, 219, 235, 0, 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 81, 162, 48, 73, 239, + 188, 222, 58, 14, 156, 133, 234, 122, 240, 90, 40, 212, 222, 49, 249, 10, 228, 74, 7, + 197, 250, 24, 9, 1, 40, 35, 112, 17, 4, 32, 53, 168, 221, 106, 101, 237, 66, 153, 18, + 210, 219, 5, 68, 98, 199, 232, 192, 17, 150, 90, 167, 106, 118, 53, 106, 105, 180, 200, + 129, 128, 140, 48, 0, 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 42, 57, 7, 97, 185, 151, 137, 122, + 254, 81, 84, 12, 57, 223, 235, 92, 120, 208, 7, 129, 165, 71, 210, 184, 59, 30, 114, + 37, 152, 148, 222, 165, 16, 4, 32, 57, 148, 116, 246, 83, 186, 107, 123, 56, 57, 164, + 62, 208, 250, 53, 255, 205, 221, 94, 250, 29, 14, 112, 130, 148, 27, 214, 36, 12, 33, + 159, 128, 0, 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 179, 242, 143, 156, 194, 109, 249, 14, 164, + 158, 19, 227, 205, 151, 192, 29, 119, 46, 157, 102, 9, 69, 62, 145, 212, 54, 158, 247, + 142, 56, 128, 160, 4, 32, 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, + 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, 0, + 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 127, 174, 137, 184, 136, 178, 63, 79, 189, 174, 210, 251, + 153, 10, 31, 66, 114, 122, 239, 91, 210, 168, 185, 31, 140, 185, 112, 87, 9, 9, 171, + 57, 16, 4, 32, 127, 61, 253, 44, 203, 5, 79, 65, 14, 231, 126, 176, 46, 231, 180, 234, + 150, 7, 149, 216, 151, 70, 205, 194, 38, 221, 216, 153, 230, 172, 78, 81, 0, 9, 2, 1, + 1, 2, 1, 3, 0, 0, 0, 29, 100, 163, 249, 39, 11, 248, 184, 16, 67, 5, 186, 118, 130, + 148, 114, 243, 170, 194, 182, 255, 242, 11, 152, 172, 16, 54, 30, 197, 71, 63, 187, 17, + 4, 32, 151, 172, 124, 81, 243, 147, 225, 5, 188, 204, 9, 152, 150, 127, 129, 13, 246, + 19, 141, 93, 239, 8, 214, 194, 123, 127, 177, 23, 144, 211, 189, 239, 0, 9, 2, 1, 1, 2, + 1, 3, 0, 0, 0, 173, 183, 101, 112, 214, 79, 137, 101, 6, 134, 223, 88, 25, 65, 78, 94, + 66, 207, 126, 237, 171, 36, 96, 90, 166, 60, 75, 142, 38, 233, 14, 218, 16, 4, 32, 168, + 155, 161, 167, 178, 189, 91, 153, 252, 27, 238, 224, 90, 202, 85, 135, 174, 60, 251, + 70, 40, 210, 160, 53, 143, 32, 130, 82, 183, 232, 190, 64, 0, 9, 2, 1, 1, 2, 1, 3, 0, + 0, 0, 165, 168, 83, 4, 22, 217, 70, 37, 33, 182, 253, 147, 39, 35, 216, 151, 22, 132, + 180, 98, 14, 66, 84, 202, 240, 156, 117, 40, 158, 14, 100, 112, 4, 32, 232, 241, 234, + 234, 48, 58, 184, 92, 10, 32, 220, 110, 128, 186, 85, 30, 63, 171, 43, 133, 112, 35, + 25, 161, 34, 229, 80, 168, 115, 74, 228, 51, 0, 9, 2, 1, 1, 2, 1, 3, 0, 0, 0, 250, 29, + 144, 127, 150, 124, 72, 41, 42, 90, 243, 212, 195, 170, 212, 53, 194, 238, 146, 55, 17, + 150, 20, 214, 18, 174, 227, 180, 245, 46, 54, 20, 17, 17, 17, 1, 32, 3, 193, 33, 26, + 169, 210, 98, 57, 198, 220, 161, 230, 203, 29, 187, 130, 102, 254, 43, 149, 0, 248, + 105, 156, 132, 170, 144, 214, 35, 247, 177, 211, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0, 0, + 0, 0, 0, 61, 0, 4, 1, 1, 0, 5, 2, 1, 1, 1, 0, 114, 204, 69, 18, 112, 198, 19, 132, 211, + 88, 247, 212, 17, 53, 183, 135, 136, 1, 24, 48, 48, 26, 105, 123, 151, 163, 113, 76, + 32, 58, 54, 220, 16, 2, 20, 16, 91, 223, 25, 20, 145, 182, 114, 73, 211, 33, 243, 217, + 190, 189, 248, 44, 154, 51, 149, 254, 243, 54, 198, 11, 55, 1, 175, 5, 147, 231, 16, 1, + 70, 25, 123, 162, 209, 216, 154, 230, 95, 14, 56, 180, 32, 113, 102, 210, 182, 213, 32, + 20, 204, 112, 76, 86, 112, 130, 191, 29, 189, 101, 249, 223, 17, 2, 1, 1, 163, 1, 3, 1, + 0, 0, 30, 0, 27, 0, 0, 2, 3, 0, 20, 187, 61, 240, 37, 227, 47, 217, 13, 31, 238, 231, + 220, 164, 184, 51, 33, 198, 131, 41, 45, 0, 0, 3, 1, 1, 0, 58, 0, 55, 1, 0, 1, 1, 0, + 48, 165, 253, 2, 201, 109, 95, 96, 235, 84, 177, 91, 4, 58, 132, 237, 128, 160, 175, + 128, 78, 255, 74, 43, 254, 161, 252, 159, 237, 50, 50, 50, 199, 171, 18, 7, 35, 104, 9, + 126, 85, 100, 57, 208, 138, 160, 166, 134, 108, 0, 0, 16, 3, 1, 2, 0, 58, 0, 55, 2, 0, + 0, 1, 0, 48, 133, 255, 0, 230, 51, 147, 103, 211, 227, 30, 39, 203, 195, 60, 19, 195, + 205, 12, 110, 151, 58, 91, 144, 46, 118, 102, 141, 122, 109, 175, 131, 193, 41, 37, + 124, 199, 249, 204, 53, 225, 192, 104, 154, 109, 240, 58, 137, 29, 0, 0, 17, 1, 32, 15, + 126, 159, 152, 150, 254, 206, 186, 180, 193, 157, 65, 233, 215, 241, 108, 23, 39, 205, + 99, 217, 219, 86, 244, 213, 176, 67, 34, 242, 146, 86, 203, 127, 3, 1, 0, 0, 11, 0, 8, + 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 1, 1, 0, 5, 2, 1, 1, 1, 0, 120, 58, 98, 103, 109, 191, + 253, 1, 47, 147, 67, 239, 10, 247, 28, 27, 128, 12, 218, 25, 128, 22, 137, 223, 183, + 226, 55, 44, 204, 195, 237, 157, 16, 2, 127, 14, 148, 229, 76, 99, 255, 220, 211, 211, + 217, 1, 122, 99, 232, 47, 153, 132, 173, 229, 196, 250, 165, 157, 36, 121, 193, 16, 7, + 147, 37, 36, 16, 1, 70, 25, 123, 162, 209, 216, 154, 230, 95, 14, 56, 180, 32, 113, + 102, 210, 182, 213, 32, 20, 204, 112, 76, 86, 112, 130, 191, 29, 189, 101, 249, 223, + 17, 2, 1, 1, 120, 3, 1, 0, 0, 43, 0, 40, 0, 0, 2, 0, 0, 33, 3, 254, 101, 252, 220, 254, + 36, 45, 194, 228, 61, 101, 66, 116, 236, 156, 225, 187, 188, 157, 213, 161, 200, 137, + 69, 238, 239, 24, 204, 147, 21, 31, 127, 0, 0, 3, 1, 1, 0, 30, 0, 27, 1, 0, 1, 3, 0, + 20, 201, 79, 70, 207, 56, 184, 56, 98, 153, 15, 120, 44, 132, 172, 188, 23, 141, 123, + 2, 218, 0, 0, 16, 3, 1, 2, 0, 30, 0, 27, 2, 0, 2, 3, 0, 20, 38, 211, 135, 217, 136, 72, + 98, 249, 97, 96, 221, 89, 202, 89, 107, 220, 232, 45, 167, 70, 0, 0, 17, 1, 32, 27, 36, + 15, 203, 78, 99, 46, 120, 86, 191, 245, 139, 120, 77, 206, 188, 25, 57, 140, 115, 78, + 198, 0, 196, 101, 253, 233, 90, 35, 102, 219, 235, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 96, 0, 4, 1, 1, 0, 5, 2, 1, 1, 1, 0, 202, 58, 16, 234, 179, 184, 137, 70, + 91, 186, 81, 188, 83, 84, 19, 26, 238, 16, 68, 229, 16, 217, 237, 74, 112, 104, 209, + 24, 28, 125, 191, 205, 16, 2, 150, 38, 236, 43, 78, 136, 97, 198, 117, 178, 11, 196, + 69, 99, 51, 216, 196, 31, 208, 192, 185, 201, 240, 183, 128, 71, 198, 99, 78, 186, 184, + 239, 16, 1, 70, 25, 123, 162, 209, 216, 154, 230, 95, 14, 56, 180, 32, 113, 102, 210, + 182, 213, 32, 20, 204, 112, 76, 86, 112, 130, 191, 29, 189, 101, 249, 223, 17, 2, 1, 1, + 133, 1, 3, 1, 0, 0, 30, 0, 27, 0, 0, 3, 2, 0, 20, 251, 217, 218, 165, 153, 61, 229, + 106, 46, 67, 70, 183, 199, 47, 245, 88, 94, 255, 250, 171, 0, 0, 3, 1, 1, 0, 43, 0, 40, + 1, 0, 3, 0, 0, 33, 3, 253, 201, 64, 62, 182, 240, 5, 219, 112, 14, 120, 65, 98, 127, + 79, 146, 231, 198, 93, 22, 115, 132, 205, 87, 164, 244, 228, 101, 131, 194, 26, 254, 0, + 0, 16, 3, 1, 2, 0, 43, 0, 40, 2, 0, 0, 0, 0, 33, 3, 112, 52, 70, 247, 124, 141, 177, + 251, 172, 111, 52, 34, 200, 224, 69, 9, 138, 219, 102, 44, 11, 98, 10, 21, 184, 196, + 217, 236, 210, 163, 222, 250, 0, 0, 17, 1, 32, 53, 168, 221, 106, 101, 237, 66, 153, + 18, 210, 219, 5, 68, 98, 199, 232, 192, 17, 150, 90, 167, 106, 118, 53, 106, 105, 180, + 200, 129, 128, 140, 48, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0, 0, 0, 0, 0, 66, 0, 4, 1, 1, + 0, 5, 2, 1, 1, 1, 0, 215, 243, 151, 168, 22, 242, 63, 50, 233, 166, 205, 42, 181, 176, + 61, 91, 109, 48, 116, 44, 240, 181, 133, 23, 242, 118, 217, 247, 92, 28, 77, 97, 16, 2, + 191, 213, 104, 106, 224, 210, 167, 104, 76, 47, 110, 211, 167, 65, 154, 67, 106, 83, + 137, 175, 201, 168, 74, 27, 178, 42, 29, 236, 223, 167, 98, 93, 16, 1, 70, 25, 123, + 162, 209, 216, 154, 230, 95, 14, 56, 180, 32, 113, 102, 210, 182, 213, 32, 20, 204, + 112, 76, 86, 112, 130, 191, 29, 189, 101, 249, 223, 17, 2, 1, 1, 163, 1, 3, 1, 0, 0, + 30, 0, 27, 0, 0, 2, 3, 0, 20, 94, 14, 73, 216, 8, 173, 33, 208, 29, 7, 221, 121, 154, + 117, 189, 27, 71, 39, 136, 167, 0, 0, 3, 1, 1, 0, 58, 0, 55, 1, 0, 0, 1, 0, 48, 151, + 200, 216, 16, 45, 33, 104, 24, 198, 147, 220, 70, 97, 76, 233, 36, 43, 142, 84, 224, + 90, 143, 241, 245, 32, 163, 105, 75, 148, 129, 9, 29, 146, 144, 107, 19, 185, 178, 118, + 43, 18, 126, 228, 240, 126, 145, 17, 158, 0, 0, 16, 3, 1, 2, 0, 58, 0, 55, 2, 0, 3, 1, + 0, 48, 137, 73, 201, 109, 218, 132, 146, 104, 4, 78, 23, 109, 189, 186, 69, 143, 181, + 222, 172, 129, 233, 145, 135, 147, 189, 184, 55, 245, 175, 238, 12, 36, 150, 165, 147, + 13, 70, 209, 254, 55, 206, 83, 108, 190, 248, 233, 91, 180, 0, 0, 17, 1, 32, 57, 148, + 116, 246, 83, 186, 107, 123, 56, 57, 164, 62, 208, 250, 53, 255, 205, 221, 94, 250, 29, + 14, 112, 130, 148, 27, 214, 36, 12, 33, 159, 128, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0, + 0, 0, 0, 0, 12, 0, 4, 1, 1, 0, 5, 2, 1, 1, 1, 0, 169, 64, 58, 164, 8, 175, 53, 210, + 103, 152, 13, 255, 241, 112, 109, 112, 165, 155, 109, 186, 134, 125, 11, 86, 140, 168, + 197, 183, 117, 96, 214, 122, 16, 2, 118, 203, 254, 130, 45, 123, 159, 104, 99, 249, + 160, 107, 102, 128, 151, 69, 142, 18, 63, 243, 133, 227, 28, 41, 216, 48, 208, 63, 17, + 72, 151, 58, 16, 1, 70, 25, 123, 162, 209, 216, 154, 230, 95, 14, 56, 180, 32, 113, + 102, 210, 182, 213, 32, 20, 204, 112, 76, 86, 112, 130, 191, 29, 189, 101, 249, 223, + 17, 2, 1, 1, 135, 1, 3, 1, 0, 0, 58, 0, 55, 0, 0, 0, 1, 0, 48, 183, 157, 76, 170, 134, + 95, 132, 32, 113, 36, 195, 211, 4, 67, 3, 114, 243, 157, 124, 24, 162, 55, 223, 58, + 113, 227, 196, 251, 123, 169, 171, 152, 22, 67, 154, 128, 155, 235, 134, 6, 195, 187, + 82, 213, 58, 83, 100, 89, 0, 0, 3, 1, 1, 0, 30, 0, 27, 1, 0, 3, 2, 0, 20, 100, 6, 165, + 8, 43, 35, 19, 64, 114, 109, 76, 208, 222, 36, 82, 188, 115, 163, 48, 3, 0, 0, 16, 3, + 1, 2, 0, 30, 0, 27, 2, 0, 1, 3, 0, 20, 74, 199, 180, 47, 82, 78, 29, 27, 34, 9, 143, + 133, 173, 252, 167, 82, 96, 14, 249, 160, 0, 0, 17, 1, 32, 62, 171, 130, 51, 233, 19, + 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108, + 99, 133, 34, 187, 243, 162, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0, 0, 0, 0, 0, 16, 0, 4, + 1, 1, 0, 5, 2, 1, 1, 1, 0, 214, 81, 34, 23, 150, 181, 32, 106, 91, 150, 120, 164, 217, + 153, 93, 81, 157, 139, 158, 117, 232, 125, 133, 229, 126, 255, 185, 31, 130, 162, 62, + 141, 16, 2, 188, 248, 74, 136, 44, 15, 114, 221, 13, 82, 10, 105, 84, 179, 225, 136, + 127, 165, 91, 125, 198, 118, 53, 180, 69, 22, 133, 107, 49, 253, 32, 168, 16, 1, 70, + 25, 123, 162, 209, 216, 154, 230, 95, 14, 56, 180, 32, 113, 102, 210, 182, 213, 32, 20, + 204, 112, 76, 86, 112, 130, 191, 29, 189, 101, 249, 223, 17, 2, 1, 1, 148, 1, 3, 1, 0, + 0, 30, 0, 27, 0, 0, 1, 2, 0, 20, 68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182, + 152, 93, 122, 242, 149, 191, 209, 26, 0, 0, 3, 1, 1, 0, 58, 0, 55, 1, 0, 2, 1, 0, 48, + 151, 57, 136, 178, 145, 253, 27, 202, 134, 217, 6, 114, 62, 51, 91, 223, 19, 211, 235, + 186, 223, 234, 49, 221, 22, 75, 60, 103, 44, 22, 218, 114, 175, 142, 110, 223, 192, + 186, 196, 75, 146, 184, 197, 54, 215, 8, 220, 51, 0, 0, 16, 3, 1, 2, 0, 43, 0, 40, 2, + 0, 3, 0, 0, 33, 3, 96, 218, 121, 197, 137, 149, 228, 236, 136, 81, 42, 249, 164, 68, + 12, 164, 242, 215, 191, 232, 66, 64, 225, 126, 255, 196, 221, 140, 233, 64, 51, 162, 0, + 0, 17, 1, 32, 127, 61, 253, 44, 203, 5, 79, 65, 14, 231, 126, 176, 46, 231, 180, 234, + 150, 7, 149, 216, 151, 70, 205, 194, 38, 221, 216, 153, 230, 172, 78, 81, 127, 3, 1, 0, + 0, 11, 0, 8, 0, 0, 0, 0, 0, 0, 0, 88, 0, 4, 1, 1, 0, 5, 2, 1, 1, 1, 0, 217, 95, 249, + 131, 219, 147, 62, 220, 103, 84, 135, 166, 244, 227, 136, 252, 242, 219, 89, 49, 58, + 234, 181, 244, 89, 145, 167, 242, 71, 23, 116, 71, 16, 2, 53, 95, 152, 195, 143, 216, + 124, 165, 119, 94, 94, 69, 18, 67, 235, 17, 48, 14, 217, 31, 201, 80, 234, 32, 76, 10, + 116, 185, 161, 153, 26, 37, 16, 1, 70, 25, 123, 162, 209, 216, 154, 230, 95, 14, 56, + 180, 32, 113, 102, 210, 182, 213, 32, 20, 204, 112, 76, 86, 112, 130, 191, 29, 189, + 101, 249, 223, 17, 2, 1, 1, 163, 1, 3, 1, 0, 0, 58, 0, 55, 0, 0, 3, 1, 0, 48, 179, 66, + 56, 68, 186, 232, 165, 145, 187, 251, 67, 123, 85, 86, 107, 93, 97, 229, 78, 230, 79, + 147, 53, 27, 10, 59, 157, 75, 115, 20, 69, 210, 92, 227, 103, 247, 174, 223, 203, 50, + 189, 60, 209, 67, 8, 165, 76, 245, 0, 0, 3, 1, 1, 0, 58, 0, 55, 1, 0, 1, 1, 0, 48, 161, + 84, 193, 144, 130, 172, 107, 95, 236, 114, 184, 31, 100, 136, 85, 15, 236, 113, 73, + 213, 47, 102, 180, 70, 57, 21, 166, 17, 121, 196, 241, 248, 80, 125, 54, 102, 20, 180, + 84, 218, 191, 44, 148, 34, 53, 202, 173, 1, 0, 0, 16, 3, 1, 2, 0, 30, 0, 27, 2, 0, 3, + 3, 0, 20, 10, 140, 20, 116, 92, 152, 47, 159, 220, 67, 170, 152, 92, 2, 177, 229, 191, + 246, 196, 3, 0, 0, 17, 1, 32, 151, 172, 124, 81, 243, 147, 225, 5, 188, 204, 9, 152, + 150, 127, 129, 13, 246, 19, 141, 93, 239, 8, 214, 194, 123, 127, 177, 23, 144, 211, + 189, 239, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0, 0, 0, 0, 0, 98, 0, 4, 1, 1, 0, 5, 2, 1, + 1, 1, 0, 65, 44, 30, 125, 226, 57, 77, 205, 0, 146, 35, 235, 140, 58, 36, 227, 75, 147, + 167, 196, 141, 240, 187, 134, 73, 145, 96, 163, 30, 169, 219, 219, 16, 2, 24, 5, 144, + 238, 195, 51, 151, 3, 70, 117, 243, 121, 207, 23, 246, 44, 14, 119, 209, 119, 36, 160, + 50, 56, 220, 211, 242, 22, 164, 188, 149, 9, 16, 1, 70, 25, 123, 162, 209, 216, 154, + 230, 95, 14, 56, 180, 32, 113, 102, 210, 182, 213, 32, 20, 204, 112, 76, 86, 112, 130, + 191, 29, 189, 101, 249, 223, 17, 2, 1, 1, 148, 1, 3, 1, 0, 0, 58, 0, 55, 0, 0, 2, 1, 0, + 48, 175, 164, 55, 10, 165, 164, 138, 178, 243, 171, 81, 12, 202, 186, 59, 109, 140, + 245, 23, 82, 48, 69, 7, 230, 163, 65, 196, 228, 255, 106, 167, 192, 118, 16, 165, 3, + 180, 47, 71, 152, 52, 176, 50, 210, 93, 209, 96, 89, 0, 0, 3, 1, 1, 0, 43, 0, 40, 1, 0, + 3, 0, 0, 33, 3, 169, 88, 76, 69, 128, 209, 101, 210, 116, 75, 164, 154, 112, 71, 38, + 83, 145, 91, 253, 190, 196, 190, 244, 113, 226, 108, 228, 193, 201, 230, 198, 171, 0, + 0, 16, 3, 1, 2, 0, 30, 0, 27, 2, 0, 1, 2, 0, 20, 69, 208, 69, 88, 162, 107, 140, 160, + 75, 72, 105, 87, 200, 171, 245, 171, 242, 78, 199, 111, 0, 0, 17, 1, 32, 168, 155, 161, + 167, 178, 189, 91, 153, 252, 27, 238, 224, 90, 202, 85, 135, 174, 60, 251, 70, 40, 210, + 160, 53, 143, 32, 130, 82, 183, 232, 190, 64, 127, 3, 1, 0, 0, 11, 0, 8, 0, 0, 0, 0, 0, + 0, 0, 93, 0, 4, 1, 1, 0, 5, 2, 1, 1, 1, 0, 241, 64, 24, 106, 107, 212, 19, 165, 8, 20, + 219, 72, 75, 0, 57, 140, 46, 126, 109, 169, 251, 226, 203, 83, 103, 40, 232, 128, 222, + 183, 80, 96, 16, 2, 119, 103, 247, 95, 222, 212, 127, 148, 166, 248, 28, 103, 29, 68, + 139, 237, 219, 108, 39, 39, 241, 242, 9, 186, 1, 91, 248, 222, 115, 49, 193, 60, 16, 1, + 70, 25, 123, 162, 209, 216, 154, 230, 95, 14, 56, 180, 32, 113, 102, 210, 182, 213, 32, + 20, 204, 112, 76, 86, 112, 130, 191, 29, 189, 101, 249, 223, 17, 2, 1, 1, 133, 1, 3, 1, + 0, 0, 43, 0, 40, 0, 0, 0, 0, 0, 33, 2, 238, 189, 47, 145, 129, 138, 35, 78, 24, 121, + 248, 165, 86, 82, 241, 229, 36, 25, 173, 22, 139, 143, 39, 185, 27, 230, 183, 153, 88, + 247, 165, 81, 0, 0, 3, 1, 1, 0, 43, 0, 40, 1, 0, 2, 0, 0, 33, 2, 20, 169, 29, 252, 179, + 103, 24, 32, 154, 94, 231, 156, 41, 0, 41, 184, 73, 241, 206, 47, 238, 246, 88, 90, 59, + 63, 163, 125, 4, 251, 98, 183, 0, 0, 16, 3, 1, 2, 0, 30, 0, 27, 2, 0, 3, 2, 0, 20, 78, + 228, 144, 8, 65, 96, 252, 139, 30, 115, 54, 29, 90, 76, 5, 91, 238, 231, 125, 140, 0, + 0, 17, 1, 32, 232, 241, 234, 234, 48, 58, 184, 92, 10, 32, 220, 110, 128, 186, 85, 30, + 63, 171, 43, 133, 112, 35, 25, 161, 34, 229, 80, 168, 115, 74, 228, 51, 127, 3, 1, 0, + 0, 11, 0, 8, 0, 0, 0, 0, 0, 0, 0, 79, 0, 4, 1, 1, 0, 5, 2, 1, 1, 1, 0, 235, 144, 179, + 198, 217, 165, 71, 227, 184, 161, 17, 31, 98, 30, 13, 190, 91, 252, 104, 168, 25, 99, + 113, 212, 151, 203, 41, 18, 250, 128, 157, 0, 16, 2, 171, 128, 206, 123, 108, 164, 135, + 93, 188, 125, 193, 240, 217, 2, 85, 22, 40, 201, 123, 35, 131, 194, 125, 4, 83, 141, + 70, 169, 125, 60, 173, 67, 16, 1, 70, 25, 123, 162, 209, 216, 154, 230, 95, 14, 56, + 180, 32, 113, 102, 210, 182, 213, 32, 20, 204, 112, 76, 86, 112, 130, 191, 29, 189, + 101, 249, 223, 17, 2, 1, 1, 135, 1, 3, 1, 0, 0, 30, 0, 27, 0, 0, 2, 3, 0, 20, 154, 6, + 31, 49, 115, 76, 95, 95, 11, 17, 154, 183, 45, 67, 60, 154, 241, 51, 211, 166, 0, 0, 3, + 1, 1, 0, 58, 0, 55, 1, 0, 1, 1, 0, 48, 150, 225, 252, 99, 25, 52, 161, 74, 205, 49, 63, + 242, 140, 162, 156, 158, 155, 67, 24, 27, 141, 242, 147, 134, 112, 43, 26, 45, 101, + 167, 204, 130, 54, 131, 245, 115, 62, 41, 111, 180, 12, 115, 100, 139, 201, 203, 246, + 37, 0, 0, 16, 3, 1, 2, 0, 30, 0, 27, 2, 0, 1, 2, 0, 20, 116, 241, 133, 170, 82, 127, + 49, 32, 36, 66, 210, 8, 205, 178, 144, 95, 167, 20, 3, 41, 0, 0, 17, 2, 1, 96, 159, 6, + 4, 32, 3, 193, 33, 26, 169, 210, 98, 57, 198, 220, 161, 230, 203, 29, 187, 130, 102, + 254, 43, 149, 0, 248, 105, 156, 132, 170, 144, 214, 35, 247, 177, 211, 0, 11, 3, 253, + 164, 217, 58, 64, 48, 23, 0, 0, 0, 149, 132, 12, 107, 224, 86, 237, 61, 25, 157, 237, + 245, 38, 90, 93, 61, 175, 209, 149, 170, 76, 181, 76, 162, 105, 67, 247, 224, 146, 165, + 240, 105, 4, 32, 15, 126, 159, 152, 150, 254, 206, 186, 180, 193, 157, 65, 233, 215, + 241, 108, 23, 39, 205, 99, 217, 219, 86, 244, 213, 176, 67, 34, 242, 146, 86, 203, 0, + 11, 3, 253, 98, 19, 45, 65, 7, 24, 0, 0, 0, 185, 222, 201, 37, 149, 229, 234, 187, 109, + 224, 69, 120, 40, 39, 189, 152, 182, 11, 146, 82, 40, 126, 236, 15, 142, 52, 80, 234, + 124, 89, 97, 155, 16, 4, 32, 27, 36, 15, 203, 78, 99, 46, 120, 86, 191, 245, 139, 120, + 77, 206, 188, 25, 57, 140, 115, 78, 198, 0, 196, 101, 253, 233, 90, 35, 102, 219, 235, + 0, 11, 3, 253, 142, 41, 118, 29, 84, 5, 0, 0, 0, 56, 13, 26, 140, 179, 81, 27, 62, 207, + 119, 10, 29, 129, 244, 12, 41, 49, 130, 210, 156, 240, 87, 73, 98, 219, 80, 196, 207, + 182, 38, 253, 183, 17, 4, 32, 53, 168, 221, 106, 101, 237, 66, 153, 18, 210, 219, 5, + 68, 98, 199, 232, 192, 17, 150, 90, 167, 106, 118, 53, 106, 105, 180, 200, 129, 128, + 140, 48, 0, 11, 3, 253, 98, 185, 191, 225, 53, 25, 0, 0, 0, 46, 239, 167, 82, 56, 101, + 128, 195, 16, 132, 181, 79, 33, 25, 151, 60, 206, 246, 172, 146, 252, 56, 96, 126, 134, + 9, 232, 150, 201, 153, 76, 62, 16, 4, 32, 57, 148, 116, 246, 83, 186, 107, 123, 56, 57, + 164, 62, 208, 250, 53, 255, 205, 221, 94, 250, 29, 14, 112, 130, 148, 27, 214, 36, 12, + 33, 159, 128, 0, 11, 3, 253, 208, 161, 183, 238, 226, 20, 0, 0, 0, 34, 113, 182, 72, + 168, 146, 91, 140, 113, 117, 67, 69, 58, 89, 163, 162, 10, 60, 82, 206, 155, 62, 95, + 199, 147, 152, 60, 100, 249, 246, 254, 160, 4, 32, 62, 171, 130, 51, 233, 19, 45, 191, + 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, + 34, 187, 243, 162, 0, 11, 3, 253, 28, 177, 42, 91, 38, 20, 0, 0, 0, 104, 243, 24, 41, + 234, 236, 2, 247, 229, 237, 218, 218, 18, 157, 73, 129, 169, 155, 218, 14, 92, 15, 212, + 239, 243, 194, 62, 175, 194, 199, 154, 2, 16, 4, 32, 127, 61, 253, 44, 203, 5, 79, 65, + 14, 231, 126, 176, 46, 231, 180, 234, 150, 7, 149, 216, 151, 70, 205, 194, 38, 221, + 216, 153, 230, 172, 78, 81, 0, 11, 3, 253, 88, 107, 162, 93, 31, 26, 0, 0, 0, 94, 59, + 56, 166, 217, 190, 222, 37, 14, 208, 182, 18, 208, 25, 21, 167, 129, 130, 238, 24, 216, + 25, 208, 125, 67, 174, 146, 87, 40, 180, 45, 45, 17, 4, 32, 151, 172, 124, 81, 243, + 147, 225, 5, 188, 204, 9, 152, 150, 127, 129, 13, 246, 19, 141, 93, 239, 8, 214, 194, + 123, 127, 177, 23, 144, 211, 189, 239, 0, 11, 3, 253, 18, 11, 81, 244, 234, 16, 0, 0, + 0, 190, 56, 11, 19, 207, 215, 20, 147, 50, 229, 172, 129, 138, 232, 77, 49, 228, 190, + 17, 155, 192, 235, 215, 23, 71, 86, 48, 246, 243, 139, 110, 144, 16, 4, 32, 168, 155, + 161, 167, 178, 189, 91, 153, 252, 27, 238, 224, 90, 202, 85, 135, 174, 60, 251, 70, 40, + 210, 160, 53, 143, 32, 130, 82, 183, 232, 190, 64, 0, 11, 3, 253, 80, 93, 108, 146, + 111, 13, 0, 0, 0, 149, 0, 32, 76, 105, 140, 193, 47, 201, 103, 116, 163, 79, 119, 65, + 92, 55, 55, 111, 241, 123, 73, 40, 56, 228, 20, 215, 116, 181, 183, 190, 193, 4, 32, + 232, 241, 234, 234, 48, 58, 184, 92, 10, 32, 220, 110, 128, 186, 85, 30, 63, 171, 43, + 133, 112, 35, 25, 161, 34, 229, 80, 168, 115, 74, 228, 51, 0, 11, 3, 253, 30, 7, 137, + 132, 105, 8, 0, 0, 0, 100, 217, 149, 244, 181, 182, 44, 72, 10, 4, 241, 184, 251, 76, + 122, 48, 182, 7, 241, 45, 164, 171, 195, 87, 153, 62, 231, 80, 91, 225, 155, 38, 17, + 17, 17, + ] + } + + #[test] + fn test_verify_full_identity_by_public_key_hash() { + let proof: &[u8] = single_identity_proof(); + let key_hash: PublicKeyHash = [ + 68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182, 152, 93, 122, 242, 149, 191, + 209, 26, + ]; + let (root_hash, proved_identity) = + Drive::verify_full_identity_by_public_key_hash(proof, key_hash).expect("should verify"); + // verify part of the identity, make sure it's the correct one + assert!(proved_identity.is_some()); + let proved_identity = proved_identity.unwrap(); + assert_eq!(proved_identity.protocol_version, 1); + assert_eq!(proved_identity.public_keys.len(), 3); + assert_eq!(proved_identity.balance, 11077485418638); + } + + #[test] + fn multiple_identity_proofs() { + let proof = multiple_identity_proof(); + let key_hashes: &[PublicKeyHash] = &[ + [ + 31, 8, 21, 38, 154, 252, 1, 45, 228, 66, 96, 206, 178, 138, 68, 150, 211, 24, 65, + 132, + ], + [ + 68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182, 152, 93, 122, 242, 149, 191, + 209, 26, + ], + [ + 94, 14, 73, 216, 8, 173, 33, 208, 29, 7, 221, 121, 154, 117, 189, 27, 71, 39, 136, + 167, + ], + [ + 103, 137, 42, 243, 144, 205, 43, 118, 83, 169, 24, 199, 182, 146, 200, 91, 135, + 180, 77, 50, + ], + [ + 154, 6, 31, 49, 115, 76, 95, 95, 11, 17, 154, 183, 45, 67, 60, 154, 241, 51, 211, + 166, + ], + [ + 165, 73, 33, 187, 41, 182, 126, 49, 137, 142, 254, 188, 41, 242, 65, 177, 174, 250, + 77, 202, + ], + [ + 179, 191, 206, 71, 141, 233, 111, 227, 12, 211, 113, 59, 248, 140, 231, 114, 134, + 135, 218, 138, + ], + [ + 187, 61, 240, 37, 227, 47, 217, 13, 31, 238, 231, 220, 164, 184, 51, 33, 198, 131, + 41, 45, + ], + [ + 237, 115, 138, 170, 221, 117, 209, 103, 127, 239, 236, 202, 221, 3, 63, 18, 108, + 254, 231, 106, + ], + [ + 251, 217, 218, 165, 153, 61, 229, 106, 46, 67, 70, 183, 199, 47, 245, 88, 94, 255, + 250, 171, + ], + ]; + + let (_, proved_identities): ([u8; 32], BTreeMap>) = + Drive::verify_full_identities_by_public_key_hashes(proof, &key_hashes) + .expect("expect that this be verified"); + assert_eq!(proved_identities.len(), 10); + dbg!(proved_identities.values()); + } + + #[test] + fn verify_full_identity_by_identity_id() { + let proof = single_identity_proof(); + let identity_id: [u8; 32] = [ + 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, + 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, + ]; + dbg!(hex::encode(identity_id)); + let (root_hash, maybe_identity) = + Drive::verify_full_identity_by_identity_id(proof, true, identity_id) + .expect("verification failed"); + let identity = maybe_identity.expect("couldn't get identity"); + assert_eq!(identity.protocol_version, 1); + assert_eq!(identity.public_keys.len(), 3); + assert_eq!(identity.balance, 11077485418638); + } + + #[test] + fn verify_identity_id_by_public_key_hash() { + let proof = multiple_identity_proof(); + let public_key_hash: PublicKeyHash = [ + 31, 8, 21, 38, 154, 252, 1, 45, 228, 66, 96, 206, 178, 138, 68, 150, 211, 24, 65, 132, + ]; + let (root_hash, maybe_identity_id) = + Drive::verify_identity_id_by_public_key_hash(proof, true, public_key_hash) + .expect("should verify"); + let expected_identity_id: [u8; 32] = [ + 15, 126, 159, 152, 150, 254, 206, 186, 180, 193, 157, 65, 233, 215, 241, 108, 23, 39, + 205, 99, 217, 219, 86, 244, 213, 176, 67, 34, 242, 146, 86, 203, + ]; + let actual_identity_id = maybe_identity_id.expect("should have identity id"); + assert_eq!(expected_identity_id, actual_identity_id); + } + + #[ignore] + #[test] + fn verify_identity_balance_by_identity_id() { + // TODO: given identity proof is a subset proof but this verify function expects non-subset proof + let proof = single_identity_proof(); + let identity_id: [u8; 32] = [ + 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, + 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, + ]; + let (root_hash, maybe_balance) = + Drive::verify_identity_balance_for_identity_id(proof, identity_id) + .expect("should verify"); + let actual_balance = maybe_balance.expect("should have balance"); + assert_eq!(actual_balance, 11077485418639); + } + + #[test] + fn verify_identity_balances_by_identity_ids() { + let proof = multiple_identity_proof(); + let identity_ids: &[[u8; 32]] = &[ + [ + 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, + 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, + ], + [ + 151, 172, 124, 81, 243, 147, 225, 5, 188, 204, 9, 152, 150, 127, 129, 13, 246, 19, + 141, 93, 239, 8, 214, 194, 123, 127, 177, 23, 144, 211, 189, 239, + ], + ]; + let (_, balances): (RootHash, Vec<([u8; 32], Option)>) = + Drive::verify_identity_balances_for_identity_ids(proof, true, identity_ids) + .expect("should verify"); + assert_eq!(balances.len(), 2); + assert_eq!(balances[0].1.unwrap(), 11077485418638); + assert_eq!(balances[1].1.unwrap(), 9300653671817); + } + + #[test] + fn verify_identity_ids_by_public_key_hashes() { + let proof = multiple_identity_proof(); + let public_key_hashes: &[PublicKeyHash] = &[ + [ + 31, 8, 21, 38, 154, 252, 1, 45, 228, 66, 96, 206, 178, 138, 68, 150, 211, 24, 65, + 132, + ], + [ + 68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182, 152, 93, 122, 242, 149, 191, + 209, 26, + ], + [ + 94, 14, 73, 216, 8, 173, 33, 208, 29, 7, 221, 121, 154, 117, 189, 27, 71, 39, 136, + 167, + ], + ]; + let (_, ids): (RootHash, Vec<([u8; 20], Option<[u8; 32]>)>) = + Drive::verify_identity_ids_by_public_key_hashes(proof, true, public_key_hashes) + .expect("should verify"); + assert_eq!(ids.len(), 3); + assert_eq!( + ids[0].1.unwrap(), + [ + 15, 126, 159, 152, 150, 254, 206, 186, 180, 193, 157, 65, 233, 215, 241, 108, 23, + 39, 205, 99, 217, 219, 86, 244, 213, 176, 67, 34, 242, 146, 86, 203 + ] + ); + assert_eq!( + ids[1].1.unwrap(), + [ + 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, + 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, + ] + ); + assert_eq!( + ids[2].1.unwrap(), + [ + 53, 168, 221, 106, 101, 237, 66, 153, 18, 210, 219, 5, 68, 98, 199, 232, 192, 17, + 150, 90, 167, 106, 118, 53, 106, 105, 180, 200, 129, 128, 140, 48, + ] + ); + } +} diff --git a/packages/rs-drive-verify-c-binding/src/types.rs b/packages/rs-drive-verify-c-binding/src/types.rs new file mode 100644 index 00000000000..66b42773b73 --- /dev/null +++ b/packages/rs-drive-verify-c-binding/src/types.rs @@ -0,0 +1,203 @@ +/// Type alias for a public key hash +pub(crate) type PublicKeyHash = [u8; 20]; + +/// Represents proof verification result + full identity +#[repr(C)] +pub struct IdentityVerificationResult { + pub is_valid: bool, + pub root_hash: *const [u8; 32], + pub has_identity: bool, + pub identity: *const Identity, +} + +impl Default for IdentityVerificationResult { + fn default() -> Self { + Self { + is_valid: false, + root_hash: std::ptr::null(), + has_identity: false, + identity: std::ptr::null(), + } + } +} + +/// Represent proof verification result + multiple identities +#[repr(C)] +pub struct MultipleIdentityVerificationResult { + pub is_valid: bool, + pub root_hash: *const [u8; 32], + pub public_key_hash_identity_map: *const *const PublicKeyHashIdentityMap, + pub map_size: usize, +} + +impl Default for MultipleIdentityVerificationResult { + fn default() -> Self { + Self { + is_valid: false, + root_hash: std::ptr::null(), + public_key_hash_identity_map: std::ptr::null(), + map_size: 0, + } + } +} + +/// Maps a public key hash to an identity +#[repr(C)] +pub struct PublicKeyHashIdentityMap { + pub public_key_hash: *const u8, + pub public_key_hash_length: usize, + pub has_identity: bool, + pub identity: *const Identity, +} + +/// Represents proof verification result + identity id result +#[repr(C)] +pub struct IdentityIdVerificationResult { + pub is_valid: bool, + pub root_hash: *const [u8; 32], + pub has_identity_id: bool, + pub identity_id: *const u8, + pub id_size: usize, +} + +impl Default for IdentityIdVerificationResult { + fn default() -> Self { + Self { + is_valid: false, + root_hash: std::ptr::null(), + has_identity_id: false, + identity_id: std::ptr::null(), + id_size: 0, + } + } +} + +/// Represent proof verification result + multiple identity balance result +#[repr(C)] +pub struct MultipleIdentityBalanceVerificationResult { + pub is_valid: bool, + pub root_hash: *const [u8; 32], + pub identity_id_balance_map: *const *const IdentityIdBalanceMap, + pub map_size: usize, +} + +impl Default for MultipleIdentityBalanceVerificationResult { + fn default() -> Self { + Self { + is_valid: true, + root_hash: std::ptr::null(), + identity_id_balance_map: std::ptr::null(), + map_size: 0, + } + } +} + +/// Maps from an identity id to an optional balance +#[repr(C)] +pub struct IdentityIdBalanceMap { + pub identity_id: *const u8, + pub id_size: usize, + pub has_balance: bool, + pub balance: u64, +} + +/// Represents proof verification result + multiple identity id result +#[repr(C)] +pub struct MultipleIdentityIdVerificationResult { + pub is_valid: bool, + pub root_hash: *const [u8; 32], + pub map_size: usize, + pub public_key_hash_identity_id_map: *const *const PublicKeyHashIdentityIdMap, +} + +impl Default for MultipleIdentityIdVerificationResult { + fn default() -> Self { + Self { + is_valid: true, + root_hash: std::ptr::null(), + map_size: 0, + public_key_hash_identity_id_map: std::ptr::null(), + } + } +} + +/// Maps a public key hash to an identity id +#[repr(C)] +pub struct PublicKeyHashIdentityIdMap { + pub public_key_hash: *const u8, + pub public_key_hash_size: usize, + pub has_identity_id: bool, + pub identity_id: *const u8, + pub id_size: usize, +} + +/// Represents an identity +#[repr(C)] +pub struct Identity { + pub protocol_version: u32, + pub id: *const [u8; 32], + pub public_keys_count: usize, + pub public_keys: *const *const IdPublicKeyMap, + pub balance: u64, + pub revision: u64, + pub has_asset_lock_proof: bool, + pub asset_lock_proof: *const AssetLockProof, + pub has_metadata: bool, + pub meta_data: *const MetaData, +} + +/// Maps a key id to a public key +#[repr(C)] +pub struct IdPublicKeyMap { + pub key: u32, + pub public_key: *const IdentityPublicKey, +} + +/// Represents an identity public key +#[repr(C)] +pub struct IdentityPublicKey { + pub id: u32, + + // AUTHENTICATION = 0, + // ENCRYPTION = 1, + // DECRYPTION = 2, + // WITHDRAW = 3 + pub purpose: u8, + + // MASTER = 0, + // CRITICAL = 1, + // HIGH = 2, + // MEDIUM = 3 + pub security_level: u8, + + // ECDSA_SECP256K1 = 0, + // BLS312_381 = 1, + // ECDSA_HASH160 = 2, + // BIP13_SCRIPT_HASH = 3 + pub key_type: u8, + + pub read_only: bool, + pub data_length: usize, + pub data: *const u8, + pub has_disabled_at: bool, + pub disabled_at: u64, +} + +/// Represents an asset lock proof +// TODO: add the actual asset lock types +#[repr(C)] +pub struct AssetLockProof { + pub is_instant: bool, + // pub instant_asset_lock_proof: *const InstantAssetLocKProof, + pub is_chain: bool, + // pub chain_asset_lock_proof: *const ChainAssetLockProof, +} + +/// Represents identity metat data +#[repr(C)] +pub struct MetaData { + pub block_height: u64, + pub core_chain_locked_height: u64, + pub time_ms: u64, + pub protocol_version: u32, +} diff --git a/packages/rs-drive-verify-c-binding/src/util.rs b/packages/rs-drive-verify-c-binding/src/util.rs new file mode 100644 index 00000000000..4c69ccfca4f --- /dev/null +++ b/packages/rs-drive-verify-c-binding/src/util.rs @@ -0,0 +1,102 @@ +use crate::types::{ + AssetLockProof, IdPublicKeyMap, Identity, IdentityPublicKey, MetaData, PublicKeyHash, +}; +use crate::{DppAssetLockProof, DppIdentity}; +use std::{mem, slice}; + +pub(crate) fn build_c_identity_struct(maybe_identity: Option) -> *mut Identity { + maybe_identity + .map(|identity| { + Box::into_raw(Box::from(Identity { + protocol_version: identity.protocol_version, + id: Box::into_raw(Box::from(identity.id.0 .0)), + public_keys_count: identity.public_keys.len(), + public_keys: build_c_public_keys_struct(&identity), + balance: identity.balance, + revision: identity.revision, + has_asset_lock_proof: identity.asset_lock_proof.is_some(), + asset_lock_proof: build_c_asset_lock_proof_struct(&identity), + has_metadata: identity.metadata.is_some(), + meta_data: build_c_metadata_struct(&identity), + })) + }) + .unwrap_or(std::ptr::null_mut()) +} + +pub(crate) fn build_c_public_keys_struct(identity: &DppIdentity) -> *const *const IdPublicKeyMap { + let mut id_public_key_map_as_vec: Vec<*const IdPublicKeyMap> = vec![]; + for (key_id, identity_public_key) in &identity.public_keys { + id_public_key_map_as_vec.push(Box::into_raw(Box::from(IdPublicKeyMap { + key: key_id.clone(), + public_key: Box::into_raw(Box::from(IdentityPublicKey { + id: identity_public_key.id, + purpose: identity_public_key.purpose as u8, + security_level: identity_public_key.security_level as u8, + key_type: identity_public_key.key_type as u8, + read_only: identity_public_key.read_only, + data_length: identity_public_key.data.len(), + data: vec_to_pointer(identity_public_key.data.to_vec()), + has_disabled_at: identity_public_key.disabled_at.is_some(), + disabled_at: identity_public_key.disabled_at.unwrap_or(0), + })), + }))) + } + let pointer = id_public_key_map_as_vec.as_ptr(); + mem::forget(id_public_key_map_as_vec); + pointer +} + +pub(crate) fn build_c_asset_lock_proof_struct(identity: &DppIdentity) -> *const AssetLockProof { + let asset_lock_proof = &identity.asset_lock_proof; + if let Some(asset_lock_proof) = asset_lock_proof { + // TODO: construct the actual asset lock proofs + match asset_lock_proof { + DppAssetLockProof::Instant(..) => Box::into_raw(Box::from(AssetLockProof { + is_chain: false, + is_instant: true, + })), + DppAssetLockProof::Chain(..) => Box::into_raw(Box::from(AssetLockProof { + is_chain: true, + is_instant: false, + })), + } + } else { + Box::into_raw(Box::from(AssetLockProof { + is_chain: false, + is_instant: false, + })) + } +} + +pub(crate) fn build_c_metadata_struct(identity: &DppIdentity) -> *const MetaData { + let metadata = &identity.metadata; + if let Some(metadata) = metadata { + Box::into_raw(Box::from(MetaData { + block_height: metadata.block_height, + core_chain_locked_height: metadata.core_chain_locked_height, + time_ms: metadata.time_ms, + protocol_version: metadata.protocol_version, + })) + } else { + std::ptr::null() + } +} + +pub(crate) fn extract_vector_from_pointer( + ptr: *const *const u8, + count: usize, +) -> Vec { + let mut result = Vec::new(); + let inner_pointers = unsafe { slice::from_raw_parts(ptr, count) }; + for i in 0..count { + let inner_item: T = unsafe { std::ptr::read(inner_pointers[i] as *const T )}; + result.push(inner_item); + } + result +} + +pub(crate) fn vec_to_pointer(a: Vec) -> *const T { + let ptr = a.as_ptr(); + mem::forget(a); + ptr +} From b798bd1085a040b2c240177367d93e9ef3f2b4b4 Mon Sep 17 00:00:00 2001 From: Wisdom Ogwu Date: Mon, 27 Mar 2023 09:19:48 +0100 Subject: [PATCH 5/7] fmt --- packages/rs-drive-verify-c-binding/src/util.rs | 7 ++----- packages/rs-drive/src/drive/grove_operations.rs | 2 +- packages/rs-drive/src/drive/test_utils.rs | 2 +- packages/rs-drive/src/drive/verify/mod.rs | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/rs-drive-verify-c-binding/src/util.rs b/packages/rs-drive-verify-c-binding/src/util.rs index 4c69ccfca4f..8a05bd2156b 100644 --- a/packages/rs-drive-verify-c-binding/src/util.rs +++ b/packages/rs-drive-verify-c-binding/src/util.rs @@ -82,14 +82,11 @@ pub(crate) fn build_c_metadata_struct(identity: &DppIdentity) -> *const MetaData } } -pub(crate) fn extract_vector_from_pointer( - ptr: *const *const u8, - count: usize, -) -> Vec { +pub(crate) fn extract_vector_from_pointer(ptr: *const *const u8, count: usize) -> Vec { let mut result = Vec::new(); let inner_pointers = unsafe { slice::from_raw_parts(ptr, count) }; for i in 0..count { - let inner_item: T = unsafe { std::ptr::read(inner_pointers[i] as *const T )}; + let inner_item: T = unsafe { std::ptr::read(inner_pointers[i] as *const T) }; result.push(inner_item); } result diff --git a/packages/rs-drive/src/drive/grove_operations.rs b/packages/rs-drive/src/drive/grove_operations.rs index 66990aa2db1..aecc540b0dc 100644 --- a/packages/rs-drive/src/drive/grove_operations.rs +++ b/packages/rs-drive/src/drive/grove_operations.rs @@ -1727,7 +1727,7 @@ impl Drive { deleting_non_empty_trees_returns_error: true, disable_operation_consistency_check: false, base_root_storage_is_free: true, - batch_pause_height: None + batch_pause_height: None, }), |_, _, _| Ok(false), |_, _, _| Err(GroveError::InternalError("not implemented")), diff --git a/packages/rs-drive/src/drive/test_utils.rs b/packages/rs-drive/src/drive/test_utils.rs index d0180bb85f9..2a09c45277b 100644 --- a/packages/rs-drive/src/drive/test_utils.rs +++ b/packages/rs-drive/src/drive/test_utils.rs @@ -1,8 +1,8 @@ use std::cell::RefCell; +use dpp::dashcore::anyhow; use dpp::util::entropy_generator::EntropyGenerator; use rand::{rngs::SmallRng, Rng, SeedableRng}; -use dpp::dashcore::anyhow; pub(crate) struct TestEntropyGenerator { rng: RefCell, diff --git a/packages/rs-drive/src/drive/verify/mod.rs b/packages/rs-drive/src/drive/verify/mod.rs index 5ddc9193d37..62c1d76b517 100644 --- a/packages/rs-drive/src/drive/verify/mod.rs +++ b/packages/rs-drive/src/drive/verify/mod.rs @@ -8,7 +8,7 @@ use crate::error::proof::ProofError; use crate::error::Error; use dpp::identifier::Identifier; use dpp::identity::{IdentityPublicKey, KeyID}; -pub use dpp::prelude::{Identity, Revision, AssetLockProof}; +pub use dpp::prelude::{AssetLockProof, Identity, Revision}; use crate::fee::credits::Credits; use grovedb::GroveDb; From 95bed1f95932199dedd96f0c5a6e0b1c727a9ce7 Mon Sep 17 00:00:00 2001 From: Wisdom Ogwu Date: Mon, 27 Mar 2023 09:22:14 +0100 Subject: [PATCH 6/7] fmt --- packages/rs-dpp/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/rs-dpp/src/lib.rs b/packages/rs-dpp/src/lib.rs index 4cabdfb7a78..1b3ffa46f38 100644 --- a/packages/rs-dpp/src/lib.rs +++ b/packages/rs-dpp/src/lib.rs @@ -52,10 +52,10 @@ pub mod prelude { pub use crate::document::ExtendedDocument; pub use crate::errors::ProtocolError; pub use crate::identifier::Identifier; + pub use crate::identity::state_transition::asset_lock_proof::AssetLockProof; pub use crate::identity::Identity; pub use crate::identity::IdentityPublicKey; pub use crate::validation::ValidationResult; - pub use crate::identity::state_transition::asset_lock_proof::AssetLockProof; pub use super::convertible::Convertible; pub type TimestampMillis = u64; From ee6e60d087c54dd24da2a3cb2aff4fe8a73d0d2a Mon Sep 17 00:00:00 2001 From: Wisdom Ogwu Date: Thu, 30 Mar 2023 08:44:50 +0100 Subject: [PATCH 7/7] fix clippy errors --- packages/rs-drive-verify-c-binding/build.rs | 4 +-- packages/rs-drive-verify-c-binding/src/lib.rs | 30 +++++++++---------- .../rs-drive-verify-c-binding/src/util.rs | 4 +-- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/packages/rs-drive-verify-c-binding/build.rs b/packages/rs-drive-verify-c-binding/build.rs index f44a99b622d..9369ce57341 100644 --- a/packages/rs-drive-verify-c-binding/build.rs +++ b/packages/rs-drive-verify-c-binding/build.rs @@ -1,4 +1,4 @@ -use cbindgen; + use std::env; @@ -6,7 +6,7 @@ fn main() { let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); let mut config: cbindgen::Config = Default::default(); config.language = cbindgen::Language::C; - cbindgen::generate_with_config(&crate_dir, config) + cbindgen::generate_with_config(crate_dir, config) .unwrap() .write_to_file("target/drive.h"); } diff --git a/packages/rs-drive-verify-c-binding/src/lib.rs b/packages/rs-drive-verify-c-binding/src/lib.rs index 61adefc109c..ebf54d86c68 100644 --- a/packages/rs-drive-verify-c-binding/src/lib.rs +++ b/packages/rs-drive-verify-c-binding/src/lib.rs @@ -9,13 +9,13 @@ use crate::types::{ }; use crate::util::{build_c_identity_struct, extract_vector_from_pointer, vec_to_pointer}; use drive::drive::verify::Identity as DppIdentity; -use drive::drive::verify::{AssetLockProof as DppAssetLockProof, RootHash}; +use drive::drive::verify::{AssetLockProof as DppAssetLockProof}; use drive::drive::Drive; use std::collections::BTreeMap; -use std::{mem, slice}; +use std::{slice}; #[no_mangle] -pub extern "C" fn verify_full_identity_by_public_key_hash( +pub unsafe extern "C" fn verify_full_identity_by_public_key_hash( proof_array: *const u8, proof_len: usize, public_key_hash: *const PublicKeyHash, @@ -38,7 +38,7 @@ pub extern "C" fn verify_full_identity_by_public_key_hash( } #[no_mangle] -pub extern "C" fn verify_full_identities_by_public_key_hashes( +pub unsafe extern "C" fn verify_full_identities_by_public_key_hashes( proof_array: *const u8, proof_len: usize, public_key_hashes_c: *const *const u8, @@ -78,7 +78,7 @@ pub extern "C" fn verify_full_identities_by_public_key_hashes( } #[no_mangle] -pub extern "C" fn verify_full_identity_by_identity_id( +pub unsafe extern "C" fn verify_full_identity_by_identity_id( proof_array: *const u8, proof_len: usize, is_proof_subset: bool, @@ -100,7 +100,7 @@ pub extern "C" fn verify_full_identity_by_identity_id( } #[no_mangle] -pub extern "C" fn verify_identity_id_by_public_key_hash( +pub unsafe extern "C" fn verify_identity_id_by_public_key_hash( proof_array: *const u8, proof_len: usize, is_proof_subset: bool, @@ -129,7 +129,7 @@ pub extern "C" fn verify_identity_id_by_public_key_hash( } #[no_mangle] -pub extern "C" fn verify_identity_balances_by_identity_ids( +pub unsafe extern "C" fn verify_identity_balances_by_identity_ids( proof_array: *const u8, proof_len: usize, is_proof_subset: bool, @@ -152,7 +152,7 @@ pub extern "C" fn verify_identity_balances_by_identity_ids( identity_id: vec_to_pointer(identity_id.to_vec()), id_size: 32, has_balance: maybe_balance.is_some(), - balance: maybe_balance.map(|b| b).unwrap_or(0), + balance: maybe_balance.unwrap_or(0), }, ))); } @@ -170,7 +170,7 @@ pub extern "C" fn verify_identity_balances_by_identity_ids( } #[no_mangle] -pub extern "C" fn verify_identity_ids_by_public_key_hashes( +pub unsafe extern "C" fn verify_identity_ids_by_public_key_hashes( proof_array: *const u8, proof_len: usize, is_proof_subset: bool, @@ -213,8 +213,6 @@ pub extern "C" fn verify_identity_ids_by_public_key_hashes( } } -// TODO: handle memory deallocation - #[cfg(test)] mod tests { use super::*; @@ -602,7 +600,7 @@ mod tests { 68, 99, 161, 169, 148, 213, 4, 14, 105, 192, 144, 182, 152, 93, 122, 242, 149, 191, 209, 26, ]; - let (root_hash, proved_identity) = + let (_root_hash, proved_identity) = Drive::verify_full_identity_by_public_key_hash(proof, key_hash).expect("should verify"); // verify part of the identity, make sure it's the correct one assert!(proved_identity.is_some()); @@ -659,7 +657,7 @@ mod tests { ]; let (_, proved_identities): ([u8; 32], BTreeMap>) = - Drive::verify_full_identities_by_public_key_hashes(proof, &key_hashes) + Drive::verify_full_identities_by_public_key_hashes(proof, key_hashes) .expect("expect that this be verified"); assert_eq!(proved_identities.len(), 10); dbg!(proved_identities.values()); @@ -673,7 +671,7 @@ mod tests { 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, ]; dbg!(hex::encode(identity_id)); - let (root_hash, maybe_identity) = + let (_root_hash, maybe_identity) = Drive::verify_full_identity_by_identity_id(proof, true, identity_id) .expect("verification failed"); let identity = maybe_identity.expect("couldn't get identity"); @@ -688,7 +686,7 @@ mod tests { let public_key_hash: PublicKeyHash = [ 31, 8, 21, 38, 154, 252, 1, 45, 228, 66, 96, 206, 178, 138, 68, 150, 211, 24, 65, 132, ]; - let (root_hash, maybe_identity_id) = + let (_root_hash, maybe_identity_id) = Drive::verify_identity_id_by_public_key_hash(proof, true, public_key_hash) .expect("should verify"); let expected_identity_id: [u8; 32] = [ @@ -708,7 +706,7 @@ mod tests { 62, 171, 130, 51, 233, 19, 45, 191, 194, 183, 0, 171, 182, 77, 93, 70, 216, 67, 22, 47, 39, 25, 156, 146, 35, 108, 99, 133, 34, 187, 243, 162, ]; - let (root_hash, maybe_balance) = + let (_root_hash, maybe_balance) = Drive::verify_identity_balance_for_identity_id(proof, identity_id) .expect("should verify"); let actual_balance = maybe_balance.expect("should have balance"); diff --git a/packages/rs-drive-verify-c-binding/src/util.rs b/packages/rs-drive-verify-c-binding/src/util.rs index 8a05bd2156b..3d8cf531096 100644 --- a/packages/rs-drive-verify-c-binding/src/util.rs +++ b/packages/rs-drive-verify-c-binding/src/util.rs @@ -1,5 +1,5 @@ use crate::types::{ - AssetLockProof, IdPublicKeyMap, Identity, IdentityPublicKey, MetaData, PublicKeyHash, + AssetLockProof, IdPublicKeyMap, Identity, IdentityPublicKey, MetaData, }; use crate::{DppAssetLockProof, DppIdentity}; use std::{mem, slice}; @@ -27,7 +27,7 @@ pub(crate) fn build_c_public_keys_struct(identity: &DppIdentity) -> *const *cons let mut id_public_key_map_as_vec: Vec<*const IdPublicKeyMap> = vec![]; for (key_id, identity_public_key) in &identity.public_keys { id_public_key_map_as_vec.push(Box::into_raw(Box::from(IdPublicKeyMap { - key: key_id.clone(), + key: *key_id, public_key: Box::into_raw(Box::from(IdentityPublicKey { id: identity_public_key.id, purpose: identity_public_key.purpose as u8,