semaphore-protocol / semaphore

A zero-knowledge protocol for anonymous interactions.
https://semaphore.pse.dev
MIT License
887 stars 194 forks source link

verifyProof always return true #842

Closed tochy-open closed 1 month ago

tochy-open commented 1 month ago

Describe the bug When I use verifyProof of @semaphore-protocol/proof, always return true Semaphore contract return valid result

To Reproduce Steps to reproduce the behavior:

import { ethers } from 'hardhat'
import { Identity } from '@semaphore-protocol/identity'
import { generateProof, Group } from '@semaphore-protocol/core'
import { verifyProof } from '@semaphore-protocol/proof'
import { expect } from 'chai'
const poseidonT3Factory = await ethers.getContractFactory('PoseidonT3')
const poseidonT3Lib = await poseidonT3Factory.deploy()

const verifier = await ethers.deployContract('SemaphoreVerifier')
const semaphore = await ethers.deployContract('Semaphore', [verifier.target], {
    libraries: {
        'PoseidonT3': poseidonT3Lib.target
    }
})

const groupId = await semaphore['createGroup()'].staticCall()
await semaphore['createGroup()']()

const target = new Identity('target')
let identities = []
for (let i = 0; i < 8; i++) {
    identities.push(new Identity(`pk-${i}`))
}

const members = [...identities, target]
const commitments = members.map(identity => identity.commitment)

const group = new Group(commitments)
await semaphore.addMembers(groupId, commitments)

const proof = await generateProof(new Identity(), group.generateMerkleProof(0), 'message', 'scope')
console.log("invalid identity", await verifyProof(proof)) // why return true?

for(let index in members) {

    const merkleProof = group.generateMerkleProof(Number(index))
    const proof = await generateProof(target, merkleProof, 'message', 'scope')

    // typescript
    console.log("ts verified", await verifyProof(proof)) // always return true

    // contract
    expect(await semaphore.hasMember(groupId, members[Number(index)].commitment)).to.be.true
    switch(Number(index)) {
        case members.indexOf(target):
            expect(await semaphore.verifyProof(groupId, proof)).to.be.true
            break
        default:
            await expect(semaphore.verifyProof(groupId, proof))
                .to.be.revertedWithCustomError(semaphore, 'Semaphore__MerkleTreeRootIsNotPartOfTheGroup')
    }
}

Expected behavior I think verifyProof(invalidProof) should be returned false

Technologies (please complete the following information):

Additional context Add any other context about the problem here.

cedoor commented 1 month ago

Hi @tochy-open, thank you so much for this issue! Good catch. We found the problem and we'll release a new version with the patch tomorrow 👍🏽 Nothing related to the circuit, fortunately.