Skip to content

Commit d428102

Browse files
committed
zkcamp updates
1 parent 8472f63 commit d428102

24 files changed

+8768
-122
lines changed

foundry-voting/.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ docs/
1313
# Dotenv file
1414
.env
1515

16-
circuits/target/*
16+
node_modules
17+
crs

foundry-voting/README.md

+23-7
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,30 @@
44

55
This example project shows how to create a simple zk voting circuit in Noir with a corresponding Solidity contract to track eligible voters, proposals and votes.
66

7+
This example was last tested with Noir version 0.10.3. You can install it with [noirup](https://noir-lang.org/getting_started/nargo_installation#option-1-noirup) using
8+
9+
```bash
10+
noirup -v 0.10.3
11+
```
12+
713
## Overview
814

915
This is the model used for creating the [circuit](circuits/src/main.nr) and the [zkVote contract](src/zkVote.sol) to manage private voting.
1016

1117
1. Create a set of voters. A merkle root is stored in the zkVote Solidity contract that voters will use to verify membership against. In this example, there are 4 accounts in the set of voters. The private keys are 0, 1, 2, 3 and the secret value to create the commitment is 9.
1218

13-
| Private Key | Commitment = pedersen(private key, secret) |
19+
| Private Key | Commitment = pedersen(secret) |
1420
| ----------- | ------------------------------------------------------------------ |
15-
| 0 | 0x0693591673540bc503c2fa5b68bdab8063375683b2752b183c3cf0e04ca42f78 |
16-
| 1 | 0x1af5235d0f22035d0f266865faa1884e036235131e0068f82ab824d3ec833226 |
17-
| 2 | 0x230b5a55179da08c06dfe23fcd5e18c5a3364dc8c43f8d86db32404481a85723 |
18-
| 3 | 0x0ae54d4588816ca99bc592ff436e844287a605a2f7268d6816e3f1bf5c2fc5cf |
21+
| 1 | 0x09489945604c9686e698cb69d7bd6fc0cdb02e9faae3e1a433f1c342c1a5ecc4 |
22+
| 2 | 0x2d961d9814298c04a4639a56c5c95030d704340ab6d13c135a326da5e515559d |
23+
| 3 | 0x0a1d1f62bdd17dbdd447feccd23471821e7e43f1ce9165f636513b83a9933474 |
24+
| 4 | 0x273e0772e851cd0d83d77f05f334d156bc53194e42e8680c6d9469b3aa887eb1 |
1925

20-
This gives intermediate hashes of `0x0a93e3f9a5af4abe169499e3ecb3e0025014467d673983c959a359a1ae5f25b7` (`pedersen(commitment0, commitment1)`) and `0x189f8f83d5a665aa299216fb5562f7064885af3e879ac53aeba450d73ca425b3` (`pedersen(commitment2, commitment3)`) and a root hash of `0x19ac85420cee4b5231c575ed4ab7a4bdade6c4de28ca651a406a02307f3e6ca1`.
26+
This gives intermediate hashes of `0x083ed6aeca136c6159a761749f6db0c192bacf04294e22ed968ae1a845f97285` (`pedersen(commitment0, commitment1)`) and `0x1501e80783ee5c988327f46f5fcdce388cb97aa7e959ad345c1e2cbaa0b42b83` (`pedersen(commitment2, commitment3)`) and a root hash of `0x29fd5ee89e33f559a7b32ac39f57400aa5a6c77492e28c088f9eb511b0c73e78`.
2127

2228
2. Users will input their information into the circuit and generate a proof (see example inputs in [Prover.toml](./circuits/Prover.toml) and run `nargo prove` to generate the proof.)
2329
1. Public inputs and outputs are printed in [Verifier.toml](./circuits/Verifier.toml).
30+
2. The proof is saved to `./proofs/foundry_voting.proof`.
2431
3. The generated proof + the contents of Verifier.toml are sent in a transaction to the `castVote` function in the [zkVote](./src/zkVote.sol) contract. The function verifies that the sender is authorized to vote on the proposal, that they haven't already voted and tallies their vote.
2532

2633
## Testing
@@ -29,10 +36,19 @@ You can run the Noir tests (also defined in main.nr) with `nargo test`. To print
2936

3037
See the test file [here](./test/zkVote.t.sol). Run tests with `forge test`.
3138

39+
1. Run `nargo compile` to compile the circuit.
40+
2. Run `nargo prove` to generate the proof (with the inputs in Prover.toml).
41+
3. Run `yarn test` to run the Foundry test the Solidity verifier contract at `./test/zkVote.t.sol`.
42+
4. Run `yarn integration-test` to run Javascript tests (at `./test/integration.test.ts`) using [bb.js](https://www.npmjs.com/package/@aztec/bb.js).
43+
3244
## Development
3345

3446
If you change the circuit at `./circuits/src/main.nr` you will need to recompile (`nargo compile`) the circuit and regenerate the Solidity verifier (saved to `./circuits/contract/plonk_vk.sol`).
3547

36-
The merkle tree will need to be recalculated whenever there are users added to the set or if there are any changes to the voters private keys (private keys are an input to the merkle membership commitment, so changing a key changes the corresponding leaf in the merkle tree, which changes the root). See `test_build_merkle_tree` for an example calculation.
48+
The merkle tree will need to be recalculated whenever there are users added to the set or if there are any changes to the voters secrets (secrets are the input to the merkle membership commitment, so changing a key changes the corresponding leaf in the merkle tree, which changes the root). See `test_valid_build_merkle_tree` for an example calculation.
3749

3850
Run `nargo test --show-output` in `./circuits` to print the example merkle tree.
51+
52+
## Contributions
53+
54+
Thanks to the folks at zkCamp modifying the original example and adding tests. You can see their repo [here](https://github.com/ZKCamp/noir-voting/tree/6-security).

foundry-voting/circuits/Nargo.toml

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[package]
22
authors = [""]
3-
compiler_version = "~0.9.0"
4-
name="foundry-voting"
3+
compiler_version = "~0.10.3"
4+
name="foundry_voting"
5+
type="bin"
56

67
[dependencies]

foundry-voting/circuits/Prover.toml

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
hash_path = ["0x1af5235d0f22035d0f266865faa1884e036235131e0068f82ab824d3ec833226", "0x189f8f83d5a665aa299216fb5562f7064885af3e879ac53aeba450d73ca425b3"]
1+
hash_path = [
2+
"0x2d961d9814298c04a4639a56c5c95030d704340ab6d13c135a326da5e515559d",
3+
"0x1501e80783ee5c988327f46f5fcdce388cb97aa7e959ad345c1e2cbaa0b42b83"
4+
]
25
index = "0"
3-
priv_key = "0"
46
proposalId = "0"
5-
root = "0x19ac85420cee4b5231c575ed4ab7a4bdade6c4de28ca651a406a02307f3e6ca1"
6-
secret = "9"
7+
root = "0x29fd5ee89e33f559a7b32ac39f57400aa5a6c77492e28c088f9eb511b0c73e78"
8+
secret = "1"
79
vote = "1"

foundry-voting/circuits/Verifier.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
proposalId = "0x0000000000000000000000000000000000000000000000000000000000000000"
2-
return = "0x1f2a72a3c5164d009ac411547f6b01902ab8617fedf46801b828024a3ff75a1f"
3-
root = "0x19ac85420cee4b5231c575ed4ab7a4bdade6c4de28ca651a406a02307f3e6ca1"
2+
return = "0x1cbb284a43dde14da2c3790e12872bcb7e53c53e27b5187384c617841174ace5"
3+
root = "0x29fd5ee89e33f559a7b32ac39f57400aa5a6c77492e28c088f9eb511b0c73e78"
44
vote = "0x0000000000000000000000000000000000000000000000000000000000000001"

foundry-voting/circuits/contract/plonk_vk.sol renamed to foundry-voting/circuits/contract/foundry_voting/plonk_vk.sol

+38-38
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
// Verification Key Hash: b3695c624942d6c3800d6fb1e7beeb468279b1f28ddda4ea2ca83b81fb7e8435
1+
// Verification Key Hash: da5a5e70e0e0c2d136ca2f74c2877691df22658142d6cb0af0b4e8926ed89db9
22
// SPDX-License-Identifier: Apache-2.0
33
// Copyright 2022 Aztec
44
pragma solidity >=0.8.4;
55

66
library UltraVerificationKey {
77
function verificationKeyHash() internal pure returns(bytes32) {
8-
return 0xb3695c624942d6c3800d6fb1e7beeb468279b1f28ddda4ea2ca83b81fb7e8435;
8+
return 0xda5a5e70e0e0c2d136ca2f74c2877691df22658142d6cb0af0b4e8926ed89db9;
99
}
1010

1111
function loadVerificationKey(uint256 _vk, uint256 _omegaInverseLoc) internal pure {
@@ -14,34 +14,34 @@ library UltraVerificationKey {
1414
mstore(add(_vk, 0x20), 0x0000000000000000000000000000000000000000000000000000000000000004) // vk.num_inputs
1515
mstore(add(_vk, 0x40), 0x2d965651cdd9e4811f4e51b80ddca8a8b4a93ee17420aae6adaa01c2617c6e85) // vk.work_root
1616
mstore(add(_vk, 0x60), 0x30638ce1a7661b6337a964756aa75257c6bf4778d89789ab819ce60c19b04001) // vk.domain_inverse
17-
mstore(add(_vk, 0x80), 0x06893744587a78e6b22f43c95681e1d165ad3e571aa20d3a961735d5912b7167) // vk.Q1.x
18-
mstore(add(_vk, 0xa0), 0x0384ebc0f205cde5b8209ad74ba4f27a020a0d43098e0a6c55afb7a36f6d75be) // vk.Q1.y
19-
mstore(add(_vk, 0xc0), 0x1d2f0336a962798061347ac13004e443d6d40eb8ea5309e4e508dd3ba7de582d) // vk.Q2.x
20-
mstore(add(_vk, 0xe0), 0x0f0db413f8c7110c86b5ce8eb425fd9fdc5267dbd5694c3b1dd95ac33e534e42) // vk.Q2.y
21-
mstore(add(_vk, 0x100), 0x002d7e6854ea4c473f86d62824cebdee1901d092cb59b4c8d9bab1c3f6f2210a) // vk.Q3.x
22-
mstore(add(_vk, 0x120), 0x1e51ff2e7a80cf9b952668d5e3d236ecab32ab7a5613a8bc4d3ec04cf39047fd) // vk.Q3.y
23-
mstore(add(_vk, 0x140), 0x2a8c62c6c272cabb1cede4c909f3cfa7f0543c57fafef9b9de4dd28a1cfc985d) // vk.Q4.x
24-
mstore(add(_vk, 0x160), 0x1e80bc6920ecce585f36230f7a07f6eebf55688bae6293e729212e36fbc30be4) // vk.Q4.y
25-
mstore(add(_vk, 0x180), 0x11cccad225bc19c13f4bc640ef2fe9a5ebf223076c0d8d92428a97125eae783e) // vk.Q_M.x
26-
mstore(add(_vk, 0x1a0), 0x0a872f033666474aeebf086b8191b82fab3d5832202aecc59ea5ffd76acfea75) // vk.Q_M.y
27-
mstore(add(_vk, 0x1c0), 0x115215c8ae254f91205ecac007728561820122f2b4c8cbbec4d93fb807abda89) // vk.Q_C.x
28-
mstore(add(_vk, 0x1e0), 0x24a23924c358d293c161cc4bc3b8bcf3ff1657f7fb4c64a68e93bef76f7d63a3) // vk.Q_C.y
29-
mstore(add(_vk, 0x200), 0x05662759e52ce6832ee3f65777d75c322d2b3f9c3444c70b58a9800ac357f075) // vk.Q_ARITHMETIC.x
30-
mstore(add(_vk, 0x220), 0x158ac1a2820981144053d468aa52d0f346e72e17786ecc07566281992e86be68) // vk.Q_ARITHMETIC.y
31-
mstore(add(_vk, 0x240), 0x044dd066ce1d43f94cf8ee69b736bdf227ee38f69ae06d4c39fffacfcd8d4e87) // vk.QSORT.x
32-
mstore(add(_vk, 0x260), 0x112d1606e42e7d1962d22b3a16df8026b971b8788bb460efb9bb5375fe4698cd) // vk.QSORT.y
33-
mstore(add(_vk, 0x280), 0x18284a46d5a4fc069851084dc72f3d271a5fc0869e7f12581d080645100e57a5) // vk.Q_ELLIPTIC.x
34-
mstore(add(_vk, 0x2a0), 0x0472b23370d87786283484af4e5b10b78d0c83a89bd4b195478ecb4fa281eea0) // vk.Q_ELLIPTIC.y
17+
mstore(add(_vk, 0x80), 0x2dfdec1c24af7ea1ec6a7dbd88a8edb3baec0f3740a3eccfdb93800bfd08c9c3) // vk.Q1.x
18+
mstore(add(_vk, 0xa0), 0x2781fa9c03cfb6de679f99923abbeaec7a6181e417fc9f6e50ab5d05d3815a79) // vk.Q1.y
19+
mstore(add(_vk, 0xc0), 0x29f7c3c3b3554485138fbcdd7a9239d5206d0107518c2a8fcf7425e7448416c1) // vk.Q2.x
20+
mstore(add(_vk, 0xe0), 0x2e05f7fe8bfe301e9f162ed47bd4964c7286ec6da6e99f24a7bfbf9999a8190d) // vk.Q2.y
21+
mstore(add(_vk, 0x100), 0x170647ce252c0515d2923a5817a8a69590f514ebe833deb666bddde866382943) // vk.Q3.x
22+
mstore(add(_vk, 0x120), 0x27d6e9e9e426b8c1f8124be468738bc35eb66f99999de656785810f6ae745596) // vk.Q3.y
23+
mstore(add(_vk, 0x140), 0x04b1c3effa71f9dcbe5e4ae45ff157ce241e9c870853e966b66f0b74f732e878) // vk.Q4.x
24+
mstore(add(_vk, 0x160), 0x281bd97f1dab20ef27188c237ad4915b01136a081ffe0ee1155c5f616c305494) // vk.Q4.y
25+
mstore(add(_vk, 0x180), 0x1b801fa24e430163449328ddf55857ec271af7a102f1565b1b6cf37b2cc653a2) // vk.Q_M.x
26+
mstore(add(_vk, 0x1a0), 0x13410e80fd1d1e23a3faf025c4afaf15f388d75b20bb0fef26a4f12062644dd9) // vk.Q_M.y
27+
mstore(add(_vk, 0x1c0), 0x2987db21d6700e8e857d7a06c3ed20b9973ed4597b3bc9e39541831862882385) // vk.Q_C.x
28+
mstore(add(_vk, 0x1e0), 0x0557c9c50fdabe48ff74c722c431dcd4a698487fb16d5915fd2946f415c66adb) // vk.Q_C.y
29+
mstore(add(_vk, 0x200), 0x1fc4da1e4b16936c3a64bacd001de24641e7846b4b7d76c91773d4e8c4190931) // vk.Q_ARITHMETIC.x
30+
mstore(add(_vk, 0x220), 0x1d10cbcfc1827f5faa5ae28533ecf122497588c7a9ec056dd4bd14b2c8329869) // vk.Q_ARITHMETIC.y
31+
mstore(add(_vk, 0x240), 0x095b878c7b6b1ccc9e88a8ec3d384be4909ea92251e901b1e8607f3ad2fff30d) // vk.QSORT.x
32+
mstore(add(_vk, 0x260), 0x209c9e9eaedfbf9ae8cc12e46a71275b2afd367f7d3b1b78a93141951d0c0436) // vk.QSORT.y
33+
mstore(add(_vk, 0x280), 0x04aab36b9d942b0a90df6e83ce9feb7beff3e9d96722ea67212eb11b31d8de88) // vk.Q_ELLIPTIC.x
34+
mstore(add(_vk, 0x2a0), 0x2fd7b92e77690611a826a1cda4991ade3ba1588ee79258af32922f8908d69bd0) // vk.Q_ELLIPTIC.y
3535
mstore(add(_vk, 0x2c0), 0x2c4c5b5ebd83d5248c92a7ef9552c3b45bcd805ed7c28e911beb9634f3ee5843) // vk.Q_AUX.x
3636
mstore(add(_vk, 0x2e0), 0x1c3e8854a1e23d7f9d2e76f71b85de046c50622c7c3346787f392f89d5c29526) // vk.Q_AUX.y
37-
mstore(add(_vk, 0x300), 0x0bdc9990d118ba303feb573892e1612b0e98178183618a06c6e3e3dee07b3c28) // vk.SIGMA1.x
38-
mstore(add(_vk, 0x320), 0x1badaafa69dae5f0ee685d4bbc23dd2a7902552d5c5468517807ba82f66deb86) // vk.SIGMA1.y
39-
mstore(add(_vk, 0x340), 0x13210c63eba88f5d343bbc792ba902c3ba5f7ffebfbc8f5d9b51fb490ecd4cd2) // vk.SIGMA2.x
40-
mstore(add(_vk, 0x360), 0x2e3a7851e752d34fdf4a5c293cb8e58f21ab6542f81c31e057143966a3d05459) // vk.SIGMA2.y
41-
mstore(add(_vk, 0x380), 0x0ba14b991f5d82ba099ed4d8f992d751d71d61f93d59d2b3e9133b8023002554) // vk.SIGMA3.x
42-
mstore(add(_vk, 0x3a0), 0x2fc8093a0ddf66da4245ac37130ba3b54bf296360cd335213c62fec90a70bf9b) // vk.SIGMA3.y
43-
mstore(add(_vk, 0x3c0), 0x1c3356d8aeaf1a9e45cdb93fd3fd01c858662b3c985318c26814c814d1a6c5f7) // vk.SIGMA4.x
44-
mstore(add(_vk, 0x3e0), 0x18c6a83677935bfa483821542c5329343e9eee9c4fc5bf7d20502ba843e63b1d) // vk.SIGMA4.y
37+
mstore(add(_vk, 0x300), 0x2f63e0c6209436ee7e53aad9c6c54f5fd5a31b43d0a2f80decfdd79d4b9a00f9) // vk.SIGMA1.x
38+
mstore(add(_vk, 0x320), 0x2a1e4285c14945f095b83b605ba65edf65d6e9aed7ad561e137a7447a59fba16) // vk.SIGMA1.y
39+
mstore(add(_vk, 0x340), 0x0f317660f71793831134920360d57981324f3dbdbd96846a348ac2d885d181a2) // vk.SIGMA2.x
40+
mstore(add(_vk, 0x360), 0x1d3bb219f7e9e6c71c4e9f028055620871730555394c151a95c276ab97b7dee1) // vk.SIGMA2.y
41+
mstore(add(_vk, 0x380), 0x2086658ef3b7aed5b38d35b39ea41eb696468d6f2d748a24d1eae055eae10ec9) // vk.SIGMA3.x
42+
mstore(add(_vk, 0x3a0), 0x02f38917edcd1d7f04f49bff16711ce19a75be82134c6967eef6640bb41da9ad) // vk.SIGMA3.y
43+
mstore(add(_vk, 0x3c0), 0x00c0653f73ed99d028d10181add2a7968bd18bfea65104512a6723488c2ecc3c) // vk.SIGMA4.x
44+
mstore(add(_vk, 0x3e0), 0x0f05133d72ed5f69c55f3b838d522afed45535824972e790892ab774cba7e27b) // vk.SIGMA4.y
4545
mstore(add(_vk, 0x400), 0x1967204ca4d4bcda212da5d8c3d167670fa8eb4f194821e2b58d4e903fdaf697) // vk.TABLE1.x
4646
mstore(add(_vk, 0x420), 0x2c2c5f454b384ceab390e24e72e967cb05eead9e45a234b182ca96303adf9004) // vk.TABLE1.y
4747
mstore(add(_vk, 0x440), 0x23214c84f0e5004bb8d81b18355e527236e4c790e60c7d063cd23b92cf311bd6) // vk.TABLE2.x
@@ -50,16 +50,16 @@ library UltraVerificationKey {
5050
mstore(add(_vk, 0x4a0), 0x2de768e6c0360d2e8ef2ee405cf1f4c5b0fa47a0942f0ffa078832bc563d6db5) // vk.TABLE3.y
5151
mstore(add(_vk, 0x4c0), 0x195d9df89ed03300614b539f468481451efc9869ad8ca7c921ff209ca4431715) // vk.TABLE4.x
5252
mstore(add(_vk, 0x4e0), 0x2b74a335fb3df4112ca1c451f833a83fe65b7ba143da8ae5223071926da2efce) // vk.TABLE4.y
53-
mstore(add(_vk, 0x500), 0x0878601dcd2bf47445e7f72095b674581de2e52f1221e82b1b1e97273c194864) // vk.TABLE_TYPE.x
54-
mstore(add(_vk, 0x520), 0x2228322e96e72a589ed4484f41c3ba9a24e390b4bfeea2eb458330a6c004ee1a) // vk.TABLE_TYPE.y
55-
mstore(add(_vk, 0x540), 0x0c127fb59accbcea2e6b11ba591ccebeafdf7c38ad799e4a736e816d73dc1970) // vk.ID1.x
56-
mstore(add(_vk, 0x560), 0x160714458c92ebad65969ac900a708cb1eeee8942815f69f2ff997f9add297c0) // vk.ID1.y
57-
mstore(add(_vk, 0x580), 0x04f74d6dfb6d56eb2126abaa0bb1acc568df454fe9b88c4494d47edf7e1ce87f) // vk.ID2.x
58-
mstore(add(_vk, 0x5a0), 0x14300956aa59112899f9aaf1c36b5b6c752770842b280275b760b23d7c85eeed) // vk.ID2.y
59-
mstore(add(_vk, 0x5c0), 0x1e6d216a0491f40125ac4a4329f8f7eba5fbd15ef4b31893038101179409b9e3) // vk.ID3.x
60-
mstore(add(_vk, 0x5e0), 0x23c74092c41c87fe5dd24579a8fb2a7b39b12521b879a258a36bf920d4b7560c) // vk.ID3.y
61-
mstore(add(_vk, 0x600), 0x1c398a08551103c30f2d3b0293f75594145387242b6fcaaa8ca631bf435e53f7) // vk.ID4.x
62-
mstore(add(_vk, 0x620), 0x2459150ee6bf1b45f65b1671d08ec9d67b4b0373e8c69e0995e24616919d4224) // vk.ID4.y
53+
mstore(add(_vk, 0x500), 0x04dc7b142f1e099d13302d1817f2af1fead5f6ce44e8ad026c821ecfdc027be4) // vk.TABLE_TYPE.x
54+
mstore(add(_vk, 0x520), 0x21de2049ef458a725349839be44f0df2ac9e1ffc07f43aa16755d15a48c7e5a9) // vk.TABLE_TYPE.y
55+
mstore(add(_vk, 0x540), 0x232b1ac5a3d368bb761a4de0b99a4b066950c0f15150f9c4ba9d58426aeaf0e8) // vk.ID1.x
56+
mstore(add(_vk, 0x560), 0x1f982a159461b265480c31f627fca54d7043012bd7e3fe62a81721d8b3fdff8f) // vk.ID1.y
57+
mstore(add(_vk, 0x580), 0x2749c843e6f563c973cf089aa3cf643c41a29b7135fd01064db958b1b21bc14f) // vk.ID2.x
58+
mstore(add(_vk, 0x5a0), 0x1affc8f2677c84c1ef07ad18cd8ecd0cdd6a705f4d980edc893a6a5ecff08398) // vk.ID2.y
59+
mstore(add(_vk, 0x5c0), 0x0a072cf26a17d76319d383592ed78da817dff9eb6e396a40c2539cde14521dee) // vk.ID3.x
60+
mstore(add(_vk, 0x5e0), 0x01e3e00fd2ab5c0b90c9c840f7fbb4ed761d76b941c29ffc170bc9e1c0a718c4) // vk.ID3.y
61+
mstore(add(_vk, 0x600), 0x14d037bd5a1b75d876bc1c185602aeb84d0115c048807897ec9397e9b13ac8fb) // vk.ID4.x
62+
mstore(add(_vk, 0x620), 0x053c6997ab4dac3ba9feefbfc979a5a74e322dc33b884766475784be19fe7f15) // vk.ID4.y
6363
mstore(add(_vk, 0x640), 0x00) // vk.contains_recursive_proof
6464
mstore(add(_vk, 0x660), 0) // vk.recursive_proof_public_input_indices
6565
mstore(add(_vk, 0x680), 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1) // vk.g2_x.X.c1

0 commit comments

Comments
 (0)