From 697f4dbc8eda2128d39973bf712574367583dad7 Mon Sep 17 00:00:00 2001 From: Sergey Timoshin Date: Mon, 23 Dec 2024 17:04:42 +0000 Subject: [PATCH 1/6] chore: add GitHub Actions workflows and configuration for linting, testing, and dependency updates --- .github/actionlint.yaml | 11 ++++++ .github/dependabot.yml | 18 ++++++++++ .github/workflows/ci-lint.yml | 15 +++++++++ .github/workflows/js.yml | 62 ++++++++++++++++++++++++++++++++++ .github/workflows/rust.yml | 63 +++++++++++++++++++++++++++++++++++ 5 files changed, 169 insertions(+) create mode 100644 .github/actionlint.yaml create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/ci-lint.yml create mode 100644 .github/workflows/js.yml create mode 100644 .github/workflows/rust.yml diff --git a/.github/actionlint.yaml b/.github/actionlint.yaml new file mode 100644 index 0000000..3f55237 --- /dev/null +++ b/.github/actionlint.yaml @@ -0,0 +1,11 @@ +self-hosted-runner: + # Labels of self-hosted runner in array of strings. + labels: + - buildjet-2vcpu-ubuntu-2204 + - buildjet-4vcpu-ubuntu-2204 + - buildjet-8vcpu-ubuntu-2204 + - buildjet-16vcpu-ubuntu-2204 +# Configuration variables in array of strings defined in your repository or +# organization. `null` means disabling configuration variables check. +# Empty array means no configuration variable is allowed. +config-variables: null diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..b8bade9 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,18 @@ +# Please see the documentation for all configuration options: +# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file + +version: 2 +updates: + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + # pnpm is handled by the "npm" package ecosystem + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/ci-lint.yml b/.github/workflows/ci-lint.yml new file mode 100644 index 0000000..0bc7914 --- /dev/null +++ b/.github/workflows/ci-lint.yml @@ -0,0 +1,15 @@ +name: Lint GitHub Actions workflows +on: [push, pull_request] + +jobs: + actionlint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Download actionlint + id: get_actionlint + run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) + shell: bash + - name: Check workflow files + run: ${{ steps.get_actionlint.outputs.executable }} -color + shell: bash \ No newline at end of file diff --git a/.github/workflows/js.yml b/.github/workflows/js.yml new file mode 100644 index 0000000..cd0a57d --- /dev/null +++ b/.github/workflows/js.yml @@ -0,0 +1,62 @@ +on: + push: + branches: + - main + pull_request: + branches: + - "*" + types: + - opened + - synchronize + - reopened + - ready_for_review + +name: js-tests + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + stateless-js: + name: stateless-js + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + targets: wasm32-unknown-unknown + + - name: Install wasm-pack + run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22' + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: | + ~/.cargo + **/target + **/node_modules + key: ${{ runner.os }}-deps-${{ hashFiles('**/Cargo.lock', '**/pnpm-lock.yaml') }} + + - name: Run hasher.rs tests + working-directory: hasher.rs + run: | + pnpm install + pnpm build + pnpm test \ No newline at end of file diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..19045ff --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,63 @@ +on: + push: + branches: + - main + paths: + - ".cargo/**" + - "**/*.rs" + - "**/Cargo.*" + - ".github/workflows/rust.yml" + pull_request: + branches: + - "*" + paths: + - "**/*.rs" + - "**/Cargo.*" + - ".github/workflows/rust.yml" + + types: + - opened + - synchronize + - reopened + - ready_for_review + +name: rust + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + + - name: Install Rust + uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: | + ~/.cargo + **/target + key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }} + + - name: Run cargo fmt + run: cargo fmt --all -- --check + + - name: Run clippy + run: cargo clippy --all-targets -- -D warnings + + - name: Run tests + run: | + for dir in concurrent bounded-vec hash-set indexed; do + cd $dir + cargo test --all-targets + cd .. + done \ No newline at end of file From 6134dac2ce73eeff693e2392fb54ab19d013f061 Mon Sep 17 00:00:00 2001 From: Sergey Timoshin Date: Mon, 23 Dec 2024 17:06:00 +0000 Subject: [PATCH 2/6] chore: rename js job in GitHub Actions workflow for clarity --- .github/workflows/js.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/js.yml b/.github/workflows/js.yml index cd0a57d..53179cd 100644 --- a/.github/workflows/js.yml +++ b/.github/workflows/js.yml @@ -18,8 +18,8 @@ concurrency: cancel-in-progress: true jobs: - stateless-js: - name: stateless-js + js: + name: js tests if: github.event.pull_request.draft == false runs-on: ubuntu-latest From 9e0503a19fbdd4c04c400a5a3ecf45f1071e217e Mon Sep 17 00:00:00 2001 From: Sergey Timoshin Date: Mon, 23 Dec 2024 17:10:02 +0000 Subject: [PATCH 3/6] chore: consolidate formatting, linting, and testing steps in GitHub Actions workflow --- .github/workflows/rust.yml | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 19045ff..86fa6e8 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -48,16 +48,12 @@ jobs: **/target key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }} - - name: Run cargo fmt - run: cargo fmt --all -- --check - - - name: Run clippy - run: cargo clippy --all-targets -- -D warnings - - - name: Run tests + - name: Check formatting, lint & run tests run: | for dir in concurrent bounded-vec hash-set indexed; do cd $dir + cargo fmt -- --check + cargo clippy --all-targets -- -D warnings cargo test --all-targets cd .. done \ No newline at end of file From aa6ce7c63814fffc7e20863826621c41c7a968f8 Mon Sep 17 00:00:00 2001 From: Sergey Timoshin Date: Mon, 23 Dec 2024 17:51:32 +0000 Subject: [PATCH 4/6] refactor: fix lint errors --- bounded-vec/src/lib.rs | 3 +- bounded-vec/src/offset/copy.rs | 4 +-- concurrent/src/zero_copy.rs | 8 ++--- concurrent/tests/tests.rs | 33 +++++++++--------- hash-set/src/lib.rs | 62 ++++++++++++++++------------------ hash-set/src/zero_copy.rs | 17 ++++------ indexed/src/array.rs | 2 +- indexed/src/zero_copy.rs | 12 +++---- indexed/tests/tests.rs | 2 +- 9 files changed, 69 insertions(+), 74 deletions(-) diff --git a/bounded-vec/src/lib.rs b/bounded-vec/src/lib.rs index 7f7c673..6d1d77a 100644 --- a/bounded-vec/src/lib.rs +++ b/bounded-vec/src/lib.rs @@ -1270,7 +1270,7 @@ mod test { } for element in vec.iter_mut() { - *element = *element * 2; + *element *= 2; } for (i, element) in vec.iter().enumerate() { @@ -1491,6 +1491,7 @@ mod test { } #[test] + #[allow(clippy::unnecessary_cast)] fn test_cyclic_bounded_vec_first() { let mut vec = CyclicBoundedVec::with_capacity(500); diff --git a/bounded-vec/src/offset/copy.rs b/bounded-vec/src/offset/copy.rs index acc94a7..b124a7b 100644 --- a/bounded-vec/src/offset/copy.rs +++ b/bounded-vec/src/offset/copy.rs @@ -214,7 +214,7 @@ mod test { assert_eq!(offset, 0); let vec: BoundedVec = read_bounded_vec_at(&buf, &mut offset, &metadata); for (i, element) in vec.iter().enumerate() { - assert_eq!(i as i64, -(*element as i64)); + assert_eq!(i as i64, - *element); } assert_eq!(offset, 256); @@ -223,7 +223,7 @@ mod test { assert_eq!(offset, 256); let vec: BoundedVec = read_bounded_vec_at(&buf, &mut offset, &metadata); for (i, element) in vec.iter().enumerate() { - assert_eq!(i as u64, *element as u64); + assert_eq!(i as u64, *element); } assert_eq!(offset, 512); diff --git a/concurrent/src/zero_copy.rs b/concurrent/src/zero_copy.rs index a2e1103..c728a57 100644 --- a/concurrent/src/zero_copy.rs +++ b/concurrent/src/zero_copy.rs @@ -128,7 +128,7 @@ where } } -impl<'a, H, const HEIGHT: usize> Deref for ConcurrentMerkleTreeZeroCopy<'a, H, HEIGHT> +impl Deref for ConcurrentMerkleTreeZeroCopy<'_, H, HEIGHT> where H: Hasher, { @@ -139,7 +139,7 @@ where } } -impl<'a, H, const HEIGHT: usize> Drop for ConcurrentMerkleTreeZeroCopy<'a, H, HEIGHT> +impl Drop for ConcurrentMerkleTreeZeroCopy<'_, H, HEIGHT> where H: Hasher, { @@ -244,7 +244,7 @@ where } } -impl<'a, H, const HEIGHT: usize> Deref for ConcurrentMerkleTreeZeroCopyMut<'a, H, HEIGHT> +impl Deref for ConcurrentMerkleTreeZeroCopyMut<'_, H, HEIGHT> where H: Hasher, { @@ -254,7 +254,7 @@ where &self.0.merkle_tree } } -impl<'a, H, const HEIGHT: usize> DerefMut for ConcurrentMerkleTreeZeroCopyMut<'a, H, HEIGHT> +impl DerefMut for ConcurrentMerkleTreeZeroCopyMut<'_, H, HEIGHT> where H: Hasher, { diff --git a/concurrent/tests/tests.rs b/concurrent/tests/tests.rs index c1ce8b1..73b00da 100644 --- a/concurrent/tests/tests.rs +++ b/concurrent/tests/tests.rs @@ -289,7 +289,7 @@ fn invalid_updates( let res = merkle_tree.update( changelog_index, &invalid_old_leaf, - &new_leaf, + new_leaf, 0, &mut proof_clone, ); @@ -392,9 +392,9 @@ where ]; let mut expected_canopy = Vec::new(); - for canopy_level in 0..CANOPY { + for (canopy_level, canopy) in canopy_levels.iter().enumerate().take(CANOPY) { println!("canopy_level: {canopy_level}"); - expected_canopy.extend_from_slice(&canopy_levels[canopy_level]); + expected_canopy.extend_from_slice(canopy); } assert_eq!(merkle_tree.changelog_index(), 4 % CHANGELOG); @@ -468,8 +468,8 @@ where ][..], ]; let mut expected_canopy = Vec::new(); - for canopy_level in 0..CANOPY { - expected_canopy.extend_from_slice(&canopy_levels[canopy_level]); + for canopy in canopy_levels.iter().take(CANOPY) { + expected_canopy.extend_from_slice(canopy); } assert_eq!(merkle_tree.changelog_index(), 5 % CHANGELOG); @@ -542,8 +542,8 @@ where ][..], ]; let mut expected_canopy = Vec::new(); - for canopy_level in 0..CANOPY { - expected_canopy.extend_from_slice(&canopy_levels[canopy_level]); + for canopy in canopy_levels.iter().take(CANOPY) { + expected_canopy.extend_from_slice(canopy); } assert_eq!(merkle_tree.changelog_index(), 6 % CHANGELOG); @@ -615,8 +615,8 @@ where ][..], ]; let mut expected_canopy = Vec::new(); - for canopy_level in 0..CANOPY { - expected_canopy.extend_from_slice(&canopy_levels[canopy_level]); + for canopy in canopy_levels.iter().take(CANOPY) { + expected_canopy.extend_from_slice(canopy); } assert_eq!(merkle_tree.changelog_index(), 7 % CHANGELOG); @@ -688,8 +688,8 @@ where ][..], ]; let mut expected_canopy = Vec::new(); - for canopy_level in 0..CANOPY { - expected_canopy.extend_from_slice(&canopy_levels[canopy_level]); + for canopy in canopy_levels.iter().take(CANOPY) { + expected_canopy.extend_from_slice(canopy); } assert_eq!(merkle_tree.changelog_index(), 8 % CHANGELOG); @@ -1395,7 +1395,7 @@ async fn test_spl_compat() { .update(changelog_index, &old_leaf, &new_leaf, 0, &mut proof) .unwrap(); spl_concurrent_mt - .set_leaf(root, old_leaf, new_leaf, proof.as_slice(), 0 as u32) + .set_leaf(root, old_leaf, new_leaf, proof.as_slice(), 0) .unwrap(); reference_tree.update(&new_leaf, 0).unwrap(); @@ -2170,8 +2170,7 @@ pub fn test_100_nullify_mt() { let leaf_cell = queue.get_unmarked_bucket(queue_index).unwrap().unwrap(); let leaf_index = crank_merkle_tree .get_leaf_index(&leaf_cell.value_bytes()) - .unwrap() - .clone(); + .unwrap(); let mut proof = crank_merkle_tree .get_proof_of_leaf(leaf_index, false) @@ -2397,7 +2396,7 @@ fn test_subtree_updates() { spl_concurrent_mt.initialize().unwrap(); con_mt.init().unwrap(); assert_eq!(ref_mt.root(), con_mt.root()); - for (_, leaf) in LEAVES_WITH_NULLIFICATIONS.iter().enumerate() { + for leaf in LEAVES_WITH_NULLIFICATIONS { match leaf.1 { Some(index) => { let change_log_index = con_mt.changelog_index(); @@ -3377,7 +3376,7 @@ where tree.append(&leaf_0).unwrap(); tree.append(&leaf_1).unwrap(); tree.append(&leaf_2).unwrap(); - let old_canopy = tree.canopy.as_slice()[0].clone(); + let old_canopy = tree.canopy.as_slice()[0]; let new_leaf_0 = [1; 32]; let mut leaf_0_proof = BoundedVec::with_capacity(2); @@ -3390,7 +3389,7 @@ where &mut leaf_0_proof, ) .unwrap(); - let new_canopy = tree.canopy.as_slice()[0].clone(); + let new_canopy = tree.canopy.as_slice()[0]; assert_ne!(old_canopy, new_canopy); diff --git a/hash-set/src/lib.rs b/hash-set/src/lib.rs index c7cbbb3..701d77e 100644 --- a/hash-set/src/lib.rs +++ b/hash-set/src/lib.rs @@ -598,10 +598,10 @@ mod test { sequence_number: None, }; // It should be always valid, no matter the sequence number. - assert_eq!(cell.is_valid(0), true); + assert!(cell.is_valid(0)); for _ in 0..100 { let seq: usize = rng.gen(); - assert_eq!(cell.is_valid(seq), true); + assert!(cell.is_valid(seq)); } let cell = HashSetCell { @@ -610,10 +610,10 @@ mod test { }; // Sequence numbers up to 2400 should succeed. for i in 0..2400 { - assert_eq!(cell.is_valid(i), true); + assert!(cell.is_valid(i)); } for i in 2400..10000 { - assert_eq!(cell.is_valid(i), false); + assert!(!cell.is_valid(i)); } } @@ -630,7 +630,7 @@ mod test { hs.mark_with_sequence_number(index_1_1, 1).unwrap(); // Check if element exists in the set. - assert_eq!(hs.contains(&element_1_1, Some(1)).unwrap(), true); + assert!(hs.contains(&element_1_1, Some(1)).unwrap()); // Try inserting the same element, even though we didn't reach the // threshold. assert!(matches!( @@ -649,10 +649,10 @@ mod test { let index_2_6 = hs.insert(&element_2_6, 1).unwrap(); let index_2_8 = hs.insert(&element_2_8, 1).unwrap(); let index_2_9 = hs.insert(&element_2_9, 1).unwrap(); - assert_eq!(hs.contains(&element_2_3, Some(2)).unwrap(), true); - assert_eq!(hs.contains(&element_2_6, Some(2)).unwrap(), true); - assert_eq!(hs.contains(&element_2_8, Some(2)).unwrap(), true); - assert_eq!(hs.contains(&element_2_9, Some(2)).unwrap(), true); + assert!(hs.contains(&element_2_3, Some(2)).unwrap()); + assert!(hs.contains(&element_2_6, Some(2)).unwrap()); + assert!(hs.contains(&element_2_8, Some(2)).unwrap()); + assert!(hs.contains(&element_2_9, Some(2)).unwrap()); hs.mark_with_sequence_number(index_2_3, 2).unwrap(); hs.mark_with_sequence_number(index_2_6, 2).unwrap(); hs.mark_with_sequence_number(index_2_8, 2).unwrap(); @@ -682,10 +682,10 @@ mod test { let index_3_13 = hs.insert(&element_3_13, 2).unwrap(); let index_3_21 = hs.insert(&element_3_21, 2).unwrap(); let index_3_29 = hs.insert(&element_3_29, 2).unwrap(); - assert_eq!(hs.contains(&element_3_11, Some(3)).unwrap(), true); - assert_eq!(hs.contains(&element_3_13, Some(3)).unwrap(), true); - assert_eq!(hs.contains(&element_3_21, Some(3)).unwrap(), true); - assert_eq!(hs.contains(&element_3_29, Some(3)).unwrap(), true); + assert!(hs.contains(&element_3_11, Some(3)).unwrap()); + assert!(hs.contains(&element_3_13, Some(3)).unwrap()); + assert!(hs.contains(&element_3_21, Some(3)).unwrap()); + assert!(hs.contains(&element_3_29, Some(3)).unwrap()); hs.mark_with_sequence_number(index_3_11, 3).unwrap(); hs.mark_with_sequence_number(index_3_13, 3).unwrap(); hs.mark_with_sequence_number(index_3_21, 3).unwrap(); @@ -715,10 +715,10 @@ mod test { let index_4_65 = hs.insert(&element_4_65, 3).unwrap(); let index_4_72 = hs.insert(&element_4_72, 3).unwrap(); let index_4_15 = hs.insert(&element_4_15, 3).unwrap(); - assert_eq!(hs.contains(&element_4_93, Some(4)).unwrap(), true); - assert_eq!(hs.contains(&element_4_65, Some(4)).unwrap(), true); - assert_eq!(hs.contains(&element_4_72, Some(4)).unwrap(), true); - assert_eq!(hs.contains(&element_4_15, Some(4)).unwrap(), true); + assert!(hs.contains(&element_4_93, Some(4)).unwrap()); + assert!(hs.contains(&element_4_65, Some(4)).unwrap()); + assert!(hs.contains(&element_4_72, Some(4)).unwrap()); + assert!(hs.contains(&element_4_15, Some(4)).unwrap()); hs.mark_with_sequence_number(index_4_93, 4).unwrap(); hs.mark_with_sequence_number(index_4_65, 4).unwrap(); hs.mark_with_sequence_number(index_4_72, 4).unwrap(); @@ -770,22 +770,21 @@ mod test { std::array::from_fn(|_| BigUint::from(Fr::rand(&mut rng))); for nf_chunk in nullifiers.chunks(2400) { for nullifier in nf_chunk.iter() { - assert_eq!(hs.contains(&nullifier, Some(seq)).unwrap(), false); - let index = hs.insert(&nullifier, seq as usize).unwrap(); - assert_eq!(hs.contains(&nullifier, Some(seq)).unwrap(), true); + assert!(!hs.contains(nullifier, Some(seq)).unwrap()); + let index = hs.insert(nullifier, seq).unwrap(); + assert!(hs.contains(nullifier, Some(seq)).unwrap()); - let nullifier_bytes = bigint_to_be_bytes_array(&nullifier).unwrap(); + let nullifier_bytes = bigint_to_be_bytes_array(nullifier).unwrap(); - let element = hs - .find_element(&nullifier, Some(seq)) + let element = *hs + .find_element(nullifier, Some(seq)) .unwrap() .unwrap() - .0 - .clone(); + .0; assert_eq!( element, HashSetCell { - value: bigint_to_be_bytes_array(&nullifier).unwrap(), + value: bigint_to_be_bytes_array(nullifier).unwrap(), sequence_number: None, } ); @@ -796,12 +795,11 @@ mod test { assert!(element.is_valid(seq)); hs.mark_with_sequence_number(index, seq).unwrap(); - let element = hs - .find_element(&nullifier, Some(seq)) + let element = *hs + .find_element(nullifier, Some(seq)) .unwrap() .unwrap() - .0 - .clone(); + .0; assert_eq!( element, @@ -819,7 +817,7 @@ mod test { // Trying to insert the same nullifier, before reaching the // sequence threshold, should fail. assert!(matches!( - hs.insert(&nullifier, seq as usize + 2399), + hs.insert(nullifier, seq + 2399), Err(HashSetError::ElementAlreadyExists), )); seq += 1; @@ -1023,7 +1021,7 @@ mod test { std::array::from_fn(|_| BigUint::from(Fr::rand(&mut rng))); for nullifier in nullifiers.iter() { - hs.insert(&nullifier, 0).unwrap(); + hs.insert(nullifier, 0).unwrap(); } let mut sorted_nullifiers = nullifiers.iter().collect::>(); diff --git a/hash-set/src/zero_copy.rs b/hash-set/src/zero_copy.rs index 91e4590..e4e35d6 100644 --- a/hash-set/src/zero_copy.rs +++ b/hash-set/src/zero_copy.rs @@ -119,7 +119,7 @@ impl<'a> HashSetZeroCopy<'a> { } } -impl<'a> Drop for HashSetZeroCopy<'a> { +impl Drop for HashSetZeroCopy<'_> { fn drop(&mut self) { // SAFETY: Don't do anything here! Why? // @@ -134,7 +134,7 @@ impl<'a> Drop for HashSetZeroCopy<'a> { } } -impl<'a> Deref for HashSetZeroCopy<'a> { +impl Deref for HashSetZeroCopy<'_> { type Target = HashSet; fn deref(&self) -> &Self::Target { @@ -142,7 +142,7 @@ impl<'a> Deref for HashSetZeroCopy<'a> { } } -impl<'a> DerefMut for HashSetZeroCopy<'a> { +impl DerefMut for HashSetZeroCopy<'_> { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.hash_set } @@ -190,7 +190,7 @@ mod test { } for (seq, nullifier) in nullifiers.iter().enumerate() { - let index = hs.insert(&nullifier, seq).unwrap(); + let index = hs.insert(nullifier, seq).unwrap(); hs.mark_with_sequence_number(index, seq).unwrap(); } } @@ -201,11 +201,11 @@ mod test { unsafe { HashSetZeroCopy::from_bytes_zero_copy_mut(bytes.as_mut_slice()).unwrap() }; for (seq, nullifier) in nullifiers.iter().enumerate() { - assert_eq!(hs.contains(nullifier, Some(seq)).unwrap(), true); + assert!(hs.contains(nullifier, Some(seq)).unwrap()); } for (seq, nullifier) in nullifiers.iter().enumerate() { - hs.insert(&nullifier, 2400 + seq as usize).unwrap(); + hs.insert(nullifier, 2400 + seq).unwrap(); } drop(hs); } @@ -215,10 +215,7 @@ mod test { let hs = unsafe { HashSet::from_bytes_copy(bytes.as_mut_slice()).unwrap() }; for (seq, nullifier) in nullifiers.iter().enumerate() { - assert_eq!( - hs.contains(nullifier, Some(2400 + seq as usize)).unwrap(), - true - ); + assert!(hs.contains(nullifier, Some(2400 + seq)).unwrap()); } } } diff --git a/indexed/src/array.rs b/indexed/src/array.rs index 6641061..3ef4c57 100644 --- a/indexed/src/array.rs +++ b/indexed/src/array.rs @@ -444,7 +444,7 @@ where } } -impl<'a, H, I> DoubleEndedIterator for IndexingArrayIter<'a, H, I> +impl DoubleEndedIterator for IndexingArrayIter<'_, H, I> where H: Hasher, I: CheckedAdd + CheckedSub + Copy + Clone + PartialOrd + ToBytes + TryFrom + Unsigned, diff --git a/indexed/src/zero_copy.rs b/indexed/src/zero_copy.rs index d0a4fdd..1bb8b37 100644 --- a/indexed/src/zero_copy.rs +++ b/indexed/src/zero_copy.rs @@ -97,8 +97,8 @@ where } } -impl<'a, H, I, const HEIGHT: usize, const NET_HEIGHT: usize> Deref - for IndexedMerkleTreeZeroCopy<'a, H, I, HEIGHT, NET_HEIGHT> +impl Deref + for IndexedMerkleTreeZeroCopy<'_, H, I, HEIGHT, NET_HEIGHT> where H: Hasher, I: CheckedAdd @@ -204,8 +204,8 @@ where } } -impl<'a, H, I, const HEIGHT: usize, const NET_HEIGHT: usize> Deref - for IndexedMerkleTreeZeroCopyMut<'a, H, I, HEIGHT, NET_HEIGHT> +impl Deref + for IndexedMerkleTreeZeroCopyMut<'_, H, I, HEIGHT, NET_HEIGHT> where H: Hasher, I: CheckedAdd @@ -226,8 +226,8 @@ where } } -impl<'a, H, I, const HEIGHT: usize, const NET_HEIGHT: usize> DerefMut - for IndexedMerkleTreeZeroCopyMut<'a, H, I, HEIGHT, NET_HEIGHT> +impl DerefMut + for IndexedMerkleTreeZeroCopyMut<'_, H, I, HEIGHT, NET_HEIGHT> where H: Hasher, I: CheckedAdd diff --git a/indexed/tests/tests.rs b/indexed/tests/tests.rs index 5962201..fbaab80 100644 --- a/indexed/tests/tests.rs +++ b/indexed/tests/tests.rs @@ -736,7 +736,7 @@ pub fn print_test_data() { let proof = relayer_merkle_tree.get_proof_of_leaf(2, true).unwrap(); - let leaf = relayer_merkle_tree.merkle_tree.get_leaf(2).unwrap(); + let leaf = relayer_merkle_tree.merkle_tree.leaf(2); let leaf_bn = BigUint::from_bytes_be(&leaf); println!("(30) leaf_hash[2] = {:?}", leaf_bn); From 0263d6b554d25e9cb8f714bdf0ec30cff9329335 Mon Sep 17 00:00:00 2001 From: Sergey Timoshin Date: Tue, 24 Dec 2024 01:19:41 +0000 Subject: [PATCH 5/6] feat: add missing modules + fix linter errors --- concurrent/Cargo.lock | 46 +- concurrent/Cargo.toml | 10 +- concurrent/src/copy.rs | 2 +- concurrent/src/zero_copy.rs | 2 +- hash-set/Cargo.lock | 13 +- hash-set/Cargo.toml | 2 +- hasher/Cargo.lock | 1655 +++++++++++++++++++++ hasher/Cargo.toml | 27 + hasher/src/bytes.rs | 267 ++++ hasher/src/errors.rs | 35 + hasher/src/keccak.rs | 51 + hasher/src/lib.rs | 37 + hasher/src/poseidon.rs | 128 ++ hasher/src/sha256.rs | 51 + hasher/src/syscalls/definitions.rs | 40 + hasher/src/syscalls/mod.rs | 12 + hasher/src/zero_bytes/keccak.rs | 209 +++ hasher/src/zero_bytes/mod.rs | 7 + hasher/src/zero_bytes/poseidon.rs | 209 +++ hasher/src/zero_bytes/sha256.rs | 209 +++ hasher/src/zero_indexed_leaf/keccak.rs | 7 + hasher/src/zero_indexed_leaf/mod.rs | 3 + hasher/src/zero_indexed_leaf/poseidon.rs | 7 + hasher/src/zero_indexed_leaf/sha256.rs | 7 + indexed/Cargo.lock | 61 +- indexed/Cargo.toml | 15 +- reference/Cargo.lock | 1674 ++++++++++++++++++++++ reference/Cargo.toml | 13 + reference/src/lib.rs | 375 +++++ reference/src/sparse_merkle_tree.rs | 114 ++ reference/tests/tests.rs | 732 ++++++++++ utils/Cargo.toml | 23 + utils/src/bigint.rs | 390 +++++ utils/src/fee.rs | 89 ++ utils/src/hashchain.rs | 351 +++++ utils/src/lib.rs | 218 +++ utils/src/prime.rs | 139 ++ utils/src/rand.rs | 102 ++ 38 files changed, 7271 insertions(+), 61 deletions(-) create mode 100644 hasher/Cargo.lock create mode 100644 hasher/Cargo.toml create mode 100644 hasher/src/bytes.rs create mode 100644 hasher/src/errors.rs create mode 100644 hasher/src/keccak.rs create mode 100644 hasher/src/lib.rs create mode 100644 hasher/src/poseidon.rs create mode 100644 hasher/src/sha256.rs create mode 100644 hasher/src/syscalls/definitions.rs create mode 100644 hasher/src/syscalls/mod.rs create mode 100644 hasher/src/zero_bytes/keccak.rs create mode 100644 hasher/src/zero_bytes/mod.rs create mode 100644 hasher/src/zero_bytes/poseidon.rs create mode 100644 hasher/src/zero_bytes/sha256.rs create mode 100644 hasher/src/zero_indexed_leaf/keccak.rs create mode 100644 hasher/src/zero_indexed_leaf/mod.rs create mode 100644 hasher/src/zero_indexed_leaf/poseidon.rs create mode 100644 hasher/src/zero_indexed_leaf/sha256.rs create mode 100644 reference/Cargo.lock create mode 100644 reference/Cargo.toml create mode 100644 reference/src/lib.rs create mode 100644 reference/src/sparse_merkle_tree.rs create mode 100644 reference/tests/tests.rs create mode 100644 utils/Cargo.toml create mode 100644 utils/src/bigint.rs create mode 100644 utils/src/fee.rs create mode 100644 utils/src/hashchain.rs create mode 100644 utils/src/lib.rs create mode 100644 utils/src/prime.rs create mode 100644 utils/src/rand.rs diff --git a/concurrent/Cargo.lock b/concurrent/Cargo.lock index c74b5b4..2fe8e7b 100644 --- a/concurrent/Cargo.lock +++ b/concurrent/Cargo.lock @@ -1044,6 +1044,16 @@ dependencies = [ "libsecp256k1-core", ] +[[package]] +name = "light-bounded-vec" +version = "1.1.0" +dependencies = [ + "bytemuck", + "memoffset", + "solana-program 1.18.22", + "thiserror", +] + [[package]] name = "light-bounded-vec" version = "1.1.0" @@ -1052,7 +1062,6 @@ checksum = "47ced86d6f1b163a04d5d0be44f8bbeedb11d32f73af27812bbd144e0f1f1a42" dependencies = [ "bytemuck", "memoffset", - "solana-program 1.18.22", "thiserror", ] @@ -1064,11 +1073,11 @@ dependencies = [ "ark-ff", "borsh 0.10.4", "bytemuck", - "light-bounded-vec", + "light-bounded-vec 1.1.0", "light-hash-set", "light-hasher", "light-merkle-tree-reference", - "light-utils", + "light-utils 1.1.0", "memoffset", "num-bigint", "num-traits", @@ -1083,12 +1092,10 @@ dependencies = [ [[package]] name = "light-hash-set" version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7cd392ed4df05a545dfb8a58ef72639fbba9dee7a0605b81c3370d02161932b" dependencies = [ - "light-bounded-vec", + "light-bounded-vec 1.1.0", "light-heap", - "light-utils", + "light-utils 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset", "num-bigint", "num-traits", @@ -1099,8 +1106,6 @@ dependencies = [ [[package]] name = "light-hasher" version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932ed98282fa564ff4518416de688593a0f425c81d68cfa70e98da21a17a36f" dependencies = [ "ark-bn254", "light-poseidon", @@ -1122,12 +1127,10 @@ dependencies = [ [[package]] name = "light-merkle-tree-reference" version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9153fd97f1bdba3ec1de6f4c4f20134c6e5e1285676bcb9ef5ebe493f41afa" dependencies = [ - "light-bounded-vec", + "light-bounded-vec 1.1.0", "light-hasher", - "log", + "num-bigint", "thiserror", ] @@ -1143,6 +1146,21 @@ dependencies = [ "thiserror", ] +[[package]] +name = "light-utils" +version = "1.1.0" +dependencies = [ + "anyhow", + "ark-bn254", + "ark-ff", + "light-bounded-vec 1.1.0", + "light-hasher", + "num-bigint", + "rand 0.8.5", + "solana-program 1.18.22", + "thiserror", +] + [[package]] name = "light-utils" version = "1.1.0" @@ -1152,7 +1170,7 @@ dependencies = [ "anyhow", "ark-bn254", "ark-ff", - "light-bounded-vec", + "light-bounded-vec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint", "rand 0.8.5", "solana-program 1.18.22", diff --git a/concurrent/Cargo.toml b/concurrent/Cargo.toml index d7a4195..b94bef8 100644 --- a/concurrent/Cargo.toml +++ b/concurrent/Cargo.toml @@ -17,9 +17,9 @@ solana = [ [dependencies] borsh = "0.10" bytemuck = { version = "1.17", features = ["derive"] } -light-bounded-vec = { version = "1.1.0" } -light-hasher = { version = "1.1.0" } -light-utils = { version = "1.1.0" } +light-bounded-vec = { version = "1.1.0", path = "../bounded-vec" } +light-hasher = { version = "1.1.0", path = "../hasher" } +light-utils = { version = "1.1.0", path = "../utils" } memoffset = "0.9" solana-program = { version="=1.18.22", optional = true } thiserror = "1.0" @@ -27,8 +27,8 @@ thiserror = "1.0" [dev-dependencies] ark-bn254 = "0.4" ark-ff = "0.4" -light-merkle-tree-reference = { version = "1.1.0" } -light-hash-set = { version = "1.1.0", features = ["solana"] } +light-merkle-tree-reference = { version = "1.1.0", path = "../reference" } +light-hash-set = { version = "1.1.0", features = ["solana"], path = "../hash-set" } rand = "0.8" solana-program = { version="=1.18.22" } spl-account-compression = { version = "0.3.0", default-features = false} diff --git a/concurrent/src/copy.rs b/concurrent/src/copy.rs index 068be11..e2c8ce3 100644 --- a/concurrent/src/copy.rs +++ b/concurrent/src/copy.rs @@ -3,7 +3,7 @@ use std::ops::Deref; use crate::{errors::ConcurrentMerkleTreeError, ConcurrentMerkleTree}; use light_bounded_vec::{BoundedVecMetadata, CyclicBoundedVecMetadata}; use light_hasher::Hasher; -use light_utils::offset::copy::{read_bounded_vec_at, read_cyclic_bounded_vec_at, read_value_at}; +use light_bounded_vec::offset::copy::{read_bounded_vec_at, read_cyclic_bounded_vec_at, read_value_at}; use memoffset::{offset_of, span_of}; #[derive(Debug)] diff --git a/concurrent/src/zero_copy.rs b/concurrent/src/zero_copy.rs index c728a57..42e41a8 100644 --- a/concurrent/src/zero_copy.rs +++ b/concurrent/src/zero_copy.rs @@ -8,7 +8,7 @@ use light_bounded_vec::{ BoundedVec, BoundedVecMetadata, CyclicBoundedVec, CyclicBoundedVecMetadata, }; use light_hasher::Hasher; -use light_utils::offset::zero_copy::{read_array_like_ptr_at, read_ptr_at, write_at}; +use light_bounded_vec::offset::zero_copy::{read_array_like_ptr_at, read_ptr_at, write_at}; use memoffset::{offset_of, span_of}; use crate::{errors::ConcurrentMerkleTreeError, ConcurrentMerkleTree}; diff --git a/hash-set/Cargo.lock b/hash-set/Cargo.lock index e99243a..ef35ebd 100644 --- a/hash-set/Cargo.lock +++ b/hash-set/Cargo.lock @@ -953,6 +953,15 @@ dependencies = [ "libsecp256k1-core", ] +[[package]] +name = "light-bounded-vec" +version = "1.1.0" +dependencies = [ + "bytemuck", + "memoffset", + "thiserror", +] + [[package]] name = "light-bounded-vec" version = "1.1.0" @@ -970,7 +979,7 @@ version = "1.2.0" dependencies = [ "ark-bn254", "ark-ff", - "light-bounded-vec", + "light-bounded-vec 1.1.0", "light-heap", "light-utils", "memoffset", @@ -1011,7 +1020,7 @@ dependencies = [ "anyhow", "ark-bn254", "ark-ff", - "light-bounded-vec", + "light-bounded-vec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint", "rand 0.8.5", "solana-program", diff --git a/hash-set/Cargo.toml b/hash-set/Cargo.toml index d2bad1a..c3a1cf4 100644 --- a/hash-set/Cargo.toml +++ b/hash-set/Cargo.toml @@ -10,7 +10,7 @@ edition = "2021" solana = ["solana-program"] [dependencies] -light-bounded-vec = { version = "1.1.0" } +light-bounded-vec = { version = "1.1.0", path = "../bounded-vec" } light-utils = { version = "1.1.0" } memoffset = "0.9" num-bigint = "0.4" diff --git a/hasher/Cargo.lock b/hasher/Cargo.lock new file mode 100644 index 0000000..163d085 --- /dev/null +++ b/hasher/Cargo.lock @@ -0,0 +1,1655 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.15", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "anyhow" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" + +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] + +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + +[[package]] +name = "blake3" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "borsh" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" +dependencies = [ + "borsh-derive 0.9.3", + "hashbrown 0.11.2", +] + +[[package]] +name = "borsh" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115e54d64eb62cdebad391c19efc9dce4981c690c85a33a12199d99bb9546fee" +dependencies = [ + "borsh-derive 0.10.4", + "hashbrown 0.13.2", +] + +[[package]] +name = "borsh" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03" +dependencies = [ + "borsh-derive 1.5.3", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" +dependencies = [ + "borsh-derive-internal 0.9.3", + "borsh-schema-derive-internal 0.9.3", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" +dependencies = [ + "borsh-derive-internal 0.10.4", + "borsh-schema-derive-internal 0.10.4", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2593a3b8b938bd68373196c9832f516be11fa487ef4ae745eb282e6a56a7244" +dependencies = [ + "once_cell", + "proc-macro-crate 3.2.0", + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65d6ba50644c98714aa2a70d13d7df3cd75cd2b523a2b452bf010443800976b3" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276691d96f063427be83e6692b86148e488ebba9f48f77788724ca027ba3b6d4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] + +[[package]] +name = "bytemuck" +version = "1.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "cpufeatures" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "serde", + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.8", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.11", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac", +] + +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "rayon", + "serde", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown 0.15.2", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "light-hasher" +version = "1.1.0" +dependencies = [ + "ark-bn254", + "light-poseidon", + "sha2 0.10.8", + "sha3", + "solana-program", + "thiserror", +] + +[[package]] +name = "light-poseidon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" +dependencies = [ + "ark-bn254", + "ark-ff", + "num-bigint", + "thiserror", +] + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +dependencies = [ + "crypto-mac", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" + +[[package]] +name = "serde" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "serde_json" +version = "1.0.134" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "solana-frozen-abi" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03ab2c30c15311b511c0d1151e4ab6bc9a3e080a37e7c6e7c2d96f5784cf9434" +dependencies = [ + "block-buffer 0.10.4", + "bs58", + "bv", + "either", + "generic-array", + "im", + "lazy_static", + "log", + "memmap2", + "rustc_version", + "serde", + "serde_bytes", + "serde_derive", + "sha2 0.10.8", + "solana-frozen-abi-macro", + "subtle", + "thiserror", +] + +[[package]] +name = "solana-frozen-abi-macro" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c142f779c3633ac83c84d04ff06c70e1f558c876f13358bed77ba629c7417932" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.91", +] + +[[package]] +name = "solana-program" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c10f4588cefd716b24a1a40dd32c278e43a560ab8ce4de6b5805c9d113afdfa1" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "base64 0.21.7", + "bincode", + "bitflags", + "blake3", + "borsh 0.10.4", + "borsh 0.9.3", + "borsh 1.5.3", + "bs58", + "bv", + "bytemuck", + "cc", + "console_error_panic_hook", + "console_log", + "curve25519-dalek", + "getrandom 0.2.15", + "itertools", + "js-sys", + "lazy_static", + "libc", + "libsecp256k1", + "light-poseidon", + "log", + "memoffset", + "num-bigint", + "num-derive", + "num-traits", + "parking_lot", + "rand 0.8.5", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "sha2 0.10.8", + "sha3", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk-macro", + "thiserror", + "tiny-bip39", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "solana-sdk-macro" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b75d0f193a27719257af19144fdaebec0415d1c9e9226ae4bd29b791be5e9bd" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.91", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "tiny-bip39" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" +dependencies = [ + "anyhow", + "hmac", + "once_cell", + "pbkdf2", + "rand 0.7.3", + "rustc-hash", + "sha2 0.9.9", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "tinyvec" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.91", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" + +[[package]] +name = "web-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "zeroize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] diff --git a/hasher/Cargo.toml b/hasher/Cargo.toml new file mode 100644 index 0000000..f29b5ff --- /dev/null +++ b/hasher/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "light-hasher" +version = "1.1.0" +description = "Trait for generic usage of hash functions on Solana" +repository = "https://github.com/Lightprotocol/light-protocol" +license = "Apache-2.0" +edition = "2021" + +[features] +solana = [] + +[dependencies] +light-poseidon = "0.2.0" +solana-program = { version = "1.18.22" } +thiserror = "1.0" + +[target.'cfg(not(target_os = "solana"))'.dependencies] +ark-bn254 = "0.4.0" +sha2 = "0.10" +sha3 = "0.10" + +[lints.rust.unexpected_cfgs] +level = "allow" +check-cfg = [ + 'cfg(target_os, values("solana"))', + 'cfg(feature, values("frozen-abi", "no-entrypoint"))', +] diff --git a/hasher/src/bytes.rs b/hasher/src/bytes.rs new file mode 100644 index 0000000..e489ce4 --- /dev/null +++ b/hasher/src/bytes.rs @@ -0,0 +1,267 @@ +/// A trait providing [`as_byte_vec()`](AsByteVec::as_byte_vec) method for types which +/// are used inside compressed accounts. +pub trait AsByteVec { + fn as_byte_vec(&self) -> Vec>; +} + +macro_rules! impl_as_byte_vec_for_integer_type { + ($int_ty:ty) => { + impl AsByteVec for $int_ty { + fn as_byte_vec(&self) -> Vec> { + vec![self.to_le_bytes().to_vec()] + } + } + }; +} + +// Special implementation for `bool` since bool doesn't implement `ToLeBytes`. +impl AsByteVec for bool { + fn as_byte_vec(&self) -> Vec> { + vec![vec![*self as u8]] + } +} + +impl_as_byte_vec_for_integer_type!(i8); +impl_as_byte_vec_for_integer_type!(u8); +impl_as_byte_vec_for_integer_type!(i16); +impl_as_byte_vec_for_integer_type!(u16); +impl_as_byte_vec_for_integer_type!(i32); +impl_as_byte_vec_for_integer_type!(u32); +impl_as_byte_vec_for_integer_type!(i64); +impl_as_byte_vec_for_integer_type!(u64); +impl_as_byte_vec_for_integer_type!(isize); +impl_as_byte_vec_for_integer_type!(usize); +impl_as_byte_vec_for_integer_type!(i128); +impl_as_byte_vec_for_integer_type!(u128); + +impl AsByteVec for Option +where + T: AsByteVec, +{ + fn as_byte_vec(&self) -> Vec> { + match self { + Some(hashable) => { + let mut bytes = hashable.as_byte_vec(); + bytes.reserve(1); + bytes.insert(0, vec![1]); + bytes + } + None => vec![vec![0]], + } + } +} + +impl AsByteVec for [u8; N] { + fn as_byte_vec(&self) -> Vec> { + vec![self.to_vec()] + } +} + +impl AsByteVec for String { + fn as_byte_vec(&self) -> Vec> { + vec![self.as_bytes().to_vec()] + } +} + +impl AsByteVec for solana_program::pubkey::Pubkey { + fn as_byte_vec(&self) -> Vec> { + vec![self.to_bytes().to_vec()] + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_as_byte_vec_integers() { + let i8_min: &dyn AsByteVec = &i8::MIN; + let i8_min_bytes = i8_min.as_byte_vec(); + assert_eq!(i8_min_bytes, &[&[128]]); + assert_eq!(i8_min_bytes, &[i8::MIN.to_le_bytes()]); + let i8_max: &dyn AsByteVec = &i8::MAX; + let i8_max_bytes = i8_max.as_byte_vec(); + assert_eq!(i8_max_bytes, &[&[127]]); + assert_eq!(i8_max_bytes, &[i8::MAX.to_le_bytes()]); + + let u8_min: &dyn AsByteVec = &u8::MIN; + let u8_min_bytes = u8_min.as_byte_vec(); + assert_eq!(u8_min_bytes, &[&[0]]); + assert_eq!(u8_min_bytes, &[u8::MIN.to_le_bytes()]); + let u8_max: &dyn AsByteVec = &u8::MAX; + let u8_max_bytes = u8_max.as_byte_vec(); + assert_eq!(u8_max_bytes, &[&[255]]); + assert_eq!(u8_max_bytes, &[u8::MAX.to_le_bytes()]); + + let i16_min: &dyn AsByteVec = &i16::MIN; + let i16_min_bytes = i16_min.as_byte_vec(); + assert_eq!(i16_min_bytes, &[&[0, 128]]); + assert_eq!(i16_min_bytes, &[&i16::MIN.to_le_bytes()]); + let i16_max: &dyn AsByteVec = &i16::MAX; + let i16_max_bytes = i16_max.as_byte_vec(); + assert_eq!(i16_max_bytes, &[&[255, 127]]); + assert_eq!(i16_max_bytes, &[i16::MAX.to_le_bytes()]); + + let u16_min: &dyn AsByteVec = &u16::MIN; + let u16_min_bytes = u16_min.as_byte_vec(); + assert_eq!(u16_min_bytes, &[&[0, 0]]); + assert_eq!(u16_min_bytes, &[u16::MIN.to_le_bytes()]); + let u16_max: &dyn AsByteVec = &u16::MAX; + let u16_max_bytes = u16_max.as_byte_vec(); + assert_eq!(u16_max_bytes, &[&[255, 255]]); + assert_eq!(u16_max_bytes, &[u16::MAX.to_le_bytes()]); + + let i32_min: &dyn AsByteVec = &i32::MIN; + let i32_min_bytes = i32_min.as_byte_vec(); + assert_eq!(i32_min_bytes, &[&[0, 0, 0, 128]]); + assert_eq!(i32_min_bytes, &[i32::MIN.to_le_bytes()]); + let i32_max: &dyn AsByteVec = &i32::MAX; + let i32_max_bytes = i32_max.as_byte_vec(); + assert_eq!(i32_max_bytes, &[&[255, 255, 255, 127]]); + assert_eq!(i32_max_bytes, &[i32::MAX.to_le_bytes()]); + + let u32_min: &dyn AsByteVec = &u32::MIN; + let u32_min_bytes = u32_min.as_byte_vec(); + assert_eq!(u32_min_bytes, &[&[0, 0, 0, 0]]); + assert_eq!(u32_min_bytes, &[u32::MIN.to_le_bytes()]); + let u32_max: &dyn AsByteVec = &u32::MAX; + let u32_max_bytes = u32_max.as_byte_vec(); + assert_eq!(u32_max_bytes, &[&[255, 255, 255, 255]]); + assert_eq!(u32_max_bytes, &[u32::MAX.to_le_bytes()]); + + let i64_min: &dyn AsByteVec = &i64::MIN; + let i64_min_bytes = i64_min.as_byte_vec(); + assert_eq!(i64_min_bytes, &[&[0, 0, 0, 0, 0, 0, 0, 128]]); + assert_eq!(i64_min_bytes, &[i64::MIN.to_le_bytes()]); + let i64_max: &dyn AsByteVec = &i64::MAX; + let i64_max_bytes = i64_max.as_byte_vec(); + assert_eq!(i64_max_bytes, &[&[255, 255, 255, 255, 255, 255, 255, 127]]); + assert_eq!(i64_max_bytes, &[i64::MAX.to_le_bytes()]); + + let u64_min: &dyn AsByteVec = &u64::MIN; + let u64_min_bytes = u64_min.as_byte_vec(); + assert_eq!(u64_min_bytes, &[[0, 0, 0, 0, 0, 0, 0, 0]]); + assert_eq!(i64_min_bytes, &[i64::MIN.to_le_bytes()]); + let u64_max: &dyn AsByteVec = &u64::MAX; + let u64_max_bytes = u64_max.as_byte_vec(); + assert_eq!(u64_max_bytes, &[&[255, 255, 255, 255, 255, 255, 255, 255]]); + assert_eq!(u64_max_bytes, &[u64::MAX.to_le_bytes()]); + + let i128_min: &dyn AsByteVec = &i128::MIN; + let i128_min_bytes = i128_min.as_byte_vec(); + assert_eq!( + i128_min_bytes, + &[&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128]] + ); + assert_eq!(i128_min_bytes, &[i128::MIN.to_le_bytes()]); + let i128_max: &dyn AsByteVec = &i128::MAX; + let i128_max_bytes = i128_max.as_byte_vec(); + assert_eq!( + i128_max_bytes, + &[&[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127]] + ); + assert_eq!(i128_max_bytes, &[i128::MAX.to_le_bytes()]); + + let u128_min: &dyn AsByteVec = &u128::MIN; + let u128_min_bytes = u128_min.as_byte_vec(); + assert_eq!( + u128_min_bytes, + &[&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] + ); + assert_eq!(u128_min_bytes, &[u128::MIN.to_le_bytes()]); + let u128_max: &dyn AsByteVec = &u128::MAX; + let u128_max_bytes = u128_max.as_byte_vec(); + assert_eq!( + u128_max_bytes, + &[&[255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]] + ); + assert_eq!(u128_max_bytes, &[u128::MAX.to_le_bytes()]); + } + + #[test] + fn test_as_byte_vec_primitives() { + let bool_false: &dyn AsByteVec = &false; + assert_eq!(bool_false.as_byte_vec(), &[&[0]]); + + let bool_true: &dyn AsByteVec = &true; + assert_eq!(bool_true.as_byte_vec(), &[&[1]]); + } + + #[test] + fn test_as_byte_vec_option() { + // Very important property - `None` and `Some(0)` always have to be + // different and should produce different hashes! + let u8_none: Option = None; + let u8_none: &dyn AsByteVec = &u8_none; + assert_eq!(u8_none.as_byte_vec(), &[&[0]]); + + let u8_some_zero: Option = Some(0); + let u8_some_zero: &dyn AsByteVec = &u8_some_zero; + assert_eq!(u8_some_zero.as_byte_vec(), &[&[1], &[0]]); + + let u16_none: Option = None; + let u16_none: &dyn AsByteVec = &u16_none; + assert_eq!(u16_none.as_byte_vec(), &[&[0]]); + + let u16_some_zero: Option = Some(0); + let u16_some_zero: &dyn AsByteVec = &u16_some_zero; + assert_eq!(u16_some_zero.as_byte_vec(), &[&[1][..], &[0, 0][..]]); + + let u32_none: Option = None; + let u32_none: &dyn AsByteVec = &u32_none; + assert_eq!(u32_none.as_byte_vec(), &[&[0]]); + + let u32_some_zero: Option = Some(0); + let u32_some_zero: &dyn AsByteVec = &u32_some_zero; + assert_eq!(u32_some_zero.as_byte_vec(), &[&[1][..], &[0, 0, 0, 0][..]]); + + let u64_none: Option = None; + let u64_none: &dyn AsByteVec = &u64_none; + assert_eq!(u64_none.as_byte_vec(), &[&[0]]); + + let u64_some_zero: Option = Some(0); + let u64_some_zero: &dyn AsByteVec = &u64_some_zero; + assert_eq!( + u64_some_zero.as_byte_vec(), + &[&[1][..], &[0, 0, 0, 0, 0, 0, 0, 0][..]] + ); + + let u128_none: Option = None; + let u128_none: &dyn AsByteVec = &u128_none; + assert_eq!(u128_none.as_byte_vec(), &[&[0]]); + + let u128_some_zero: Option = Some(0); + let u128_some_zero: &dyn AsByteVec = &u128_some_zero; + assert_eq!( + u128_some_zero.as_byte_vec(), + &[ + &[1][..], + &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0][..] + ] + ); + } + + #[test] + fn test_as_byte_vec_array() { + let arr: [u8; 0] = []; + let arr: &dyn AsByteVec = &arr; + assert_eq!(arr.as_byte_vec(), &[&[]]); + + let arr: [u8; 1] = [255]; + let arr: &dyn AsByteVec = &arr; + assert_eq!(arr.as_byte_vec(), &[&[255]]); + + let arr: [u8; 4] = [255, 255, 255, 255]; + let arr: &dyn AsByteVec = &arr; + assert_eq!(arr.as_byte_vec(), &[&[255, 255, 255, 255]]); + } + + #[test] + fn test_as_byte_vec_string() { + let s: &dyn AsByteVec = &"".to_string(); + assert_eq!(s.as_byte_vec(), &[b""]); + + let s: &dyn AsByteVec = &"foobar".to_string(); + assert_eq!(s.as_byte_vec(), &[b"foobar"]); + } +} diff --git a/hasher/src/errors.rs b/hasher/src/errors.rs new file mode 100644 index 0000000..a47e1ab --- /dev/null +++ b/hasher/src/errors.rs @@ -0,0 +1,35 @@ +use light_poseidon::PoseidonError; +use thiserror::Error; + +use crate::poseidon::PoseidonSyscallError; + +#[derive(Debug, Error, PartialEq)] +pub enum HasherError { + #[error("Integer overflow, value too large")] + IntegerOverflow, + #[error("Poseidon hasher error: {0}")] + Poseidon(#[from] PoseidonError), + #[error("Poseidon syscall error: {0}")] + PoseidonSyscall(#[from] PoseidonSyscallError), + #[error("Unknown Solana syscall error: {0}")] + UnknownSolanaSyscall(u64), +} + +// NOTE(vadorovsky): Unfortunately, we need to do it by hand. `num_derive::ToPrimitive` +// doesn't support data-carrying enums. +impl From for u32 { + fn from(e: HasherError) -> u32 { + match e { + HasherError::IntegerOverflow => 7001, + HasherError::Poseidon(_) => 7002, + HasherError::PoseidonSyscall(e) => (u64::from(e)).try_into().unwrap_or(7003), + HasherError::UnknownSolanaSyscall(e) => e.try_into().unwrap_or(7004), + } + } +} + +impl From for solana_program::program_error::ProgramError { + fn from(e: HasherError) -> Self { + solana_program::program_error::ProgramError::Custom(e.into()) + } +} diff --git a/hasher/src/keccak.rs b/hasher/src/keccak.rs new file mode 100644 index 0000000..1f16278 --- /dev/null +++ b/hasher/src/keccak.rs @@ -0,0 +1,51 @@ +use crate::{ + errors::HasherError, + zero_bytes::{keccak::ZERO_BYTES, ZeroBytes}, + zero_indexed_leaf::keccak::ZERO_INDEXED_LEAF, + Hash, Hasher, +}; + +#[derive(Clone, Copy)] // To allow using with zero copy Solana accounts. +pub struct Keccak; + +impl Hasher for Keccak { + fn hash(val: &[u8]) -> Result { + Self::hashv(&[val]) + } + + fn hashv(vals: &[&[u8]]) -> Result { + #[cfg(not(target_os = "solana"))] + { + use sha3::{Digest, Keccak256}; + + let mut hasher = Keccak256::default(); + for val in vals { + hasher.update(val); + } + Ok(hasher.finalize().into()) + } + // Call via a system call to perform the calculation + #[cfg(target_os = "solana")] + { + use crate::HASH_BYTES; + + let mut hash_result = [0; HASH_BYTES]; + unsafe { + crate::syscalls::sol_keccak256( + vals as *const _ as *const u8, + vals.len() as u64, + &mut hash_result as *mut _ as *mut u8, + ); + } + Ok(hash_result) + } + } + + fn zero_bytes() -> ZeroBytes { + ZERO_BYTES + } + + fn zero_indexed_leaf() -> [u8; 32] { + ZERO_INDEXED_LEAF + } +} diff --git a/hasher/src/lib.rs b/hasher/src/lib.rs new file mode 100644 index 0000000..e703b58 --- /dev/null +++ b/hasher/src/lib.rs @@ -0,0 +1,37 @@ +pub mod bytes; +pub mod errors; +pub mod keccak; +pub mod poseidon; +pub mod sha256; +pub mod syscalls; +pub mod zero_bytes; +pub mod zero_indexed_leaf; + +pub use keccak::Keccak; +pub use poseidon::Poseidon; +pub use sha256::Sha256; + +pub use crate::errors::HasherError; +use crate::zero_bytes::ZeroBytes; + +pub const HASH_BYTES: usize = 32; + +pub type Hash = [u8; HASH_BYTES]; + +pub trait Hasher { + fn hash(val: &[u8]) -> Result; + fn hashv(vals: &[&[u8]]) -> Result; + fn zero_bytes() -> ZeroBytes; + fn zero_indexed_leaf() -> [u8; 32]; +} + +pub trait DataHasher { + fn hash(&self) -> Result<[u8; 32], HasherError>; +} + +pub trait Discriminator { + const DISCRIMINATOR: [u8; 8]; + fn discriminator() -> [u8; 8] { + Self::DISCRIMINATOR + } +} diff --git a/hasher/src/poseidon.rs b/hasher/src/poseidon.rs new file mode 100644 index 0000000..25badb2 --- /dev/null +++ b/hasher/src/poseidon.rs @@ -0,0 +1,128 @@ +use thiserror::{self, Error}; + +use crate::{ + errors::HasherError, + zero_bytes::{poseidon::ZERO_BYTES, ZeroBytes}, + zero_indexed_leaf::poseidon::ZERO_INDEXED_LEAF, + Hash, Hasher, +}; + +#[derive(Debug, Error, PartialEq)] +pub enum PoseidonSyscallError { + #[error("Invalid parameters.")] + InvalidParameters, + #[error("Invalid endianness.")] + InvalidEndianness, + #[error("Invalid number of inputs. Maximum allowed is 12.")] + InvalidNumberOfInputs, + #[error("Input is an empty slice.")] + EmptyInput, + #[error( + "Invalid length of the input. The length matching the modulus of the prime field is 32." + )] + InvalidInputLength, + #[error("Failed to convert bytest into a prime field element.")] + BytesToPrimeFieldElement, + #[error("Input is larger than the modulus of the prime field.")] + InputLargerThanModulus, + #[error("Failed to convert a vector of bytes into an array.")] + VecToArray, + #[error("Failed to convert the number of inputs from u64 to u8.")] + U64Tou8, + #[error("Failed to convert bytes to BigInt")] + BytesToBigInt, + #[error("Invalid width. Choose a width between 2 and 16 for 1 to 15 inputs.")] + InvalidWidthCircom, + #[error("Unexpected error")] + Unexpected, +} +impl From for PoseidonSyscallError { + fn from(error: u64) -> Self { + match error { + 1 => PoseidonSyscallError::InvalidParameters, + 2 => PoseidonSyscallError::InvalidEndianness, + 3 => PoseidonSyscallError::InvalidNumberOfInputs, + 4 => PoseidonSyscallError::EmptyInput, + 5 => PoseidonSyscallError::InvalidInputLength, + 6 => PoseidonSyscallError::BytesToPrimeFieldElement, + 7 => PoseidonSyscallError::InputLargerThanModulus, + 8 => PoseidonSyscallError::VecToArray, + 9 => PoseidonSyscallError::U64Tou8, + 10 => PoseidonSyscallError::BytesToBigInt, + 11 => PoseidonSyscallError::InvalidWidthCircom, + _ => PoseidonSyscallError::Unexpected, + } + } +} + +impl From for u64 { + fn from(error: PoseidonSyscallError) -> Self { + match error { + PoseidonSyscallError::InvalidParameters => 1, + PoseidonSyscallError::InvalidEndianness => 2, + PoseidonSyscallError::InvalidNumberOfInputs => 3, + PoseidonSyscallError::EmptyInput => 4, + PoseidonSyscallError::InvalidInputLength => 5, + PoseidonSyscallError::BytesToPrimeFieldElement => 6, + PoseidonSyscallError::InputLargerThanModulus => 7, + PoseidonSyscallError::VecToArray => 8, + PoseidonSyscallError::U64Tou8 => 9, + PoseidonSyscallError::BytesToBigInt => 10, + PoseidonSyscallError::InvalidWidthCircom => 11, + PoseidonSyscallError::Unexpected => 12, + } + } +} + +#[derive(Debug, Clone, Copy)] +pub struct Poseidon; + +impl Hasher for Poseidon { + fn hash(val: &[u8]) -> Result { + Self::hashv(&[val]) + } + + fn hashv(vals: &[&[u8]]) -> Result { + // Perform the calculation inline, calling this from within a program is + // not supported. + #[cfg(not(target_os = "solana"))] + { + use ark_bn254::Fr; + use light_poseidon::{Poseidon, PoseidonBytesHasher}; + + let mut hasher = Poseidon::::new_circom(vals.len())?; + let res = hasher.hash_bytes_be(vals)?; + + Ok(res) + } + // Call via a system call to perform the calculation. + #[cfg(target_os = "solana")] + { + use crate::HASH_BYTES; + + let mut hash_result = [0; HASH_BYTES]; + let result = unsafe { + crate::syscalls::sol_poseidon( + 0, // bn254 + 0, // big-endian + vals as *const _ as *const u8, + vals.len() as u64, + &mut hash_result as *mut _ as *mut u8, + ) + }; + + match result { + 0 => Ok(hash_result), + e => Err(HasherError::from(PoseidonSyscallError::from(e))), + } + } + } + + fn zero_bytes() -> ZeroBytes { + ZERO_BYTES + } + + fn zero_indexed_leaf() -> [u8; 32] { + ZERO_INDEXED_LEAF + } +} diff --git a/hasher/src/sha256.rs b/hasher/src/sha256.rs new file mode 100644 index 0000000..8a4b985 --- /dev/null +++ b/hasher/src/sha256.rs @@ -0,0 +1,51 @@ +use crate::{ + errors::HasherError, + zero_bytes::{sha256::ZERO_BYTES, ZeroBytes}, + zero_indexed_leaf::sha256::ZERO_INDEXED_LEAF, + Hash, Hasher, +}; + +#[derive(Clone, Copy)] // To allow using with zero copy Solana accounts. +pub struct Sha256; + +impl Hasher for Sha256 { + fn hash(val: &[u8]) -> Result { + Self::hashv(&[val]) + } + + fn hashv(vals: &[&[u8]]) -> Result { + #[cfg(not(target_os = "solana"))] + { + use sha2::{Digest, Sha256}; + + let mut hasher = Sha256::default(); + for val in vals { + hasher.update(val); + } + Ok(hasher.finalize().into()) + } + // Call via a system call to perform the calculation + #[cfg(target_os = "solana")] + { + use crate::HASH_BYTES; + + let mut hash_result = [0; HASH_BYTES]; + unsafe { + crate::syscalls::sol_sha256( + vals as *const _ as *const u8, + vals.len() as u64, + &mut hash_result as *mut _ as *mut u8, + ); + } + Ok(hash_result) + } + } + + fn zero_bytes() -> ZeroBytes { + ZERO_BYTES + } + + fn zero_indexed_leaf() -> [u8; 32] { + ZERO_INDEXED_LEAF + } +} diff --git a/hasher/src/syscalls/definitions.rs b/hasher/src/syscalls/definitions.rs new file mode 100644 index 0000000..38f5d3a --- /dev/null +++ b/hasher/src/syscalls/definitions.rs @@ -0,0 +1,40 @@ +//! This module is a partial copy from +//! [solana-program](https://github.com/solana-labs/solana/blob/master/sdk/program/src/syscalls/definitions.rs), +//! which is licensed under Apache License 2.0. + +#[cfg(target_feature = "static-syscalls")] +macro_rules! define_syscall { + (fn $name:ident($($arg:ident: $typ:ty),*) -> $ret:ty) => { + #[inline] + pub unsafe fn $name($($arg: $typ),*) -> $ret { + // this enum is used to force the hash to be computed in a const context + #[repr(usize)] + enum Syscall { + Code = sys_hash(stringify!($name)), + } + + let syscall: extern "C" fn($($arg: $typ),*) -> $ret = core::mem::transmute(Syscall::Code); + syscall($($arg),*) + } + + }; + (fn $name:ident($($arg:ident: $typ:ty),*)) => { + define_syscall!(fn $name($($arg: $typ),*) -> ()); + } +} + +#[cfg(not(target_feature = "static-syscalls"))] +macro_rules! define_syscall { + (fn $name:ident($($arg:ident: $typ:ty),*) -> $ret:ty) => { + extern "C" { + pub fn $name($($arg: $typ),*) -> $ret; + } + }; + (fn $name:ident($($arg:ident: $typ:ty),*)) => { + define_syscall!(fn $name($($arg: $typ),*) -> ()); + } +} + +define_syscall!(fn sol_sha256(vals: *const u8, val_len: u64, hash_result: *mut u8) -> u64); +define_syscall!(fn sol_keccak256(vals: *const u8, val_len: u64, hash_result: *mut u8) -> u64); +define_syscall!(fn sol_poseidon(parameters: u64, endianness: u64, vals: *const u8, val_len: u64, hash_result: *mut u8) -> u64); diff --git a/hasher/src/syscalls/mod.rs b/hasher/src/syscalls/mod.rs new file mode 100644 index 0000000..478f941 --- /dev/null +++ b/hasher/src/syscalls/mod.rs @@ -0,0 +1,12 @@ +//! This module is a partial copy from +//! [solana-program](https://github.com/solana-labs/solana/blob/master/sdk/program/src/syscalls/definitions.rs), +//! which is licensed under Apache License 2.0. +//! +//! The purpose of the module is to provide definition of Poseidon syscall +//! without upgrading solana-program and Anchor just yet. + +#[cfg(target_os = "solana")] +mod definitions; + +#[cfg(target_os = "solana")] +pub use definitions::*; diff --git a/hasher/src/zero_bytes/keccak.rs b/hasher/src/zero_bytes/keccak.rs new file mode 100644 index 0000000..c068089 --- /dev/null +++ b/hasher/src/zero_bytes/keccak.rs @@ -0,0 +1,209 @@ +// This file is generated by xtask. Do not edit it manually. + +use super::ZeroBytes; +pub const ZERO_BYTES: ZeroBytes = [ + [ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + ], + [ + 173u8, 50u8, 40u8, 182u8, 118u8, 247u8, 211u8, 205u8, 66u8, 132u8, 165u8, 68u8, 63u8, 23u8, + 241u8, 150u8, 43u8, 54u8, 228u8, 145u8, 179u8, 10u8, 64u8, 178u8, 64u8, 88u8, 73u8, 229u8, + 151u8, 186u8, 95u8, 181u8, + ], + [ + 180u8, 193u8, 25u8, 81u8, 149u8, 124u8, 111u8, 143u8, 100u8, 44u8, 74u8, 246u8, 28u8, + 214u8, 178u8, 70u8, 64u8, 254u8, 198u8, 220u8, 127u8, 198u8, 7u8, 238u8, 130u8, 6u8, 169u8, + 158u8, 146u8, 65u8, 13u8, 48u8, + ], + [ + 33u8, 221u8, 185u8, 163u8, 86u8, 129u8, 92u8, 63u8, 172u8, 16u8, 38u8, 182u8, 222u8, 197u8, + 223u8, 49u8, 36u8, 175u8, 186u8, 219u8, 72u8, 92u8, 155u8, 165u8, 163u8, 227u8, 57u8, + 138u8, 4u8, 183u8, 186u8, 133u8, + ], + [ + 229u8, 135u8, 105u8, 179u8, 42u8, 27u8, 234u8, 241u8, 234u8, 39u8, 55u8, 90u8, 68u8, 9u8, + 90u8, 13u8, 31u8, 182u8, 100u8, 206u8, 45u8, 211u8, 88u8, 231u8, 252u8, 191u8, 183u8, + 140u8, 38u8, 161u8, 147u8, 68u8, + ], + [ + 14u8, 176u8, 30u8, 191u8, 201u8, 237u8, 39u8, 80u8, 12u8, 212u8, 223u8, 201u8, 121u8, 39u8, + 45u8, 31u8, 9u8, 19u8, 204u8, 159u8, 102u8, 84u8, 13u8, 126u8, 128u8, 5u8, 129u8, 17u8, + 9u8, 225u8, 207u8, 45u8, + ], + [ + 136u8, 124u8, 34u8, 189u8, 135u8, 80u8, 211u8, 64u8, 22u8, 172u8, 60u8, 102u8, 181u8, + 255u8, 16u8, 45u8, 172u8, 221u8, 115u8, 246u8, 176u8, 20u8, 231u8, 16u8, 181u8, 30u8, + 128u8, 34u8, 175u8, 154u8, 25u8, 104u8, + ], + [ + 255u8, 215u8, 1u8, 87u8, 228u8, 128u8, 99u8, 252u8, 51u8, 201u8, 122u8, 5u8, 15u8, 127u8, + 100u8, 2u8, 51u8, 191u8, 100u8, 108u8, 201u8, 141u8, 149u8, 36u8, 198u8, 185u8, 43u8, + 207u8, 58u8, 181u8, 111u8, 131u8, + ], + [ + 152u8, 103u8, 204u8, 95u8, 127u8, 25u8, 107u8, 147u8, 186u8, 225u8, 226u8, 126u8, 99u8, + 32u8, 116u8, 36u8, 69u8, 210u8, 144u8, 242u8, 38u8, 56u8, 39u8, 73u8, 139u8, 84u8, 254u8, + 197u8, 57u8, 247u8, 86u8, 175u8, + ], + [ + 206u8, 250u8, 212u8, 229u8, 8u8, 192u8, 152u8, 185u8, 167u8, 225u8, 216u8, 254u8, 177u8, + 153u8, 85u8, 251u8, 2u8, 186u8, 150u8, 117u8, 88u8, 80u8, 120u8, 113u8, 9u8, 105u8, 211u8, + 68u8, 15u8, 80u8, 84u8, 224u8, + ], + [ + 249u8, 220u8, 62u8, 127u8, 224u8, 22u8, 224u8, 80u8, 239u8, 242u8, 96u8, 51u8, 79u8, 24u8, + 165u8, 212u8, 254u8, 57u8, 29u8, 130u8, 9u8, 35u8, 25u8, 245u8, 150u8, 79u8, 46u8, 46u8, + 183u8, 193u8, 195u8, 165u8, + ], + [ + 248u8, 177u8, 58u8, 73u8, 226u8, 130u8, 246u8, 9u8, 195u8, 23u8, 168u8, 51u8, 251u8, 141u8, + 151u8, 109u8, 17u8, 81u8, 124u8, 87u8, 29u8, 18u8, 33u8, 162u8, 101u8, 210u8, 90u8, 247u8, + 120u8, 236u8, 248u8, 146u8, + ], + [ + 52u8, 144u8, 198u8, 206u8, 235u8, 69u8, 10u8, 236u8, 220u8, 130u8, 226u8, 130u8, 147u8, + 3u8, 29u8, 16u8, 199u8, 215u8, 59u8, 248u8, 94u8, 87u8, 191u8, 4u8, 26u8, 151u8, 54u8, + 10u8, 162u8, 197u8, 217u8, 156u8, + ], + [ + 193u8, 223u8, 130u8, 217u8, 196u8, 184u8, 116u8, 19u8, 234u8, 226u8, 239u8, 4u8, 143u8, + 148u8, 180u8, 211u8, 85u8, 76u8, 234u8, 115u8, 217u8, 43u8, 15u8, 122u8, 249u8, 110u8, 2u8, + 113u8, 198u8, 145u8, 226u8, 187u8, + ], + [ + 92u8, 103u8, 173u8, 215u8, 198u8, 202u8, 243u8, 2u8, 37u8, 106u8, 222u8, 223u8, 122u8, + 177u8, 20u8, 218u8, 10u8, 207u8, 232u8, 112u8, 212u8, 73u8, 163u8, 164u8, 137u8, 247u8, + 129u8, 214u8, 89u8, 232u8, 190u8, 204u8, + ], + [ + 218u8, 123u8, 206u8, 159u8, 78u8, 134u8, 24u8, 182u8, 189u8, 47u8, 65u8, 50u8, 206u8, + 121u8, 140u8, 220u8, 122u8, 96u8, 231u8, 225u8, 70u8, 10u8, 114u8, 153u8, 227u8, 198u8, + 52u8, 42u8, 87u8, 150u8, 38u8, 210u8, + ], + [ + 39u8, 51u8, 229u8, 15u8, 82u8, 110u8, 194u8, 250u8, 25u8, 162u8, 43u8, 49u8, 232u8, 237u8, + 80u8, 242u8, 60u8, 209u8, 253u8, 249u8, 76u8, 145u8, 84u8, 237u8, 58u8, 118u8, 9u8, 162u8, + 241u8, 255u8, 152u8, 31u8, + ], + [ + 225u8, 211u8, 181u8, 200u8, 7u8, 178u8, 129u8, 228u8, 104u8, 60u8, 198u8, 214u8, 49u8, + 92u8, 249u8, 91u8, 154u8, 222u8, 134u8, 65u8, 222u8, 252u8, 179u8, 35u8, 114u8, 241u8, + 193u8, 38u8, 227u8, 152u8, 239u8, 122u8, + ], + [ + 90u8, 45u8, 206u8, 10u8, 138u8, 127u8, 104u8, 187u8, 116u8, 86u8, 15u8, 143u8, 113u8, + 131u8, 124u8, 44u8, 46u8, 187u8, 203u8, 247u8, 255u8, 251u8, 66u8, 174u8, 24u8, 150u8, + 241u8, 63u8, 124u8, 116u8, 121u8, 160u8, + ], + [ + 180u8, 106u8, 40u8, 182u8, 245u8, 85u8, 64u8, 248u8, 148u8, 68u8, 246u8, 61u8, 224u8, 55u8, + 142u8, 61u8, 18u8, 27u8, 224u8, 158u8, 6u8, 204u8, 157u8, 237u8, 28u8, 32u8, 230u8, 88u8, + 118u8, 211u8, 106u8, 160u8, + ], + [ + 198u8, 94u8, 150u8, 69u8, 100u8, 71u8, 134u8, 182u8, 32u8, 226u8, 221u8, 42u8, 214u8, 72u8, + 221u8, 252u8, 191u8, 74u8, 126u8, 91u8, 26u8, 58u8, 78u8, 207u8, 231u8, 246u8, 70u8, 103u8, + 163u8, 240u8, 183u8, 226u8, + ], + [ + 244u8, 65u8, 133u8, 136u8, 237u8, 53u8, 162u8, 69u8, 140u8, 255u8, 235u8, 57u8, 185u8, + 61u8, 38u8, 241u8, 141u8, 42u8, 177u8, 59u8, 220u8, 230u8, 174u8, 229u8, 142u8, 123u8, + 153u8, 53u8, 158u8, 194u8, 223u8, 217u8, + ], + [ + 90u8, 156u8, 22u8, 220u8, 0u8, 214u8, 239u8, 24u8, 183u8, 147u8, 58u8, 111u8, 141u8, 198u8, + 92u8, 203u8, 85u8, 102u8, 113u8, 56u8, 119u8, 111u8, 125u8, 234u8, 16u8, 16u8, 112u8, + 220u8, 135u8, 150u8, 227u8, 119u8, + ], + [ + 77u8, 248u8, 79u8, 64u8, 174u8, 12u8, 130u8, 41u8, 208u8, 214u8, 6u8, 158u8, 92u8, 143u8, + 57u8, 167u8, 194u8, 153u8, 103u8, 122u8, 9u8, 211u8, 103u8, 252u8, 123u8, 5u8, 227u8, + 188u8, 56u8, 14u8, 230u8, 82u8, + ], + [ + 205u8, 199u8, 37u8, 149u8, 247u8, 76u8, 123u8, 16u8, 67u8, 208u8, 225u8, 255u8, 186u8, + 183u8, 52u8, 100u8, 140u8, 131u8, 141u8, 251u8, 5u8, 39u8, 217u8, 113u8, 182u8, 2u8, 188u8, + 33u8, 108u8, 150u8, 25u8, 239u8, + ], + [ + 10u8, 191u8, 90u8, 201u8, 116u8, 161u8, 237u8, 87u8, 244u8, 5u8, 10u8, 165u8, 16u8, 221u8, + 156u8, 116u8, 245u8, 8u8, 39u8, 123u8, 57u8, 215u8, 151u8, 59u8, 178u8, 223u8, 204u8, + 197u8, 238u8, 176u8, 97u8, 141u8, + ], + [ + 184u8, 205u8, 116u8, 4u8, 111u8, 243u8, 55u8, 240u8, 167u8, 191u8, 44u8, 142u8, 3u8, 225u8, + 15u8, 100u8, 44u8, 24u8, 134u8, 121u8, 141u8, 113u8, 128u8, 106u8, 177u8, 232u8, 136u8, + 217u8, 229u8, 238u8, 135u8, 208u8, + ], + [ + 131u8, 140u8, 86u8, 85u8, 203u8, 33u8, 198u8, 203u8, 131u8, 49u8, 59u8, 90u8, 99u8, 17u8, + 117u8, 223u8, 244u8, 150u8, 55u8, 114u8, 204u8, 233u8, 16u8, 129u8, 136u8, 179u8, 74u8, + 200u8, 124u8, 129u8, 196u8, 30u8, + ], + [ + 102u8, 46u8, 228u8, 221u8, 45u8, 215u8, 178u8, 188u8, 112u8, 121u8, 97u8, 177u8, 230u8, + 70u8, 196u8, 4u8, 118u8, 105u8, 220u8, 182u8, 88u8, 79u8, 13u8, 141u8, 119u8, 13u8, 175u8, + 93u8, 126u8, 125u8, 235u8, 46u8, + ], + [ + 56u8, 138u8, 178u8, 14u8, 37u8, 115u8, 209u8, 113u8, 168u8, 129u8, 8u8, 231u8, 157u8, + 130u8, 14u8, 152u8, 242u8, 108u8, 11u8, 132u8, 170u8, 139u8, 47u8, 74u8, 164u8, 150u8, + 141u8, 187u8, 129u8, 142u8, 163u8, 34u8, + ], + [ + 147u8, 35u8, 124u8, 80u8, 186u8, 117u8, 238u8, 72u8, 95u8, 76u8, 34u8, 173u8, 242u8, 247u8, + 65u8, 64u8, 11u8, 223u8, 141u8, 106u8, 156u8, 199u8, 223u8, 126u8, 202u8, 229u8, 118u8, + 34u8, 22u8, 101u8, 215u8, 53u8, + ], + [ + 132u8, 72u8, 129u8, 139u8, 180u8, 174u8, 69u8, 98u8, 132u8, 158u8, 148u8, 158u8, 23u8, + 172u8, 22u8, 224u8, 190u8, 22u8, 104u8, 142u8, 21u8, 107u8, 92u8, 241u8, 94u8, 9u8, 140u8, + 98u8, 124u8, 0u8, 86u8, 169u8, + ], + [ + 39u8, 174u8, 91u8, 160u8, 141u8, 114u8, 145u8, 201u8, 108u8, 140u8, 189u8, 220u8, 193u8, + 72u8, 191u8, 72u8, 166u8, 214u8, 140u8, 121u8, 116u8, 185u8, 67u8, 86u8, 245u8, 55u8, 84u8, + 239u8, 97u8, 113u8, 215u8, 87u8, + ], + [ + 191u8, 85u8, 139u8, 235u8, 210u8, 206u8, 236u8, 127u8, 60u8, 93u8, 206u8, 4u8, 164u8, + 120u8, 47u8, 136u8, 194u8, 198u8, 3u8, 106u8, 231u8, 142u8, 226u8, 6u8, 208u8, 188u8, 82u8, + 137u8, 210u8, 4u8, 97u8, 162u8, + ], + [ + 226u8, 25u8, 8u8, 194u8, 150u8, 140u8, 6u8, 153u8, 4u8, 10u8, 111u8, 216u8, 102u8, 165u8, + 119u8, 169u8, 154u8, 157u8, 46u8, 200u8, 135u8, 69u8, 200u8, 21u8, 253u8, 74u8, 71u8, 44u8, + 120u8, 146u8, 68u8, 218u8, + ], + [ + 174u8, 130u8, 77u8, 114u8, 221u8, 194u8, 114u8, 170u8, 182u8, 138u8, 140u8, 48u8, 34u8, + 227u8, 111u8, 16u8, 69u8, 68u8, 55u8, 193u8, 136u8, 111u8, 63u8, 249u8, 146u8, 123u8, + 100u8, 242u8, 50u8, 223u8, 65u8, 79u8, + ], + [ + 39u8, 228u8, 41u8, 164u8, 190u8, 243u8, 8u8, 59u8, 195u8, 26u8, 103u8, 29u8, 4u8, 110u8, + 165u8, 193u8, 245u8, 184u8, 195u8, 9u8, 77u8, 114u8, 134u8, 141u8, 157u8, 253u8, 193u8, + 44u8, 115u8, 52u8, 172u8, 95u8, + ], + [ + 116u8, 60u8, 197u8, 195u8, 101u8, 169u8, 166u8, 161u8, 92u8, 31u8, 36u8, 10u8, 194u8, 88u8, + 128u8, 199u8, 169u8, 209u8, 222u8, 41u8, 6u8, 150u8, 203u8, 118u8, 96u8, 116u8, 161u8, + 216u8, 61u8, 146u8, 120u8, 22u8, + ], + [ + 74u8, 220u8, 246u8, 22u8, 195u8, 191u8, 171u8, 246u8, 57u8, 153u8, 160u8, 25u8, 102u8, + 201u8, 152u8, 183u8, 187u8, 87u8, 39u8, 116u8, 3u8, 90u8, 99u8, 234u8, 212u8, 157u8, 167u8, + 59u8, 89u8, 135u8, 243u8, 71u8, + ], + [ + 117u8, 120u8, 102u8, 69u8, 208u8, 197u8, 221u8, 124u8, 4u8, 162u8, 248u8, 167u8, 93u8, + 202u8, 224u8, 133u8, 33u8, 54u8, 82u8, 245u8, 188u8, 227u8, 234u8, 139u8, 155u8, 155u8, + 237u8, 209u8, 202u8, 179u8, 197u8, 233u8, + ], + [ + 184u8, 139u8, 21u8, 44u8, 155u8, 138u8, 123u8, 121u8, 99u8, 125u8, 53u8, 145u8, 24u8, 72u8, + 176u8, 196u8, 30u8, 124u8, 199u8, 204u8, 162u8, 171u8, 79u8, 233u8, 161u8, 95u8, 156u8, + 56u8, 187u8, 75u8, 185u8, 57u8, + ], +]; diff --git a/hasher/src/zero_bytes/mod.rs b/hasher/src/zero_bytes/mod.rs new file mode 100644 index 0000000..d23e7a8 --- /dev/null +++ b/hasher/src/zero_bytes/mod.rs @@ -0,0 +1,7 @@ +pub mod keccak; +pub mod poseidon; +pub mod sha256; + +pub const MAX_HEIGHT: usize = 40; + +pub type ZeroBytes = [[u8; 32]; MAX_HEIGHT + 1]; diff --git a/hasher/src/zero_bytes/poseidon.rs b/hasher/src/zero_bytes/poseidon.rs new file mode 100644 index 0000000..9fafb4f --- /dev/null +++ b/hasher/src/zero_bytes/poseidon.rs @@ -0,0 +1,209 @@ +// This file is generated by xtask. Do not edit it manually. + +use super::ZeroBytes; +pub const ZERO_BYTES: ZeroBytes = [ + [ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + ], + [ + 32u8, 152u8, 245u8, 251u8, 158u8, 35u8, 158u8, 171u8, 60u8, 234u8, 195u8, 242u8, 123u8, + 129u8, 228u8, 129u8, 220u8, 49u8, 36u8, 213u8, 95u8, 254u8, 213u8, 35u8, 168u8, 57u8, + 238u8, 132u8, 70u8, 182u8, 72u8, 100u8, + ], + [ + 16u8, 105u8, 103u8, 61u8, 205u8, 177u8, 34u8, 99u8, 223u8, 48u8, 26u8, 111u8, 245u8, 132u8, + 167u8, 236u8, 38u8, 26u8, 68u8, 203u8, 157u8, 198u8, 141u8, 240u8, 103u8, 164u8, 119u8, + 68u8, 96u8, 177u8, 241u8, 225u8, + ], + [ + 24u8, 244u8, 51u8, 49u8, 83u8, 126u8, 226u8, 175u8, 46u8, 61u8, 117u8, 141u8, 80u8, 247u8, + 33u8, 6u8, 70u8, 124u8, 110u8, 234u8, 80u8, 55u8, 29u8, 213u8, 40u8, 213u8, 126u8, 178u8, + 184u8, 86u8, 210u8, 56u8, + ], + [ + 7u8, 249u8, 216u8, 55u8, 203u8, 23u8, 176u8, 211u8, 99u8, 32u8, 255u8, 233u8, 59u8, 165u8, + 35u8, 69u8, 241u8, 183u8, 40u8, 87u8, 26u8, 86u8, 130u8, 101u8, 202u8, 172u8, 151u8, 85u8, + 157u8, 188u8, 149u8, 42u8, + ], + [ + 43u8, 148u8, 207u8, 94u8, 135u8, 70u8, 179u8, 245u8, 201u8, 99u8, 31u8, 76u8, 93u8, 243u8, + 41u8, 7u8, 166u8, 153u8, 197u8, 140u8, 148u8, 178u8, 173u8, 77u8, 123u8, 92u8, 236u8, 22u8, + 57u8, 24u8, 63u8, 85u8, + ], + [ + 45u8, 238u8, 147u8, 197u8, 166u8, 102u8, 69u8, 150u8, 70u8, 234u8, 125u8, 34u8, 204u8, + 169u8, 225u8, 188u8, 254u8, 215u8, 30u8, 105u8, 81u8, 185u8, 83u8, 97u8, 29u8, 17u8, 221u8, + 163u8, 46u8, 160u8, 157u8, 120u8, + ], + [ + 7u8, 130u8, 149u8, 229u8, 162u8, 43u8, 132u8, 233u8, 130u8, 207u8, 96u8, 30u8, 182u8, 57u8, + 89u8, 123u8, 139u8, 5u8, 21u8, 168u8, 140u8, 181u8, 172u8, 127u8, 168u8, 164u8, 170u8, + 190u8, 60u8, 135u8, 52u8, 157u8, + ], + [ + 47u8, 165u8, 229u8, 241u8, 143u8, 96u8, 39u8, 166u8, 80u8, 27u8, 236u8, 134u8, 69u8, 100u8, + 71u8, 42u8, 97u8, 107u8, 46u8, 39u8, 74u8, 65u8, 33u8, 26u8, 68u8, 76u8, 190u8, 58u8, + 153u8, 243u8, 204u8, 97u8, + ], + [ + 14u8, 136u8, 67u8, 118u8, 208u8, 216u8, 253u8, 33u8, 236u8, 183u8, 128u8, 56u8, 158u8, + 148u8, 31u8, 102u8, 228u8, 94u8, 122u8, 204u8, 227u8, 226u8, 40u8, 171u8, 62u8, 33u8, 86u8, + 166u8, 20u8, 252u8, 215u8, 71u8, + ], + [ + 27u8, 114u8, 1u8, 218u8, 114u8, 73u8, 79u8, 30u8, 40u8, 113u8, 122u8, 209u8, 165u8, 46u8, + 180u8, 105u8, 249u8, 88u8, 146u8, 249u8, 87u8, 113u8, 53u8, 51u8, 222u8, 97u8, 117u8, + 229u8, 218u8, 25u8, 10u8, 242u8, + ], + [ + 31u8, 141u8, 136u8, 34u8, 114u8, 94u8, 54u8, 56u8, 82u8, 0u8, 192u8, 178u8, 1u8, 36u8, + 152u8, 25u8, 166u8, 230u8, 225u8, 228u8, 101u8, 8u8, 8u8, 181u8, 190u8, 188u8, 107u8, + 250u8, 206u8, 125u8, 118u8, 54u8, + ], + [ + 44u8, 93u8, 130u8, 246u8, 108u8, 145u8, 75u8, 175u8, 185u8, 112u8, 21u8, 137u8, 186u8, + 140u8, 252u8, 251u8, 97u8, 98u8, 176u8, 161u8, 42u8, 207u8, 136u8, 168u8, 208u8, 135u8, + 154u8, 4u8, 113u8, 181u8, 248u8, 90u8, + ], + [ + 20u8, 197u8, 65u8, 72u8, 160u8, 148u8, 11u8, 184u8, 32u8, 149u8, 127u8, 90u8, 223u8, 63u8, + 161u8, 19u8, 78u8, 245u8, 196u8, 170u8, 161u8, 19u8, 244u8, 100u8, 100u8, 88u8, 242u8, + 112u8, 224u8, 191u8, 191u8, 208u8, + ], + [ + 25u8, 13u8, 51u8, 177u8, 47u8, 152u8, 111u8, 150u8, 30u8, 16u8, 192u8, 238u8, 68u8, 216u8, + 185u8, 175u8, 17u8, 190u8, 37u8, 88u8, 140u8, 173u8, 137u8, 212u8, 22u8, 17u8, 142u8, 75u8, + 244u8, 235u8, 232u8, 12u8, + ], + [ + 34u8, 249u8, 138u8, 169u8, 206u8, 112u8, 65u8, 82u8, 172u8, 23u8, 53u8, 73u8, 20u8, 173u8, + 115u8, 237u8, 17u8, 103u8, 174u8, 101u8, 150u8, 175u8, 81u8, 10u8, 165u8, 179u8, 100u8, + 147u8, 37u8, 224u8, 108u8, 146u8, + ], + [ + 42u8, 124u8, 124u8, 155u8, 108u8, 229u8, 136u8, 11u8, 159u8, 111u8, 34u8, 141u8, 114u8, + 191u8, 106u8, 87u8, 90u8, 82u8, 111u8, 41u8, 198u8, 110u8, 204u8, 238u8, 248u8, 183u8, + 83u8, 211u8, 139u8, 186u8, 115u8, 35u8, + ], + [ + 46u8, 129u8, 134u8, 229u8, 88u8, 105u8, 142u8, 193u8, 198u8, 122u8, 249u8, 193u8, 77u8, + 70u8, 63u8, 252u8, 71u8, 0u8, 67u8, 201u8, 194u8, 152u8, 139u8, 149u8, 77u8, 117u8, 221u8, + 100u8, 63u8, 54u8, 185u8, 146u8, + ], + [ + 15u8, 87u8, 197u8, 87u8, 30u8, 154u8, 78u8, 171u8, 73u8, 226u8, 200u8, 207u8, 5u8, 13u8, + 174u8, 148u8, 138u8, 239u8, 110u8, 173u8, 100u8, 115u8, 146u8, 39u8, 53u8, 70u8, 36u8, + 157u8, 28u8, 31u8, 241u8, 15u8, + ], + [ + 24u8, 48u8, 238u8, 103u8, 181u8, 251u8, 85u8, 74u8, 213u8, 246u8, 61u8, 67u8, 136u8, 128u8, + 14u8, 28u8, 254u8, 120u8, 227u8, 16u8, 105u8, 125u8, 70u8, 228u8, 60u8, 156u8, 227u8, 97u8, + 52u8, 247u8, 44u8, 202u8, + ], + [ + 33u8, 52u8, 231u8, 106u8, 197u8, 210u8, 26u8, 171u8, 24u8, 108u8, 43u8, 225u8, 221u8, + 143u8, 132u8, 238u8, 136u8, 10u8, 30u8, 70u8, 234u8, 247u8, 18u8, 249u8, 211u8, 113u8, + 182u8, 223u8, 34u8, 25u8, 31u8, 62u8, + ], + [ + 25u8, 223u8, 144u8, 236u8, 132u8, 78u8, 188u8, 79u8, 254u8, 235u8, 216u8, 102u8, 243u8, + 56u8, 89u8, 176u8, 192u8, 81u8, 216u8, 201u8, 88u8, 238u8, 58u8, 168u8, 143u8, 143u8, + 141u8, 243u8, 219u8, 145u8, 165u8, 177u8, + ], + [ + 24u8, 204u8, 162u8, 166u8, 107u8, 92u8, 7u8, 135u8, 152u8, 30u8, 105u8, 174u8, 253u8, + 132u8, 133u8, 45u8, 116u8, 175u8, 14u8, 147u8, 239u8, 73u8, 18u8, 180u8, 100u8, 140u8, 5u8, + 247u8, 34u8, 239u8, 229u8, 43u8, + ], + [ + 35u8, 136u8, 144u8, 148u8, 21u8, 35u8, 13u8, 27u8, 77u8, 19u8, 4u8, 210u8, 213u8, 79u8, + 71u8, 58u8, 98u8, 131u8, 56u8, 242u8, 239u8, 173u8, 131u8, 250u8, 223u8, 5u8, 100u8, 69u8, + 73u8, 210u8, 83u8, 141u8, + ], + [ + 39u8, 23u8, 31u8, 180u8, 169u8, 123u8, 108u8, 192u8, 233u8, 232u8, 245u8, 67u8, 181u8, + 41u8, 77u8, 232u8, 102u8, 162u8, 175u8, 44u8, 156u8, 141u8, 11u8, 29u8, 150u8, 230u8, + 115u8, 228u8, 82u8, 158u8, 213u8, 64u8, + ], + [ + 47u8, 246u8, 101u8, 5u8, 64u8, 246u8, 41u8, 253u8, 87u8, 17u8, 160u8, 188u8, 116u8, 252u8, + 13u8, 40u8, 220u8, 178u8, 48u8, 185u8, 57u8, 37u8, 131u8, 229u8, 248u8, 213u8, 150u8, + 150u8, 221u8, 230u8, 174u8, 33u8, + ], + [ + 18u8, 12u8, 88u8, 241u8, 67u8, 212u8, 145u8, 233u8, 89u8, 2u8, 247u8, 245u8, 39u8, 119u8, + 120u8, 162u8, 224u8, 173u8, 81u8, 104u8, 246u8, 173u8, 215u8, 86u8, 105u8, 147u8, 38u8, + 48u8, 206u8, 97u8, 21u8, 24u8, + ], + [ + 31u8, 33u8, 254u8, 183u8, 13u8, 63u8, 33u8, 176u8, 123u8, 248u8, 83u8, 213u8, 229u8, 219u8, + 3u8, 7u8, 30u8, 196u8, 149u8, 160u8, 165u8, 101u8, 162u8, 29u8, 162u8, 214u8, 101u8, 210u8, + 121u8, 72u8, 55u8, 149u8, + ], + [ + 36u8, 190u8, 144u8, 95u8, 167u8, 19u8, 53u8, 225u8, 76u8, 99u8, 140u8, 192u8, 246u8, 106u8, + 134u8, 35u8, 168u8, 38u8, 231u8, 104u8, 6u8, 138u8, 158u8, 150u8, 139u8, 177u8, 161u8, + 221u8, 225u8, 138u8, 114u8, 210u8, + ], + [ + 15u8, 134u8, 102u8, 182u8, 46u8, 209u8, 116u8, 145u8, 197u8, 12u8, 234u8, 222u8, 173u8, + 87u8, 212u8, 205u8, 89u8, 126u8, 243u8, 130u8, 29u8, 101u8, 195u8, 40u8, 116u8, 76u8, + 116u8, 229u8, 83u8, 218u8, 194u8, 109u8, + ], + [ + 9u8, 24u8, 212u8, 107u8, 245u8, 45u8, 152u8, 176u8, 52u8, 65u8, 63u8, 74u8, 26u8, 28u8, + 65u8, 89u8, 78u8, 122u8, 122u8, 63u8, 106u8, 224u8, 140u8, 180u8, 61u8, 26u8, 42u8, 35u8, + 14u8, 25u8, 89u8, 239u8, + ], + [ + 27u8, 190u8, 176u8, 27u8, 76u8, 71u8, 158u8, 205u8, 231u8, 105u8, 23u8, 100u8, 94u8, 64u8, + 77u8, 250u8, 46u8, 38u8, 249u8, 13u8, 10u8, 252u8, 90u8, 101u8, 18u8, 133u8, 19u8, 173u8, + 55u8, 92u8, 95u8, 242u8, + ], + [ + 47u8, 104u8, 161u8, 197u8, 142u8, 37u8, 126u8, 66u8, 161u8, 122u8, 108u8, 97u8, 223u8, + 245u8, 85u8, 30u8, 213u8, 96u8, 185u8, 146u8, 42u8, 177u8, 25u8, 213u8, 172u8, 142u8, 24u8, + 76u8, 151u8, 52u8, 234u8, 217u8, + ], + [ + 17u8, 2u8, 210u8, 248u8, 219u8, 5u8, 228u8, 175u8, 72u8, 66u8, 232u8, 173u8, 61u8, 133u8, + 237u8, 69u8, 235u8, 40u8, 68u8, 126u8, 183u8, 33u8, 34u8, 53u8, 162u8, 40u8, 29u8, 90u8, + 181u8, 216u8, 29u8, 17u8, + ], + [ + 42u8, 248u8, 193u8, 202u8, 245u8, 96u8, 221u8, 65u8, 249u8, 151u8, 160u8, 31u8, 248u8, + 149u8, 178u8, 30u8, 13u8, 31u8, 237u8, 183u8, 134u8, 231u8, 202u8, 210u8, 153u8, 1u8, + 225u8, 35u8, 16u8, 99u8, 139u8, 220u8, + ], + [ + 1u8, 29u8, 146u8, 59u8, 193u8, 75u8, 90u8, 19u8, 151u8, 42u8, 199u8, 223u8, 230u8, 66u8, + 11u8, 21u8, 176u8, 66u8, 92u8, 152u8, 186u8, 128u8, 237u8, 175u8, 94u8, 2u8, 145u8, 180u8, + 162u8, 101u8, 224u8, 165u8, + ], + [ + 34u8, 76u8, 204u8, 37u8, 152u8, 24u8, 34u8, 212u8, 197u8, 182u8, 252u8, 25u8, 159u8, 188u8, + 116u8, 130u8, 132u8, 136u8, 116u8, 28u8, 113u8, 81u8, 166u8, 21u8, 158u8, 207u8, 170u8, + 183u8, 194u8, 168u8, 186u8, 201u8, + ], + [ + 39u8, 232u8, 57u8, 246u8, 245u8, 85u8, 254u8, 174u8, 130u8, 74u8, 180u8, 51u8, 227u8, 75u8, + 28u8, 14u8, 100u8, 206u8, 92u8, 117u8, 150u8, 45u8, 255u8, 193u8, 60u8, 104u8, 87u8, 29u8, + 107u8, 74u8, 97u8, 14u8, + ], + [ + 42u8, 186u8, 32u8, 63u8, 189u8, 4u8, 191u8, 171u8, 200u8, 107u8, 77u8, 80u8, 214u8, 171u8, + 173u8, 195u8, 194u8, 79u8, 55u8, 239u8, 160u8, 14u8, 112u8, 14u8, 244u8, 209u8, 119u8, + 100u8, 194u8, 204u8, 213u8, 124u8, + ], + [ + 17u8, 239u8, 244u8, 246u8, 12u8, 44u8, 220u8, 197u8, 72u8, 193u8, 224u8, 119u8, 12u8, 61u8, + 100u8, 180u8, 156u8, 1u8, 227u8, 77u8, 164u8, 175u8, 41u8, 207u8, 234u8, 87u8, 90u8, 25u8, + 190u8, 250u8, 102u8, 156u8, + ], + [ + 19u8, 52u8, 250u8, 75u8, 85u8, 47u8, 0u8, 239u8, 64u8, 51u8, 97u8, 201u8, 53u8, 193u8, + 171u8, 207u8, 137u8, 104u8, 81u8, 0u8, 60u8, 64u8, 218u8, 169u8, 59u8, 176u8, 253u8, 10u8, + 11u8, 185u8, 168u8, 129u8, + ], +]; diff --git a/hasher/src/zero_bytes/sha256.rs b/hasher/src/zero_bytes/sha256.rs new file mode 100644 index 0000000..21a968a --- /dev/null +++ b/hasher/src/zero_bytes/sha256.rs @@ -0,0 +1,209 @@ +// This file is generated by xtask. Do not edit it manually. + +use super::ZeroBytes; +pub const ZERO_BYTES: ZeroBytes = [ + [ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + ], + [ + 245u8, 165u8, 253u8, 66u8, 209u8, 106u8, 32u8, 48u8, 39u8, 152u8, 239u8, 110u8, 211u8, 9u8, + 151u8, 155u8, 67u8, 0u8, 61u8, 35u8, 32u8, 217u8, 240u8, 232u8, 234u8, 152u8, 49u8, 169u8, + 39u8, 89u8, 251u8, 75u8, + ], + [ + 219u8, 86u8, 17u8, 78u8, 0u8, 253u8, 212u8, 193u8, 248u8, 92u8, 137u8, 43u8, 243u8, 90u8, + 201u8, 168u8, 146u8, 137u8, 170u8, 236u8, 177u8, 235u8, 208u8, 169u8, 108u8, 222u8, 96u8, + 106u8, 116u8, 139u8, 93u8, 113u8, + ], + [ + 199u8, 128u8, 9u8, 253u8, 240u8, 127u8, 197u8, 106u8, 17u8, 241u8, 34u8, 55u8, 6u8, 88u8, + 163u8, 83u8, 170u8, 165u8, 66u8, 237u8, 99u8, 228u8, 76u8, 75u8, 193u8, 95u8, 244u8, 205u8, + 16u8, 90u8, 179u8, 60u8, + ], + [ + 83u8, 109u8, 152u8, 131u8, 127u8, 45u8, 209u8, 101u8, 165u8, 93u8, 94u8, 234u8, 233u8, + 20u8, 133u8, 149u8, 68u8, 114u8, 213u8, 111u8, 36u8, 109u8, 242u8, 86u8, 191u8, 60u8, + 174u8, 25u8, 53u8, 42u8, 18u8, 60u8, + ], + [ + 158u8, 253u8, 224u8, 82u8, 170u8, 21u8, 66u8, 159u8, 174u8, 5u8, 186u8, 212u8, 208u8, + 177u8, 215u8, 198u8, 77u8, 166u8, 77u8, 3u8, 215u8, 161u8, 133u8, 74u8, 88u8, 140u8, 44u8, + 184u8, 67u8, 12u8, 13u8, 48u8, + ], + [ + 216u8, 141u8, 223u8, 238u8, 212u8, 0u8, 168u8, 117u8, 85u8, 150u8, 178u8, 25u8, 66u8, + 193u8, 73u8, 126u8, 17u8, 76u8, 48u8, 46u8, 97u8, 24u8, 41u8, 15u8, 145u8, 230u8, 119u8, + 41u8, 118u8, 4u8, 31u8, 161u8, + ], + [ + 135u8, 235u8, 13u8, 219u8, 165u8, 126u8, 53u8, 246u8, 210u8, 134u8, 103u8, 56u8, 2u8, + 164u8, 175u8, 89u8, 117u8, 226u8, 37u8, 6u8, 199u8, 207u8, 76u8, 100u8, 187u8, 107u8, + 229u8, 238u8, 17u8, 82u8, 127u8, 44u8, + ], + [ + 38u8, 132u8, 100u8, 118u8, 253u8, 95u8, 197u8, 74u8, 93u8, 67u8, 56u8, 81u8, 103u8, 201u8, + 81u8, 68u8, 242u8, 100u8, 63u8, 83u8, 60u8, 200u8, 91u8, 185u8, 209u8, 107u8, 120u8, 47u8, + 141u8, 125u8, 177u8, 147u8, + ], + [ + 80u8, 109u8, 134u8, 88u8, 45u8, 37u8, 36u8, 5u8, 184u8, 64u8, 1u8, 135u8, 146u8, 202u8, + 210u8, 191u8, 18u8, 89u8, 241u8, 239u8, 90u8, 165u8, 248u8, 135u8, 225u8, 60u8, 178u8, + 240u8, 9u8, 79u8, 81u8, 225u8, + ], + [ + 255u8, 255u8, 10u8, 215u8, 230u8, 89u8, 119u8, 47u8, 149u8, 52u8, 193u8, 149u8, 200u8, + 21u8, 239u8, 196u8, 1u8, 78u8, 241u8, 225u8, 218u8, 237u8, 68u8, 4u8, 192u8, 99u8, 133u8, + 209u8, 17u8, 146u8, 233u8, 43u8, + ], + [ + 108u8, 240u8, 65u8, 39u8, 219u8, 5u8, 68u8, 28u8, 216u8, 51u8, 16u8, 122u8, 82u8, 190u8, + 133u8, 40u8, 104u8, 137u8, 14u8, 67u8, 23u8, 230u8, 160u8, 42u8, 180u8, 118u8, 131u8, + 170u8, 117u8, 150u8, 66u8, 32u8, + ], + [ + 183u8, 208u8, 95u8, 135u8, 95u8, 20u8, 0u8, 39u8, 239u8, 81u8, 24u8, 162u8, 36u8, 123u8, + 187u8, 132u8, 206u8, 143u8, 47u8, 15u8, 17u8, 35u8, 98u8, 48u8, 133u8, 218u8, 247u8, 150u8, + 12u8, 50u8, 159u8, 95u8, + ], + [ + 223u8, 106u8, 245u8, 245u8, 187u8, 219u8, 107u8, 233u8, 239u8, 138u8, 166u8, 24u8, 228u8, + 191u8, 128u8, 115u8, 150u8, 8u8, 103u8, 23u8, 30u8, 41u8, 103u8, 111u8, 139u8, 40u8, 77u8, + 234u8, 106u8, 8u8, 168u8, 94u8, + ], + [ + 181u8, 141u8, 144u8, 15u8, 94u8, 24u8, 46u8, 60u8, 80u8, 239u8, 116u8, 150u8, 158u8, 161u8, + 108u8, 119u8, 38u8, 197u8, 73u8, 117u8, 124u8, 194u8, 53u8, 35u8, 195u8, 105u8, 88u8, + 125u8, 167u8, 41u8, 55u8, 132u8, + ], + [ + 212u8, 154u8, 117u8, 2u8, 255u8, 207u8, 176u8, 52u8, 11u8, 29u8, 120u8, 133u8, 104u8, + 133u8, 0u8, 202u8, 48u8, 129u8, 97u8, 167u8, 249u8, 107u8, 98u8, 223u8, 157u8, 8u8, 59u8, + 113u8, 252u8, 200u8, 242u8, 187u8, + ], + [ + 143u8, 230u8, 177u8, 104u8, 146u8, 86u8, 192u8, 211u8, 133u8, 244u8, 47u8, 91u8, 190u8, + 32u8, 39u8, 162u8, 44u8, 25u8, 150u8, 225u8, 16u8, 186u8, 151u8, 193u8, 113u8, 211u8, + 229u8, 148u8, 141u8, 233u8, 43u8, 235u8, + ], + [ + 141u8, 13u8, 99u8, 195u8, 158u8, 186u8, 222u8, 133u8, 9u8, 224u8, 174u8, 60u8, 156u8, 56u8, + 118u8, 251u8, 95u8, 161u8, 18u8, 190u8, 24u8, 249u8, 5u8, 236u8, 172u8, 254u8, 203u8, + 146u8, 5u8, 118u8, 3u8, 171u8, + ], + [ + 149u8, 238u8, 200u8, 178u8, 229u8, 65u8, 202u8, 212u8, 233u8, 29u8, 227u8, 131u8, 133u8, + 242u8, 224u8, 70u8, 97u8, 159u8, 84u8, 73u8, 108u8, 35u8, 130u8, 203u8, 108u8, 172u8, + 213u8, 185u8, 140u8, 38u8, 245u8, 164u8, + ], + [ + 248u8, 147u8, 233u8, 8u8, 145u8, 119u8, 117u8, 182u8, 43u8, 255u8, 35u8, 41u8, 77u8, 187u8, + 227u8, 161u8, 205u8, 142u8, 108u8, 193u8, 195u8, 91u8, 72u8, 1u8, 136u8, 123u8, 100u8, + 106u8, 111u8, 129u8, 241u8, 127u8, + ], + [ + 205u8, 219u8, 167u8, 181u8, 146u8, 227u8, 19u8, 51u8, 147u8, 193u8, 97u8, 148u8, 250u8, + 199u8, 67u8, 26u8, 191u8, 47u8, 84u8, 133u8, 237u8, 113u8, 29u8, 178u8, 130u8, 24u8, 60u8, + 129u8, 158u8, 8u8, 235u8, 170u8, + ], + [ + 138u8, 141u8, 127u8, 227u8, 175u8, 140u8, 170u8, 8u8, 90u8, 118u8, 57u8, 168u8, 50u8, 0u8, + 20u8, 87u8, 223u8, 185u8, 18u8, 138u8, 128u8, 97u8, 20u8, 42u8, 208u8, 51u8, 86u8, 41u8, + 255u8, 35u8, 255u8, 156u8, + ], + [ + 254u8, 179u8, 195u8, 55u8, 215u8, 165u8, 26u8, 111u8, 191u8, 0u8, 185u8, 227u8, 76u8, 82u8, + 225u8, 201u8, 25u8, 92u8, 150u8, 155u8, 212u8, 231u8, 160u8, 191u8, 213u8, 29u8, 92u8, + 91u8, 237u8, 156u8, 17u8, 103u8, + ], + [ + 231u8, 31u8, 10u8, 168u8, 60u8, 195u8, 46u8, 223u8, 190u8, 250u8, 159u8, 77u8, 62u8, 1u8, + 116u8, 202u8, 133u8, 24u8, 46u8, 236u8, 159u8, 58u8, 9u8, 246u8, 166u8, 192u8, 223u8, 99u8, + 119u8, 165u8, 16u8, 215u8, + ], + [ + 49u8, 32u8, 111u8, 168u8, 10u8, 80u8, 187u8, 106u8, 190u8, 41u8, 8u8, 80u8, 88u8, 241u8, + 98u8, 18u8, 33u8, 42u8, 96u8, 238u8, 200u8, 240u8, 73u8, 254u8, 203u8, 146u8, 216u8, 200u8, + 224u8, 168u8, 75u8, 192u8, + ], + [ + 33u8, 53u8, 43u8, 254u8, 203u8, 237u8, 221u8, 233u8, 147u8, 131u8, 159u8, 97u8, 76u8, 61u8, + 172u8, 10u8, 62u8, 227u8, 117u8, 67u8, 249u8, 180u8, 18u8, 177u8, 97u8, 153u8, 220u8, 21u8, + 142u8, 35u8, 181u8, 68u8, + ], + [ + 97u8, 158u8, 49u8, 39u8, 36u8, 187u8, 109u8, 124u8, 49u8, 83u8, 237u8, 157u8, 231u8, 145u8, + 215u8, 100u8, 163u8, 102u8, 179u8, 137u8, 175u8, 19u8, 197u8, 139u8, 248u8, 168u8, 217u8, + 4u8, 129u8, 164u8, 103u8, 101u8, + ], + [ + 124u8, 221u8, 41u8, 134u8, 38u8, 130u8, 80u8, 98u8, 141u8, 12u8, 16u8, 227u8, 133u8, 197u8, + 140u8, 97u8, 145u8, 230u8, 251u8, 224u8, 81u8, 145u8, 188u8, 192u8, 79u8, 19u8, 63u8, 44u8, + 234u8, 114u8, 193u8, 196u8, + ], + [ + 132u8, 137u8, 48u8, 189u8, 123u8, 168u8, 202u8, 197u8, 70u8, 97u8, 7u8, 33u8, 19u8, 251u8, + 39u8, 136u8, 105u8, 224u8, 123u8, 184u8, 88u8, 127u8, 145u8, 57u8, 41u8, 51u8, 55u8, 77u8, + 1u8, 123u8, 203u8, 225u8, + ], + [ + 136u8, 105u8, 255u8, 44u8, 34u8, 178u8, 140u8, 193u8, 5u8, 16u8, 217u8, 133u8, 50u8, 146u8, + 128u8, 51u8, 40u8, 190u8, 79u8, 176u8, 232u8, 4u8, 149u8, 232u8, 187u8, 141u8, 39u8, 31u8, + 91u8, 136u8, 150u8, 54u8, + ], + [ + 181u8, 254u8, 40u8, 231u8, 159u8, 27u8, 133u8, 15u8, 134u8, 88u8, 36u8, 108u8, 233u8, + 182u8, 161u8, 231u8, 180u8, 159u8, 192u8, 109u8, 183u8, 20u8, 62u8, 143u8, 224u8, 180u8, + 242u8, 176u8, 197u8, 82u8, 58u8, 92u8, + ], + [ + 152u8, 94u8, 146u8, 159u8, 112u8, 175u8, 40u8, 208u8, 189u8, 209u8, 169u8, 10u8, 128u8, + 143u8, 151u8, 127u8, 89u8, 124u8, 124u8, 119u8, 140u8, 72u8, 158u8, 152u8, 211u8, 189u8, + 137u8, 16u8, 211u8, 26u8, 192u8, 247u8, + ], + [ + 198u8, 246u8, 126u8, 2u8, 230u8, 228u8, 225u8, 189u8, 239u8, 185u8, 148u8, 198u8, 9u8, + 137u8, 83u8, 243u8, 70u8, 54u8, 186u8, 43u8, 108u8, 162u8, 10u8, 71u8, 33u8, 210u8, 178u8, + 106u8, 136u8, 103u8, 34u8, 255u8, + ], + [ + 28u8, 154u8, 126u8, 95u8, 241u8, 207u8, 72u8, 180u8, 173u8, 21u8, 130u8, 211u8, 244u8, + 228u8, 161u8, 0u8, 79u8, 59u8, 32u8, 216u8, 197u8, 162u8, 183u8, 19u8, 135u8, 164u8, 37u8, + 74u8, 217u8, 51u8, 235u8, 197u8, + ], + [ + 47u8, 7u8, 90u8, 226u8, 41u8, 100u8, 107u8, 111u8, 106u8, 237u8, 25u8, 165u8, 227u8, 114u8, + 207u8, 41u8, 80u8, 129u8, 64u8, 30u8, 184u8, 147u8, 255u8, 89u8, 155u8, 63u8, 154u8, 204u8, + 12u8, 13u8, 62u8, 125u8, + ], + [ + 50u8, 137u8, 33u8, 222u8, 181u8, 150u8, 18u8, 7u8, 104u8, 1u8, 232u8, 205u8, 97u8, 89u8, + 33u8, 7u8, 181u8, 198u8, 124u8, 121u8, 184u8, 70u8, 89u8, 92u8, 198u8, 50u8, 12u8, 57u8, + 91u8, 70u8, 54u8, 44u8, + ], + [ + 191u8, 185u8, 9u8, 253u8, 178u8, 54u8, 173u8, 36u8, 17u8, 180u8, 228u8, 136u8, 56u8, 16u8, + 160u8, 116u8, 184u8, 64u8, 70u8, 70u8, 137u8, 152u8, 108u8, 63u8, 138u8, 128u8, 145u8, + 130u8, 126u8, 23u8, 195u8, 39u8, + ], + [ + 85u8, 216u8, 251u8, 54u8, 135u8, 186u8, 59u8, 164u8, 159u8, 52u8, 44u8, 119u8, 245u8, + 161u8, 248u8, 155u8, 236u8, 131u8, 216u8, 17u8, 68u8, 110u8, 26u8, 70u8, 113u8, 57u8, 33u8, + 61u8, 100u8, 11u8, 106u8, 116u8, + ], + [ + 247u8, 33u8, 13u8, 79u8, 142u8, 126u8, 16u8, 57u8, 121u8, 14u8, 123u8, 244u8, 239u8, 162u8, + 7u8, 85u8, 90u8, 16u8, 166u8, 219u8, 29u8, 212u8, 185u8, 93u8, 163u8, 19u8, 170u8, 168u8, + 139u8, 136u8, 254u8, 118u8, + ], + [ + 173u8, 33u8, 181u8, 22u8, 203u8, 198u8, 69u8, 255u8, 227u8, 74u8, 181u8, 222u8, 28u8, + 138u8, 239u8, 140u8, 212u8, 231u8, 248u8, 210u8, 181u8, 30u8, 142u8, 20u8, 86u8, 173u8, + 199u8, 86u8, 60u8, 218u8, 32u8, 111u8, + ], + [ + 107u8, 254u8, 141u8, 43u8, 204u8, 66u8, 55u8, 183u8, 74u8, 80u8, 71u8, 5u8, 142u8, 244u8, + 85u8, 51u8, 158u8, 205u8, 115u8, 96u8, 203u8, 99u8, 191u8, 187u8, 142u8, 229u8, 68u8, + 142u8, 100u8, 48u8, 186u8, 4u8, + ], +]; diff --git a/hasher/src/zero_indexed_leaf/keccak.rs b/hasher/src/zero_indexed_leaf/keccak.rs new file mode 100644 index 0000000..fbd72fe --- /dev/null +++ b/hasher/src/zero_indexed_leaf/keccak.rs @@ -0,0 +1,7 @@ +// This file is generated by xtask. Do not edit it manually. + +pub const ZERO_INDEXED_LEAF: [u8; 32] = [ + 60u8, 172u8, 49u8, 121u8, 8u8, 198u8, 153u8, 254u8, 135u8, 58u8, 127u8, 110u8, 228u8, 232u8, + 205u8, 99u8, 251u8, 233u8, 145u8, 139u8, 35u8, 21u8, 201u8, 123u8, 233u8, 21u8, 133u8, 89u8, + 1u8, 104u8, 227u8, 1u8, +]; diff --git a/hasher/src/zero_indexed_leaf/mod.rs b/hasher/src/zero_indexed_leaf/mod.rs new file mode 100644 index 0000000..748e118 --- /dev/null +++ b/hasher/src/zero_indexed_leaf/mod.rs @@ -0,0 +1,3 @@ +pub mod keccak; +pub mod poseidon; +pub mod sha256; diff --git a/hasher/src/zero_indexed_leaf/poseidon.rs b/hasher/src/zero_indexed_leaf/poseidon.rs new file mode 100644 index 0000000..9b0a395 --- /dev/null +++ b/hasher/src/zero_indexed_leaf/poseidon.rs @@ -0,0 +1,7 @@ +// This file is generated by xtask. Do not edit it manually. + +pub const ZERO_INDEXED_LEAF: [u8; 32] = [ + 11u8, 193u8, 136u8, 210u8, 125u8, 204u8, 234u8, 220u8, 29u8, 207u8, 182u8, 175u8, 10u8, 122u8, + 240u8, 143u8, 226u8, 134u8, 78u8, 236u8, 236u8, 150u8, 197u8, 174u8, 124u8, 238u8, 109u8, + 179u8, 27u8, 165u8, 153u8, 170u8, +]; diff --git a/hasher/src/zero_indexed_leaf/sha256.rs b/hasher/src/zero_indexed_leaf/sha256.rs new file mode 100644 index 0000000..d648927 --- /dev/null +++ b/hasher/src/zero_indexed_leaf/sha256.rs @@ -0,0 +1,7 @@ +// This file is generated by xtask. Do not edit it manually. + +pub const ZERO_INDEXED_LEAF: [u8; 32] = [ + 131u8, 74u8, 112u8, 155u8, 162u8, 83u8, 78u8, 190u8, 62u8, 225u8, 57u8, 127u8, 212u8, 247u8, + 189u8, 40u8, 139u8, 42u8, 204u8, 29u8, 32u8, 160u8, 141u8, 108u8, 134u8, 45u8, 205u8, 153u8, + 182u8, 240u8, 68u8, 0u8, +]; diff --git a/indexed/Cargo.lock b/indexed/Cargo.lock index 3baf21f..63709cc 100644 --- a/indexed/Cargo.lock +++ b/indexed/Cargo.lock @@ -803,12 +803,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - [[package]] name = "hmac" version = "0.8.1" @@ -959,6 +953,16 @@ dependencies = [ "libsecp256k1-core", ] +[[package]] +name = "light-bounded-vec" +version = "1.1.0" +dependencies = [ + "bytemuck", + "memoffset", + "solana-program", + "thiserror", +] + [[package]] name = "light-bounded-vec" version = "1.1.0" @@ -967,21 +971,18 @@ checksum = "47ced86d6f1b163a04d5d0be44f8bbeedb11d32f73af27812bbd144e0f1f1a42" dependencies = [ "bytemuck", "memoffset", - "solana-program", "thiserror", ] [[package]] name = "light-concurrent-merkle-tree" version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d84ffa991f38260b12f9fb60e7087aeb2d696513936eaee249e6f3e739651a" dependencies = [ "borsh 0.10.4", "bytemuck", - "light-bounded-vec", + "light-bounded-vec 1.1.0", "light-hasher", - "light-utils", + "light-utils 1.1.0", "memoffset", "solana-program", "thiserror", @@ -993,9 +994,9 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7cd392ed4df05a545dfb8a58ef72639fbba9dee7a0605b81c3370d02161932b" dependencies = [ - "light-bounded-vec", + "light-bounded-vec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "light-heap", - "light-utils", + "light-utils 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "memoffset", "num-bigint", "num-traits", @@ -1005,8 +1006,6 @@ dependencies = [ [[package]] name = "light-hasher" version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932ed98282fa564ff4518416de688593a0f425c81d68cfa70e98da21a17a36f" dependencies = [ "ark-bn254", "light-poseidon", @@ -1029,20 +1028,15 @@ dependencies = [ name = "light-indexed-merkle-tree" version = "1.1.0" dependencies = [ - "borsh 0.10.4", - "hex", - "light-bounded-vec", + "light-bounded-vec 1.1.0", "light-concurrent-merkle-tree", "light-hash-set", "light-hasher", "light-merkle-tree-reference", - "light-utils", - "memoffset", + "light-utils 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint", "num-traits", "rand 0.8.5", - "serde", - "serde_json", "solana-program", "thiserror", ] @@ -1050,12 +1044,10 @@ dependencies = [ [[package]] name = "light-merkle-tree-reference" version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9153fd97f1bdba3ec1de6f4c4f20134c6e5e1285676bcb9ef5ebe493f41afa" dependencies = [ - "light-bounded-vec", + "light-bounded-vec 1.1.0", "light-hasher", - "log", + "num-bigint", "thiserror", ] @@ -1071,6 +1063,21 @@ dependencies = [ "thiserror", ] +[[package]] +name = "light-utils" +version = "1.1.0" +dependencies = [ + "anyhow", + "ark-bn254", + "ark-ff", + "light-bounded-vec 1.1.0", + "light-hasher", + "num-bigint", + "rand 0.8.5", + "solana-program", + "thiserror", +] + [[package]] name = "light-utils" version = "1.1.0" @@ -1080,7 +1087,7 @@ dependencies = [ "anyhow", "ark-bn254", "ark-ff", - "light-bounded-vec", + "light-bounded-vec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "num-bigint", "rand 0.8.5", "solana-program", diff --git a/indexed/Cargo.toml b/indexed/Cargo.toml index 7532ea4..48f0ed0 100644 --- a/indexed/Cargo.toml +++ b/indexed/Cargo.toml @@ -13,13 +13,11 @@ solana = [ ] [dependencies] -borsh = { version = "0.10" } -light-bounded-vec = { version = "1.1.0" } -light-hasher = { version = "1.1.0" } -light-concurrent-merkle-tree = { version = "1.1.0" } -light-merkle-tree-reference = { version = "1.1.0" } +light-bounded-vec = { version = "1.1.0", path = "../bounded-vec" } +light-hasher = { version = "1.1.0", path = "../hasher" } +light-concurrent-merkle-tree = { version = "1.1.0", path = "../concurrent" } +light-merkle-tree-reference = { version = "1.1.0", path = "../reference" } light-utils = { version = "1.1.0" } -memoffset = "0.9" num-bigint = "0.4" num-traits = "0.2" @@ -29,7 +27,4 @@ thiserror = "1.0" [dev-dependencies] light-hash-set = { version = "1.1.0" } thiserror = "1.0" -rand = "0.8" -hex = "0.4" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" \ No newline at end of file +rand = "0.8" \ No newline at end of file diff --git a/reference/Cargo.lock b/reference/Cargo.lock new file mode 100644 index 0000000..7f54fd9 --- /dev/null +++ b/reference/Cargo.lock @@ -0,0 +1,1674 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.15", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "anyhow" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" + +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] + +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + +[[package]] +name = "blake3" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "borsh" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" +dependencies = [ + "borsh-derive 0.9.3", + "hashbrown 0.11.2", +] + +[[package]] +name = "borsh" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115e54d64eb62cdebad391c19efc9dce4981c690c85a33a12199d99bb9546fee" +dependencies = [ + "borsh-derive 0.10.4", + "hashbrown 0.13.2", +] + +[[package]] +name = "borsh" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03" +dependencies = [ + "borsh-derive 1.5.3", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" +dependencies = [ + "borsh-derive-internal 0.9.3", + "borsh-schema-derive-internal 0.9.3", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" +dependencies = [ + "borsh-derive-internal 0.10.4", + "borsh-schema-derive-internal 0.10.4", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2593a3b8b938bd68373196c9832f516be11fa487ef4ae745eb282e6a56a7244" +dependencies = [ + "once_cell", + "proc-macro-crate 3.2.0", + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65d6ba50644c98714aa2a70d13d7df3cd75cd2b523a2b452bf010443800976b3" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276691d96f063427be83e6692b86148e488ebba9f48f77788724ca027ba3b6d4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] + +[[package]] +name = "bytemuck" +version = "1.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "cpufeatures" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "serde", + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.8", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.11", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac", +] + +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "rayon", + "serde", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown 0.15.2", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "light-bounded-vec" +version = "1.1.0" +dependencies = [ + "bytemuck", + "memoffset", + "thiserror", +] + +[[package]] +name = "light-hasher" +version = "1.1.0" +dependencies = [ + "ark-bn254", + "light-poseidon", + "sha2 0.10.8", + "sha3", + "solana-program", + "thiserror", +] + +[[package]] +name = "light-merkle-tree-reference" +version = "1.1.0" +dependencies = [ + "light-bounded-vec", + "light-hasher", + "num-bigint", + "thiserror", +] + +[[package]] +name = "light-poseidon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" +dependencies = [ + "ark-bn254", + "ark-ff", + "num-bigint", + "thiserror", +] + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +dependencies = [ + "crypto-mac", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" + +[[package]] +name = "serde" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "serde_json" +version = "1.0.134" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "solana-frozen-abi" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03ab2c30c15311b511c0d1151e4ab6bc9a3e080a37e7c6e7c2d96f5784cf9434" +dependencies = [ + "block-buffer 0.10.4", + "bs58", + "bv", + "either", + "generic-array", + "im", + "lazy_static", + "log", + "memmap2", + "rustc_version", + "serde", + "serde_bytes", + "serde_derive", + "sha2 0.10.8", + "solana-frozen-abi-macro", + "subtle", + "thiserror", +] + +[[package]] +name = "solana-frozen-abi-macro" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c142f779c3633ac83c84d04ff06c70e1f558c876f13358bed77ba629c7417932" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.91", +] + +[[package]] +name = "solana-program" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c10f4588cefd716b24a1a40dd32c278e43a560ab8ce4de6b5805c9d113afdfa1" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "base64 0.21.7", + "bincode", + "bitflags", + "blake3", + "borsh 0.10.4", + "borsh 0.9.3", + "borsh 1.5.3", + "bs58", + "bv", + "bytemuck", + "cc", + "console_error_panic_hook", + "console_log", + "curve25519-dalek", + "getrandom 0.2.15", + "itertools", + "js-sys", + "lazy_static", + "libc", + "libsecp256k1", + "light-poseidon", + "log", + "memoffset", + "num-bigint", + "num-derive", + "num-traits", + "parking_lot", + "rand 0.8.5", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "sha2 0.10.8", + "sha3", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk-macro", + "thiserror", + "tiny-bip39", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "solana-sdk-macro" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b75d0f193a27719257af19144fdaebec0415d1c9e9226ae4bd29b791be5e9bd" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.91", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "tiny-bip39" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" +dependencies = [ + "anyhow", + "hmac", + "once_cell", + "pbkdf2", + "rand 0.7.3", + "rustc-hash", + "sha2 0.9.9", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "tinyvec" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.91", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" + +[[package]] +name = "web-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "zeroize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] diff --git a/reference/Cargo.toml b/reference/Cargo.toml new file mode 100644 index 0000000..6d83d2b --- /dev/null +++ b/reference/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "light-merkle-tree-reference" +version = "1.1.0" +description = "Non-sparse reference Merkle tree implementation" +repository = "https://github.com/Lightprotocol/light-protocol" +license = "Apache-2.0" +edition = "2021" + +[dependencies] +light-bounded-vec = { path = "../bounded-vec", version = "1.1.0" } +light-hasher = { path = "../hasher", version = "1.1.0" } +thiserror = "1.0" +num-bigint = "0.4" \ No newline at end of file diff --git a/reference/src/lib.rs b/reference/src/lib.rs new file mode 100644 index 0000000..2a67a70 --- /dev/null +++ b/reference/src/lib.rs @@ -0,0 +1,375 @@ +pub mod sparse_merkle_tree; + +use std::marker::PhantomData; + +use light_bounded_vec::{BoundedVec, BoundedVecError}; +use light_hasher::{errors::HasherError, Hasher}; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum ReferenceMerkleTreeError { + #[error("Leaf {0} does not exist")] + LeafDoesNotExist(usize), + #[error("Hasher error: {0}")] + Hasher(#[from] HasherError), + #[error("Invalid proof length provided: {0} required {1}")] + InvalidProofLength(usize, usize), +} + +#[derive(Debug, Clone)] +pub struct MerkleTree +where + H: Hasher, +{ + pub height: usize, + pub capacity: usize, + pub canopy_depth: usize, + pub layers: Vec>, + pub roots: Vec<[u8; 32]>, + pub rightmost_index: usize, + pub sequence_number: usize, + + _hasher: PhantomData, +} + +impl MerkleTree +where + H: Hasher, +{ + pub fn new(height: usize, canopy_depth: usize) -> Self { + Self { + height, + capacity: 1 << height, + canopy_depth, + layers: vec![Vec::new(); height], + roots: vec![H::zero_bytes()[height]], + rightmost_index: 0, + sequence_number: 0, + + _hasher: PhantomData, + } + } + + /// Number of nodes to include in canopy, based on `canopy_depth`. + pub fn canopy_size(&self) -> usize { + (1 << (self.canopy_depth + 1)) - 2 + } + + fn update_upper_layers(&mut self, mut i: usize) -> Result<(), HasherError> { + for level in 1..self.height { + i /= 2; + + let left_index = i * 2; + let right_index = i * 2 + 1; + + let left_child = self.layers[level - 1] + .get(left_index) + .cloned() + .unwrap_or(H::zero_bytes()[level - 1]); + let right_child = self.layers[level - 1] + .get(right_index) + .cloned() + .unwrap_or(H::zero_bytes()[level - 1]); + + let node = H::hashv(&[&left_child[..], &right_child[..]])?; + if self.layers[level].len() > i { + // A node already exists and we are overwriting it. + self.layers[level][i] = node; + } else { + // A node didn't exist before. + self.layers[level].push(node); + } + } + + let left_child = &self.layers[self.height - 1] + .first() + .cloned() + .unwrap_or(H::zero_bytes()[self.height - 1]); + let right_child = &self.layers[self.height - 1] + .get(1) + .cloned() + .unwrap_or(H::zero_bytes()[self.height - 1]); + let root = H::hashv(&[&left_child[..], &right_child[..]])?; + + self.roots.push(root); + + Ok(()) + } + + pub fn append(&mut self, leaf: &[u8; 32]) -> Result<(), HasherError> { + self.layers[0].push(*leaf); + + let i = self.rightmost_index; + if self.rightmost_index == self.capacity { + println!("Merkle tree full"); + return Err(HasherError::IntegerOverflow); + } + self.rightmost_index += 1; + + self.update_upper_layers(i)?; + + self.sequence_number += 1; + Ok(()) + } + + pub fn append_batch(&mut self, leaves: &[&[u8; 32]]) -> Result<(), HasherError> { + for leaf in leaves { + self.append(leaf)?; + } + Ok(()) + } + + pub fn update( + &mut self, + leaf: &[u8; 32], + leaf_index: usize, + ) -> Result<(), ReferenceMerkleTreeError> { + *self.layers[0] + .get_mut(leaf_index) + .ok_or(ReferenceMerkleTreeError::LeafDoesNotExist(leaf_index))? = *leaf; + + self.update_upper_layers(leaf_index)?; + + self.sequence_number += 1; + Ok(()) + } + + pub fn root(&self) -> [u8; 32] { + // PANICS: We always initialize the Merkle tree with a + // root (from zero bytes), so the following should never + // panic. + self.roots.last().cloned().unwrap() + } + + pub fn get_path_of_leaf( + &self, + mut index: usize, + full: bool, + ) -> Result, BoundedVecError> { + let mut path = BoundedVec::with_capacity(self.height); + let limit = match full { + true => self.height, + false => self.height - self.canopy_depth, + }; + + for level in 0..limit { + let node = self.layers[level] + .get(index) + .cloned() + .unwrap_or(H::zero_bytes()[level]); + path.push(node)?; + + index /= 2; + } + + Ok(path) + } + + pub fn get_proof_of_leaf( + &self, + mut index: usize, + full: bool, + ) -> Result, BoundedVecError> { + let mut proof = BoundedVec::with_capacity(self.height); + let limit = match full { + true => self.height, + false => self.height - self.canopy_depth, + }; + + for level in 0..limit { + let is_left = index % 2 == 0; + + let sibling_index = if is_left { index + 1 } else { index - 1 }; + let node = self.layers[level] + .get(sibling_index) + .cloned() + .unwrap_or(H::zero_bytes()[level]); + proof.push(node)?; + + index /= 2; + } + + Ok(proof) + } + + pub fn get_canopy(&self) -> Result, BoundedVecError> { + if self.canopy_depth == 0 { + return Ok(BoundedVec::with_capacity(0)); + } + let mut canopy = BoundedVec::with_capacity(self.canopy_size()); + + let mut num_nodes_in_level = 2; + for i in 0..self.canopy_depth { + let level = self.height - 1 - i; + for j in 0..num_nodes_in_level { + let node = self.layers[level] + .get(j) + .cloned() + .unwrap_or(H::zero_bytes()[level]); + canopy.push(node)?; + } + num_nodes_in_level *= 2; + } + + Ok(canopy) + } + + pub fn leaf(&self, leaf_index: usize) -> [u8; 32] { + self.layers[0] + .get(leaf_index) + .cloned() + .unwrap_or(H::zero_bytes()[0]) + } + + pub fn get_leaf_index(&self, leaf: &[u8; 32]) -> Option { + self.layers[0].iter().position(|node| node == leaf) + } + + pub fn leaves(&self) -> &[[u8; 32]] { + self.layers[0].as_slice() + } + + pub fn verify( + &self, + leaf: &[u8; 32], + proof: &BoundedVec<[u8; 32]>, + leaf_index: usize, + ) -> Result { + if leaf_index >= self.capacity { + return Err(ReferenceMerkleTreeError::LeafDoesNotExist(leaf_index)); + } + if proof.len() != self.height { + return Err(ReferenceMerkleTreeError::InvalidProofLength( + proof.len(), + self.height, + )); + } + + let mut computed_hash = *leaf; + let mut current_index = leaf_index; + + for sibling_hash in proof.iter() { + let is_left = current_index % 2 == 0; + let hashes = if is_left { + [&computed_hash[..], &sibling_hash[..]] + } else { + [&sibling_hash[..], &computed_hash[..]] + }; + + computed_hash = H::hashv(&hashes)?; + // Move to the parent index for the next iteration + current_index /= 2; + } + + // Compare the computed hash to the last known root + Ok(computed_hash == self.root()) + } + + /// Returns the filled subtrees of the Merkle tree. + /// Subtrees are the rightmost left node of each level. + /// Subtrees can be used for efficient append operations. + pub fn get_subtrees(&self) -> Vec<[u8; 32]> { + let mut subtrees = H::zero_bytes()[0..self.height].to_vec(); + if self.layers.last().and_then(|layer| layer.first()).is_some() { + for level in (0..self.height).rev() { + if let Some(left_child) = self.layers.get(level).and_then(|layer| { + if layer.len() % 2 == 0 { + layer.get(layer.len() - 2) + } else { + layer.last() + } + }) { + subtrees[level] = *left_child; + } + } + } + subtrees + } + + pub fn get_next_index(&self) -> usize { + self.rightmost_index + 1 + } + + pub fn get_leaf(&self, index: usize) -> Result<[u8; 32], ReferenceMerkleTreeError> { + self.layers[0] + .get(index) + .cloned() + .ok_or(ReferenceMerkleTreeError::LeafDoesNotExist(index)) + } +} + +#[cfg(test)] +mod tests { + use light_hasher::{zero_bytes::poseidon::ZERO_BYTES, Poseidon}; + + use super::*; + + const TREE_AFTER_1_UPDATE: [[u8; 32]; 4] = [ + [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, + ], + [ + 0, 122, 243, 70, 226, 211, 4, 39, 158, 121, 224, 169, 243, 2, 63, 119, 18, 148, 167, + 138, 203, 112, 231, 63, 144, 175, 226, 124, 173, 64, 30, 129, + ], + [ + 4, 163, 62, 195, 162, 201, 237, 49, 131, 153, 66, 155, 106, 112, 192, 40, 76, 131, 230, + 239, 224, 130, 106, 36, 128, 57, 172, 107, 60, 247, 103, 194, + ], + [ + 7, 118, 172, 114, 242, 52, 137, 62, 111, 106, 113, 139, 123, 161, 39, 255, 86, 13, 105, + 167, 223, 52, 15, 29, 137, 37, 106, 178, 49, 44, 226, 75, + ], + ]; + + const TREE_AFTER_2_UPDATES: [[u8; 32]; 4] = [ + [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, + ], + [ + 0, 122, 243, 70, 226, 211, 4, 39, 158, 121, 224, 169, 243, 2, 63, 119, 18, 148, 167, + 138, 203, 112, 231, 63, 144, 175, 226, 124, 173, 64, 30, 129, + ], + [ + 18, 102, 129, 25, 152, 42, 192, 218, 100, 215, 169, 202, 77, 24, 100, 133, 45, 152, 17, + 121, 103, 9, 187, 226, 182, 36, 35, 35, 126, 255, 244, 140, + ], + [ + 11, 230, 92, 56, 65, 91, 231, 137, 40, 92, 11, 193, 90, 225, 123, 79, 82, 17, 212, 147, + 43, 41, 126, 223, 49, 2, 139, 211, 249, 138, 7, 12, + ], + ]; + + #[test] + fn test_subtrees() { + let tree_depth = 4; + let mut tree = MerkleTree::::new(tree_depth, 0); + + let subtrees = tree.get_subtrees(); + for (i, subtree) in subtrees.iter().enumerate() { + assert_eq!(*subtree, ZERO_BYTES[i]); + } + + let mut leaf_0: [u8; 32] = [0; 32]; + leaf_0[31] = 1; + tree.append(&leaf_0).unwrap(); + tree.append(&leaf_0).unwrap(); + + let subtrees = tree.get_subtrees(); + for (i, subtree) in subtrees.iter().enumerate() { + assert_eq!(*subtree, TREE_AFTER_1_UPDATE[i]); + } + + let mut leaf_1: [u8; 32] = [0; 32]; + leaf_1[31] = 2; + tree.append(&leaf_1).unwrap(); + tree.append(&leaf_1).unwrap(); + + let subtrees = tree.get_subtrees(); + for (i, subtree) in subtrees.iter().enumerate() { + assert_eq!(*subtree, TREE_AFTER_2_UPDATES[i]); + } + } +} diff --git a/reference/src/sparse_merkle_tree.rs b/reference/src/sparse_merkle_tree.rs new file mode 100644 index 0000000..f98a002 --- /dev/null +++ b/reference/src/sparse_merkle_tree.rs @@ -0,0 +1,114 @@ +use std::marker::PhantomData; + +use light_hasher::Hasher; +use num_bigint::BigUint; + +#[derive(Clone, Debug)] +pub struct SparseMerkleTree { + subtrees: [[u8; 32]; HEIGHT], + next_index: usize, + root: [u8; 32], + _hasher: PhantomData, +} + +impl SparseMerkleTree +where + H: Hasher, +{ + pub fn new(subtrees: [[u8; 32]; HEIGHT], next_index: usize) -> Self { + Self { + subtrees, + next_index, + root: [0u8; 32], + _hasher: PhantomData, + } + } + + pub fn new_empty() -> Self { + Self { + subtrees: H::zero_bytes()[0..HEIGHT].try_into().unwrap(), + next_index: 0, + root: H::zero_bytes()[HEIGHT], + _hasher: PhantomData, + } + } + + pub fn append(&mut self, leaf: [u8; 32]) -> [[u8; 32]; HEIGHT] { + let mut current_index = self.next_index; + let mut current_level_hash = leaf; + let mut left; + let mut right; + let mut proof: [[u8; 32]; HEIGHT] = [[0u8; 32]; HEIGHT]; + + for (i, (subtree, zero_byte)) in self + .subtrees + .iter_mut() + .zip(H::zero_bytes().iter()) + .enumerate() + { + if current_index % 2 == 0 { + left = current_level_hash; + right = *zero_byte; + *subtree = current_level_hash; + proof[i] = right; + } else { + left = *subtree; + right = current_level_hash; + proof[i] = left; + } + current_level_hash = H::hashv(&[&left, &right]).unwrap(); + current_index /= 2; + } + self.root = current_level_hash; + self.next_index += 1; + + proof + } + + pub fn root(&self) -> [u8; 32] { + self.root + } + + pub fn get_subtrees(&self) -> [[u8; 32]; HEIGHT] { + self.subtrees + } + + pub fn get_height(&self) -> usize { + HEIGHT + } + + pub fn get_next_index(&self) -> usize { + self.next_index + } +} + +pub fn arr_to_string(arr: [u8; 32]) -> String { + format!("0x{}", BigUint::from_bytes_be(&arr).to_str_radix(16)) +} + +#[cfg(test)] +mod test { + use light_hasher::Poseidon; + + use super::*; + use crate::MerkleTree; + + #[test] + fn test_sparse_merkle_tree() { + let height = 10; + let mut merkle_tree = SparseMerkleTree::::new_empty(); + let mut reference_merkle_tree = MerkleTree::::new(height, 0); + for i in 0..1 << height { + let mut leaf = [0u8; 32]; + leaf[24..].copy_from_slice(&(i as u64).to_be_bytes()); + println!("i: {}, leaf: {:?}", i, leaf); + merkle_tree.append(leaf); + reference_merkle_tree.append(&leaf).unwrap(); + assert_eq!(merkle_tree.root(), reference_merkle_tree.root()); + assert_eq!(merkle_tree.get_next_index(), i + 1); + let subtrees = merkle_tree.get_subtrees(); + let reference_subtrees = reference_merkle_tree.get_subtrees(); + assert_eq!(subtrees.to_vec(), reference_subtrees); + } + } +} diff --git a/reference/tests/tests.rs b/reference/tests/tests.rs new file mode 100644 index 0000000..eca4d0a --- /dev/null +++ b/reference/tests/tests.rs @@ -0,0 +1,732 @@ +use light_bounded_vec::BoundedVec; +use light_hasher::{Hasher, Keccak, Poseidon, Sha256}; +use light_merkle_tree_reference::MerkleTree; + +fn append(canopy_depth: usize) +where + H: Hasher, +{ + const HEIGHT: usize = 4; + + let mut mt = MerkleTree::::new(4, canopy_depth); + + let leaf_1 = [1_u8; 32]; + mt.append(&leaf_1).unwrap(); + + // The hash of our new leaf and its sibling (a zero value). + // + // H1 + // / \ + // L1 Z[0] + let h1 = H::hashv(&[&leaf_1, &H::zero_bytes()[0]]).unwrap(); + + // The hash of `h1` and its sibling (a subtree represented by `Z[1]`). + // + // H2 + // /-/ \-\ + // H1 Z[1] + // / \ / \ + // L1 Z[0] Z[0] Z[0] + // + // `Z[1]` represents the whole subtree on the right from `h2`. In the next + // examples, we are just going to show empty subtrees instead of the whole + // hierarchy. + let h2 = H::hashv(&[&h1, &H::zero_bytes()[1]]).unwrap(); + + // The hash of `h3` and its sibling (a subtree represented by `Z[2]`). + // + // H3 + // / \ + // H2 Z[2] + // / \ + // H1 Z[1] + // / \ + // L1 Z[0] + let h3 = H::hashv(&[&h2, &H::zero_bytes()[2]]).unwrap(); + + // The hash of `h4` and its sibling (a subtree represented by `Z[3]`), + // which is the root. + // + // R + // / \ + // H3 Z[3] + // / \ + // H2 Z[2] + // / \ + // H1 Z[1] + // / \ + // L1 Z[0] + let expected_root = H::hashv(&[&h3, &H::zero_bytes()[3]]).unwrap(); + assert_eq!(mt.root(), expected_root); + + // The Merkle path of L1 consists of nodes from L1 up to the root. + // In this case: L1, H1, H2, H3. + // + // R + // / \ + // *H3* Z[3] + // / \ + // *H2* Z[2] + // / \ + // *H1* Z[1] + // / \ + // *L1* Z[0] + let expected_merkle_path = &[leaf_1, h1, h2, h3]; + + let full_merkle_path = mt.get_path_of_leaf(0, true).unwrap(); + assert_eq!(full_merkle_path.as_slice(), expected_merkle_path); + + let partial_merkle_path = mt.get_path_of_leaf(0, false).unwrap(); + assert_eq!( + partial_merkle_path.as_slice(), + &expected_merkle_path[..HEIGHT - canopy_depth] + ); + + // The Merkle proof consists of siblings of L1 and all its parent + // nodes. In this case, these are just zero bytes: Z[0], Z[1], Z[2], + // Z[3]. + // + // R + // / \ + // H3 *Z[3]* + // / \ + // H2 *Z[2]* + // / \ + // H1 *Z[1]* + // / \ + // L1 *Z[0]* + let expected_merkle_proof = &H::zero_bytes()[..HEIGHT]; + + let full_merkle_proof = mt.get_proof_of_leaf(0, true).unwrap(); + assert_eq!(full_merkle_proof.as_slice(), expected_merkle_proof); + + let partial_merkle_proof = mt.get_proof_of_leaf(0, false).unwrap(); + assert_eq!( + partial_merkle_proof.as_slice(), + &expected_merkle_proof[..HEIGHT - canopy_depth] + ); + + // Appending the 2nd leaf should result in recomputing the root due to the + // change of the `h1`, which now is a hash of the two non-zero leafs. So + // when computing hashes from H2 up to the root, we are still going to use + // zero bytes. + // + // The other subtrees still remain the same. + // + // R + // / \ + // H3 Z[3] + // / \ + // H2 Z[2] + // / \ + // H1 Z[1] + // / \ + // L1 L2 + let leaf_2 = H::hash(&[2u8; 32]).unwrap(); + mt.append(&leaf_2).unwrap(); + + let h1 = H::hashv(&[&leaf_1, &leaf_2]).unwrap(); + let h2 = H::hashv(&[&h1, &H::zero_bytes()[1]]).unwrap(); + let h3 = H::hashv(&[&h2, &H::zero_bytes()[2]]).unwrap(); + + let expected_root = H::hashv(&[&h3, &H::zero_bytes()[3]]).unwrap(); + assert_eq!(mt.root(), expected_root); + + // The Merkle path of L2 consists of nodes from L2 up to the root. + // In this case: L2, H1, H2, H3. + // + // R + // / \ + // *H3* Z[3] + // / \ + // *H2* Z[2] + // / \ + // *H1* Z[1] + // / \ + // L1 *L2* + let expected_merkle_path = &[leaf_2, h1, h2, h3]; + + let full_merkle_path = mt.get_path_of_leaf(1, true).unwrap(); + assert_eq!(full_merkle_path.as_slice(), expected_merkle_path); + + let partial_merkle_path = mt.get_path_of_leaf(1, false).unwrap(); + assert_eq!( + partial_merkle_path.as_slice(), + &expected_merkle_path[..HEIGHT - canopy_depth] + ); + + // The Merkle proof consists of siblings of L2 and all its parent + // nodes. In this case, these are: L1, Z[1], Z[2], Z[3]. + // + // R + // / \ + // H3 *Z[3]* + // / \ + // H2 *Z[2]* + // / \ + // H1 *Z[1]* + // / \ + // *L1* L2 + let expected_merkle_proof = &[ + leaf_1, + H::zero_bytes()[1], + H::zero_bytes()[2], + H::zero_bytes()[3], + ]; + + let full_merkle_proof = mt.get_proof_of_leaf(1, true).unwrap(); + assert_eq!(full_merkle_proof.as_slice(), expected_merkle_proof); + + let partial_merkle_proof = mt.get_proof_of_leaf(1, false).unwrap(); + assert_eq!( + partial_merkle_proof.as_slice(), + &expected_merkle_proof[..HEIGHT - canopy_depth] + ); + + // Appending the 3rd leaf alters the next subtree on the right. + // Instead of using Z[1], we will end up with the hash of the new leaf and + // Z[0]. + // + // The other subtrees still remain the same. + // + // R + // / \ + // H4 Z[3] + // / \ + // H3 Z[2] + // / \ + // H1 H2 + // / \ / \ + // L1 L2 L3 Z[0] + let leaf_3 = H::hash(&[3u8; 32]).unwrap(); + mt.append(&leaf_3).unwrap(); + + let h1 = H::hashv(&[&leaf_1, &leaf_2]).unwrap(); + let h2 = H::hashv(&[&leaf_3, &H::zero_bytes()[0]]).unwrap(); + let h3 = H::hashv(&[&h1, &h2]).unwrap(); + let h4 = H::hashv(&[&h3, &H::zero_bytes()[2]]).unwrap(); + + let expected_root = H::hashv(&[&h4, &H::zero_bytes()[3]]).unwrap(); + assert_eq!(mt.root(), expected_root); + + // The Merkle path of L3 consists of nodes from L3 up to the root. + // In this case: L3, H2, H3, H4. + // + // R + // / \ + // *H4* Z[3] + // / \ + // *H3* Z[2] + // / \ + // H1 *H2* + // / \ / \ + // L1 L2 *L3* Z[0] + let expected_merkle_path = &[leaf_3, h2, h3, h4]; + + let full_merkle_path = mt.get_path_of_leaf(2, true).unwrap(); + assert_eq!(full_merkle_path.as_slice(), expected_merkle_path); + + let partial_merkle_path = mt.get_path_of_leaf(2, false).unwrap(); + assert_eq!( + partial_merkle_path.as_slice(), + &expected_merkle_path[..HEIGHT - canopy_depth] + ); + + // The Merkle proof consists of siblings of L2 and all its parent + // nodes. In this case, these are: Z[0], H1, Z[2], Z[3]. + // + // R + // / \ + // H4 *Z[3]* + // / \ + // H3 *Z[2]* + // / \ + // *H1* H2 + // / \ / \ + // L1 L2 L3 *Z[0]* + let expected_merkle_proof = &[ + H::zero_bytes()[0], + h1, + H::zero_bytes()[2], + H::zero_bytes()[3], + ]; + + let full_merkle_proof = mt.get_proof_of_leaf(2, true).unwrap(); + assert_eq!(full_merkle_proof.as_slice(), expected_merkle_proof); + + let partial_merkle_proof = mt.get_proof_of_leaf(2, false).unwrap(); + assert_eq!( + partial_merkle_proof.as_slice(), + &expected_merkle_proof[..HEIGHT - canopy_depth] + ); + + // Appending the 4th leaf alters the next subtree on the right. + // Instead of using Z[1], we will end up with the hash of the new leaf and + // Z[0]. + // + // The other subtrees still remain the same. + // + // R + // / \ + // H4 Z[3] + // / \ + // H3 Z[2] + // / \ + // H1 H2 + // / \ / \ + // L1 L2 L3 L4 + let leaf_4 = H::hash(&[4u8; 32]).unwrap(); + mt.append(&leaf_4).unwrap(); + + let h1 = H::hashv(&[&leaf_1, &leaf_2]).unwrap(); + let h2 = H::hashv(&[&leaf_3, &leaf_4]).unwrap(); + let h3 = H::hashv(&[&h1, &h2]).unwrap(); + let h4 = H::hashv(&[&h3, &H::zero_bytes()[2]]).unwrap(); + + let expected_root = H::hashv(&[&h4, &H::zero_bytes()[3]]).unwrap(); + assert_eq!(mt.root(), expected_root); +} + +#[test] +fn test_append_keccak_4_0() { + append::(0) +} + +#[test] +fn test_append_poseidon_4_0() { + append::(0) +} + +#[test] +fn test_append_sha256_4_0() { + append::(0) +} + +#[test] +fn test_append_keccak_4_1() { + append::(1) +} + +#[test] +fn test_append_poseidon_4_1() { + append::(1) +} + +#[test] +fn test_append_sha256_4_1() { + append::(1) +} + +#[test] +fn test_append_keccak_4_2() { + append::(2) +} + +#[test] +fn test_append_poseidon_4_2() { + append::(2) +} + +#[test] +fn test_append_sha256_4_2() { + append::(2) +} + +fn update() +where + H: Hasher, +{ + const HEIGHT: usize = 4; + const CANOPY: usize = 0; + + let mut merkle_tree = MerkleTree::::new(HEIGHT, CANOPY); + + let leaf1 = H::hash(&[1u8; 32]).unwrap(); + + // The hash of our new leaf and its sibling (a zero value). + // + // H1 + // / \ + // L1 Z[0] + let h1 = H::hashv(&[&leaf1, &H::zero_bytes()[0]]).unwrap(); + + // The hash of `h1` and its sibling (a subtree represented by `Z[1]`). + // + // H2 + // /-/ \-\ + // H1 Z[1] + // / \ / \ + // L1 Z[0] Z[0] Z[0] + // + // `Z[1]` represents the whole subtree on the right from `h2`. In the next + // examples, we are just going to show empty subtrees instead of the whole + // hierarchy. + let h2 = H::hashv(&[&h1, &H::zero_bytes()[1]]).unwrap(); + + // The hash of `h3` and its sibling (a subtree represented by `Z[2]`). + // + // H3 + // / \ + // H2 Z[2] + // / \ + // H1 Z[1] + // / \ + // L1 Z[0] + let h3 = H::hashv(&[&h2, &H::zero_bytes()[2]]).unwrap(); + + // The hash of `h4` and its sibling (a subtree represented by `Z[3]`), + // which is the root. + // + // R + // / \ + // H3 Z[3] + // / \ + // H2 Z[2] + // / \ + // H1 Z[1] + // / \ + // L1 Z[0] + let expected_root = H::hashv(&[&h3, &H::zero_bytes()[3]]).unwrap(); + // The Merkle path is: + // [L1, H1, H2, H3] + let expected_path = BoundedVec::from_array(&[leaf1, h1, h2, h3]); + let expected_proof = BoundedVec::from_array(&[ + H::zero_bytes()[0], + H::zero_bytes()[1], + H::zero_bytes()[2], + H::zero_bytes()[3], + ]); + + merkle_tree.append(&leaf1).unwrap(); + + assert_eq!(merkle_tree.root(), expected_root); + assert_eq!( + merkle_tree.get_path_of_leaf(0, false).unwrap(), + expected_path + ); + assert_eq!( + merkle_tree.get_proof_of_leaf(0, false).unwrap(), + expected_proof + ); + + // Appending the 2nd leaf should result in recomputing the root due to the + // change of the `h1`, which now is a hash of the two non-zero leafs. So + // when computing all hashes up to the root, we are still going to use + // zero bytes from 1 to 8. + // + // The other subtrees still remain the same. + // + // R + // / \ + // H3 Z[3] + // / \ + // H2 Z[2] + // / \ + // H1 Z[1] + // / \ + // L1 L2 + let leaf2 = H::hash(&[2u8; 32]).unwrap(); + + let h1 = H::hashv(&[&leaf1, &leaf2]).unwrap(); + let h2 = H::hashv(&[&h1, &H::zero_bytes()[1]]).unwrap(); + let h3 = H::hashv(&[&h2, &H::zero_bytes()[2]]).unwrap(); + let expected_root = H::hashv(&[&h3, &H::zero_bytes()[3]]).unwrap(); + // The Merkle path is: + // [L2, H1, H2, H3] + let expected_path = BoundedVec::from_array(&[leaf2, h1, h2, h3]); + let expected_proof = BoundedVec::from_array(&[ + leaf1, + H::zero_bytes()[1], + H::zero_bytes()[2], + H::zero_bytes()[3], + ]); + + merkle_tree.append(&leaf2).unwrap(); + + assert_eq!(merkle_tree.root(), expected_root); + assert_eq!( + merkle_tree.get_path_of_leaf(1, false).unwrap(), + expected_path + ); + assert_eq!( + merkle_tree.get_proof_of_leaf(1, false).unwrap(), + expected_proof + ); + + // Appending the 3rd leaf alters the next subtree on the right. + // Instead of using Z[1], we will end up with the hash of the new leaf and + // Z[0]. + // + // The other subtrees still remain the same. + // + // R + // / \ + // H4 Z[3] + // / \ + // H3 Z[2] + // / \ + // H1 H2 + // / \ / \ + // L1 L2 L3 Z[0] + let leaf3 = H::hash(&[3u8; 32]).unwrap(); + + let h1 = H::hashv(&[&leaf1, &leaf2]).unwrap(); + let h2 = H::hashv(&[&leaf3, &H::zero_bytes()[0]]).unwrap(); + let h3 = H::hashv(&[&h1, &h2]).unwrap(); + let h4 = H::hashv(&[&h3, &H::zero_bytes()[2]]).unwrap(); + let expected_root = H::hashv(&[&h4, &H::zero_bytes()[3]]).unwrap(); + // The Merkle path is: + // [L3, H2, H3, H4] + let expected_path = BoundedVec::from_array(&[leaf3, h2, h3, h4]); + let expected_proof = BoundedVec::from_array(&[ + H::zero_bytes()[0], + h1, + H::zero_bytes()[2], + H::zero_bytes()[3], + ]); + + merkle_tree.append(&leaf3).unwrap(); + + assert_eq!(merkle_tree.root(), expected_root); + assert_eq!( + merkle_tree.get_path_of_leaf(2, false).unwrap(), + expected_path + ); + assert_eq!( + merkle_tree.get_proof_of_leaf(2, false).unwrap(), + expected_proof + ); + + // Appending the 4th leaf alters the next subtree on the right. + // Instead of using Z[1], we will end up with the hash of the new leaf and + // Z[0]. + // + // The other subtrees still remain the same. + // + // R + // / \ + // H4 Z[3] + // / \ + // H3 Z[2] + // / \ + // H1 H2 + // / \ / \ + // L1 L2 L3 L4 + let leaf4 = H::hash(&[4u8; 32]).unwrap(); + + let h1 = H::hashv(&[&leaf1, &leaf2]).unwrap(); + let h2 = H::hashv(&[&leaf3, &leaf4]).unwrap(); + let h3 = H::hashv(&[&h1, &h2]).unwrap(); + let h4 = H::hashv(&[&h3, &H::zero_bytes()[2]]).unwrap(); + let expected_root = H::hashv(&[&h4, &H::zero_bytes()[3]]).unwrap(); + // The Merkle path is: + // [L4, H2, H3, H4] + let expected_path = BoundedVec::from_array(&[leaf4, h2, h3, h4]); + let expected_proof = + BoundedVec::from_array(&[leaf3, h1, H::zero_bytes()[2], H::zero_bytes()[3]]); + + merkle_tree.append(&leaf4).unwrap(); + + assert_eq!(merkle_tree.root(), expected_root); + assert_eq!( + merkle_tree.get_path_of_leaf(3, false).unwrap(), + expected_path + ); + assert_eq!( + merkle_tree.get_proof_of_leaf(3, false).unwrap(), + expected_proof + ); + + // Update `leaf1`. + let new_leaf1 = [9u8; 32]; + + // Updating L1 affects H1 and all parent hashes up to the root. + // + // R + // / \ + // *H4* Z[3] + // / \ + // *H3* Z[2] + // / \ + // *H1* H2 + // / \ / \ + // *L1* L2 L3 L4 + // + // Merkle proof for the replaced leaf L1 is: + // [L2, H2, Z[2], Z[3]] + // + // Our Merkle tree implementation should be smart enough to fill up the + // proof with zero bytes, so we can skip them and just define the proof as: + // [L2, H2] + merkle_tree.update(&new_leaf1, 0).unwrap(); + + let h1 = H::hashv(&[&new_leaf1, &leaf2]).unwrap(); + let h2 = H::hashv(&[&leaf3, &leaf4]).unwrap(); + let h3 = H::hashv(&[&h1, &h2]).unwrap(); + let h4 = H::hashv(&[&h3, &H::zero_bytes()[2]]).unwrap(); + let expected_root = H::hashv(&[&h4, &H::zero_bytes()[3]]).unwrap(); + // The Merkle path is: + // [L1, H1, H3, H4] + let expected_path = BoundedVec::from_array(&[new_leaf1, h1, h3, h4]); + let expected_proof = + BoundedVec::from_array(&[leaf2, h2, H::zero_bytes()[2], H::zero_bytes()[3]]); + + assert_eq!(merkle_tree.root(), expected_root); + assert_eq!( + merkle_tree.get_path_of_leaf(0, false).unwrap(), + expected_path + ); + assert_eq!( + merkle_tree.get_proof_of_leaf(0, false).unwrap(), + expected_proof + ); + + // Update `leaf2`. + let new_leaf2 = H::hash(&[8u8; 32]).unwrap(); + + // Updating L2 affects H1 and all parent hashes up to the root. + // + // R + // / \ + // *H4* Z[3] + // / \ + // *H3* Z[2] + // / \ + // *H1* H2 + // / \ / \ + // L1 *L2* L3 L4 + // + // Merkle proof for the replaced leaf L2 is: + // [L1, H2] + merkle_tree.update(&new_leaf2, 1).unwrap(); + + let h1 = H::hashv(&[&new_leaf1, &new_leaf2]).unwrap(); + let h2 = H::hashv(&[&leaf3, &leaf4]).unwrap(); + let h3 = H::hashv(&[&h1, &h2]).unwrap(); + let h4 = H::hashv(&[&h3, &H::zero_bytes()[2]]).unwrap(); + let expected_root = H::hashv(&[&h4, &H::zero_bytes()[3]]).unwrap(); + // The Merkle path is: + // [L2, H1, H3, H4] + let expected_path = BoundedVec::from_array(&[new_leaf2, h1, h3, h4]); + let expected_proof = + BoundedVec::from_array(&[new_leaf1, h2, H::zero_bytes()[2], H::zero_bytes()[3]]); + + assert_eq!(merkle_tree.root(), expected_root); + assert_eq!( + merkle_tree.get_path_of_leaf(1, false).unwrap(), + expected_path + ); + assert_eq!( + merkle_tree.get_proof_of_leaf(1, false).unwrap(), + expected_proof + ); + + // Update `leaf3`. + let new_leaf3 = H::hash(&[7u8; 32]).unwrap(); + + // Updating L3 affects H1 and all parent hashes up to the root. + // + // R + // / \ + // *H4* Z[3] + // / \ + // *H3* Z[2] + // / \ + // H1 *H2* + // / \ / \ + // L1 L2 *L3* L4 + // + // Merkle proof for the replaced leaf L3 is: + // [L4, H1] + merkle_tree.update(&new_leaf3, 2).unwrap(); + + let h1 = H::hashv(&[&new_leaf1, &new_leaf2]).unwrap(); + let h2 = H::hashv(&[&new_leaf3, &leaf4]).unwrap(); + let h3 = H::hashv(&[&h1, &h2]).unwrap(); + let h4 = H::hashv(&[&h3, &H::zero_bytes()[2]]).unwrap(); + let expected_root = H::hashv(&[&h4, &H::zero_bytes()[3]]).unwrap(); + // The Merkle path is: + // [L3, H2, H3, H4] + let expected_path = BoundedVec::from_array(&[new_leaf3, h2, h3, h4]); + let expected_proof = + BoundedVec::from_array(&[leaf4, h1, H::zero_bytes()[2], H::zero_bytes()[3]]); + + assert_eq!(merkle_tree.root(), expected_root); + assert_eq!( + merkle_tree.get_path_of_leaf(2, false).unwrap(), + expected_path + ); + assert_eq!( + merkle_tree.get_proof_of_leaf(2, false).unwrap(), + expected_proof + ); + + // Update `leaf4`. + let new_leaf4 = H::hash(&[6u8; 32]).unwrap(); + + // Updating L4 affects H1 and all parent hashes up to the root. + // + // R + // / \ + // *H4* Z[3] + // / \ + // *H3* Z[2] + // / \ + // H1 *H2* + // / \ / \ + // L1 L2 L3 *L4* + // + // Merkle proof for the replaced leaf L4 is: + // [L3, H1] + merkle_tree.update(&new_leaf4, 3).unwrap(); + + let h1 = H::hashv(&[&new_leaf1, &new_leaf2]).unwrap(); + let h2 = H::hashv(&[&new_leaf3, &new_leaf4]).unwrap(); + let h3 = H::hashv(&[&h1, &h2]).unwrap(); + let h4 = H::hashv(&[&h3, &H::zero_bytes()[2]]).unwrap(); + let expected_root = H::hashv(&[&h4, &H::zero_bytes()[3]]).unwrap(); + // The Merkle path is: + // [L4, H2, H3, H4] + let expected_path = BoundedVec::from_array(&[new_leaf4, h2, h3, h4]); + let expected_proof = + BoundedVec::from_array(&[new_leaf3, h1, H::zero_bytes()[2], H::zero_bytes()[3]]); + + assert_eq!(merkle_tree.root(), expected_root); + assert_eq!( + merkle_tree.get_path_of_leaf(3, false).unwrap(), + expected_path + ); + assert_eq!( + merkle_tree.get_proof_of_leaf(3, false).unwrap(), + expected_proof + ); +} + +#[test] +fn test_update_keccak() { + update::() +} + +#[test] +fn test_update_poseidon() { + update::() +} + +#[test] +fn test_update_sha256() { + update::() +} + +#[test] +fn test_sequence_number() { + let mut merkle_tree = MerkleTree::::new(4, 0); + assert_eq!(merkle_tree.sequence_number, 0); + + let leaf1 = Poseidon::hash(&[1u8; 32]).unwrap(); + merkle_tree.append(&leaf1).unwrap(); + assert_eq!(merkle_tree.sequence_number, 1); + + let leaf2 = Poseidon::hash(&[2u8; 32]).unwrap(); + merkle_tree.update(&leaf2, 0).unwrap(); + assert_eq!(merkle_tree.sequence_number, 2); +} diff --git a/utils/Cargo.toml b/utils/Cargo.toml new file mode 100644 index 0000000..564d3ac --- /dev/null +++ b/utils/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "light-utils" +version = "1.1.0" +description = "Common utility functions used in Light Protocol" +repository = "https://github.com/Lightprotocol/light-protocol" +license = "Apache-2.0" +edition = "2021" + +[dependencies] +anyhow = "1.0" +ark-ff = "0.4" +light-bounded-vec = { version = "1.1.0", path = "../bounded-vec" } +light-hasher = { version = "1.1.0", path = "../hasher" } +num-bigint = { version = "0.4", features = ["rand"] } +thiserror = "1.0" +solana-program = { version = "1.18.22" } +ark-bn254 = "0.4.0" +rand = "0.8" + +[dev-dependencies] +bytemuck = "1.17" +memoffset = "0.9" +light-poseidon = "0.2.0" \ No newline at end of file diff --git a/utils/src/bigint.rs b/utils/src/bigint.rs new file mode 100644 index 0000000..151bf6b --- /dev/null +++ b/utils/src/bigint.rs @@ -0,0 +1,390 @@ +use num_bigint::BigUint; + +use crate::UtilsError; + +/// Converts the given [`num_bigint::BigUint`](num_bigint::BigUint) into a little-endian +/// byte array. +pub fn bigint_to_le_bytes_array( + bigint: &BigUint, +) -> Result<[u8; BYTES_SIZE], UtilsError> { + let mut array = [0u8; BYTES_SIZE]; + let bytes = bigint.to_bytes_le(); + + if bytes.len() > BYTES_SIZE { + return Err(UtilsError::InputTooLarge(BYTES_SIZE)); + } + + array[..bytes.len()].copy_from_slice(bytes.as_slice()); + Ok(array) +} + +/// Converts the given [`ark_ff::BigUint`](ark_ff::BigUint) into a big-endian +/// byte array. +pub fn bigint_to_be_bytes_array( + bigint: &BigUint, +) -> Result<[u8; BYTES_SIZE], UtilsError> { + let mut array = [0u8; BYTES_SIZE]; + let bytes = bigint.to_bytes_be(); + + if bytes.len() > BYTES_SIZE { + return Err(UtilsError::InputTooLarge(BYTES_SIZE)); + } + + let start_pos = BYTES_SIZE - bytes.len(); + array[start_pos..].copy_from_slice(bytes.as_slice()); + Ok(array) +} + +#[cfg(test)] +mod test { + use num_bigint::{RandBigInt, ToBigUint}; + use rand::thread_rng; + + use super::*; + + const ITERATIONS: usize = 64; + + #[test] + fn test_bigint_conversion_rand() { + let mut rng = thread_rng(); + + for _ in 0..ITERATIONS { + let b64 = rng.gen_biguint(32); + let b64_converted: [u8; 8] = bigint_to_be_bytes_array(&b64).unwrap(); + let b64_converted = BigUint::from_bytes_be(&b64_converted); + assert_eq!(b64, b64_converted); + let b64_converted: [u8; 8] = bigint_to_le_bytes_array(&b64).unwrap(); + let b64_converted = BigUint::from_bytes_le(&b64_converted); + assert_eq!(b64, b64_converted); + + let b128 = rng.gen_biguint(128); + let b128_converted: [u8; 16] = bigint_to_be_bytes_array(&b128).unwrap(); + let b128_converted = BigUint::from_bytes_be(&b128_converted); + assert_eq!(b128, b128_converted); + let b128_converted: [u8; 16] = bigint_to_le_bytes_array(&b128).unwrap(); + let b128_converted = BigUint::from_bytes_le(&b128_converted); + assert_eq!(b128, b128_converted); + + let b256 = rng.gen_biguint(256); + let b256_converted: [u8; 32] = bigint_to_be_bytes_array(&b256).unwrap(); + let b256_converted = BigUint::from_bytes_be(&b256_converted); + assert_eq!(b256, b256_converted); + let b256_converted: [u8; 32] = bigint_to_le_bytes_array(&b256).unwrap(); + let b256_converted = BigUint::from_bytes_le(&b256_converted); + assert_eq!(b256, b256_converted); + + let b320 = rng.gen_biguint(320); + let b320_converted: [u8; 40] = bigint_to_be_bytes_array(&b320).unwrap(); + let b320_converted = BigUint::from_bytes_be(&b320_converted); + assert_eq!(b320, b320_converted); + let b320_converted: [u8; 40] = bigint_to_le_bytes_array(&b320).unwrap(); + let b320_converted = BigUint::from_bytes_le(&b320_converted); + assert_eq!(b320, b320_converted); + + let b384 = rng.gen_biguint(384); + let b384_converted: [u8; 48] = bigint_to_be_bytes_array(&b384).unwrap(); + let b384_converted = BigUint::from_bytes_be(&b384_converted); + assert_eq!(b384, b384_converted); + let b384_converted: [u8; 48] = bigint_to_le_bytes_array(&b384).unwrap(); + let b384_converted = BigUint::from_bytes_le(&b384_converted); + assert_eq!(b384, b384_converted); + + let b448 = rng.gen_biguint(448); + let b448_converted: [u8; 56] = bigint_to_be_bytes_array(&b448).unwrap(); + let b448_converted = BigUint::from_bytes_be(&b448_converted); + assert_eq!(b448, b448_converted); + let b448_converted: [u8; 56] = bigint_to_le_bytes_array(&b448).unwrap(); + let b448_converted = BigUint::from_bytes_le(&b448_converted); + assert_eq!(b448, b448_converted); + + let b768 = rng.gen_biguint(768); + let b768_converted: [u8; 96] = bigint_to_be_bytes_array(&b768).unwrap(); + let b768_converted = BigUint::from_bytes_be(&b768_converted); + assert_eq!(b768, b768_converted); + let b768_converted: [u8; 96] = bigint_to_le_bytes_array(&b768).unwrap(); + let b768_converted = BigUint::from_bytes_le(&b768_converted); + assert_eq!(b768, b768_converted); + + let b832 = rng.gen_biguint(832); + let b832_converted: [u8; 104] = bigint_to_be_bytes_array(&b832).unwrap(); + let b832_converted = BigUint::from_bytes_be(&b832_converted); + assert_eq!(b832, b832_converted); + let b832_converted: [u8; 104] = bigint_to_le_bytes_array(&b832).unwrap(); + let b832_converted = BigUint::from_bytes_le(&b832_converted); + assert_eq!(b832, b832_converted); + } + } + + #[test] + fn test_bigint_conversion_zero() { + let zero = 0_u32.to_biguint().unwrap(); + + let b64_converted: [u8; 8] = bigint_to_be_bytes_array(&zero).unwrap(); + let b64_converted = BigUint::from_bytes_be(&b64_converted); + assert_eq!(zero, b64_converted); + let b64_converted: [u8; 8] = bigint_to_le_bytes_array(&zero).unwrap(); + let b64_converted = BigUint::from_bytes_le(&b64_converted); + assert_eq!(zero, b64_converted); + + let b128_converted: [u8; 16] = bigint_to_be_bytes_array(&zero).unwrap(); + let b128_converted = BigUint::from_bytes_be(&b128_converted); + assert_eq!(zero, b128_converted); + let b128_converted: [u8; 16] = bigint_to_le_bytes_array(&zero).unwrap(); + let b128_converted = BigUint::from_bytes_le(&b128_converted); + assert_eq!(zero, b128_converted); + + let b256_converted: [u8; 32] = bigint_to_be_bytes_array(&zero).unwrap(); + let b256_converted = BigUint::from_bytes_be(&b256_converted); + assert_eq!(zero, b256_converted); + let b256_converted: [u8; 32] = bigint_to_le_bytes_array(&zero).unwrap(); + let b256_converted = BigUint::from_bytes_le(&b256_converted); + assert_eq!(zero, b256_converted); + + let b320_converted: [u8; 40] = bigint_to_be_bytes_array(&zero).unwrap(); + let b320_converted = BigUint::from_bytes_be(&b320_converted); + assert_eq!(zero, b320_converted); + let b320_converted: [u8; 40] = bigint_to_le_bytes_array(&zero).unwrap(); + let b320_converted = BigUint::from_bytes_le(&b320_converted); + assert_eq!(zero, b320_converted); + + let b384_converted: [u8; 48] = bigint_to_be_bytes_array(&zero).unwrap(); + let b384_converted = BigUint::from_bytes_be(&b384_converted); + assert_eq!(zero, b384_converted); + let b384_converted: [u8; 48] = bigint_to_le_bytes_array(&zero).unwrap(); + let b384_converted = BigUint::from_bytes_le(&b384_converted); + assert_eq!(zero, b384_converted); + + let b448_converted: [u8; 56] = bigint_to_be_bytes_array(&zero).unwrap(); + let b448_converted = BigUint::from_bytes_be(&b448_converted); + assert_eq!(zero, b448_converted); + let b448_converted: [u8; 56] = bigint_to_le_bytes_array(&zero).unwrap(); + let b448_converted = BigUint::from_bytes_le(&b448_converted); + assert_eq!(zero, b448_converted); + + let b768_converted: [u8; 96] = bigint_to_be_bytes_array(&zero).unwrap(); + let b768_converted = BigUint::from_bytes_be(&b768_converted); + assert_eq!(zero, b768_converted); + let b768_converted: [u8; 96] = bigint_to_le_bytes_array(&zero).unwrap(); + let b768_converted = BigUint::from_bytes_le(&b768_converted); + assert_eq!(zero, b768_converted); + + let b832_converted: [u8; 104] = bigint_to_be_bytes_array(&zero).unwrap(); + let b832_converted = BigUint::from_bytes_be(&b832_converted); + assert_eq!(zero, b832_converted); + let b832_converted: [u8; 104] = bigint_to_le_bytes_array(&zero).unwrap(); + let b832_converted = BigUint::from_bytes_le(&b832_converted); + assert_eq!(zero, b832_converted); + } + + #[test] + fn test_bigint_conversion_one() { + let one = 1_u32.to_biguint().unwrap(); + + let b64_converted: [u8; 8] = bigint_to_be_bytes_array(&one).unwrap(); + let b64_converted = BigUint::from_bytes_be(&b64_converted); + assert_eq!(one, b64_converted); + let b64_converted: [u8; 8] = bigint_to_le_bytes_array(&one).unwrap(); + let b64_converted = BigUint::from_bytes_le(&b64_converted); + assert_eq!(one, b64_converted); + let b64 = BigUint::from_bytes_be(&[0, 0, 0, 0, 0, 0, 0, 1]); + assert_eq!(one, b64); + let b64 = BigUint::from_bytes_le(&[1, 0, 0, 0, 0, 0, 0, 0]); + assert_eq!(one, b64); + + let b128_converted: [u8; 16] = bigint_to_be_bytes_array(&one).unwrap(); + let b128_converted = BigUint::from_bytes_be(&b128_converted); + assert_eq!(one, b128_converted); + let b128_converted: [u8; 16] = bigint_to_le_bytes_array(&one).unwrap(); + let b128_converted = BigUint::from_bytes_le(&b128_converted); + assert_eq!(one, b128_converted); + + let b256_converted: [u8; 32] = bigint_to_be_bytes_array(&one).unwrap(); + let b256_converted = BigUint::from_bytes_be(&b256_converted); + assert_eq!(one, b256_converted); + let b256_converted: [u8; 32] = bigint_to_le_bytes_array(&one).unwrap(); + let b256_converted = BigUint::from_bytes_le(&b256_converted); + assert_eq!(one, b256_converted); + + let b320_converted: [u8; 40] = bigint_to_be_bytes_array(&one).unwrap(); + let b320_converted = BigUint::from_bytes_be(&b320_converted); + assert_eq!(one, b320_converted); + let b320_converted: [u8; 40] = bigint_to_le_bytes_array(&one).unwrap(); + let b320_converted = BigUint::from_bytes_le(&b320_converted); + assert_eq!(one, b320_converted); + + let b384_converted: [u8; 48] = bigint_to_be_bytes_array(&one).unwrap(); + let b384_converted = BigUint::from_bytes_be(&b384_converted); + assert_eq!(one, b384_converted); + let b384_converted: [u8; 48] = bigint_to_le_bytes_array(&one).unwrap(); + let b384_converted = BigUint::from_bytes_le(&b384_converted); + assert_eq!(one, b384_converted); + + let b448_converted: [u8; 56] = bigint_to_be_bytes_array(&one).unwrap(); + let b448_converted = BigUint::from_bytes_be(&b448_converted); + assert_eq!(one, b448_converted); + let b448_converted: [u8; 56] = bigint_to_le_bytes_array(&one).unwrap(); + let b448_converted = BigUint::from_bytes_le(&b448_converted); + assert_eq!(one, b448_converted); + + let b768_converted: [u8; 96] = bigint_to_be_bytes_array(&one).unwrap(); + let b768_converted = BigUint::from_bytes_be(&b768_converted); + assert_eq!(one, b768_converted); + let b768_converted: [u8; 96] = bigint_to_le_bytes_array(&one).unwrap(); + let b768_converted = BigUint::from_bytes_le(&b768_converted); + assert_eq!(one, b768_converted); + + let b832_converted: [u8; 104] = bigint_to_be_bytes_array(&one).unwrap(); + let b832_converted = BigUint::from_bytes_be(&b832_converted); + assert_eq!(one, b832_converted); + let b832_converted: [u8; 104] = bigint_to_le_bytes_array(&one).unwrap(); + let b832_converted = BigUint::from_bytes_le(&b832_converted); + assert_eq!(one, b832_converted); + } + + #[test] + fn test_bigint_conversion_invalid_size() { + let b8 = BigUint::from_bytes_be(&[1; 8]); + let res: Result<[u8; 1], UtilsError> = bigint_to_be_bytes_array(&b8); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 7], UtilsError> = bigint_to_be_bytes_array(&b8); + assert!(matches!(res, Err(UtilsError::InputTooLarge(7)))); + let res: Result<[u8; 8], UtilsError> = bigint_to_be_bytes_array(&b8); + assert!(res.is_ok()); + + let b8 = BigUint::from_bytes_le(&[1; 8]); + let res: Result<[u8; 1], UtilsError> = bigint_to_le_bytes_array(&b8); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 7], UtilsError> = bigint_to_le_bytes_array(&b8); + assert!(matches!(res, Err(UtilsError::InputTooLarge(7)))); + let res: Result<[u8; 8], UtilsError> = bigint_to_le_bytes_array(&b8); + assert!(res.is_ok()); + + let b16 = BigUint::from_bytes_be(&[1; 16]); + let res: Result<[u8; 1], UtilsError> = bigint_to_be_bytes_array(&b16); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 15], UtilsError> = bigint_to_be_bytes_array(&b16); + assert!(matches!(res, Err(UtilsError::InputTooLarge(15)))); + let res: Result<[u8; 16], UtilsError> = bigint_to_be_bytes_array(&b16); + assert!(res.is_ok()); + + let b16 = BigUint::from_bytes_le(&[1; 16]); + let res: Result<[u8; 1], UtilsError> = bigint_to_le_bytes_array(&b16); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 15], UtilsError> = bigint_to_le_bytes_array(&b16); + assert!(matches!(res, Err(UtilsError::InputTooLarge(15)))); + let res: Result<[u8; 16], UtilsError> = bigint_to_le_bytes_array(&b16); + assert!(res.is_ok()); + + let b32 = BigUint::from_bytes_be(&[1; 32]); + let res: Result<[u8; 1], UtilsError> = bigint_to_be_bytes_array(&b32); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 31], UtilsError> = bigint_to_be_bytes_array(&b32); + assert!(matches!(res, Err(UtilsError::InputTooLarge(31)))); + let res: Result<[u8; 32], UtilsError> = bigint_to_be_bytes_array(&b32); + assert!(res.is_ok()); + + let b32 = BigUint::from_bytes_le(&[1; 32]); + let res: Result<[u8; 1], UtilsError> = bigint_to_le_bytes_array(&b32); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 31], UtilsError> = bigint_to_le_bytes_array(&b32); + assert!(matches!(res, Err(UtilsError::InputTooLarge(31)))); + let res: Result<[u8; 32], UtilsError> = bigint_to_le_bytes_array(&b32); + assert!(res.is_ok()); + + let b64 = BigUint::from_bytes_be(&[1; 64]); + let res: Result<[u8; 1], UtilsError> = bigint_to_be_bytes_array(&b64); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 63], UtilsError> = bigint_to_be_bytes_array(&b64); + assert!(matches!(res, Err(UtilsError::InputTooLarge(63)))); + let res: Result<[u8; 64], UtilsError> = bigint_to_be_bytes_array(&b64); + assert!(res.is_ok()); + + let b64 = BigUint::from_bytes_le(&[1; 64]); + let res: Result<[u8; 1], UtilsError> = bigint_to_le_bytes_array(&b64); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 63], UtilsError> = bigint_to_le_bytes_array(&b64); + assert!(matches!(res, Err(UtilsError::InputTooLarge(63)))); + let res: Result<[u8; 64], UtilsError> = bigint_to_le_bytes_array(&b64); + assert!(res.is_ok()); + + let b128 = BigUint::from_bytes_be(&[1; 128]); + let res: Result<[u8; 1], UtilsError> = bigint_to_be_bytes_array(&b128); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 127], UtilsError> = bigint_to_be_bytes_array(&b128); + assert!(matches!(res, Err(UtilsError::InputTooLarge(127)))); + let res: Result<[u8; 128], UtilsError> = bigint_to_be_bytes_array(&b128); + assert!(res.is_ok()); + + let b128 = BigUint::from_bytes_le(&[1; 128]); + let res: Result<[u8; 1], UtilsError> = bigint_to_le_bytes_array(&b128); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 127], UtilsError> = bigint_to_le_bytes_array(&b128); + assert!(matches!(res, Err(UtilsError::InputTooLarge(127)))); + let res: Result<[u8; 128], UtilsError> = bigint_to_le_bytes_array(&b128); + assert!(res.is_ok()); + + let b256 = BigUint::from_bytes_be(&[1; 256]); + let res: Result<[u8; 1], UtilsError> = bigint_to_be_bytes_array(&b256); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 255], UtilsError> = bigint_to_be_bytes_array(&b256); + assert!(matches!(res, Err(UtilsError::InputTooLarge(255)))); + let res: Result<[u8; 256], UtilsError> = bigint_to_be_bytes_array(&b256); + assert!(res.is_ok()); + + let b256 = BigUint::from_bytes_le(&[1; 256]); + let res: Result<[u8; 1], UtilsError> = bigint_to_le_bytes_array(&b256); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 255], UtilsError> = bigint_to_le_bytes_array(&b256); + assert!(matches!(res, Err(UtilsError::InputTooLarge(255)))); + let res: Result<[u8; 256], UtilsError> = bigint_to_le_bytes_array(&b256); + assert!(res.is_ok()); + + let b512 = BigUint::from_bytes_be(&[1; 512]); + let res: Result<[u8; 1], UtilsError> = bigint_to_be_bytes_array(&b512); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 511], UtilsError> = bigint_to_be_bytes_array(&b512); + assert!(matches!(res, Err(UtilsError::InputTooLarge(511)))); + let res: Result<[u8; 512], UtilsError> = bigint_to_be_bytes_array(&b512); + assert!(res.is_ok()); + + let b512 = BigUint::from_bytes_le(&[1; 512]); + let res: Result<[u8; 1], UtilsError> = bigint_to_le_bytes_array(&b512); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 511], UtilsError> = bigint_to_le_bytes_array(&b512); + assert!(matches!(res, Err(UtilsError::InputTooLarge(511)))); + let res: Result<[u8; 512], UtilsError> = bigint_to_le_bytes_array(&b512); + assert!(res.is_ok()); + + let b768 = BigUint::from_bytes_be(&[1; 768]); + let res: Result<[u8; 1], UtilsError> = bigint_to_be_bytes_array(&b768); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 767], UtilsError> = bigint_to_be_bytes_array(&b768); + assert!(matches!(res, Err(UtilsError::InputTooLarge(767)))); + let res: Result<[u8; 768], UtilsError> = bigint_to_be_bytes_array(&b768); + assert!(res.is_ok()); + + let b768 = BigUint::from_bytes_le(&[1; 768]); + let res: Result<[u8; 1], UtilsError> = bigint_to_le_bytes_array(&b768); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 767], UtilsError> = bigint_to_le_bytes_array(&b768); + assert!(matches!(res, Err(UtilsError::InputTooLarge(767)))); + let res: Result<[u8; 768], UtilsError> = bigint_to_le_bytes_array(&b768); + assert!(res.is_ok()); + + let b1024 = BigUint::from_bytes_be(&[1; 1024]); + let res: Result<[u8; 1], UtilsError> = bigint_to_be_bytes_array(&b1024); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 1023], UtilsError> = bigint_to_be_bytes_array(&b1024); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1023)))); + let res: Result<[u8; 1024], UtilsError> = bigint_to_be_bytes_array(&b1024); + assert!(res.is_ok()); + + let b1024 = BigUint::from_bytes_le(&[1; 1024]); + let res: Result<[u8; 1], UtilsError> = bigint_to_le_bytes_array(&b1024); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1)))); + let res: Result<[u8; 1023], UtilsError> = bigint_to_le_bytes_array(&b1024); + assert!(matches!(res, Err(UtilsError::InputTooLarge(1023)))); + let res: Result<[u8; 1024], UtilsError> = bigint_to_le_bytes_array(&b1024); + assert!(res.is_ok()); + } +} diff --git a/utils/src/fee.rs b/utils/src/fee.rs new file mode 100644 index 0000000..10d9730 --- /dev/null +++ b/utils/src/fee.rs @@ -0,0 +1,89 @@ +use crate::UtilsError; + +pub fn compute_rollover_fee( + rollover_threshold: u64, + tree_height: u32, + rent: u64, +) -> Result { + let number_of_transactions = 1 << tree_height; + if rollover_threshold > 100 { + return Err(UtilsError::InvalidRolloverThreshold); + } + if rollover_threshold == 0 { + return Ok(rent); + } + // rent / (total_number_of_leaves * (rollover_threshold / 100)) + // (with ceil division) + Ok((rent * 100).div_ceil(number_of_transactions * rollover_threshold)) +} + +#[test] +fn test_compute_rollover_fee() { + let rollover_threshold = 100; + let tree_height = 26; + let rent = 1392890880; + let total_number_of_leaves = 1 << tree_height; + + let fee = compute_rollover_fee(rollover_threshold, tree_height, rent).unwrap(); + // assert_ne!(fee, 0u64); + assert!((fee + 1) * (total_number_of_leaves * 100 / rollover_threshold) > rent); + + let rollover_threshold = 50; + let fee = compute_rollover_fee(rollover_threshold, tree_height, rent).unwrap(); + assert!((fee + 1) * (total_number_of_leaves * 100 / rollover_threshold) > rent); + let rollover_threshold: u64 = 95; + + let fee = compute_rollover_fee(rollover_threshold, tree_height, rent).unwrap(); + assert!((fee + 1) * (total_number_of_leaves * 100 / rollover_threshold) > rent); +} + +#[test] +fn test_concurrent_tree_compute_rollover_fee() { + let merkle_tree_lamports = 9496836480; + let queue_lamports = 2293180800; + let cpi_context_lamports = 143487360; + let rollover_threshold = 95; + let height = 26; + let rollover_fee = compute_rollover_fee( + rollover_threshold, + height, + merkle_tree_lamports + cpi_context_lamports, + ) + .unwrap() + + compute_rollover_fee(rollover_threshold, height, queue_lamports).unwrap(); + let lifetime_lamports = rollover_fee * ((2u64.pow(height)) as f64 * 0.95) as u64; + println!("rollover_fee: {}", rollover_fee); + println!("lifetime_lamports: {}", lifetime_lamports); + println!( + "lifetime_lamports < total lamports: {}", + lifetime_lamports > merkle_tree_lamports + queue_lamports + cpi_context_lamports + ); + println!( + "lifetime_lamports - total lamports: {}", + lifetime_lamports - (merkle_tree_lamports + queue_lamports + cpi_context_lamports) + ); + assert!(lifetime_lamports > (merkle_tree_lamports + queue_lamports + cpi_context_lamports)); +} + +#[test] +fn test_address_tree_compute_rollover_fee() { + let merkle_tree_lamports = 9639711360; + let queue_lamports = 2293180800; + let rollover_threshold = 95; + let height = 26; + let rollover_fee = compute_rollover_fee(rollover_threshold, height, merkle_tree_lamports) + .unwrap() + + compute_rollover_fee(rollover_threshold, height, queue_lamports).unwrap(); + let lifetime_lamports = rollover_fee * ((2u64.pow(height)) as f64 * 0.95) as u64; + println!("rollover_fee: {}", rollover_fee); + println!("lifetime_lamports: {}", lifetime_lamports); + println!( + "lifetime_lamports < total lamports: {}", + lifetime_lamports > merkle_tree_lamports + queue_lamports + ); + println!( + "lifetime_lamports - total lamports: {}", + lifetime_lamports - (merkle_tree_lamports + queue_lamports) + ); + assert!(lifetime_lamports > (merkle_tree_lamports + queue_lamports)); +} diff --git a/utils/src/hashchain.rs b/utils/src/hashchain.rs new file mode 100644 index 0000000..bf6bc5a --- /dev/null +++ b/utils/src/hashchain.rs @@ -0,0 +1,351 @@ +use light_hasher::{Hasher, Poseidon}; + +use crate::UtilsError; + +/// Creates a hash chain from an array of [u8;32] arrays. +/// +/// # Parameters +/// - `inputs`: An array of [u8;32] arrays to be hashed. +/// +/// # Returns +/// - `Result<[u8; 32], UtilsError>`: The resulting hash chain or an error. +pub fn create_hash_chain_from_array( + inputs: [[u8; 32]; T], +) -> Result<[u8; 32], UtilsError> { + create_hash_chain_from_slice(&inputs) +} + +/// Creates a hash chain from a slice of [u8;32] arrays. +/// +/// # Parameters +/// - `inputs`: A slice of [u8;32] array to be hashed. +/// +/// # Returns +/// - `Result<[u8; 32], UtilsError>`: The resulting hash chain or an error. +pub fn create_hash_chain_from_slice(inputs: &[[u8; 32]]) -> Result<[u8; 32], UtilsError> { + if inputs.is_empty() { + return Ok([0u8; 32]); + } + let mut hash_chain = inputs[0]; + for input in inputs.iter().skip(1) { + hash_chain = Poseidon::hashv(&[&hash_chain, input])?; + } + Ok(hash_chain) +} + +/// Creates a two inputs hash chain from two slices of [u8;32] arrays. +/// The two slices must have the same length. +/// Hashes are hashed in pairs, with the first hash from +/// the first slice and the second hash from the second slice. +/// H(i) = H(H(i-1), hashes_first[i], hashes_second[i]) +/// +/// # Parameters +/// - `hashes_first`: A slice of [u8;32] arrays to be hashed first. +/// - `hashes_second`: A slice of [u8;32] arrays to be hashed second. +/// +/// # Returns +/// - `Result<[u8; 32], UtilsError>`: The resulting hash chain or an error. +pub fn create_two_inputs_hash_chain( + hashes_first: &[[u8; 32]], + hashes_second: &[[u8; 32]], +) -> Result<[u8; 32], UtilsError> { + let first_len = hashes_first.len(); + if first_len != hashes_second.len() { + return Err(UtilsError::InvalidInputLength); + } + if hashes_first.is_empty() { + return Ok([0u8; 32]); + } + let mut hash_chain = Poseidon::hashv(&[&hashes_first[0], &hashes_second[0]])?; + + if first_len == 1 { + return Ok(hash_chain); + } + + for i in 1..first_len { + hash_chain = Poseidon::hashv(&[&hash_chain, &hashes_first[i], &hashes_second[i]])?; + } + Ok(hash_chain) +} + +/// Creates a transaction hash from the given input and output compressed account hashes and the current slot. +/// +/// # Parameters +/// - `input_compressed_account_hashes`: A slice of input compressed account hashes. +/// - `output_compressed_account_hashes`: A slice of output compressed account hashes. +/// - `current_slot`: The current slot as a 64-bit unsigned integer. +pub fn create_tx_hash( + input_compressed_account_hashes: &[[u8; 32]], + output_compressed_account_hashes: &[[u8; 32]], + current_slot: u64, +) -> Result<[u8; 32], UtilsError> { + let version = [0u8; 32]; + let mut current_slot_bytes = [0u8; 32]; + current_slot_bytes[24..].copy_from_slice(¤t_slot.to_be_bytes()); + let inputs_hash_chain = create_hash_chain_from_slice(input_compressed_account_hashes)?; + let outputs_hash_chain = create_hash_chain_from_slice(output_compressed_account_hashes)?; + let hash_chain = create_hash_chain_from_slice(&[ + version, + inputs_hash_chain, + outputs_hash_chain, + current_slot_bytes, + ])?; + Ok(hash_chain) +} + +#[cfg(test)] +mod hash_chain_tests { + use ark_ff::PrimeField; + use light_hasher::{Hasher, HasherError, Poseidon}; + use light_poseidon::PoseidonError; + use num_bigint::BigUint; + + use super::*; + use crate::bigint::bigint_to_be_bytes_array; + + /// Tests for `create_hash_chain_from_slice` function: + /// Functional tests: + /// 1. Functional - with hardcoded values. + /// 2. Functional - with manual hash comparison. + /// 3. Functional - for determinism (hashing the same input twice). + /// 4. Functional - empty input case returns zero hash. + /// + /// Failing tests: + /// 5. Failing - input larger than modulus + #[test] + fn test_create_hash_chain_from_slice() { + // 1. Functional test with hardcoded values. + { + // Define hardcoded inputs. + let inputs: [[u8; 32]; 3] = [[1u8; 32], [2u8; 32], [3u8; 32]]; + + // Manually compute the expected hash chain using Poseidon. + // Note: The expected hash values should be precomputed using the same Poseidon parameters. + // For demonstration purposes, we'll assume hypothetical hash outputs. + // In a real scenario, replace these with actual expected values. + let intermediate_hash_1 = Poseidon::hashv(&[&inputs[0], &inputs[1]]).unwrap(); + let expected_hash = Poseidon::hashv(&[&intermediate_hash_1, &inputs[2]]).unwrap(); + + // Call the function under test. + let result = create_hash_chain_from_slice(&inputs).unwrap(); + + // Assert that the result matches the expected hash. + assert_eq!( + result, expected_hash, + "Functional test with hardcoded values failed." + ); + } + + // 2. Functional test with manual hash comparison. + { + let inputs: [[u8; 32]; 2] = [[4u8; 32], [5u8; 32]]; + + // Manually compute the expected hash. + let expected_hash = Poseidon::hashv(&[&inputs[0], &inputs[1]]).unwrap(); + let hard_coded_expected_hash = [ + 13, 250, 206, 124, 182, 159, 160, 87, 57, 23, 80, 155, 25, 43, 40, 136, 228, 255, + 201, 1, 22, 168, 211, 220, 176, 187, 23, 176, 46, 198, 140, 211, + ]; + + let result = create_hash_chain_from_slice(&inputs).unwrap(); + + assert_eq!( + result, expected_hash, + "Functional test with manual hash comparison failed." + ); + assert_eq!(result, hard_coded_expected_hash); + } + + // 2. Functional test with manual hash comparison. + { + let inputs = [[4u8; 32], [5u8; 32], [6u8; 32]]; + + let expected_hash = Poseidon::hashv(&[&inputs[0], &inputs[1]]).unwrap(); + let expected_hash = Poseidon::hashv(&[&expected_hash, &inputs[2]]).unwrap(); + let hard_coded_expected_hash = [ + 12, 74, 32, 81, 132, 82, 10, 115, 75, 248, 169, 125, 228, 230, 140, 167, 149, 181, + 244, 194, 63, 201, 26, 150, 142, 4, 60, 16, 77, 145, 194, 152, + ]; + + let result = create_hash_chain_from_slice(&inputs).unwrap(); + + assert_eq!( + result, expected_hash, + "Functional test with manual hash comparison failed." + ); + assert_eq!(result, hard_coded_expected_hash); + } + + // 3. Functional test for determinism (hashing the same input twice). + { + // Define inputs. + let inputs: [[u8; 32]; 2] = [[6u8; 32], [7u8; 32]]; + + // Compute hash chain the first time. + let first_hash = create_hash_chain_from_slice(&inputs).unwrap(); + + // Compute hash chain the second time. + let second_hash = create_hash_chain_from_slice(&inputs).unwrap(); + + // Assert that both hashes are identical. + assert_eq!( + first_hash, second_hash, + "Determinism test failed: Hashes do not match." + ); + } + + // 4. Test empty input case + { + let inputs: [[u8; 32]; 0] = []; + let result = create_hash_chain_from_slice(&inputs).unwrap(); + assert_eq!(result, [0u8; 32], "Empty input should return zero hash"); + } + + // 5. Failing - input larger than modulus + { + let modulus: BigUint = ark_bn254::Fr::MODULUS.into(); + let modulus_bytes: [u8; 32] = bigint_to_be_bytes_array(&modulus).unwrap(); + let huge_input = vec![modulus_bytes, modulus_bytes]; + let result = create_hash_chain_from_slice(&huge_input); + assert!( + matches!(result, Err(UtilsError::HasherError(error)) if error == HasherError::Poseidon(PoseidonError::InputLargerThanModulus) ), + ); + } + } + + /// Tests for `create_tx_hash` function: + /// Functional tests: + /// 1. Functional - empty input slices. + /// 2. Functional - single element slices. + /// 3. Functional - multiple elements. + #[test] + fn test_create_tx_hash() { + // 1. Functional test with empty input slices. + { + let input_hashes: &[[u8; 32]] = &[]; + let output_hashes: &[[u8; 32]] = &[]; + let current_slot: u64 = 0; + let result = create_tx_hash(input_hashes, output_hashes, current_slot).unwrap(); + let result_2 = create_tx_hash(input_hashes, output_hashes, current_slot).unwrap(); + assert_eq!(result, result_2); + let expected_hash = + create_hash_chain_from_slice(&[[0u8; 32], [0u8; 32], [0u8; 32], [0u8; 32]]) + .unwrap(); + assert_eq!( + result, + [ + 34, 200, 164, 208, 164, 254, 32, 90, 32, 86, 179, 30, 247, 124, 171, 192, 209, + 57, 53, 27, 29, 19, 51, 1, 231, 57, 166, 115, 49, 208, 244, 143 + ], + ); + assert_eq!(result, expected_hash); + } + + // 2. Functional test with single element slices. + { + let input_hashes: &[[u8; 32]] = &[[1u8; 32]]; + let output_hashes: &[[u8; 32]] = &[[2u8; 32]]; + let current_slot: u64 = 1; + let result = create_tx_hash(input_hashes, output_hashes, current_slot).unwrap(); + let result_2 = create_tx_hash(input_hashes, output_hashes, current_slot).unwrap(); + assert_eq!(result, result_2); + let mut slot_bytes = [0u8; 32]; + slot_bytes[24..].copy_from_slice(¤t_slot.to_be_bytes()); + let expected_hash = create_hash_chain_from_slice(&[ + [0u8; 32], + input_hashes[0], + output_hashes[0], + slot_bytes, + ]); + let hard_coded_expected_hash = [ + 26, 2, 125, 115, 183, 17, 182, 221, 81, 35, 84, 46, 94, 86, 98, 1, 32, 169, 75, 74, + 163, 148, 202, 22, 163, 60, 43, 57, 188, 253, 203, 81, + ]; + assert_eq!(result, expected_hash.unwrap()); + assert_eq!(result, hard_coded_expected_hash); + } + + // 3. Functional test with multiple elements. + { + let input_hashes: &[[u8; 32]] = &[[1u8; 32], [2u8; 32]]; + let output_hashes: &[[u8; 32]] = &[[3u8; 32], [4u8; 32]]; + let current_slot: u64 = 2; + let result = create_tx_hash(input_hashes, output_hashes, current_slot).unwrap(); + let result_2 = create_tx_hash(input_hashes, output_hashes, current_slot).unwrap(); + assert_eq!(result, result_2); + let inclusion = Poseidon::hashv(&[&input_hashes[0], &input_hashes[1]]).unwrap(); + let outputs = Poseidon::hashv(&[&output_hashes[0], &output_hashes[1]]).unwrap(); + let mut slot_bytes = [0u8; 32]; + slot_bytes[24..].copy_from_slice(¤t_slot.to_be_bytes()); + let expected_hash = + create_hash_chain_from_slice(&[[0u8; 32], inclusion, outputs, slot_bytes]); + let hard_coded_expected_hash = [ + 16, 202, 249, 127, 226, 111, 123, 166, 255, 16, 162, 227, 122, 43, 247, 141, 81, + 139, 79, 182, 213, 250, 225, 201, 235, 241, 26, 77, 117, 4, 91, 150, + ]; + assert_eq!(result, expected_hash.unwrap()); + assert_eq!(result, hard_coded_expected_hash); + } + } + + /// Tests for `create_two_inputs_hash_chain` function: + /// 1. Functional - empty inputs. + /// 2. Functional - 1 input each. + /// 3. Functional - 2 inputs each. + /// 4. Failing - invalid input length for hashes_first. + /// 5. Failing - invalid input length for hashes_second. + #[test] + fn test_create_two_inputs_hash_chain() { + // 1. Functional test with empty inputs. + { + let hashes_first: &[[u8; 32]] = &[]; + let hashes_second: &[[u8; 32]] = &[]; + let result = create_two_inputs_hash_chain(hashes_first, hashes_second).unwrap(); + assert_eq!(result, [0u8; 32], "Empty input should return zero hash"); + } + + // 2. Functional test with 1 input each. + { + let hashes_first: &[[u8; 32]] = &[[1u8; 32]]; + let hashes_second: &[[u8; 32]] = &[[2u8; 32]]; + let expected_hash = Poseidon::hashv(&[&hashes_first[0], &hashes_second[0]]).unwrap(); + let result = create_two_inputs_hash_chain(hashes_first, hashes_second).unwrap(); + assert_eq!(result, expected_hash, "Single input each test failed"); + } + + // 3. Functional test with 2 inputs each. + { + let hashes_first: &[[u8; 32]] = &[[1u8; 32], [2u8; 32]]; + let hashes_second: &[[u8; 32]] = &[[3u8; 32], [4u8; 32]]; + let intermediate_hash = + Poseidon::hashv(&[&hashes_first[0], &hashes_second[0]]).unwrap(); + let expected_hash = + Poseidon::hashv(&[&intermediate_hash, &hashes_first[1], &hashes_second[1]]) + .unwrap(); + let result = create_two_inputs_hash_chain(hashes_first, hashes_second).unwrap(); + assert_eq!(result, expected_hash, "Two inputs each test failed"); + } + + // 4. Failing test with invalid input length for hashes_first. + { + let hashes_first: &[[u8; 32]] = &[[1u8; 32]]; + let hashes_second: &[[u8; 32]] = &[[2u8; 32], [3u8; 32]]; + let result = create_two_inputs_hash_chain(hashes_first, hashes_second); + assert!( + matches!(result, Err(UtilsError::InvalidInputLength)), + "Invalid input length for hashes_first test failed" + ); + } + + // 5. Failing test with invalid input length for hashes_second. + { + let hashes_first: &[[u8; 32]] = &[[1u8; 32], [2u8; 32]]; + let hashes_second: &[[u8; 32]] = &[[3u8; 32]]; + let result = create_two_inputs_hash_chain(hashes_first, hashes_second); + assert!( + matches!(result, Err(UtilsError::InvalidInputLength)), + "Invalid input length for hashes_second test failed" + ); + } + } +} diff --git a/utils/src/lib.rs b/utils/src/lib.rs new file mode 100644 index 0000000..7b3d19c --- /dev/null +++ b/utils/src/lib.rs @@ -0,0 +1,218 @@ +use std::{ + env, + io::{self, prelude::*}, + process::{Command, Stdio}, + thread::spawn, +}; + +use ark_ff::PrimeField; +use light_hasher::HasherError; +use num_bigint::BigUint; +use solana_program::keccak::hashv; +use thiserror::Error; + +pub mod bigint; +pub mod fee; +pub mod hashchain; +pub mod prime; +pub mod rand; + +#[derive(Debug, Error, PartialEq)] +pub enum UtilsError { + #[error("Invalid input size, expected at most {0}")] + InputTooLarge(usize), + #[error("Invalid chunk size")] + InvalidChunkSize, + #[error("Invalid seeds")] + InvalidSeeds, + #[error("Invalid rollover thresold")] + InvalidRolloverThreshold, + #[error("Invalid input lenght")] + InvalidInputLength, + #[error("Hasher error {0}")] + HasherError(#[from] HasherError), +} + +// NOTE(vadorovsky): Unfortunately, we need to do it by hand. +// `num_derive::ToPrimitive` doesn't support data-carrying enums. +impl From for u32 { + fn from(e: UtilsError) -> u32 { + match e { + UtilsError::InputTooLarge(_) => 12001, + UtilsError::InvalidChunkSize => 12002, + UtilsError::InvalidSeeds => 12003, + UtilsError::InvalidRolloverThreshold => 12004, + UtilsError::InvalidInputLength => 12005, + UtilsError::HasherError(e) => u32::from(e), + } + } +} + +impl From for solana_program::program_error::ProgramError { + fn from(e: UtilsError) -> Self { + solana_program::program_error::ProgramError::Custom(e.into()) + } +} + +pub fn is_smaller_than_bn254_field_size_be(bytes: &[u8; 32]) -> bool { + let bigint = BigUint::from_bytes_be(bytes); + bigint < ark_bn254::Fr::MODULUS.into() +} + +pub fn hash_to_bn254_field_size_be(bytes: &[u8]) -> Option<([u8; 32], u8)> { + let mut bump_seed = [u8::MAX]; + // Loops with decreasing bump seed to find a valid hash which is less than + // bn254 Fr modulo field size. + for _ in 0..u8::MAX { + { + let mut hashed_value: [u8; 32] = hashv(&[bytes, bump_seed.as_ref()]).to_bytes(); + // Truncates to 31 bytes so that value is less than bn254 Fr modulo + // field size. + hashed_value[0] = 0; + if is_smaller_than_bn254_field_size_be(&hashed_value) { + return Some((hashed_value, bump_seed[0])); + } + } + bump_seed[0] -= 1; + } + None +} + +/// Hashes the provided `bytes` with Keccak256 and ensures the result fits +/// in the BN254 prime field by repeatedly hashing the inputs with various +/// "bump seeds" and truncating the resulting hash to 31 bytes. +/// +/// The attempted "bump seeds" are bytes from 255 to 0. +/// +/// # Examples +/// +/// ``` +/// use light_utils::hashv_to_bn254_field_size_be; +/// +/// hashv_to_bn254_field_size_be(&[b"foo", b"bar"]); +/// ``` +pub fn hashv_to_bn254_field_size_be(bytes: &[&[u8]]) -> [u8; 32] { + let mut hashed_value: [u8; 32] = hashv(bytes).to_bytes(); + // Truncates to 31 bytes so that value is less than bn254 Fr modulo + // field size. + hashed_value[0] = 0; + hashed_value +} + +/// Applies `rustfmt` on the given string containing Rust code. The purpose of +/// this function is to be able to format autogenerated code (e.g. with `quote` +/// macro). +pub fn rustfmt(code: String) -> Result, anyhow::Error> { + let mut cmd = match env::var_os("RUSTFMT") { + Some(r) => Command::new(r), + None => Command::new("rustfmt"), + }; + + let mut cmd = cmd + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn()?; + + let mut stdin = cmd.stdin.take().unwrap(); + let mut stdout = cmd.stdout.take().unwrap(); + + let stdin_handle = spawn(move || { + stdin.write_all(code.as_bytes()).unwrap(); + }); + + let mut formatted_code = vec![]; + io::copy(&mut stdout, &mut formatted_code)?; + + let _ = cmd.wait(); + stdin_handle.join().unwrap(); + + Ok(formatted_code) +} + +#[cfg(test)] +mod tests { + use num_bigint::ToBigUint; + use solana_program::pubkey::Pubkey; + + use super::*; + use crate::bigint::bigint_to_be_bytes_array; + + #[test] + fn test_is_smaller_than_bn254_field_size_be() { + let modulus: BigUint = ark_bn254::Fr::MODULUS.into(); + let modulus_bytes: [u8; 32] = bigint_to_be_bytes_array(&modulus).unwrap(); + assert!(!is_smaller_than_bn254_field_size_be(&modulus_bytes)); + + let bigint = modulus.clone() - 1.to_biguint().unwrap(); + let bigint_bytes: [u8; 32] = bigint_to_be_bytes_array(&bigint).unwrap(); + assert!(is_smaller_than_bn254_field_size_be(&bigint_bytes)); + + let bigint = modulus + 1.to_biguint().unwrap(); + let bigint_bytes: [u8; 32] = bigint_to_be_bytes_array(&bigint).unwrap(); + assert!(!is_smaller_than_bn254_field_size_be(&bigint_bytes)); + } + + #[test] + fn test_hash_to_bn254_field_size_be() { + for _ in 0..10_000 { + let input_bytes = Pubkey::new_unique().to_bytes(); // Sample input + let (hashed_value, bump) = hash_to_bn254_field_size_be(input_bytes.as_slice()) + .expect("Failed to find a hash within BN254 field size"); + assert_eq!(bump, 255, "Bump seed should be 0"); + assert!( + is_smaller_than_bn254_field_size_be(&hashed_value), + "Hashed value should be within BN254 field size" + ); + } + + let max_input = [u8::MAX; 32]; + let (hashed_value, bump) = hash_to_bn254_field_size_be(max_input.as_slice()) + .expect("Failed to find a hash within BN254 field size"); + assert_eq!(bump, 255, "Bump seed should be 255"); + assert!( + is_smaller_than_bn254_field_size_be(&hashed_value), + "Hashed value should be within BN254 field size" + ); + } + + #[test] + fn test_hashv_to_bn254_field_size_be() { + for _ in 0..10_000 { + let input_bytes = [Pubkey::new_unique().to_bytes(); 4]; + let input_bytes = input_bytes.iter().map(|x| x.as_slice()).collect::>(); + let hashed_value = hashv_to_bn254_field_size_be(input_bytes.as_slice()); + assert!( + is_smaller_than_bn254_field_size_be(&hashed_value), + "Hashed value should be within BN254 field size" + ); + } + + let max_input = [[u8::MAX; 32]; 16]; + let max_input = max_input.iter().map(|x| x.as_slice()).collect::>(); + let hashed_value = hashv_to_bn254_field_size_be(max_input.as_slice()); + assert!( + is_smaller_than_bn254_field_size_be(&hashed_value), + "Hashed value should be within BN254 field size" + ); + } + + #[test] + fn test_rustfmt() { + let unformatted_code = "use std::mem; + +fn main() { println!(\"{}\", mem::size_of::()); } + " + .to_string(); + let formatted_code = rustfmt(unformatted_code).unwrap(); + assert_eq!( + String::from_utf8_lossy(&formatted_code), + "use std::mem; + +fn main() { + println!(\"{}\", mem::size_of::()); +} +" + ); + } +} diff --git a/utils/src/prime.rs b/utils/src/prime.rs new file mode 100644 index 0000000..fa40f29 --- /dev/null +++ b/utils/src/prime.rs @@ -0,0 +1,139 @@ +/// Finds the lowest prime number which is greater than the provided number +/// `n`. +pub fn find_next_prime(mut n: u32) -> u32 { + // Handle small numbers separately + if n <= 2 { + return 2; + } else if n <= 3 { + return 3; + } + + // All prime numbers greater than 3 are of the form 6k + 1 or 6k + 5 (or + // 6k - 1). + // That's because: + // + // 6k is divisible by 2 and 3. + // 6k + 2 = 2(3k + 1) is divisible by 2. + // 6k + 3 = 3(2k + 1) is divisible by 3. + // 6k + 4 = 2(3k + 2) is divisible by 2. + // + // This leaves only 6k + 1 and 6k + 5 as candidates. + + // Ensure the candidate is of the form 6k - 1 or 6k + 1. + let remainder = n % 6; + if remainder != 0 { + // Check if `n` already satisfies the pattern and is prime. + if remainder == 5 && is_prime(n) { + return n; + } + if remainder == 1 && is_prime(n) { + return n; + } + + // Add `6 - remainder` to `n`, to it satisfies the `6k` pattern. + n = n + 6 - remainder; + // Check if `6k - 1` candidate is prime. + let candidate = n - 1; + if is_prime(candidate) { + return candidate; + } + } + + // Consequently add `6`, keep checking `6k + 1` and `6k + 5` candidates. + loop { + let candidate = n + 1; + if is_prime(candidate) { + return candidate; + } + let candidate = n + 5; + if is_prime(candidate) { + return candidate; + } + + n += 6; + } +} + +pub fn find_next_prime_with_load_factor(n: u32, load_factor: f64) -> u32 { + // SAFETY: These type coercions should not cause any issues. + // + // * `f64` can precisely represent all integer values up to 2^53, which is + // more than `u32::MAX`. `u64` and `usize` would be too large though. + // * We want to return and find an integer (prime number), so coercing `f64` + // back to `u32` is intentional here. + let minimum = n as f64 / load_factor; + find_next_prime(minimum as u32) +} + +/// Checks whether the provided number `n` is a prime number. +pub fn is_prime(n: u32) -> bool { + if n <= 1 { + return false; + } + if n <= 3 { + return true; + } + if n % 2 == 0 || n % 3 == 0 { + return false; + } + let mut i = 5; + while i * i <= n { + if n % i == 0 || n % (i + 2) == 0 { + return false; + } + i += 6; + } + true +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_find_next_prime() { + assert_eq!(find_next_prime(0), 2); + assert_eq!(find_next_prime(2), 2); + assert_eq!(find_next_prime(3), 3); + assert_eq!(find_next_prime(4), 5); + + assert_eq!(find_next_prime(10), 11); + assert_eq!(find_next_prime(17), 17); + assert_eq!(find_next_prime(19), 19); + assert_eq!(find_next_prime(28), 29); + + assert_eq!(find_next_prime(100), 101); + assert_eq!(find_next_prime(102), 103); + assert_eq!(find_next_prime(105), 107); + + assert_eq!(find_next_prime(1000), 1009); + assert_eq!(find_next_prime(2000), 2003); + assert_eq!(find_next_prime(3000), 3001); + assert_eq!(find_next_prime(4000), 4001); + + assert_eq!(find_next_prime(4800), 4801); + assert_eq!(find_next_prime(5000), 5003); + assert_eq!(find_next_prime(6000), 6007); + assert_eq!(find_next_prime(6850), 6857); + + assert_eq!(find_next_prime(7000), 7001); + assert_eq!(find_next_prime(7900), 7901); + assert_eq!(find_next_prime(7907), 7907); + } + + #[test] + fn test_find_next_prime_with_load_factor() { + assert_eq!(find_next_prime_with_load_factor(4800, 0.5), 9601); + assert_eq!(find_next_prime_with_load_factor(4800, 0.7), 6857); + } + + #[test] + fn test_is_prime() { + assert_eq!(is_prime(1), false); + assert_eq!(is_prime(2), true); + assert_eq!(is_prime(3), true); + assert_eq!(is_prime(4), false); + assert_eq!(is_prime(17), true); + assert_eq!(is_prime(19), true); + } +} diff --git a/utils/src/rand.rs b/utils/src/rand.rs new file mode 100644 index 0000000..cf9530b --- /dev/null +++ b/utils/src/rand.rs @@ -0,0 +1,102 @@ +use std::ops::{Bound, RangeBounds}; + +use rand::{ + distributions::uniform::{SampleRange, SampleUniform}, + Rng, +}; + +use crate::prime::find_next_prime; + +const PRIME_RETRIES: usize = 10; + +/// Generates a random prime number in the given range. It returns `None` when +/// generating such number was not possible. +pub fn gen_prime(rng: &mut N, range: R) -> Option +where + N: Rng, + R: Clone + RangeBounds + SampleRange, + T: Into + From + Copy + PartialOrd + SampleUniform, +{ + for _ in 0..PRIME_RETRIES { + let sample: T = rng.gen_range(range.clone()); + let next_prime = find_next_prime(sample.into()); + + match range.end_bound() { + Bound::Included(end) => { + if next_prime > (*end).into() { + continue; + } + } + Bound::Excluded(end) => { + if next_prime >= (*end).into() { + continue; + } + } + _ => {} + }; + + return Some(T::from(next_prime)); + } + + None +} + +/// Generates a random value in the given range, excluding the values provided +/// in `exclude`. +pub fn gen_range_exclude(rng: &mut N, range: R, exclude: &[T]) -> T +where + N: Rng, + R: Clone + SampleRange, + T: PartialEq + SampleUniform, +{ + loop { + // This utility is supposed to be used only in unit tests. This `clone` + // is harmless and necessary (can't pass a reference to range, it has + // to be moved). + let sample = rng.gen_range(range.clone()); + if !exclude.contains(&sample) { + return sample; + } + } +} + +#[cfg(test)] +mod test { + use rand::Rng; + + use super::*; + use crate::prime::is_prime; + + #[test] + fn test_gen_prime() { + let mut rng = rand::thread_rng(); + + let mut successful_gens = 0; + for i in 0..10_000 { + let sample: Option = gen_prime(&mut rng, 1..10_000); + println!("sample {i}: {sample:?}"); + if let Some(sample) = sample { + successful_gens += 1; + assert!(is_prime(sample)); + } + } + + println!("generated {successful_gens} prime numbers out of 10000 iterations"); + } + + #[test] + fn test_gen_range_exclude() { + let mut rng = rand::thread_rng(); + + for n_excluded in 1..100 { + let excluded: Vec = (0..n_excluded).map(|_| rng.gen_range(0..100)).collect(); + + for _ in 0..10_000 { + let sample = gen_range_exclude(&mut rng, 0..100, excluded.as_slice()); + for excluded in excluded.iter() { + assert_ne!(&sample, excluded); + } + } + } + } +} From 5ce2208b24db5f5e09ed78a7f6571c792f5ffb3b Mon Sep 17 00:00:00 2001 From: Sergey Timoshin Date: Tue, 24 Dec 2024 01:20:05 +0000 Subject: [PATCH 6/6] add Cargo.lock for utils --- utils/Cargo.lock | 1683 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1683 insertions(+) create mode 100644 utils/Cargo.lock diff --git a/utils/Cargo.lock b/utils/Cargo.lock new file mode 100644 index 0000000..ac35b0f --- /dev/null +++ b/utils/Cargo.lock @@ -0,0 +1,1683 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.15", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "anyhow" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" + +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +dependencies = [ + "serde", +] + +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + +[[package]] +name = "blake3" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8ee0c1824c4dea5b5f81736aff91bae041d2c07ee1192bec91054e10e3e601e" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "borsh" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" +dependencies = [ + "borsh-derive 0.9.3", + "hashbrown 0.11.2", +] + +[[package]] +name = "borsh" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115e54d64eb62cdebad391c19efc9dce4981c690c85a33a12199d99bb9546fee" +dependencies = [ + "borsh-derive 0.10.4", + "hashbrown 0.13.2", +] + +[[package]] +name = "borsh" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2506947f73ad44e344215ccd6403ac2ae18cd8e046e581a441bf8d199f257f03" +dependencies = [ + "borsh-derive 1.5.3", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" +dependencies = [ + "borsh-derive-internal 0.9.3", + "borsh-schema-derive-internal 0.9.3", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831213f80d9423998dd696e2c5345aba6be7a0bd8cd19e31c5243e13df1cef89" +dependencies = [ + "borsh-derive-internal 0.10.4", + "borsh-schema-derive-internal 0.10.4", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2593a3b8b938bd68373196c9832f516be11fa487ef4ae745eb282e6a56a7244" +dependencies = [ + "once_cell", + "proc-macro-crate 3.2.0", + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65d6ba50644c98714aa2a70d13d7df3cd75cd2b523a2b452bf010443800976b3" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276691d96f063427be83e6692b86148e488ebba9f48f77788724ca027ba3b6d4" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] + +[[package]] +name = "bytemuck" +version = "1.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fa76293b4f7bb636ab88fd78228235b5248b4d05cc589aed610f954af5d7c7a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "cpufeatures" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common", + "subtle", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "serde", + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.8", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.11", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac", +] + +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "rayon", + "serde", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown 0.15.2", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "light-bounded-vec" +version = "1.1.0" +dependencies = [ + "bytemuck", + "memoffset", + "thiserror", +] + +[[package]] +name = "light-hasher" +version = "1.1.0" +dependencies = [ + "ark-bn254", + "light-poseidon", + "sha2 0.10.8", + "sha3", + "solana-program", + "thiserror", +] + +[[package]] +name = "light-poseidon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" +dependencies = [ + "ark-bn254", + "ark-ff", + "num-bigint", + "thiserror", +] + +[[package]] +name = "light-utils" +version = "1.1.0" +dependencies = [ + "anyhow", + "ark-bn254", + "ark-ff", + "bytemuck", + "light-bounded-vec", + "light-hasher", + "light-poseidon", + "memoffset", + "num-bigint", + "rand 0.8.5", + "solana-program", + "thiserror", +] + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +dependencies = [ + "crypto-mac", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" + +[[package]] +name = "serde" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_bytes" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "serde_json" +version = "1.0.134" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "solana-frozen-abi" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03ab2c30c15311b511c0d1151e4ab6bc9a3e080a37e7c6e7c2d96f5784cf9434" +dependencies = [ + "block-buffer 0.10.4", + "bs58", + "bv", + "either", + "generic-array", + "im", + "lazy_static", + "log", + "memmap2", + "rustc_version", + "serde", + "serde_bytes", + "serde_derive", + "sha2 0.10.8", + "solana-frozen-abi-macro", + "subtle", + "thiserror", +] + +[[package]] +name = "solana-frozen-abi-macro" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c142f779c3633ac83c84d04ff06c70e1f558c876f13358bed77ba629c7417932" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.91", +] + +[[package]] +name = "solana-program" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c10f4588cefd716b24a1a40dd32c278e43a560ab8ce4de6b5805c9d113afdfa1" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "base64 0.21.7", + "bincode", + "bitflags", + "blake3", + "borsh 0.10.4", + "borsh 0.9.3", + "borsh 1.5.3", + "bs58", + "bv", + "bytemuck", + "cc", + "console_error_panic_hook", + "console_log", + "curve25519-dalek", + "getrandom 0.2.15", + "itertools", + "js-sys", + "lazy_static", + "libc", + "libsecp256k1", + "light-poseidon", + "log", + "memoffset", + "num-bigint", + "num-derive", + "num-traits", + "parking_lot", + "rand 0.8.5", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "sha2 0.10.8", + "sha3", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk-macro", + "thiserror", + "tiny-bip39", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "solana-sdk-macro" +version = "1.18.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b75d0f193a27719257af19144fdaebec0415d1c9e9226ae4bd29b791be5e9bd" +dependencies = [ + "bs58", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.91", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "tiny-bip39" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" +dependencies = [ + "anyhow", + "hmac", + "once_cell", + "pbkdf2", + "rand 0.7.3", + "rustc-hash", + "sha2 0.9.9", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "tinyvec" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.91", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" + +[[package]] +name = "web-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "zeroize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +]