|
1 | 1 | import { bytesToHex, randomBytes } from '@ethereumjs/util'
|
2 | 2 | import { beforeAll, describe, expect, test, assert } from 'vitest'
|
3 | 3 |
|
4 |
| -import { VerkleCrypto, loadVerkleCrypto } from '../index.js' |
| 4 | +import { ProverInput, VerifierInput, loadVerkleCrypto } from '../index.js' |
5 | 5 | import { verifyExecutionWitnessPreState, Context as VerkleFFI } from '../wasm/rust_verkle_wasm.js'
|
| 6 | + |
6 | 7 | import kaustinenBlock72 from './data/kaustinen6Block72.json'
|
7 | 8 | import kaustinenBlock73 from './data/kaustinen6Block73.json'
|
8 | 9 |
|
9 | 10 | describe('bindings', () => {
|
10 | 11 | let ffi: VerkleFFI
|
11 |
| - let verkleCrypto: VerkleCrypto |
| 12 | + let verkleCrypto: Awaited<ReturnType<typeof loadVerkleCrypto>> |
12 | 13 | beforeAll(async () => {
|
13 | 14 | verkleCrypto = await loadVerkleCrypto()
|
14 | 15 | ffi = new VerkleFFI()
|
@@ -138,6 +139,99 @@ describe('bindings', () => {
|
138 | 139 | }
|
139 | 140 | })
|
140 | 141 |
|
| 142 | + test('createVerifyProof', () => { |
| 143 | + // Preparation stage |
| 144 | + // |
| 145 | + // First we will emulate having a node with children. |
| 146 | + // |
| 147 | + // In verkle, the maximum number of children an internal node can have is 256. |
| 148 | + const NUMBER_OF_CHILDREN = 256 |
| 149 | + |
| 150 | + // Populate the vector with 256 values. |
| 151 | + const children = [] |
| 152 | + for (let i = 0; i < NUMBER_OF_CHILDREN; i++) { |
| 153 | + children.push(createScalarFromIndex(i)) |
| 154 | + } |
| 155 | + |
| 156 | + // Commit to that vector/children |
| 157 | + const commitment = ffi.commitToScalars(children) |
| 158 | + |
| 159 | + // Serialize the commitment |
| 160 | + // |
| 161 | + // This is the format that they should arrive in, over the wire |
| 162 | + const serializedCommitment = ffi.serializeCommitment(commitment) |
| 163 | + |
| 164 | + // Create proof |
| 165 | + // |
| 166 | + const proofInputs: ProverInput[] = [ |
| 167 | + { serializedCommitment: serializedCommitment, vector: children, indices: [1, 2] }, |
| 168 | + ] |
| 169 | + |
| 170 | + const proof = verkleCrypto.createProof(proofInputs) |
| 171 | + |
| 172 | + // Verify proof |
| 173 | + // |
| 174 | + const verifierInputs: VerifierInput[] = [ |
| 175 | + { |
| 176 | + serializedCommitment: serializedCommitment, |
| 177 | + indexValuePairs: [ |
| 178 | + { index: 1, value: children[1] }, |
| 179 | + { index: 2, value: children[2] }, |
| 180 | + ], |
| 181 | + }, |
| 182 | + ] |
| 183 | + |
| 184 | + const valid = verkleCrypto.verifyProof(proof, verifierInputs) |
| 185 | + |
| 186 | + expect(valid).toBe(true) |
| 187 | + }) |
| 188 | + |
| 189 | + test('createVerifyProofMultipleCommitments', () => { |
| 190 | + const NUMBER_OF_CHILDREN = 256 |
| 191 | + |
| 192 | + // Create two sets of vectors |
| 193 | + const children1 = Array.from({ length: NUMBER_OF_CHILDREN }, (_, i) => createScalarFromIndex(i)) |
| 194 | + const children2 = Array.from({ length: NUMBER_OF_CHILDREN }, (_, i) => |
| 195 | + createScalarFromIndex(i + NUMBER_OF_CHILDREN), |
| 196 | + ) |
| 197 | + |
| 198 | + // Create commitments for both sets |
| 199 | + const commitment1 = ffi.commitToScalars(children1) |
| 200 | + const commitment2 = ffi.commitToScalars(children2) |
| 201 | + |
| 202 | + // Serialize the commitments |
| 203 | + const serializedCommitment1 = verkleCrypto.serializeCommitment(commitment1) |
| 204 | + const serializedCommitment2 = verkleCrypto.serializeCommitment(commitment2) |
| 205 | + |
| 206 | + // Create proof |
| 207 | + const proofInputs: ProverInput[] = [ |
| 208 | + { serializedCommitment: serializedCommitment1, vector: children1, indices: [1, 2] }, |
| 209 | + { serializedCommitment: serializedCommitment2, vector: children2, indices: [3, 4] }, |
| 210 | + ] |
| 211 | + const proof = verkleCrypto.createProof(proofInputs) |
| 212 | + |
| 213 | + // Verify proof |
| 214 | + const verifierInputs: VerifierInput[] = [ |
| 215 | + { |
| 216 | + serializedCommitment: serializedCommitment1, |
| 217 | + indexValuePairs: [ |
| 218 | + { index: 1, value: children1[1] }, |
| 219 | + { index: 2, value: children1[2] }, |
| 220 | + ], |
| 221 | + }, |
| 222 | + { |
| 223 | + serializedCommitment: serializedCommitment2, |
| 224 | + indexValuePairs: [ |
| 225 | + { index: 3, value: children2[3] }, |
| 226 | + { index: 4, value: children2[4] }, |
| 227 | + ], |
| 228 | + }, |
| 229 | + ] |
| 230 | + const valid = verkleCrypto.verifyProof(proof, verifierInputs) |
| 231 | + |
| 232 | + expect(valid).toBe(true) |
| 233 | + }) |
| 234 | + |
141 | 235 | test('serializeCommitment', () => {
|
142 | 236 | // Create a commitment that we can hash
|
143 | 237 | const scalar = new Uint8Array([
|
@@ -229,3 +323,11 @@ describe('bindings', () => {
|
229 | 323 | }).toThrow('Expected 32 bytes, got 1')
|
230 | 324 | })
|
231 | 325 | })
|
| 326 | + |
| 327 | +function createScalarFromIndex(index: number): Uint8Array { |
| 328 | + const BYTES_PER_SCALAR = 32 |
| 329 | + |
| 330 | + const scalar = new Uint8Array(BYTES_PER_SCALAR) |
| 331 | + scalar[0] = index // Set first byte to index (little-endian) |
| 332 | + return scalar |
| 333 | +} |
0 commit comments