feat: identities genSecret multipart secret updates & test updates

This commit is contained in:
bdim1
2021-12-28 00:51:34 +01:00
parent 827b883d4a
commit fe2a676f38
9 changed files with 45 additions and 56 deletions

View File

@@ -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",

View File

@@ -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])
}

View 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)

View File

@@ -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()

View File

@@ -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",

View File

@@ -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 }

View File

@@ -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();

View File

@@ -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"

View File

@@ -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
*/