Skip to content

Commit

Permalink
refactor(eddsa-proof): update docs and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vplasencia committed Jan 20, 2024
1 parent a988587 commit 34adf20
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 32 deletions.
2 changes: 1 addition & 1 deletion packages/circuits/circom/eddsa-proof.circom
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ template EddsaProof() {
signal input scope;

signal output commitment;
signal output nullifier;

var Ax, Ay;

Expand All @@ -26,6 +27,5 @@ template EddsaProof() {

// A nullifier is also computed using both the scope and the commitment, providing a value
// to prevent the same proof from being reused twice.
signal output nullifier;
nullifier <== Poseidon(2)([scope, commitment]);
}
19 changes: 8 additions & 11 deletions packages/eddsa-proof/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<p align="center">
<h1 align="center">
Poseidon proof
Eddsa proof
</h1>
<p align="center">A library to generate and verify Poseidon proofs.</p>
<p align="center">A library to generate and verify Eddsa proofs.</p>
</p>

<p align="center">
Expand Down Expand Up @@ -41,17 +41,14 @@
</h4>
</div>

| This zero-knowledge library facilitates the demonstration of having a Poseidon hash pre-image while keeping the pre-image value confidential. Additionally, it offers a mechanism to prevent the same proof from being reused. The circuit that forms the foundation of this library is accessible via this [link](https://github.com/privacy-scaling-explorations/zk-kit/blob/main/packages/circuits/templates/poseidon-proof.circom). |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| This zero-knowledge library facilitates the demonstration of having an Eddsa hash pre-image while keeping the pre-image value confidential. Additionally, it offers a mechanism to prevent the same proof from being reused. The circuit that forms the foundation of this library is accessible via this [link](https://github.com/privacy-scaling-explorations/zk-kit/blob/main/packages/circuits/templates/eddsa-proof.circom). |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

Originally developed for integration with [Semaphore V4](https://github.com/semaphore-protocol/semaphore), this library also functions effectively as a standalone tool. Notable use cases in connection with Semaphore can be:

- allowing a Semaphore user to prove that they possess the secret value associated with the identity commitment of their Semaphore identity,
- unmasking the identity of zero-knowledge proofs earlier created using Semaphore.
This library allows you to prove and verify that you have the private key of a Semaphore identity. It will mainly be used to verify it on-chain because you can verify it off-chain using the `@semaphore-protocol/identitiy` package.

The Snark artifacts (`.wasm` and `.zkey` files) can be specified or not in the `generate` function parameters and can possibly be downloaded using the following URLs:

https://github.com/privacy-scaling-explorations/zk-kit/blob/ee457299d36d2601e5bf520237977a9f16b1b599/packages/poseidon-proof/src/config.ts#L5-L8
https://github.com/privacy-scaling-explorations/zk-kit/blob/ee457299d36d2601e5bf520237977a9f16b1b599/packages/eddsa-proof/src/config.ts#L5-L8

> [!WARNING]
> The Snark artifacts currently used to generate zero-knowledge proofs are the result of an unsecure trusted setup, and the library has not yet been audited. Therefore, it is advised not to use it in production.
Expand All @@ -63,13 +60,13 @@ https://github.com/privacy-scaling-explorations/zk-kit/blob/ee457299d36d2601e5bf
Install the `@zk-kit/poseidon-proof` package:

```bash
npm i @zk-kit/poseidon-proof
npm i @zk-kit/eddsa-proof
```

or yarn:

```bash
yarn add @zk-kit/poseidon-proof
yarn add @zk-kit/eddsa-proof
```

## 📜 Usage
Expand Down
8 changes: 4 additions & 4 deletions packages/eddsa-proof/src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import packProof from "./pack-proof"
import { EddsaProof, SnarkArtifacts } from "./types"

/**
* Creates a zero-knowledge proof to prove that you have the pre-image of a hash,
* Creates a zero-knowledge proof to prove that you have the pre-image of a Semaphore commitment,
* without disclosing the actual preimage itself.
* The use of a scope parameter along with a nullifier helps ensure the uniqueness
* and non-reusability of the proofs, enhancing security in applications like
Expand Down Expand Up @@ -37,17 +37,17 @@ export default async function generate(

const { proof, publicSignals } = await prove(
{
privateKey: hash(secretScalar),
secret: secretScalar,
scope: hash(scope)
},
snarkArtifacts.wasmFilePath,
snarkArtifacts.zkeyFilePath
)

return {
commitment: publicSignals[0],
nullifier: publicSignals[1],
scope: BigNumber.from(scope).toString() as NumericString,
commitment: publicSignals[1],
nullifier: publicSignals[0],
proof: packProof(proof)
}
}
4 changes: 2 additions & 2 deletions packages/eddsa-proof/src/pack-proof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { Groth16Proof } from "@zk-kit/groth16"
import { PackedProof } from "./types"

/**
* Packs a proof into a format compatible with PoseidonProof.
* Packs a proof into a format compatible with EddsaProof.
* @param proof The Groth16 proof generated with SnarkJS.
* @returns The proof compatible with PoseidonProof.
* @returns The proof compatible with EddsaProof.
*/
export default function packProof(proof: Groth16Proof): PackedProof {
return [
Expand Down
2 changes: 1 addition & 1 deletion packages/eddsa-proof/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ export type SnarkArtifacts = {
}

export type EddsaProof = {
scope: NumericString
commitment: NumericString
nullifier: NumericString
scope: NumericString
proof: PackedProof
}

Expand Down
2 changes: 1 addition & 1 deletion packages/eddsa-proof/src/unpack-proof.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PackedProof } from "./types"

/**
* Unpacks a proof into its original form.
* @param proof The proof compatible with PoseidonProof.
* @param proof The proof compatible with EddsaProof.
* @returns The proof compatible with SnarkJS.
*/
export default function unpackProof(proof: PackedProof): Groth16Proof {
Expand Down
12 changes: 6 additions & 6 deletions packages/eddsa-proof/src/verify.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { verify as _verify } from "@zk-kit/groth16"
import hash from "./hash"
import { EddsaProof } from "./types"
import unpackProof from "./unpack-proof"
import verificationKey from "./verification-key.json"
import hash from "./hash"

/**
* Verifies that a Poseidon proof is valid.
* @param eddsaProof The Poseidon zero-knowledge proof.
* Verifies that a Eddsa proof is valid.
* @param eddsaProof The Eddsa zero-knowledge proof.
* @returns True if the proof is valid, false otherwise.
*/
export default function verify({ scope, commitment, nullifier, proof }: EddsaProof): Promise<boolean> {
export default function verify({ proof, commitment, nullifier, scope }: EddsaProof): Promise<boolean> {
return _verify(verificationKey, {
proof: unpackProof(proof),
publicSignals: [nullifier, commitment, hash(scope)]
publicSignals: [commitment, nullifier, hash(scope)],
proof: unpackProof(proof)
})
}
21 changes: 15 additions & 6 deletions packages/eddsa-proof/tests/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { buildBn128 } from "@zk-kit/groth16"
import { poseidon1, poseidon2 } from "poseidon-lite"
import { poseidon2 } from "poseidon-lite"
import { derivePublicKey } from "@zk-kit/eddsa-poseidon"
import generate from "../src/generate"
import packProof from "../src/pack-proof"
import { EddsaProof } from "../src/types"
Expand All @@ -23,15 +24,23 @@ describe("EddsaProof", () => {
})

describe("# generate", () => {
it("Should generate a Eddsa proof", async () => {
fullProof = await generate(privateKey, scope)
it("Should generate an Eddsa proof", async () => {
fullProof = await generate(privateKey, scope, {
wasmFilePath: "./packages/eddsa-proof/tests/artifacts/eddsa-proof.wasm",
zkeyFilePath: "./packages/eddsa-proof/tests/artifacts/eddsa-proof.zkey"
})

const digest = poseidon1([hash(privateKey)])
const nullifier = poseidon2([hash(scope), hash(privateKey)])
const scopeHash = hash(scope)

const publicKey = derivePublicKey(privateKey)

const commitment = poseidon2(publicKey)

const nullifier = poseidon2([scopeHash, commitment])

expect(fullProof.proof).toHaveLength(8)
expect(fullProof.scope).toBe(scope.toString())
expect(fullProof.commitment).toBe(digest.toString())
expect(fullProof.commitment).toBe(commitment.toString())
expect(fullProof.nullifier).toBe(nullifier.toString())
})
})
Expand Down

0 comments on commit 34adf20

Please sign in to comment.