docknetwork / crypto-wasm-ts

Typescript abstractions over Rust crypto library's WASM wrapper
Apache License 2.0
28 stars 9 forks source link

This line fails, the entry at the given index is sometimes not defined #2

Closed javerett closed 2 years ago

javerett commented 2 years ago

https://github.com/docknetwork/crypto-wasm-ts/blob/0d0360ba04da629b2afd1f361af264a726428aff/src/accumulator/accumulator.ts#L880

Here's a rough reproducer

async function perfTest<T>(name: string, rounds: number, f: (i: number) => Promise<T>): Promise<T[]> {
    const result: T[] = []
    const startTime = Date.now()
    for (let i = 0; i < rounds; i++) {
        result.push(await f(i))
    }
    const endTime = Date.now()

    console.log(`Performance test for ${name}: Ran ${rounds} rounds in ${endTime - startTime} ms\nAverage time: ${(endTime - startTime) / rounds} ms`)

    return result
}

const params = UniversalAccumulator.generateParams()
        const keypair = UniversalAccumulator.generateKeypair(params)
        const state = new InMemoryUniversalState()
        const init = new InMemoryInitialElementsStore()

        const test_data_count = 20
        const test_non_data_count = 10
        const accum = await UniversalAccumulator.initialize(0, params, keypair.secretKey, init)

        // Append random data
        const testData = [...Array(test_data_count)].map(() => crypto.randomBytes(32))
        await perfTest('append single', test_data_count, async (i) => {
            const data = UniversalAccumulator.encodeBytesAsAccumulatorMember(testData[i])
            await accum.add(data, keypair.sk, state)
            return data
        })

        // Generate non-membership proofs
        const nonData = [...Array(test_non_data_count)].map(() => UniversalAccumulator.encodeBytesAsAccumulatorMember(crypto.randomBytes(32)))
        const witness = await perfTest('non-member single prove', nonData.length, async (i) => {
            const witness = await accum.nonMembershipWitness(nonData[i], state, keypair.sk, params, init)
            return witness
        })

        const validator = UniversalAccumulator.fromAccumulated(accum.accumulated)
        await perfTest('non-member single validate', nonData.length, async (i) => {
            const valid = validator.verifyNonMembershipWitness(nonData[i], witness[i], keypair.pk, params)
            expect(valid).toEqual(true)
        })

        // Batch non-membership proofs
        const batch = [...Array(test_non_data_count)].map(() => UniversalAccumulator.encodeBytesAsAccumulatorMember(crypto.randomBytes(32)))
        const [batchWitness] = await perfTest('non-member batch prove', 1, async () => {
            const witness = await accum.nonMembershipWitnessesForBatch(batch, state, keypair.sk, params, init)
            return witness
        })
        void batchWitness

        // await perfTest('non-member batch verify', batchWitness.length, async (i) => {
        //  const valid = validator.verifyNonMembershipWitness(batch[i], batchWitness[i], keypair.pk, params)
        //  expect(valid).toEqual(true)
        // })
lovesh commented 2 years ago

Thanks for reporting this with a reproducer. This has been fixed in v0.24.0 and the fix lies here. I ran the above reproducer with the last few lines uncommented and it works now.

javerett commented 2 years ago

Excellent, thank you!