From 82b83a70ebe50427766303c2cb45ccc28efeed2a Mon Sep 17 00:00:00 2001 From: ananas Date: Thu, 15 Jan 2026 22:44:58 +0000 Subject: [PATCH 1/2] Include data_hash in nullifier computation Update nullifier formula from Poseidon(verification_id, private_key) to Poseidon(verification_id, private_key, data_hash) where data_hash is Poseidon(issuer_hashed, credential_pubkey). This binds the nullifier to the credential's on-chain data commitment, ensuring the nullifier is unique per credential and issuer combination. --- zk/zk-id/CLAUDE.md | 6 +- zk/zk-id/Cargo.lock | 21 +++ zk/zk-id/Cargo.toml | 29 ++++ zk/zk-id/build.rs | 2 +- .../compressed_account_merkle_proof.circom | 22 +-- zk/zk-id/programs/zk-id/src/verifying_key.rs | 125 +++--------------- zk/zk-id/tests/circuit.rs | 23 +++- zk/zk-id/tests/test.rs | 48 +++---- zk/zk-id/ts-tests/zk-id.test.ts | 44 ++++-- 9 files changed, 157 insertions(+), 163 deletions(-) diff --git a/zk/zk-id/CLAUDE.md b/zk/zk-id/CLAUDE.md index 98a1586..1395736 100644 --- a/zk/zk-id/CLAUDE.md +++ b/zk/zk-id/CLAUDE.md @@ -6,7 +6,7 @@ Zero-knowledge identity verification using Groth16 proofs with compressed accoun - Issuers create credentials for users; users prove credential ownership without revealing the credential - Credential keypair: private key = `Sha256(sign("CREDENTIAL"))` truncated to 248 bits; public key = `Poseidon(private_key)` -- Nullifier = `Poseidon(verification_id, credential_private_key)` - prevents double-use per verification context +- Nullifier = `Poseidon(verification_id, credential_private_key, data_hash)` where `data_hash = Poseidon(issuer_hashed, credential_public_key)` - prevents double-use per verification context and binds to credential's on-chain data - ZK circuit verifies 26-level Merkle proof of credential account inclusion ## [README](README.md) @@ -78,8 +78,8 @@ derive_address(&[seed_prefix, identifier], &address_tree_pubkey, &program_id) **Circuit flow**: 1. Derive `credential_pubkey = Poseidon(privateKey)` via `Keypair` template -2. Verify `nullifier = Poseidon(verification_id, privateKey)` -3. Compute `data_hash = Poseidon(issuer_hashed, credential_pubkey)` +2. Compute `data_hash = Poseidon(issuer_hashed, credential_pubkey)` +3. Verify `nullifier = Poseidon(verification_id, privateKey, data_hash)` 4. Compute account hash via `CompressedAccountHash` (adds discriminator domain `+36893488147419103232`) 5. Verify 26-level Merkle proof against `expectedRoot` 6. Verify `public_encrypted_data_hash === encrypted_data_hash` diff --git a/zk/zk-id/Cargo.lock b/zk/zk-id/Cargo.lock index 312eca3..85a9c55 100644 --- a/zk/zk-id/Cargo.lock +++ b/zk/zk-id/Cargo.lock @@ -8818,6 +8818,27 @@ dependencies = [ "tokio", ] +[[package]] +name = "zk-id-tests" +version = "0.1.0" +dependencies = [ + "anchor-lang", + "circom-prover", + "groth16-solana", + "light-client", + "light-compressed-account", + "light-hasher", + "light-merkle-tree-reference", + "light-program-test", + "light-sdk", + "num-bigint 0.4.6", + "rust-witness", + "serde_json", + "solana-sdk", + "tokio", + "zk-id", +] + [[package]] name = "zstd" version = "0.13.3" diff --git a/zk/zk-id/Cargo.toml b/zk/zk-id/Cargo.toml index bbd53ee..f178583 100644 --- a/zk/zk-id/Cargo.toml +++ b/zk/zk-id/Cargo.toml @@ -1,7 +1,36 @@ +[package] +name = "zk-id-tests" +version = "0.1.0" +edition = "2021" +publish = false + [workspace] members = ["programs/zk-id"] resolver = "2" +[dependencies] +zk-id = { path = "programs/zk-id" } + +[dev-dependencies] +anchor-lang = "0.31.1" +circom-prover = "0.1" +rust-witness = "0.1" +num-bigint = "0.4" +serde_json = "1.0" +solana-sdk = "2.2" +tokio = "1.40.0" +light-hasher = { version = "5.0.0", features = ["sha256", "keccak", "poseidon"] } +light-compressed-account = { version = "0.7.0", features = ["new-unique"] } +light-merkle-tree-reference = "4.0.0" +light-program-test = { version = "0.17.1", features = ["v2"] } +light-client = { version = "0.17.2", features = ["v2"] } +light-sdk = { version = "0.17.1", features = ["anchor", "poseidon", "merkle-tree", "v2"] } +groth16-solana = { git = "https://github.com/Lightprotocol/groth16-solana", features = ["vk", "circom"], rev = "66c0dc87d0808c4d2aadb53c61435b6edb8ddfd9" } + +[build-dependencies] +rust-witness = "0.1" +groth16-solana = { git = "https://github.com/Lightprotocol/groth16-solana", features = ["vk"], rev = "66c0dc87d0808c4d2aadb53c61435b6edb8ddfd9" } + [profile.release] overflow-checks = true lto = "fat" diff --git a/zk/zk-id/build.rs b/zk/zk-id/build.rs index 65cdd88..245d08f 100644 --- a/zk/zk-id/build.rs +++ b/zk/zk-id/build.rs @@ -6,7 +6,7 @@ fn main() { // Generate the verifying key Rust file from the JSON let vk_json_path = "./build/verification_key.json"; - let output_dir = "./src"; + let output_dir = "./programs/zk-id/src"; let output_file = "verifying_key.rs"; if std::path::Path::new(vk_json_path).exists() { diff --git a/zk/zk-id/circuits/compressed_account_merkle_proof.circom b/zk/zk-id/circuits/compressed_account_merkle_proof.circom index b915b15..7e15b59 100644 --- a/zk/zk-id/circuits/compressed_account_merkle_proof.circom +++ b/zk/zk-id/circuits/compressed_account_merkle_proof.circom @@ -49,21 +49,23 @@ template CompressedAccountMerkleProof(levels) { keypair.privateKey <== credentialPrivateKey; signal credential_pubkey_commitment <== keypair.publicKey; - // Step 2: Compute and verify nullifier - // Nullifier = Poseidon(verification_id, credentialPrivateKey) - // This ensures each credential can only be used once per verification_id - // without leaking information about the credential itself. - component nullifierHasher = Poseidon(2); - nullifierHasher.inputs[0] <== verification_id; - nullifierHasher.inputs[1] <== credentialPrivateKey; - nullifier === nullifierHasher.out; - - // Step 3: Compute the credential data hash (used internally for account hash) + // Step 2: Compute the credential data hash + // data_hash = Poseidon(issuer_hashed, credential_pubkey_commitment) component data_hasher = Poseidon(2); data_hasher.inputs[0] <== issuer_hashed; data_hasher.inputs[1] <== credential_pubkey_commitment; signal data_hash <== data_hasher.out; + // Step 3: Compute and verify nullifier + // Nullifier = Poseidon(verification_id, credentialPrivateKey, data_hash) + // This ensures each credential can only be used once per verification_id + // and binds the nullifier to the credential's on-chain data commitment. + component nullifierHasher = Poseidon(3); + nullifierHasher.inputs[0] <== verification_id; + nullifierHasher.inputs[1] <== credentialPrivateKey; + nullifierHasher.inputs[2] <== data_hash; + nullifier === nullifierHasher.out; + // Step 4: Compute compressed account hash component accountHasher = CompressedAccountHash(); accountHasher.owner_hashed <== owner_hashed; diff --git a/zk/zk-id/programs/zk-id/src/verifying_key.rs b/zk/zk-id/programs/zk-id/src/verifying_key.rs index e58ffa5..03a95e6 100644 --- a/zk/zk-id/programs/zk-id/src/verifying_key.rs +++ b/zk/zk-id/programs/zk-id/src/verifying_key.rs @@ -1,118 +1,25 @@ use groth16_solana::groth16::Groth16Verifyingkey; pub const VERIFYINGKEY: Groth16Verifyingkey = Groth16Verifyingkey { - nr_pubinputs: 8, + nr_pubinputs: 8, - vk_alpha_g1: [ - 45u8, 77u8, 154u8, 167u8, 227u8, 2u8, 217u8, 223u8, 65u8, 116u8, 157u8, 85u8, 7u8, 148u8, - 157u8, 5u8, 219u8, 234u8, 51u8, 251u8, 177u8, 108u8, 100u8, 59u8, 34u8, 245u8, 153u8, - 162u8, 190u8, 109u8, 242u8, 226u8, 20u8, 190u8, 221u8, 80u8, 60u8, 55u8, 206u8, 176u8, - 97u8, 216u8, 236u8, 96u8, 32u8, 159u8, 227u8, 69u8, 206u8, 137u8, 131u8, 10u8, 25u8, 35u8, - 3u8, 1u8, 240u8, 118u8, 202u8, 255u8, 0u8, 77u8, 25u8, 38u8, - ], + vk_alpha_g1: [45u8, 77u8, 154u8, 167u8, 227u8, 2u8, 217u8, 223u8, 65u8, 116u8, 157u8, 85u8, 7u8, 148u8, 157u8, 5u8, 219u8, 234u8, 51u8, 251u8, 177u8, 108u8, 100u8, 59u8, 34u8, 245u8, 153u8, 162u8, 190u8, 109u8, 242u8, 226u8, 20u8, 190u8, 221u8, 80u8, 60u8, 55u8, 206u8, 176u8, 97u8, 216u8, 236u8, 96u8, 32u8, 159u8, 227u8, 69u8, 206u8, 137u8, 131u8, 10u8, 25u8, 35u8, 3u8, 1u8, 240u8, 118u8, 202u8, 255u8, 0u8, 77u8, 25u8, 38u8], - vk_beta_g2: [ - 9u8, 103u8, 3u8, 47u8, 203u8, 247u8, 118u8, 209u8, 175u8, 201u8, 133u8, 248u8, 136u8, - 119u8, 241u8, 130u8, 211u8, 132u8, 128u8, 166u8, 83u8, 242u8, 222u8, 202u8, 169u8, 121u8, - 76u8, 188u8, 59u8, 243u8, 6u8, 12u8, 14u8, 24u8, 120u8, 71u8, 173u8, 76u8, 121u8, 131u8, - 116u8, 208u8, 214u8, 115u8, 43u8, 245u8, 1u8, 132u8, 125u8, 214u8, 139u8, 192u8, 224u8, - 113u8, 36u8, 30u8, 2u8, 19u8, 188u8, 127u8, 193u8, 61u8, 183u8, 171u8, 48u8, 76u8, 251u8, - 209u8, 224u8, 138u8, 112u8, 74u8, 153u8, 245u8, 232u8, 71u8, 217u8, 63u8, 140u8, 60u8, - 170u8, 253u8, 222u8, 196u8, 107u8, 122u8, 13u8, 55u8, 157u8, 166u8, 154u8, 77u8, 17u8, - 35u8, 70u8, 167u8, 23u8, 57u8, 193u8, 177u8, 164u8, 87u8, 168u8, 199u8, 49u8, 49u8, 35u8, - 210u8, 77u8, 47u8, 145u8, 146u8, 248u8, 150u8, 183u8, 198u8, 62u8, 234u8, 5u8, 169u8, - 213u8, 127u8, 6u8, 84u8, 122u8, 208u8, 206u8, 200u8, - ], + vk_beta_g2: [9u8, 103u8, 3u8, 47u8, 203u8, 247u8, 118u8, 209u8, 175u8, 201u8, 133u8, 248u8, 136u8, 119u8, 241u8, 130u8, 211u8, 132u8, 128u8, 166u8, 83u8, 242u8, 222u8, 202u8, 169u8, 121u8, 76u8, 188u8, 59u8, 243u8, 6u8, 12u8, 14u8, 24u8, 120u8, 71u8, 173u8, 76u8, 121u8, 131u8, 116u8, 208u8, 214u8, 115u8, 43u8, 245u8, 1u8, 132u8, 125u8, 214u8, 139u8, 192u8, 224u8, 113u8, 36u8, 30u8, 2u8, 19u8, 188u8, 127u8, 193u8, 61u8, 183u8, 171u8, 48u8, 76u8, 251u8, 209u8, 224u8, 138u8, 112u8, 74u8, 153u8, 245u8, 232u8, 71u8, 217u8, 63u8, 140u8, 60u8, 170u8, 253u8, 222u8, 196u8, 107u8, 122u8, 13u8, 55u8, 157u8, 166u8, 154u8, 77u8, 17u8, 35u8, 70u8, 167u8, 23u8, 57u8, 193u8, 177u8, 164u8, 87u8, 168u8, 199u8, 49u8, 49u8, 35u8, 210u8, 77u8, 47u8, 145u8, 146u8, 248u8, 150u8, 183u8, 198u8, 62u8, 234u8, 5u8, 169u8, 213u8, 127u8, 6u8, 84u8, 122u8, 208u8, 206u8, 200u8], - vk_gamma_g2: [ - 25u8, 142u8, 147u8, 147u8, 146u8, 13u8, 72u8, 58u8, 114u8, 96u8, 191u8, 183u8, 49u8, 251u8, - 93u8, 37u8, 241u8, 170u8, 73u8, 51u8, 53u8, 169u8, 231u8, 18u8, 151u8, 228u8, 133u8, 183u8, - 174u8, 243u8, 18u8, 194u8, 24u8, 0u8, 222u8, 239u8, 18u8, 31u8, 30u8, 118u8, 66u8, 106u8, - 0u8, 102u8, 94u8, 92u8, 68u8, 121u8, 103u8, 67u8, 34u8, 212u8, 247u8, 94u8, 218u8, 221u8, - 70u8, 222u8, 189u8, 92u8, 217u8, 146u8, 246u8, 237u8, 9u8, 6u8, 137u8, 208u8, 88u8, 95u8, - 240u8, 117u8, 236u8, 158u8, 153u8, 173u8, 105u8, 12u8, 51u8, 149u8, 188u8, 75u8, 49u8, - 51u8, 112u8, 179u8, 142u8, 243u8, 85u8, 172u8, 218u8, 220u8, 209u8, 34u8, 151u8, 91u8, - 18u8, 200u8, 94u8, 165u8, 219u8, 140u8, 109u8, 235u8, 74u8, 171u8, 113u8, 128u8, 141u8, - 203u8, 64u8, 143u8, 227u8, 209u8, 231u8, 105u8, 12u8, 67u8, 211u8, 123u8, 76u8, 230u8, - 204u8, 1u8, 102u8, 250u8, 125u8, 170u8, - ], + vk_gamma_g2: [25u8, 142u8, 147u8, 147u8, 146u8, 13u8, 72u8, 58u8, 114u8, 96u8, 191u8, 183u8, 49u8, 251u8, 93u8, 37u8, 241u8, 170u8, 73u8, 51u8, 53u8, 169u8, 231u8, 18u8, 151u8, 228u8, 133u8, 183u8, 174u8, 243u8, 18u8, 194u8, 24u8, 0u8, 222u8, 239u8, 18u8, 31u8, 30u8, 118u8, 66u8, 106u8, 0u8, 102u8, 94u8, 92u8, 68u8, 121u8, 103u8, 67u8, 34u8, 212u8, 247u8, 94u8, 218u8, 221u8, 70u8, 222u8, 189u8, 92u8, 217u8, 146u8, 246u8, 237u8, 9u8, 6u8, 137u8, 208u8, 88u8, 95u8, 240u8, 117u8, 236u8, 158u8, 153u8, 173u8, 105u8, 12u8, 51u8, 149u8, 188u8, 75u8, 49u8, 51u8, 112u8, 179u8, 142u8, 243u8, 85u8, 172u8, 218u8, 220u8, 209u8, 34u8, 151u8, 91u8, 18u8, 200u8, 94u8, 165u8, 219u8, 140u8, 109u8, 235u8, 74u8, 171u8, 113u8, 128u8, 141u8, 203u8, 64u8, 143u8, 227u8, 209u8, 231u8, 105u8, 12u8, 67u8, 211u8, 123u8, 76u8, 230u8, 204u8, 1u8, 102u8, 250u8, 125u8, 170u8], - vk_delta_g2: [ - 10u8, 104u8, 69u8, 40u8, 96u8, 13u8, 219u8, 182u8, 41u8, 197u8, 5u8, 185u8, 131u8, 71u8, - 64u8, 239u8, 140u8, 193u8, 51u8, 15u8, 116u8, 127u8, 45u8, 46u8, 195u8, 199u8, 198u8, 40u8, - 189u8, 252u8, 142u8, 157u8, 11u8, 220u8, 65u8, 180u8, 90u8, 206u8, 239u8, 55u8, 44u8, - 235u8, 94u8, 119u8, 34u8, 208u8, 67u8, 207u8, 87u8, 34u8, 183u8, 228u8, 11u8, 247u8, 88u8, - 51u8, 178u8, 109u8, 124u8, 112u8, 210u8, 231u8, 166u8, 41u8, 16u8, 217u8, 121u8, 56u8, - 158u8, 27u8, 53u8, 77u8, 158u8, 168u8, 195u8, 155u8, 77u8, 68u8, 233u8, 83u8, 129u8, 198u8, - 179u8, 76u8, 42u8, 79u8, 223u8, 157u8, 45u8, 23u8, 170u8, 14u8, 38u8, 242u8, 225u8, 191u8, - 6u8, 45u8, 178u8, 234u8, 57u8, 138u8, 248u8, 4u8, 11u8, 1u8, 250u8, 173u8, 52u8, 50u8, - 254u8, 24u8, 37u8, 79u8, 143u8, 33u8, 186u8, 29u8, 230u8, 72u8, 179u8, 90u8, 236u8, 250u8, - 135u8, 132u8, 22u8, 111u8, - ], + vk_delta_g2: [35u8, 93u8, 218u8, 70u8, 212u8, 161u8, 124u8, 239u8, 162u8, 255u8, 210u8, 95u8, 89u8, 201u8, 218u8, 157u8, 171u8, 171u8, 70u8, 145u8, 149u8, 94u8, 190u8, 16u8, 111u8, 39u8, 248u8, 134u8, 85u8, 250u8, 172u8, 223u8, 9u8, 14u8, 178u8, 122u8, 12u8, 141u8, 26u8, 49u8, 93u8, 25u8, 181u8, 233u8, 14u8, 235u8, 204u8, 150u8, 253u8, 145u8, 78u8, 29u8, 223u8, 194u8, 85u8, 125u8, 249u8, 104u8, 126u8, 172u8, 210u8, 214u8, 91u8, 61u8, 34u8, 228u8, 17u8, 115u8, 225u8, 247u8, 43u8, 243u8, 112u8, 123u8, 82u8, 127u8, 227u8, 18u8, 58u8, 157u8, 71u8, 96u8, 39u8, 68u8, 22u8, 163u8, 59u8, 126u8, 209u8, 180u8, 41u8, 105u8, 76u8, 53u8, 29u8, 220u8, 34u8, 176u8, 140u8, 177u8, 83u8, 42u8, 138u8, 99u8, 31u8, 143u8, 185u8, 170u8, 60u8, 142u8, 154u8, 37u8, 68u8, 227u8, 242u8, 67u8, 49u8, 34u8, 91u8, 221u8, 250u8, 100u8, 17u8, 96u8, 159u8, 61u8, 170u8, 177u8], - vk_ic: &[ - [ - 4u8, 90u8, 11u8, 151u8, 69u8, 42u8, 114u8, 212u8, 111u8, 206u8, 148u8, 104u8, 65u8, - 166u8, 159u8, 137u8, 171u8, 77u8, 109u8, 234u8, 55u8, 135u8, 203u8, 77u8, 67u8, 182u8, - 227u8, 12u8, 202u8, 57u8, 113u8, 13u8, 31u8, 182u8, 157u8, 8u8, 213u8, 65u8, 49u8, - 36u8, 11u8, 76u8, 223u8, 18u8, 37u8, 52u8, 113u8, 212u8, 75u8, 181u8, 222u8, 133u8, - 170u8, 168u8, 234u8, 180u8, 8u8, 110u8, 4u8, 142u8, 160u8, 230u8, 138u8, 175u8, - ], - [ - 6u8, 192u8, 93u8, 129u8, 197u8, 162u8, 187u8, 150u8, 148u8, 208u8, 31u8, 46u8, 2u8, - 172u8, 162u8, 123u8, 81u8, 134u8, 38u8, 219u8, 60u8, 57u8, 111u8, 148u8, 4u8, 41u8, - 227u8, 248u8, 38u8, 44u8, 175u8, 139u8, 18u8, 142u8, 35u8, 202u8, 131u8, 3u8, 138u8, - 65u8, 62u8, 66u8, 141u8, 192u8, 137u8, 210u8, 64u8, 58u8, 168u8, 102u8, 162u8, 204u8, - 187u8, 123u8, 225u8, 235u8, 197u8, 167u8, 28u8, 220u8, 183u8, 101u8, 16u8, 186u8, - ], - [ - 8u8, 193u8, 155u8, 163u8, 55u8, 80u8, 175u8, 199u8, 139u8, 31u8, 49u8, 208u8, 96u8, - 144u8, 174u8, 203u8, 159u8, 203u8, 160u8, 63u8, 135u8, 45u8, 19u8, 133u8, 103u8, 80u8, - 186u8, 102u8, 152u8, 180u8, 149u8, 18u8, 4u8, 33u8, 182u8, 15u8, 44u8, 189u8, 0u8, - 113u8, 253u8, 12u8, 194u8, 38u8, 183u8, 95u8, 252u8, 215u8, 178u8, 46u8, 83u8, 195u8, - 153u8, 75u8, 202u8, 14u8, 111u8, 237u8, 198u8, 161u8, 107u8, 187u8, 4u8, 55u8, - ], - [ - 46u8, 10u8, 95u8, 159u8, 76u8, 32u8, 246u8, 107u8, 45u8, 235u8, 75u8, 185u8, 109u8, - 26u8, 24u8, 129u8, 208u8, 166u8, 64u8, 199u8, 252u8, 251u8, 193u8, 51u8, 19u8, 88u8, - 156u8, 129u8, 114u8, 120u8, 122u8, 32u8, 26u8, 83u8, 113u8, 210u8, 130u8, 243u8, 39u8, - 58u8, 142u8, 18u8, 194u8, 142u8, 184u8, 158u8, 199u8, 113u8, 196u8, 191u8, 215u8, 77u8, - 21u8, 66u8, 162u8, 25u8, 201u8, 70u8, 148u8, 247u8, 173u8, 199u8, 191u8, 131u8, - ], - [ - 16u8, 79u8, 230u8, 65u8, 92u8, 49u8, 63u8, 19u8, 215u8, 29u8, 92u8, 70u8, 81u8, 252u8, - 134u8, 116u8, 115u8, 66u8, 113u8, 76u8, 135u8, 44u8, 188u8, 236u8, 72u8, 218u8, 47u8, - 3u8, 70u8, 85u8, 130u8, 31u8, 40u8, 64u8, 154u8, 29u8, 126u8, 193u8, 234u8, 223u8, - 171u8, 140u8, 166u8, 217u8, 211u8, 241u8, 59u8, 3u8, 20u8, 217u8, 110u8, 174u8, 132u8, - 10u8, 42u8, 121u8, 87u8, 169u8, 37u8, 10u8, 59u8, 167u8, 194u8, 106u8, - ], - [ - 44u8, 136u8, 199u8, 234u8, 22u8, 38u8, 206u8, 40u8, 223u8, 162u8, 56u8, 216u8, 109u8, - 180u8, 5u8, 169u8, 225u8, 203u8, 204u8, 153u8, 140u8, 24u8, 116u8, 123u8, 68u8, 220u8, - 131u8, 114u8, 20u8, 137u8, 230u8, 148u8, 28u8, 10u8, 38u8, 24u8, 120u8, 216u8, 11u8, - 243u8, 26u8, 233u8, 114u8, 85u8, 0u8, 3u8, 27u8, 225u8, 6u8, 41u8, 85u8, 100u8, 148u8, - 97u8, 60u8, 23u8, 64u8, 255u8, 64u8, 34u8, 115u8, 81u8, 235u8, 103u8, - ], - [ - 12u8, 140u8, 197u8, 237u8, 220u8, 64u8, 41u8, 28u8, 134u8, 122u8, 249u8, 54u8, 127u8, - 114u8, 225u8, 243u8, 158u8, 245u8, 164u8, 146u8, 238u8, 253u8, 73u8, 44u8, 88u8, 253u8, - 220u8, 76u8, 231u8, 243u8, 190u8, 184u8, 36u8, 187u8, 51u8, 119u8, 254u8, 79u8, 21u8, - 186u8, 122u8, 154u8, 95u8, 191u8, 113u8, 194u8, 251u8, 85u8, 139u8, 247u8, 155u8, - 237u8, 48u8, 185u8, 216u8, 105u8, 206u8, 92u8, 120u8, 26u8, 188u8, 117u8, 69u8, 224u8, - ], - [ - 23u8, 119u8, 153u8, 159u8, 239u8, 111u8, 103u8, 220u8, 195u8, 184u8, 64u8, 255u8, - 239u8, 78u8, 188u8, 37u8, 193u8, 254u8, 226u8, 63u8, 140u8, 124u8, 70u8, 6u8, 188u8, - 113u8, 37u8, 98u8, 54u8, 10u8, 182u8, 37u8, 9u8, 31u8, 241u8, 30u8, 102u8, 7u8, 244u8, - 97u8, 153u8, 56u8, 35u8, 254u8, 73u8, 54u8, 161u8, 123u8, 61u8, 157u8, 48u8, 66u8, 4u8, - 31u8, 143u8, 142u8, 86u8, 58u8, 162u8, 156u8, 144u8, 116u8, 170u8, 85u8, - ], - [ - 6u8, 144u8, 191u8, 115u8, 83u8, 103u8, 157u8, 108u8, 167u8, 218u8, 159u8, 203u8, 111u8, - 63u8, 129u8, 144u8, 213u8, 133u8, 69u8, 22u8, 56u8, 228u8, 46u8, 147u8, 0u8, 70u8, - 96u8, 85u8, 157u8, 72u8, 158u8, 141u8, 33u8, 26u8, 152u8, 246u8, 49u8, 94u8, 88u8, - 145u8, 79u8, 194u8, 171u8, 203u8, 149u8, 178u8, 138u8, 241u8, 125u8, 228u8, 29u8, 39u8, - 74u8, 210u8, 195u8, 67u8, 43u8, 35u8, 149u8, 225u8, 94u8, 140u8, 224u8, 83u8, - ], - ], + vk_ic: &[ + [6u8, 116u8, 25u8, 196u8, 168u8, 139u8, 50u8, 234u8, 24u8, 80u8, 72u8, 23u8, 1u8, 43u8, 230u8, 178u8, 165u8, 176u8, 101u8, 164u8, 240u8, 6u8, 228u8, 49u8, 213u8, 82u8, 106u8, 117u8, 102u8, 23u8, 57u8, 101u8, 6u8, 0u8, 22u8, 209u8, 170u8, 16u8, 2u8, 213u8, 10u8, 138u8, 98u8, 195u8, 189u8, 38u8, 61u8, 204u8, 249u8, 53u8, 98u8, 199u8, 88u8, 168u8, 175u8, 253u8, 183u8, 49u8, 46u8, 214u8, 46u8, 22u8, 20u8, 9u8], + [13u8, 221u8, 187u8, 171u8, 240u8, 78u8, 162u8, 23u8, 234u8, 32u8, 105u8, 191u8, 86u8, 204u8, 31u8, 214u8, 84u8, 22u8, 120u8, 70u8, 144u8, 122u8, 215u8, 127u8, 216u8, 149u8, 239u8, 74u8, 185u8, 2u8, 147u8, 164u8, 34u8, 238u8, 33u8, 206u8, 139u8, 82u8, 64u8, 206u8, 243u8, 191u8, 84u8, 63u8, 216u8, 199u8, 125u8, 154u8, 86u8, 80u8, 44u8, 178u8, 22u8, 156u8, 128u8, 249u8, 100u8, 55u8, 165u8, 160u8, 31u8, 78u8, 83u8, 68u8], + [43u8, 76u8, 131u8, 233u8, 121u8, 94u8, 117u8, 36u8, 121u8, 55u8, 64u8, 127u8, 145u8, 255u8, 102u8, 135u8, 55u8, 68u8, 113u8, 27u8, 67u8, 241u8, 109u8, 31u8, 175u8, 63u8, 165u8, 56u8, 19u8, 134u8, 234u8, 121u8, 44u8, 171u8, 222u8, 10u8, 13u8, 87u8, 190u8, 105u8, 216u8, 104u8, 36u8, 85u8, 97u8, 66u8, 129u8, 2u8, 137u8, 196u8, 48u8, 167u8, 118u8, 232u8, 5u8, 215u8, 87u8, 13u8, 135u8, 125u8, 159u8, 116u8, 86u8, 67u8], + [19u8, 142u8, 242u8, 236u8, 76u8, 140u8, 97u8, 35u8, 86u8, 205u8, 20u8, 168u8, 70u8, 9u8, 250u8, 3u8, 49u8, 94u8, 8u8, 224u8, 96u8, 18u8, 163u8, 69u8, 176u8, 33u8, 254u8, 86u8, 2u8, 209u8, 227u8, 61u8, 15u8, 135u8, 181u8, 253u8, 64u8, 195u8, 56u8, 76u8, 225u8, 192u8, 167u8, 233u8, 108u8, 252u8, 3u8, 177u8, 160u8, 224u8, 183u8, 203u8, 75u8, 131u8, 176u8, 112u8, 125u8, 148u8, 121u8, 119u8, 111u8, 57u8, 125u8, 168u8], + [7u8, 152u8, 186u8, 253u8, 239u8, 252u8, 239u8, 44u8, 124u8, 128u8, 115u8, 96u8, 18u8, 122u8, 90u8, 34u8, 220u8, 190u8, 223u8, 151u8, 158u8, 218u8, 50u8, 253u8, 25u8, 229u8, 119u8, 201u8, 161u8, 223u8, 178u8, 130u8, 19u8, 126u8, 235u8, 91u8, 131u8, 138u8, 103u8, 7u8, 26u8, 13u8, 203u8, 168u8, 157u8, 140u8, 119u8, 151u8, 239u8, 214u8, 41u8, 231u8, 229u8, 103u8, 234u8, 198u8, 88u8, 249u8, 131u8, 68u8, 229u8, 163u8, 99u8, 41u8], + [37u8, 58u8, 169u8, 29u8, 158u8, 74u8, 77u8, 127u8, 202u8, 187u8, 181u8, 170u8, 44u8, 94u8, 0u8, 214u8, 60u8, 127u8, 104u8, 198u8, 212u8, 0u8, 178u8, 107u8, 109u8, 133u8, 127u8, 196u8, 61u8, 122u8, 122u8, 42u8, 11u8, 1u8, 147u8, 194u8, 208u8, 97u8, 68u8, 193u8, 255u8, 251u8, 141u8, 71u8, 179u8, 93u8, 218u8, 145u8, 239u8, 38u8, 121u8, 23u8, 203u8, 219u8, 186u8, 172u8, 120u8, 223u8, 128u8, 207u8, 171u8, 134u8, 138u8, 162u8], + [40u8, 188u8, 141u8, 174u8, 217u8, 229u8, 72u8, 52u8, 232u8, 100u8, 30u8, 241u8, 1u8, 223u8, 99u8, 28u8, 92u8, 174u8, 57u8, 226u8, 1u8, 248u8, 128u8, 113u8, 182u8, 58u8, 158u8, 203u8, 148u8, 254u8, 239u8, 244u8, 18u8, 100u8, 144u8, 201u8, 214u8, 77u8, 169u8, 224u8, 59u8, 121u8, 163u8, 151u8, 16u8, 148u8, 39u8, 2u8, 224u8, 123u8, 35u8, 102u8, 204u8, 233u8, 93u8, 76u8, 101u8, 111u8, 134u8, 229u8, 26u8, 122u8, 215u8, 151u8], + [23u8, 165u8, 206u8, 29u8, 47u8, 19u8, 149u8, 232u8, 48u8, 112u8, 50u8, 201u8, 139u8, 236u8, 226u8, 197u8, 196u8, 56u8, 89u8, 146u8, 41u8, 46u8, 89u8, 82u8, 37u8, 150u8, 132u8, 32u8, 149u8, 44u8, 222u8, 131u8, 33u8, 96u8, 209u8, 108u8, 151u8, 147u8, 48u8, 101u8, 230u8, 25u8, 214u8, 140u8, 213u8, 36u8, 230u8, 174u8, 147u8, 71u8, 156u8, 44u8, 80u8, 171u8, 47u8, 45u8, 65u8, 213u8, 224u8, 147u8, 196u8, 223u8, 20u8, 230u8], + [14u8, 5u8, 129u8, 121u8, 109u8, 169u8, 0u8, 255u8, 184u8, 100u8, 232u8, 96u8, 112u8, 158u8, 194u8, 213u8, 77u8, 115u8, 130u8, 240u8, 160u8, 240u8, 243u8, 129u8, 8u8, 46u8, 239u8, 65u8, 188u8, 28u8, 236u8, 222u8, 4u8, 104u8, 112u8, 160u8, 235u8, 48u8, 64u8, 159u8, 177u8, 251u8, 42u8, 11u8, 252u8, 133u8, 19u8, 169u8, 77u8, 173u8, 99u8, 145u8, 171u8, 116u8, 203u8, 34u8, 179u8, 218u8, 18u8, 120u8, 163u8, 75u8, 157u8, 15u8] + ] }; diff --git a/zk/zk-id/tests/circuit.rs b/zk/zk-id/tests/circuit.rs index 380e0e5..151c869 100644 --- a/zk/zk-id/tests/circuit.rs +++ b/zk/zk-id/tests/circuit.rs @@ -56,14 +56,23 @@ impl CredentialKeypair { BigUint::from_bytes_be(&self.private_key) } - /// Compute nullifier for a given verification_id - pub fn compute_nullifier(&self, verification_id: &[u8; 31]) -> [u8; 32] { - // Nullifier = Poseidon(verification_id, private_key) - // Both need to be padded to 32 bytes for Poseidon + /// Compute nullifier for a given verification_id and issuer + /// Nullifier = Poseidon(verification_id, private_key, data_hash) + /// where data_hash = Poseidon(issuer_hashed, public_key) + pub fn compute_nullifier( + &self, + verification_id: &[u8; 31], + issuer_hashed: &[u8; 32], + ) -> [u8; 32] { + // First compute data_hash = Poseidon(issuer_hashed, public_key) + let data_hash = Poseidon::hashv(&[issuer_hashed, &self.public_key]).unwrap(); + + // Then compute nullifier = Poseidon(verification_id, private_key, data_hash) + // verification_id needs to be padded to 32 bytes for Poseidon let mut padded_verification = [0u8; 32]; padded_verification[1..32].copy_from_slice(verification_id); - Poseidon::hashv(&[&padded_verification, &self.private_key]).unwrap() + Poseidon::hashv(&[&padded_verification, &self.private_key, &data_hash]).unwrap() } } @@ -110,8 +119,8 @@ fn add_compressed_account_to_circuit_inputs( let mut encrypted_data_hash = Sha256::hash(&hash_input).unwrap(); encrypted_data_hash[0] = 0; - // Compute nullifier using credential private key and verification_id - let nullifier = credential.compute_nullifier(verification_id); + // Compute nullifier using credential private key, verification_id, and issuer + let nullifier = credential.compute_nullifier(verification_id, &issuer_hashed); // Add all inputs to the HashMap inputs.insert( diff --git a/zk/zk-id/tests/test.rs b/zk/zk-id/tests/test.rs index ed8cd01..5da3012 100644 --- a/zk/zk-id/tests/test.rs +++ b/zk/zk-id/tests/test.rs @@ -51,14 +51,23 @@ impl CredentialKeypair { } } - /// Compute nullifier for a given verification_id - pub fn compute_nullifier(&self, verification_id: &[u8; 31]) -> [u8; 32] { - // Nullifier = Poseidon(verification_id, private_key) - // Both need to be padded to 32 bytes for Poseidon + /// Compute nullifier for a given verification_id and issuer + /// Nullifier = Poseidon(verification_id, private_key, data_hash) + /// where data_hash = Poseidon(issuer_hashed, public_key) + pub fn compute_nullifier( + &self, + verification_id: &[u8; 31], + issuer_hashed: &[u8; 32], + ) -> [u8; 32] { + // First compute data_hash = Poseidon(issuer_hashed, public_key) + let data_hash = Poseidon::hashv(&[issuer_hashed, &self.public_key]).unwrap(); + + // Then compute nullifier = Poseidon(verification_id, private_key, data_hash) + // verification_id needs to be padded to 32 bytes for Poseidon let mut padded_verification = [0u8; 32]; padded_verification[1..32].copy_from_slice(verification_id); - Poseidon::hashv(&[&padded_verification, &self.private_key]).unwrap() + Poseidon::hashv(&[&padded_verification, &self.private_key, &data_hash]).unwrap() } } @@ -198,7 +207,8 @@ where .get_random_state_tree_info()? .pack_output_tree_index(&mut remaining_accounts)?; - let (remaining_accounts_metas, system_accounts_offset, _) = remaining_accounts.to_account_metas(); + let (remaining_accounts_metas, system_accounts_offset, _) = + remaining_accounts.to_account_metas(); let instruction_data = zk_id::instruction::CreateIssuer { proof: rpc_result.proof, @@ -213,11 +223,7 @@ where let instruction = Instruction { program_id: zk_id::ID, - accounts: [ - accounts.to_account_metas(None), - remaining_accounts_metas, - ] - .concat(), + accounts: [accounts.to_account_metas(None), remaining_accounts_metas].concat(), data: instruction_data.data(), }; @@ -273,7 +279,8 @@ where let issuer_account_parsed: zk_id::IssuerAccount = anchor_lang::AnchorDeserialize::deserialize(&mut issuer_data.data.as_slice()).unwrap(); - let (remaining_accounts_metas, system_accounts_offset, _) = remaining_accounts.to_account_metas(); + let (remaining_accounts_metas, system_accounts_offset, _) = + remaining_accounts.to_account_metas(); let instruction_data = zk_id::instruction::AddCredential { proof: rpc_result.proof, @@ -291,11 +298,7 @@ where let instruction = Instruction { program_id: zk_id::ID, - accounts: [ - accounts.to_account_metas(None), - remaining_accounts_metas, - ] - .concat(), + accounts: [accounts.to_account_metas(None), remaining_accounts_metas].concat(), data: instruction_data.data(), }; @@ -393,7 +396,8 @@ where .get_random_state_tree_info_v1()? .pack_output_tree_index(&mut remaining_accounts)?; - let (remaining_accounts_metas, system_accounts_offset, _) = remaining_accounts.to_account_metas(); + let (remaining_accounts_metas, system_accounts_offset, _) = + remaining_accounts.to_account_metas(); let instruction_data = zk_id::instruction::ZkVerifyCredential { proof: rpc_result.proof, @@ -415,11 +419,7 @@ where let instruction = Instruction { program_id: zk_id::ID, - accounts: [ - accounts.to_account_metas(None), - remaining_accounts_metas, - ] - .concat(), + accounts: [accounts.to_account_metas(None), remaining_accounts_metas].concat(), data: instruction_data.data(), }; @@ -562,7 +562,7 @@ fn generate_credential_proof( ); // Compute nullifier - let nullifier = credential.compute_nullifier(verification_id); + let nullifier = credential.compute_nullifier(verification_id, &issuer_hashed); proof_inputs.insert( "nullifier".to_string(), vec![BigUint::from_bytes_be(&nullifier).to_string()], diff --git a/zk/zk-id/ts-tests/zk-id.test.ts b/zk/zk-id/ts-tests/zk-id.test.ts index b2d84a9..79d7a6e 100644 --- a/zk/zk-id/ts-tests/zk-id.test.ts +++ b/zk/zk-id/ts-tests/zk-id.test.ts @@ -111,11 +111,26 @@ describe("zk-id", () => { return { privateKey, publicKey }; } - /** Compute nullifier = Poseidon(verification_id, credentialPrivateKey) */ - function computeNullifier(verificationId: Uint8Array, credentialPrivateKey: Uint8Array): Uint8Array { + /** Compute nullifier = Poseidon(verification_id, credentialPrivateKey, data_hash) */ + /** where data_hash = Poseidon(issuer_hashed, credential_pubkey) */ + function computeNullifier( + verificationId: Uint8Array, + credentialPrivateKey: Uint8Array, + issuerHashed: Uint8Array, + credentialPubkey: Uint8Array + ): Uint8Array { + // First compute data_hash = Poseidon(issuer_hashed, credential_pubkey) + const dataHash = poseidon([ + BigInt("0x" + Buffer.from(issuerHashed).toString("hex")), + BigInt("0x" + Buffer.from(credentialPubkey).toString("hex")), + ]); + const dataHashBigInt = poseidon.F.toObject(dataHash); + + // Then compute nullifier = Poseidon(verification_id, credentialPrivateKey, data_hash) const hash = poseidon([ BigInt("0x" + Buffer.from(verificationId).toString("hex")), BigInt("0x" + Buffer.from(credentialPrivateKey).toString("hex")), + dataHashBigInt, ]); return bigintToBytes32(poseidon.F.toObject(hash)); } @@ -259,20 +274,30 @@ describe("zk-id", () => { }); it("should compute nullifier correctly", () => { - const { privateKey } = generateCredentialKeypair(); + const { privateKey, publicKey } = generateCredentialKeypair(); const verificationId = generateFieldElement(); - const nullifier = computeNullifier(verificationId, privateKey); + const issuerHashed = hashToBn254Field(issuer.publicKey.toBytes()); + const nullifier = computeNullifier(verificationId, privateKey, issuerHashed, publicKey); + + // Compute data_hash = Poseidon(issuer_hashed, credential_pubkey) + const dataHash = poseidon([ + BigInt("0x" + Buffer.from(issuerHashed).toString("hex")), + BigInt("0x" + Buffer.from(publicKey).toString("hex")), + ]); + const dataHashBigInt = poseidon.F.toObject(dataHash); + // Compute nullifier = Poseidon(verification_id, privateKey, data_hash) const hash = poseidon([ BigInt("0x" + Buffer.from(verificationId).toString("hex")), BigInt("0x" + Buffer.from(privateKey).toString("hex")), + dataHashBigInt, ]); const computedNullifier = bigintToBytes32(poseidon.F.toObject(hash)); assert.deepStrictEqual( Array.from(nullifier), Array.from(computedNullifier), - "Nullifier should be Poseidon(verification_id, privateKey)" + "Nullifier should be Poseidon(verification_id, privateKey, data_hash)" ); }); }); @@ -291,7 +316,7 @@ describe("zk-id", () => { discriminator.set(Buffer.from([0x2e, 0x9c, 0x4a, 0x87, 0x12, 0x34, 0x56, 0x78]), 24); const verificationId = generateFieldElement(); - const nullifier = computeNullifier(verificationId, credentialPrivateKey); + const nullifier = computeNullifier(verificationId, credentialPrivateKey, issuerHashed, credentialPubkey); const encryptedDataHash = generateFieldElement(); const address = generateFieldElement(); @@ -339,13 +364,14 @@ describe("zk-id", () => { }); it("should verify nullifier uniqueness property", () => { - const { privateKey } = generateCredentialKeypair(); + const { privateKey, publicKey } = generateCredentialKeypair(); + const issuerHashed = hashToBn254Field(issuer.publicKey.toBytes()); const verificationId1 = generateFieldElement(); const verificationId2 = generateFieldElement(); - const nullifier1 = computeNullifier(verificationId1, privateKey); - const nullifier2 = computeNullifier(verificationId2, privateKey); + const nullifier1 = computeNullifier(verificationId1, privateKey, issuerHashed, publicKey); + const nullifier2 = computeNullifier(verificationId2, privateKey, issuerHashed, publicKey); assert.notDeepStrictEqual( Array.from(nullifier1), From 6533f1080f3284b2f93453ea707610bb1934262d Mon Sep 17 00:00:00 2001 From: ananas Date: Thu, 15 Jan 2026 23:54:09 +0000 Subject: [PATCH 2/2] fix buildrs --- zk/zk-id/Cargo.toml | 4 ---- zk/zk-id/{ => programs/zk-id}/build.rs | 10 +++++----- zk/zk-id/programs/zk-id/src/verifying_key.rs | 4 ++-- 3 files changed, 7 insertions(+), 11 deletions(-) rename zk/zk-id/{ => programs/zk-id}/build.rs (77%) diff --git a/zk/zk-id/Cargo.toml b/zk/zk-id/Cargo.toml index f178583..4a46804 100644 --- a/zk/zk-id/Cargo.toml +++ b/zk/zk-id/Cargo.toml @@ -27,10 +27,6 @@ light-client = { version = "0.17.2", features = ["v2"] } light-sdk = { version = "0.17.1", features = ["anchor", "poseidon", "merkle-tree", "v2"] } groth16-solana = { git = "https://github.com/Lightprotocol/groth16-solana", features = ["vk", "circom"], rev = "66c0dc87d0808c4d2aadb53c61435b6edb8ddfd9" } -[build-dependencies] -rust-witness = "0.1" -groth16-solana = { git = "https://github.com/Lightprotocol/groth16-solana", features = ["vk"], rev = "66c0dc87d0808c4d2aadb53c61435b6edb8ddfd9" } - [profile.release] overflow-checks = true lto = "fat" diff --git a/zk/zk-id/build.rs b/zk/zk-id/programs/zk-id/build.rs similarity index 77% rename from zk/zk-id/build.rs rename to zk/zk-id/programs/zk-id/build.rs index 245d08f..bb08780 100644 --- a/zk/zk-id/build.rs +++ b/zk/zk-id/programs/zk-id/build.rs @@ -1,12 +1,12 @@ use groth16_solana::vk_parser::generate_vk_file; fn main() { - println!("cargo:rerun-if-changed=build/verification_key.json"); - println!("cargo:rerun-if-changed=build/compressed_account_merkle_proof_js"); + println!("cargo:rerun-if-changed=../../build/verification_key.json"); + println!("cargo:rerun-if-changed=../../build/compressed_account_merkle_proof_js"); // Generate the verifying key Rust file from the JSON - let vk_json_path = "./build/verification_key.json"; - let output_dir = "./programs/zk-id/src"; + let vk_json_path = "../../build/verification_key.json"; + let output_dir = "./src"; let output_file = "verifying_key.rs"; if std::path::Path::new(vk_json_path).exists() { @@ -21,7 +21,7 @@ fn main() { // Check the TARGET environment variable since build scripts run on the host let target = std::env::var("TARGET").unwrap_or_default(); if !target.contains("sbf") && !target.contains("solana") { - let witness_wasm_dir = "./build/compressed_account_merkle_proof_js"; + let witness_wasm_dir = "../../build/compressed_account_merkle_proof_js"; if std::path::Path::new(witness_wasm_dir).exists() { rust_witness::transpile::transpile_wasm(witness_wasm_dir.to_string()); // Successfully transpiled witness generator diff --git a/zk/zk-id/programs/zk-id/src/verifying_key.rs b/zk/zk-id/programs/zk-id/src/verifying_key.rs index 03a95e6..ff86264 100644 --- a/zk/zk-id/programs/zk-id/src/verifying_key.rs +++ b/zk/zk-id/programs/zk-id/src/verifying_key.rs @@ -9,7 +9,7 @@ pub const VERIFYINGKEY: Groth16Verifyingkey = Groth16Verifyingkey { vk_gamma_g2: [25u8, 142u8, 147u8, 147u8, 146u8, 13u8, 72u8, 58u8, 114u8, 96u8, 191u8, 183u8, 49u8, 251u8, 93u8, 37u8, 241u8, 170u8, 73u8, 51u8, 53u8, 169u8, 231u8, 18u8, 151u8, 228u8, 133u8, 183u8, 174u8, 243u8, 18u8, 194u8, 24u8, 0u8, 222u8, 239u8, 18u8, 31u8, 30u8, 118u8, 66u8, 106u8, 0u8, 102u8, 94u8, 92u8, 68u8, 121u8, 103u8, 67u8, 34u8, 212u8, 247u8, 94u8, 218u8, 221u8, 70u8, 222u8, 189u8, 92u8, 217u8, 146u8, 246u8, 237u8, 9u8, 6u8, 137u8, 208u8, 88u8, 95u8, 240u8, 117u8, 236u8, 158u8, 153u8, 173u8, 105u8, 12u8, 51u8, 149u8, 188u8, 75u8, 49u8, 51u8, 112u8, 179u8, 142u8, 243u8, 85u8, 172u8, 218u8, 220u8, 209u8, 34u8, 151u8, 91u8, 18u8, 200u8, 94u8, 165u8, 219u8, 140u8, 109u8, 235u8, 74u8, 171u8, 113u8, 128u8, 141u8, 203u8, 64u8, 143u8, 227u8, 209u8, 231u8, 105u8, 12u8, 67u8, 211u8, 123u8, 76u8, 230u8, 204u8, 1u8, 102u8, 250u8, 125u8, 170u8], - vk_delta_g2: [35u8, 93u8, 218u8, 70u8, 212u8, 161u8, 124u8, 239u8, 162u8, 255u8, 210u8, 95u8, 89u8, 201u8, 218u8, 157u8, 171u8, 171u8, 70u8, 145u8, 149u8, 94u8, 190u8, 16u8, 111u8, 39u8, 248u8, 134u8, 85u8, 250u8, 172u8, 223u8, 9u8, 14u8, 178u8, 122u8, 12u8, 141u8, 26u8, 49u8, 93u8, 25u8, 181u8, 233u8, 14u8, 235u8, 204u8, 150u8, 253u8, 145u8, 78u8, 29u8, 223u8, 194u8, 85u8, 125u8, 249u8, 104u8, 126u8, 172u8, 210u8, 214u8, 91u8, 61u8, 34u8, 228u8, 17u8, 115u8, 225u8, 247u8, 43u8, 243u8, 112u8, 123u8, 82u8, 127u8, 227u8, 18u8, 58u8, 157u8, 71u8, 96u8, 39u8, 68u8, 22u8, 163u8, 59u8, 126u8, 209u8, 180u8, 41u8, 105u8, 76u8, 53u8, 29u8, 220u8, 34u8, 176u8, 140u8, 177u8, 83u8, 42u8, 138u8, 99u8, 31u8, 143u8, 185u8, 170u8, 60u8, 142u8, 154u8, 37u8, 68u8, 227u8, 242u8, 67u8, 49u8, 34u8, 91u8, 221u8, 250u8, 100u8, 17u8, 96u8, 159u8, 61u8, 170u8, 177u8], + vk_delta_g2: [22u8, 174u8, 147u8, 208u8, 172u8, 122u8, 235u8, 140u8, 107u8, 118u8, 81u8, 111u8, 106u8, 194u8, 142u8, 249u8, 49u8, 219u8, 251u8, 148u8, 230u8, 183u8, 217u8, 43u8, 254u8, 249u8, 149u8, 220u8, 193u8, 162u8, 70u8, 224u8, 35u8, 200u8, 228u8, 224u8, 29u8, 126u8, 95u8, 148u8, 140u8, 33u8, 169u8, 73u8, 11u8, 41u8, 152u8, 125u8, 85u8, 13u8, 242u8, 87u8, 214u8, 173u8, 202u8, 8u8, 45u8, 5u8, 68u8, 172u8, 38u8, 158u8, 137u8, 206u8, 34u8, 202u8, 165u8, 71u8, 76u8, 215u8, 55u8, 155u8, 9u8, 163u8, 153u8, 106u8, 255u8, 102u8, 135u8, 117u8, 194u8, 142u8, 126u8, 204u8, 46u8, 37u8, 0u8, 202u8, 91u8, 141u8, 174u8, 201u8, 181u8, 49u8, 91u8, 203u8, 9u8, 137u8, 122u8, 49u8, 71u8, 118u8, 0u8, 207u8, 26u8, 15u8, 37u8, 137u8, 232u8, 202u8, 186u8, 81u8, 70u8, 58u8, 123u8, 237u8, 97u8, 196u8, 207u8, 179u8, 215u8, 125u8, 98u8, 153u8, 184u8, 27u8, 176u8, 77u8], vk_ic: &[ [6u8, 116u8, 25u8, 196u8, 168u8, 139u8, 50u8, 234u8, 24u8, 80u8, 72u8, 23u8, 1u8, 43u8, 230u8, 178u8, 165u8, 176u8, 101u8, 164u8, 240u8, 6u8, 228u8, 49u8, 213u8, 82u8, 106u8, 117u8, 102u8, 23u8, 57u8, 101u8, 6u8, 0u8, 22u8, 209u8, 170u8, 16u8, 2u8, 213u8, 10u8, 138u8, 98u8, 195u8, 189u8, 38u8, 61u8, 204u8, 249u8, 53u8, 98u8, 199u8, 88u8, 168u8, 175u8, 253u8, 183u8, 49u8, 46u8, 214u8, 46u8, 22u8, 20u8, 9u8], @@ -20,6 +20,6 @@ pub const VERIFYINGKEY: Groth16Verifyingkey = Groth16Verifyingkey { [37u8, 58u8, 169u8, 29u8, 158u8, 74u8, 77u8, 127u8, 202u8, 187u8, 181u8, 170u8, 44u8, 94u8, 0u8, 214u8, 60u8, 127u8, 104u8, 198u8, 212u8, 0u8, 178u8, 107u8, 109u8, 133u8, 127u8, 196u8, 61u8, 122u8, 122u8, 42u8, 11u8, 1u8, 147u8, 194u8, 208u8, 97u8, 68u8, 193u8, 255u8, 251u8, 141u8, 71u8, 179u8, 93u8, 218u8, 145u8, 239u8, 38u8, 121u8, 23u8, 203u8, 219u8, 186u8, 172u8, 120u8, 223u8, 128u8, 207u8, 171u8, 134u8, 138u8, 162u8], [40u8, 188u8, 141u8, 174u8, 217u8, 229u8, 72u8, 52u8, 232u8, 100u8, 30u8, 241u8, 1u8, 223u8, 99u8, 28u8, 92u8, 174u8, 57u8, 226u8, 1u8, 248u8, 128u8, 113u8, 182u8, 58u8, 158u8, 203u8, 148u8, 254u8, 239u8, 244u8, 18u8, 100u8, 144u8, 201u8, 214u8, 77u8, 169u8, 224u8, 59u8, 121u8, 163u8, 151u8, 16u8, 148u8, 39u8, 2u8, 224u8, 123u8, 35u8, 102u8, 204u8, 233u8, 93u8, 76u8, 101u8, 111u8, 134u8, 229u8, 26u8, 122u8, 215u8, 151u8], [23u8, 165u8, 206u8, 29u8, 47u8, 19u8, 149u8, 232u8, 48u8, 112u8, 50u8, 201u8, 139u8, 236u8, 226u8, 197u8, 196u8, 56u8, 89u8, 146u8, 41u8, 46u8, 89u8, 82u8, 37u8, 150u8, 132u8, 32u8, 149u8, 44u8, 222u8, 131u8, 33u8, 96u8, 209u8, 108u8, 151u8, 147u8, 48u8, 101u8, 230u8, 25u8, 214u8, 140u8, 213u8, 36u8, 230u8, 174u8, 147u8, 71u8, 156u8, 44u8, 80u8, 171u8, 47u8, 45u8, 65u8, 213u8, 224u8, 147u8, 196u8, 223u8, 20u8, 230u8], - [14u8, 5u8, 129u8, 121u8, 109u8, 169u8, 0u8, 255u8, 184u8, 100u8, 232u8, 96u8, 112u8, 158u8, 194u8, 213u8, 77u8, 115u8, 130u8, 240u8, 160u8, 240u8, 243u8, 129u8, 8u8, 46u8, 239u8, 65u8, 188u8, 28u8, 236u8, 222u8, 4u8, 104u8, 112u8, 160u8, 235u8, 48u8, 64u8, 159u8, 177u8, 251u8, 42u8, 11u8, 252u8, 133u8, 19u8, 169u8, 77u8, 173u8, 99u8, 145u8, 171u8, 116u8, 203u8, 34u8, 179u8, 218u8, 18u8, 120u8, 163u8, 75u8, 157u8, 15u8] + [14u8, 5u8, 129u8, 121u8, 109u8, 169u8, 0u8, 255u8, 184u8, 100u8, 232u8, 96u8, 112u8, 158u8, 194u8, 213u8, 77u8, 115u8, 130u8, 240u8, 160u8, 240u8, 243u8, 129u8, 8u8, 46u8, 239u8, 65u8, 188u8, 28u8, 236u8, 222u8, 4u8, 104u8, 112u8, 160u8, 235u8, 48u8, 64u8, 159u8, 177u8, 251u8, 42u8, 11u8, 252u8, 133u8, 19u8, 169u8, 77u8, 173u8, 99u8, 145u8, 171u8, 116u8, 203u8, 34u8, 179u8, 218u8, 18u8, 120u8, 163u8, 75u8, 157u8, 15u8], ] };