mirror of
https://github.com/privacy-scaling-explorations/zk-kit.git
synced 2026-04-22 03:00:15 -04:00
feat: identities genSecret multipart secret updates & test updates
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@libsem/identity",
|
||||
"version": "1.0.19",
|
||||
"version": "1.0.20",
|
||||
"description": "Library for managing identites for Semaphore and Rln protocols.",
|
||||
"main": "dist/index.node.js",
|
||||
"types": "dist/types/index.d.ts",
|
||||
|
||||
@@ -2,6 +2,7 @@ import { genRandomIdentity, genIdentityFromMessage, genRandomNumber } from "./st
|
||||
import * as bigintConversion from "bigint-conversion"
|
||||
import * as ciromlibjs from "circomlibjs"
|
||||
import { Identity, SerializedIdentity } from "@libsem/types"
|
||||
import {Fq} from "./utils"
|
||||
|
||||
const poseidonHash = (data: Array<bigint>): bigint => {
|
||||
return ciromlibjs.poseidon(data)
|
||||
@@ -14,9 +15,9 @@ export enum Strategy {
|
||||
}
|
||||
|
||||
class ZkIdentity {
|
||||
private identityTrapdoor: bigint
|
||||
private identityNullifier: bigint
|
||||
private secret: Array<bigint> = []
|
||||
private identityTrapdoor: bigint;
|
||||
private identityNullifier: bigint;
|
||||
private secret: Array<bigint> = [];
|
||||
/**
|
||||
* Generates new ZkIdentity
|
||||
* @param strategy strategy for identity generation
|
||||
@@ -28,10 +29,12 @@ class ZkIdentity {
|
||||
const { identityTrapdoor, identityNullifier } = genRandomIdentity()
|
||||
this.identityTrapdoor = identityTrapdoor
|
||||
this.identityNullifier = identityNullifier
|
||||
this.genSecret()
|
||||
} else if (strategy === Strategy.MESSAGE) {
|
||||
const { identityTrapdoor, identityNullifier } = genIdentityFromMessage(metadata as string)
|
||||
this.identityTrapdoor = identityTrapdoor
|
||||
this.identityNullifier = identityNullifier
|
||||
this.genSecret()
|
||||
} else if (strategy === Strategy.SERIALIZED) {
|
||||
const { identityNullifier, identityTrapdoor, secret } = metadata as SerializedIdentity
|
||||
this.identityNullifier = bigintConversion.hexToBigint(identityNullifier)
|
||||
@@ -75,42 +78,35 @@ class ZkIdentity {
|
||||
return this.secret
|
||||
}
|
||||
|
||||
|
||||
getSecretHash(): bigint {
|
||||
return poseidonHash(this.secret)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates secret from ZkIdentity
|
||||
* @returns
|
||||
*/
|
||||
genSecretFromIdentity() {
|
||||
this.secret = [this.identityNullifier, this.identityTrapdoor]
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates random secret
|
||||
* @param parts number of parts in secret
|
||||
* @returns secret
|
||||
*/
|
||||
genRandomSecret(parts = 2) {
|
||||
this.secret = []
|
||||
for (let i = 0; i < parts; i++) {
|
||||
this.secret.push(genRandomNumber())
|
||||
genSecret(parts: number = 2): void {
|
||||
if(parts < 2) throw new Error("Invalid number of parts");
|
||||
if(parts === 2) {
|
||||
this.secret = [this.identityNullifier, this.identityTrapdoor]
|
||||
} else {
|
||||
let initialComponent = Fq.pow(this.identityNullifier, this.identityTrapdoor);
|
||||
this.secret = [initialComponent]
|
||||
for(let i = 1; i < parts; i++) {
|
||||
this.secret.push(Fq.pow(initialComponent, BigInt(i + 1)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate commitment from identity secret
|
||||
* @returns identity commitment
|
||||
*/
|
||||
genIdentityCommitmentFromSecret(): bigint {
|
||||
if (!this.secret.length) throw new Error("Secret is not generated")
|
||||
const secretHash = poseidonHash(this.secret)
|
||||
return poseidonHash([secretHash])
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate commitment from identity
|
||||
* @returns identity commitment
|
||||
*/
|
||||
genIdentityCommitment(): bigint {
|
||||
const secretHash = poseidonHash([this.identityNullifier, this.identityTrapdoor])
|
||||
const secretHash = this.getSecretHash();
|
||||
return poseidonHash([secretHash])
|
||||
}
|
||||
|
||||
|
||||
4
packages/identity/src/utils.ts
Normal file
4
packages/identity/src/utils.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export const SNARK_FIELD_SIZE = BigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617")
|
||||
|
||||
const ZqField = require("ffjavascript").ZqField
|
||||
export const Fq = new ZqField(SNARK_FIELD_SIZE)
|
||||
@@ -16,17 +16,17 @@ describe("Semaphore identity", () => {
|
||||
|
||||
it("Should generate secret from identity", async () => {
|
||||
const identity: ZkIdentity = new ZkIdentity()
|
||||
identity.genSecretFromIdentity()
|
||||
identity.genSecret()
|
||||
const identitySecret = identity.getSecret()
|
||||
|
||||
expect(identitySecret.length).toEqual(2)
|
||||
expect(typeof identitySecret).toEqual("object")
|
||||
})
|
||||
|
||||
it("Should generate random secret", async () => {
|
||||
it("Should generate multipart secret", async () => {
|
||||
const secretParts = 5
|
||||
const identity: ZkIdentity = new ZkIdentity()
|
||||
identity.genRandomSecret(secretParts)
|
||||
identity.genSecret(secretParts)
|
||||
const identitySecret = identity.getSecret()
|
||||
|
||||
expect(identitySecret.length).toEqual(5)
|
||||
@@ -35,20 +35,12 @@ describe("Semaphore identity", () => {
|
||||
|
||||
it("Should generate identity commitment from identity", async () => {
|
||||
const identity: ZkIdentity = new ZkIdentity()
|
||||
identity.genSecret();
|
||||
const identityCommitment: bigint = identity.genIdentityCommitment()
|
||||
|
||||
expect(typeof identityCommitment).toEqual("bigint")
|
||||
})
|
||||
|
||||
it("Should generate identity commitment from random secret", async () => {
|
||||
const secretParts = 5
|
||||
const identity: ZkIdentity = new ZkIdentity()
|
||||
identity.genRandomSecret(secretParts)
|
||||
const identityCommitment: bigint = identity.genIdentityCommitmentFromSecret()
|
||||
|
||||
expect(typeof identityCommitment).toEqual("bigint")
|
||||
})
|
||||
|
||||
it("Should serialize identity", async () => {
|
||||
const identity: ZkIdentity = new ZkIdentity()
|
||||
const serialized: string = identity.serializeIdentity()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@libsem/protocols",
|
||||
"version": "1.0.25",
|
||||
"version": "1.0.26",
|
||||
"description": "Client library for generating and verifying Semaphore & Rln ZK proofs.",
|
||||
"main": "dist/index.node.js",
|
||||
"types": "dist/types/index.d.ts",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Semaphore from "./semaphore"
|
||||
import Rln from "./rln"
|
||||
import NRln from "./nRln"
|
||||
import { generateMerkleProof, genExternalNullifier, genSignalHash } from "./utils"
|
||||
import { generateMerkleProof, genExternalNullifier, genSignalHash, Fq } from "./utils"
|
||||
import { Identity, MerkleProof, FullProof } from "@libsem/types"
|
||||
|
||||
export { Semaphore, Rln, NRln, generateMerkleProof, genExternalNullifier, genSignalHash, Identity, MerkleProof, FullProof }
|
||||
|
||||
@@ -13,8 +13,8 @@ beforeAll(() => {
|
||||
|
||||
for (let i = 0; i < leafIndex; i++) {
|
||||
const tmpIdentity = new ZkIdentity();
|
||||
tmpIdentity.genRandomSecret(SPAM_TRESHOLD);
|
||||
const tmpCommitment: bigint = tmpIdentity.genIdentityCommitmentFromSecret();
|
||||
tmpIdentity.genSecret(SPAM_TRESHOLD);
|
||||
const tmpCommitment: bigint = tmpIdentity.genIdentityCommitment();
|
||||
identityCommitments.push(tmpCommitment)
|
||||
}
|
||||
})
|
||||
@@ -23,9 +23,9 @@ describe("NRln", () => {
|
||||
describe("NRln functionalities", () => {
|
||||
it("Generate nrln witness", () => {
|
||||
const identity: ZkIdentity = new ZkIdentity();
|
||||
identity.genRandomSecret(SPAM_TRESHOLD);
|
||||
identity.genSecret(SPAM_TRESHOLD);
|
||||
|
||||
const identityCommitment: bigint = identity.genIdentityCommitmentFromSecret();
|
||||
const identityCommitment: bigint = identity.genIdentityCommitment();
|
||||
const identitySecret: bigint[] = identity.getSecret();
|
||||
|
||||
const commitments: Array<bigint> = Object.assign([], identityCommitments)
|
||||
@@ -35,19 +35,19 @@ describe("NRln", () => {
|
||||
const epoch: string = genExternalNullifier("test-epoch")
|
||||
const rlnIdentifier: bigint = NRln.genIdentifier()
|
||||
|
||||
const merkleProof: MerkleProof = generateMerkleProof(15, BigInt(0), 5, commitments, identityCommitment)
|
||||
const merkleProof: MerkleProof = generateMerkleProof(15, BigInt(0), 2, commitments, identityCommitment)
|
||||
const witness: FullProof = NRln.genWitness(identitySecret, merkleProof, epoch, signal, rlnIdentifier)
|
||||
|
||||
expect(typeof witness).toBe("object")
|
||||
})
|
||||
it.skip("Generate nrln proof and verify it", async () => {
|
||||
it("Generate nrln proof and verify it", async () => {
|
||||
/**
|
||||
* Compiled NRln circuits are needed to run this test so it's being skipped in hooks
|
||||
*/
|
||||
const identity: ZkIdentity = new ZkIdentity();
|
||||
identity.genRandomSecret(SPAM_TRESHOLD);
|
||||
identity.genSecret(SPAM_TRESHOLD);
|
||||
|
||||
const identityCommitment: bigint = identity.genIdentityCommitmentFromSecret();
|
||||
const identityCommitment: bigint = identity.genIdentityCommitment();
|
||||
const identitySecret: bigint[] = identity.getSecret();
|
||||
|
||||
const commitments: Array<bigint> = Object.assign([], identityCommitments)
|
||||
@@ -77,7 +77,7 @@ describe("NRln", () => {
|
||||
}, 30000)
|
||||
it("Should retrieve user secret after spaming", () => {
|
||||
const identity: ZkIdentity = new ZkIdentity();
|
||||
identity.genRandomSecret(SPAM_TRESHOLD);
|
||||
identity.genSecret(SPAM_TRESHOLD);
|
||||
|
||||
const identitySecret: bigint[] = identity.getSecret();
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ describe("Rln", () => {
|
||||
describe("Rln functionalities", () => {
|
||||
it("Generate rln witness", () => {
|
||||
const identity: ZkIdentity = new ZkIdentity();
|
||||
identity.genSecretFromIdentity();
|
||||
const identityCommitment: bigint = identity.genIdentityCommitment();
|
||||
const secretHash: bigint = poseidonHash(identity.getSecret());
|
||||
|
||||
@@ -37,12 +36,11 @@ describe("Rln", () => {
|
||||
|
||||
expect(typeof witness).toBe("object")
|
||||
})
|
||||
it.skip("Generate rln proof and verify it", async () => {
|
||||
it("Generate rln proof and verify it", async () => {
|
||||
/**
|
||||
* Compiled RLN circuits are needed to run this test so it's being skipped in hooks
|
||||
*/
|
||||
const identity: ZkIdentity = new ZkIdentity();
|
||||
identity.genSecretFromIdentity();
|
||||
const secretHash: bigint = poseidonHash(identity.getSecret());
|
||||
|
||||
const identityCommitment: bigint = identity.genIdentityCommitment();
|
||||
@@ -74,7 +72,6 @@ describe("Rln", () => {
|
||||
}, 30000)
|
||||
it("Should retrieve user secret after spaming", () => {
|
||||
const identity: ZkIdentity = new ZkIdentity();
|
||||
identity.genSecretFromIdentity();
|
||||
const secretHash: bigint = poseidonHash(identity.getSecret());
|
||||
|
||||
const signal1 = "hey hey"
|
||||
|
||||
@@ -36,7 +36,7 @@ describe("Semaphore", () => {
|
||||
|
||||
expect(typeof witness).toBe("object")
|
||||
})
|
||||
it.skip("Should generate semaphore full proof", async () => {
|
||||
it("Should generate semaphore full proof", async () => {
|
||||
/**
|
||||
* Compiled semaphore circuits are needed to run this test, so it's being skipped in hooks
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user