mirror of
https://github.com/privacy-scaling-explorations/zk-kit.git
synced 2026-04-22 03:00:15 -04:00
Merge pull request #14 from appliedzkp/fix/nrln_removal
Fix/nrln removal
Former-commit-id: ce087642840a3de09777aa5f6e3d68e5c866140d [formerly 863cbca3b895e8a71f491d3a5b9b66a016ddd92c] [formerly eb8eb59597ca60899074100f17748a0ea90af444 [formerly 66bc2137db19e911b9f677fe4f0256c2f5d32050]] [formerly aa74adb46511d8901a2bdf0463295b8cb5c7485c [formerly 3d10ffe37a542f6d615790d04b0d1d5e935732ab] [formerly b50094b9d429d0839f638f54ced6d0fb7ab4bb6a [formerly df4f263f91]]]
Former-commit-id: f8c9ba1546ae8e4331b5f14ab9d3ea5740769437 [formerly 6bcb348f661a5b593088c985c3b3c01fa681fe71] [formerly b4fa89c363713cda75f84be9dc04553e16920da3 [formerly b7431d07fa830a9ae30933430dc0a778365d8ce0]]
Former-commit-id: 2a6e2f65a78ba0c7b4548f316fbd50a79578fc8d [formerly 5effb794d540864ef73f159867001d9326775bde]
Former-commit-id: c045b25be1b6c73ed85f58388a542076fb4af8da
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { SerializedIdentity } from "@zk-kit/types"
|
||||
import { hexToBigint } from "bigint-conversion"
|
||||
import { poseidon } from "circomlibjs"
|
||||
import { Fq, genRandomNumber, sha256 } from "./utils"
|
||||
import { genRandomNumber, sha256 } from "./utils"
|
||||
|
||||
// The strategy used to generate the ZK identity.
|
||||
export enum Strategy {
|
||||
@@ -10,12 +10,6 @@ export enum Strategy {
|
||||
SERIALIZED // Identity parameters are passed from outside.
|
||||
}
|
||||
|
||||
// The secret type is used for the identity commitment generation.
|
||||
export enum SecretType {
|
||||
GENERIC, // Generic secret, composed of identityNullifier and identityTrapdoor.
|
||||
MULTIPART // Multipart secret, composed from multiple parts dependent on the spam threshold.
|
||||
}
|
||||
|
||||
/**
|
||||
* ZkIdentity is a class which can be used by protocols supported by the
|
||||
* @zk-key/protocols package and it simplifies the management of
|
||||
@@ -26,8 +20,6 @@ export default class ZkIdentity {
|
||||
private _identityNullifier: bigint
|
||||
|
||||
private _secret: bigint[] = []
|
||||
private _multipartSecret: bigint[] = []
|
||||
private _defaultMultipartSecret: bigint[] = []
|
||||
|
||||
/**
|
||||
* Initializes the class attributes based on the strategy passed as parameter.
|
||||
@@ -40,8 +32,6 @@ export default class ZkIdentity {
|
||||
this._identityTrapdoor = genRandomNumber()
|
||||
this._identityNullifier = genRandomNumber()
|
||||
this._secret = [this._identityNullifier, this._identityTrapdoor]
|
||||
this._setMultipartSecret()
|
||||
|
||||
break
|
||||
}
|
||||
case Strategy.MESSAGE: {
|
||||
@@ -58,8 +48,6 @@ export default class ZkIdentity {
|
||||
this._identityTrapdoor = hexToBigint(sha256(`${messageHash}identity_trapdoor`))
|
||||
this._identityNullifier = hexToBigint(sha256(`${messageHash}identity_nullifier`))
|
||||
this._secret = [this._identityNullifier, this._identityTrapdoor]
|
||||
this._setMultipartSecret()
|
||||
|
||||
break
|
||||
}
|
||||
case Strategy.SERIALIZED: {
|
||||
@@ -78,19 +66,16 @@ export default class ZkIdentity {
|
||||
if (
|
||||
!("identityNullifier" in metadata) ||
|
||||
!("identityTrapdoor" in metadata) ||
|
||||
!("secret" in metadata) ||
|
||||
!("multipartSecret" in metadata)
|
||||
!("secret" in metadata)
|
||||
) {
|
||||
throw new Error("The serialized identity does not contain the right parameter")
|
||||
}
|
||||
|
||||
const { identityNullifier, identityTrapdoor, secret, multipartSecret } = metadata
|
||||
const { identityNullifier, identityTrapdoor, secret } = metadata
|
||||
|
||||
this._identityNullifier = hexToBigint(identityNullifier)
|
||||
this._identityTrapdoor = hexToBigint(identityTrapdoor)
|
||||
this._secret = secret.map((item) => hexToBigint(item))
|
||||
this._multipartSecret = multipartSecret.map((item) => hexToBigint(item))
|
||||
this._defaultMultipartSecret = this._multipartSecret.slice(0, 2)
|
||||
|
||||
break
|
||||
}
|
||||
@@ -99,21 +84,6 @@ export default class ZkIdentity {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the multipart secret attribute.
|
||||
*/
|
||||
private _setMultipartSecret(): void {
|
||||
const initialComponent = Fq.pow(this._identityTrapdoor, this._identityNullifier)
|
||||
|
||||
this._multipartSecret = [initialComponent]
|
||||
|
||||
for (let i = 1; i < 16; i += 1) {
|
||||
this._multipartSecret.push(Fq.pow(initialComponent, BigInt(i + 1)))
|
||||
}
|
||||
|
||||
this._defaultMultipartSecret = this._multipartSecret.slice(0, 2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identity trapdoor.
|
||||
* @returns The identity trapdoor.
|
||||
@@ -138,15 +108,6 @@ export default class ZkIdentity {
|
||||
return this._secret
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default multipart secret or a portion of the multipart secret.
|
||||
* @param secretParts The number of the secret parts.
|
||||
* @returns The multipart secret.
|
||||
*/
|
||||
public getMultipartSecret(secretParts: number = 2): bigint[] {
|
||||
return secretParts === 2 ? this._defaultMultipartSecret : this._multipartSecret.slice(0, secretParts)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Poseidon hash of the secret.
|
||||
* @returns The hash of the secret.
|
||||
@@ -155,32 +116,13 @@ export default class ZkIdentity {
|
||||
return poseidon(this._secret)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Poseidon hash of the multipart secret.
|
||||
* @param secretParts The number of the secret parts.
|
||||
* @returns The hash of the multipart secret.
|
||||
*/
|
||||
public getMultipartSecretHash(secretParts: number = 2): bigint {
|
||||
const multipartSecret = this.getMultipartSecret(secretParts)
|
||||
|
||||
return poseidon(multipartSecret)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the identity commitment from the secret or the multipart secret.
|
||||
* @param secretType The secret type for which to generate identity commitment
|
||||
* @param secretParts The number of the secret parts.
|
||||
* Generates the identity commitment from the secret.
|
||||
* @returns identity commitment
|
||||
*/
|
||||
public genIdentityCommitment(secretType: SecretType = SecretType.GENERIC, secretParts: number = 2): bigint {
|
||||
switch (secretType) {
|
||||
case SecretType.GENERIC:
|
||||
public genIdentityCommitment(): bigint {
|
||||
return poseidon([this.getSecretHash()])
|
||||
case SecretType.MULTIPART:
|
||||
return poseidon([this.getMultipartSecretHash(secretParts)])
|
||||
default:
|
||||
throw new Error("The provided secret type is not supported")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,7 +134,6 @@ export default class ZkIdentity {
|
||||
identityNullifier: this._identityNullifier.toString(16),
|
||||
identityTrapdoor: this._identityTrapdoor.toString(16),
|
||||
secret: this._secret.map((item) => item.toString(16)),
|
||||
multipartSecret: this._multipartSecret.map((item) => item.toString(16))
|
||||
}
|
||||
|
||||
return JSON.stringify(data)
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import ZkIdentity, { SecretType, Strategy } from "./identity"
|
||||
import ZkIdentity, { Strategy } from "./identity"
|
||||
|
||||
export { ZkIdentity, Strategy, SecretType }
|
||||
export { ZkIdentity, Strategy }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SecretType, Strategy, ZkIdentity } from "../src"
|
||||
import { Strategy, ZkIdentity } from "../src"
|
||||
|
||||
describe("ZK identity", () => {
|
||||
describe("Create identity", () => {
|
||||
@@ -32,35 +32,15 @@ describe("ZK identity", () => {
|
||||
const trapdoor = identity.getTrapdoor()
|
||||
const nullifier = identity.getNullifier()
|
||||
const identitySecret = identity.getSecret()
|
||||
const identityMultipartSecret = identity.getMultipartSecret(5)
|
||||
|
||||
expect(typeof identity).toBe("object")
|
||||
expect(trapdoor).toBe(BigInt("58952291509798197436757858062402199043831251943841934828591473955215726495831"))
|
||||
expect(nullifier).toBe(BigInt("44673097405870585416457571638073245190425597599743560105244308998175651589997"))
|
||||
expect(identitySecret).toHaveLength(2)
|
||||
expect(typeof identitySecret).toBe("object")
|
||||
expect(identityMultipartSecret).toHaveLength(5)
|
||||
expect(typeof identityMultipartSecret).toBe("object")
|
||||
})
|
||||
|
||||
it("Should get the multipart secret hash", () => {
|
||||
const identity = new ZkIdentity(Strategy.MESSAGE, "message")
|
||||
|
||||
const multipartSecretHash = identity.getMultipartSecretHash(2)
|
||||
|
||||
expect(multipartSecretHash).toBe(
|
||||
BigInt("6297169125057226632028063090073601040720936421655236852498563322517193066452")
|
||||
)
|
||||
})
|
||||
|
||||
it("Should not generate identity commitment if the secret type is wrong", () => {
|
||||
const identity = new ZkIdentity()
|
||||
const fun = () => identity.genIdentityCommitment("wrong" as any)
|
||||
|
||||
expect(fun).toThrow("secret type is not supported")
|
||||
})
|
||||
|
||||
it("Should generate an identity commitment from a generic secret", () => {
|
||||
it("Should generate an identity commitment secret", () => {
|
||||
const identity = new ZkIdentity(Strategy.MESSAGE, "message")
|
||||
const identityCommitment = identity.genIdentityCommitment()
|
||||
|
||||
@@ -69,15 +49,6 @@ describe("ZK identity", () => {
|
||||
)
|
||||
})
|
||||
|
||||
it("Should generate an identity commitment from a multipart secret", () => {
|
||||
const identity = new ZkIdentity(Strategy.MESSAGE, "message")
|
||||
const identityCommitment = identity.genIdentityCommitment(SecretType.MULTIPART)
|
||||
|
||||
expect(identityCommitment).toBe(
|
||||
BigInt("2814782719841798642796697732526373861365963990553246162063123378852339665110")
|
||||
)
|
||||
})
|
||||
|
||||
it("Should serialize an identity", () => {
|
||||
const identity = new ZkIdentity()
|
||||
const serialized = identity.serializeIdentity()
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import { FullProof, MerkleProof, SolidityProof } from "@zk-kit/types"
|
||||
import RLN from "./rln"
|
||||
import NRLN from "./nrln"
|
||||
import Semaphore from "./semaphore"
|
||||
import { generateMerkleProof, genExternalNullifier, genSignalHash } from "./utils"
|
||||
|
||||
export {
|
||||
Semaphore,
|
||||
RLN,
|
||||
NRLN,
|
||||
generateMerkleProof,
|
||||
genExternalNullifier,
|
||||
genSignalHash,
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
import { MerkleProof, StrBigInt } from "@zk-kit/types"
|
||||
import { poseidon } from "circomlibjs"
|
||||
import { Fq, genSignalHash } from "./utils"
|
||||
import ZkProtocol from "./zk-protocol"
|
||||
|
||||
export default class NRLN extends ZkProtocol {
|
||||
/**
|
||||
* Creates witness for RLN proof
|
||||
* @param identitySecret identity secret
|
||||
* @param merkleProof merkle proof that identity exists in RLN tree
|
||||
* @param epoch epoch on which signal is broadcasted
|
||||
* @param signal signal that is being broadcasted
|
||||
* @param rlnIdentifier identifier used by each separate app, needed for more accurate spam filtering
|
||||
* @param shouldHash should signal be hashed before broadcast
|
||||
* @returns rln witness
|
||||
*/
|
||||
public static genWitness(
|
||||
identitySecret: bigint[],
|
||||
merkleProof: MerkleProof,
|
||||
epoch: StrBigInt,
|
||||
signal: string,
|
||||
rlnIdentifier: bigint,
|
||||
shouldHash = true
|
||||
): any {
|
||||
return {
|
||||
identity_secret: identitySecret,
|
||||
path_elements: merkleProof.siblings,
|
||||
identity_path_index: merkleProof.pathIndices,
|
||||
x: shouldHash ? genSignalHash(signal) : signal,
|
||||
epoch,
|
||||
rln_identifier: rlnIdentifier
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param identitySecret identity secret
|
||||
* @param epoch epoch
|
||||
* @param x singal hash
|
||||
* @param limit number of messages per epoch allowed
|
||||
* @param rlnIdentifier identifier used by each separate app, needed for more accurate spam filtering
|
||||
* @returns
|
||||
*/
|
||||
public static calculateOutput(
|
||||
identitySecret: bigint[],
|
||||
epoch: bigint,
|
||||
x: bigint,
|
||||
limit: number,
|
||||
rlnIdentifier: bigint
|
||||
): bigint[] {
|
||||
const a0 = poseidon(identitySecret)
|
||||
const coeffs: bigint[] = []
|
||||
|
||||
let tmpX = x
|
||||
|
||||
coeffs.push(poseidon([identitySecret[0], epoch]))
|
||||
let y: bigint = Fq.add(Fq.mul(coeffs[0], tmpX), a0)
|
||||
|
||||
for (let i = 1; i < limit; i += 1) {
|
||||
tmpX = Fq.mul(x, tmpX)
|
||||
|
||||
coeffs.push(poseidon([identitySecret[i], epoch]))
|
||||
y = Fq.add(y, Fq.mul(coeffs[i], tmpX))
|
||||
}
|
||||
|
||||
coeffs.push(poseidon([rlnIdentifier]))
|
||||
const nullifier: bigint = NRLN.genNullifier(coeffs)
|
||||
return [y, nullifier]
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates slashing nullifier
|
||||
* @param coeffs coeefitients from calculated polinomial
|
||||
* @returns slashing nullifier
|
||||
*/
|
||||
public static genNullifier(coeffs: bigint[]): bigint {
|
||||
return poseidon(coeffs)
|
||||
}
|
||||
|
||||
/**
|
||||
* When spam occurs, identity secret can be retrieved
|
||||
* @param xs
|
||||
* @param ys
|
||||
* @returns identity secret
|
||||
*/
|
||||
public static retrieveSecret(xs: bigint[], ys: bigint[]): bigint {
|
||||
if (xs.length !== ys.length) {
|
||||
throw new Error("x and y arrays must be of same size")
|
||||
}
|
||||
|
||||
const numOfPoints: number = xs.length
|
||||
let f0 = BigInt(0)
|
||||
|
||||
for (let i = 0; i < numOfPoints; i += 1) {
|
||||
let p = BigInt(1)
|
||||
for (let j = 0; j < numOfPoints; j += 1) {
|
||||
if (j !== i) {
|
||||
p = Fq.mul(p, Fq.div(xs[j], Fq.sub(xs[j], xs[i])))
|
||||
}
|
||||
}
|
||||
f0 = Fq.add(f0, Fq.mul(ys[i], p))
|
||||
}
|
||||
|
||||
return f0
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns unique identifier of the rln dapp
|
||||
*/
|
||||
public static genIdentifier(): bigint {
|
||||
return Fq.random()
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
import { SecretType, ZkIdentity } from "@zk-kit/identity"
|
||||
import { poseidon } from "circomlibjs"
|
||||
import { getCurveFromName } from "ffjavascript"
|
||||
import * as fs from "fs"
|
||||
import * as path from "path"
|
||||
import { NRLN } from "../src"
|
||||
import { generateMerkleProof, genExternalNullifier, genSignalHash } from "../src/utils"
|
||||
|
||||
describe("NRLN", () => {
|
||||
const zkeyFiles = "./packages/protocols/zkeyFiles"
|
||||
const identityCommitments: bigint[] = []
|
||||
const SPAM_TRESHOLD = 3
|
||||
|
||||
let curve: any
|
||||
|
||||
beforeAll(async () => {
|
||||
curve = await getCurveFromName("bn128")
|
||||
|
||||
const numberOfLeaves = 3
|
||||
|
||||
for (let i = 0; i < numberOfLeaves; i += 1) {
|
||||
const identity = new ZkIdentity()
|
||||
const identityCommitment = identity.genIdentityCommitment(SecretType.MULTIPART)
|
||||
|
||||
identityCommitments.push(identityCommitment)
|
||||
}
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await curve.terminate()
|
||||
})
|
||||
|
||||
describe("NRLN features", () => {
|
||||
it("Should generate NRLN witness", () => {
|
||||
const identity = new ZkIdentity()
|
||||
const identityCommitment = identity.genIdentityCommitment(SecretType.MULTIPART, SPAM_TRESHOLD)
|
||||
const identitySecret = identity.getMultipartSecret(SPAM_TRESHOLD)
|
||||
|
||||
const leaves = Object.assign([], identityCommitments)
|
||||
leaves.push(identityCommitment)
|
||||
|
||||
const signal = "hey hey"
|
||||
const epoch = genExternalNullifier("test-epoch")
|
||||
const rlnIdentifier = NRLN.genIdentifier()
|
||||
|
||||
const merkleProof = generateMerkleProof(15, BigInt(0), 2, leaves, identityCommitment)
|
||||
const witness = NRLN.genWitness(identitySecret, merkleProof, epoch, signal, rlnIdentifier)
|
||||
|
||||
expect(typeof witness).toBe("object")
|
||||
})
|
||||
|
||||
it("Should generate NRLN proof and verify it", async () => {
|
||||
const identity = new ZkIdentity()
|
||||
const identityCommitment = identity.genIdentityCommitment(SecretType.MULTIPART, SPAM_TRESHOLD)
|
||||
const identitySecret = identity.getMultipartSecret(SPAM_TRESHOLD)
|
||||
|
||||
const leaves = Object.assign([], identityCommitments)
|
||||
leaves.push(identityCommitment)
|
||||
|
||||
const signal = "hey hey"
|
||||
const signalHash = genSignalHash(signal)
|
||||
const epoch = genExternalNullifier("test-epoch")
|
||||
const rlnIdentifier = NRLN.genIdentifier()
|
||||
|
||||
const merkleProof = generateMerkleProof(15, BigInt(0), 2, leaves, identityCommitment)
|
||||
const witness = NRLN.genWitness(identitySecret, merkleProof, epoch, signal, rlnIdentifier)
|
||||
|
||||
const [y, nullifier] = NRLN.calculateOutput(
|
||||
identitySecret,
|
||||
BigInt(epoch),
|
||||
signalHash,
|
||||
SPAM_TRESHOLD,
|
||||
rlnIdentifier
|
||||
)
|
||||
const publicSignals = [y, merkleProof.root, nullifier, signalHash, epoch, rlnIdentifier]
|
||||
|
||||
const vkeyPath = path.join(zkeyFiles, "nrln", "verification_key.json")
|
||||
const vKey = JSON.parse(fs.readFileSync(vkeyPath, "utf-8"))
|
||||
|
||||
const wasmFilePath = path.join(zkeyFiles, "nrln", "rln.wasm")
|
||||
const finalZkeyPath = path.join(zkeyFiles, "nrln", "rln_final.zkey")
|
||||
|
||||
const fullProof = await NRLN.genProof(witness, wasmFilePath, finalZkeyPath)
|
||||
const response = await NRLN.verifyProof(vKey, { proof: fullProof.proof, publicSignals })
|
||||
|
||||
expect(response).toBe(true)
|
||||
}, 30000)
|
||||
|
||||
it("Should retrieve user secret after spaming", () => {
|
||||
const identity = new ZkIdentity()
|
||||
|
||||
const identitySecret = identity.getMultipartSecret(SPAM_TRESHOLD)
|
||||
|
||||
const signal1 = "hey 1"
|
||||
const signalHash1 = genSignalHash(signal1)
|
||||
const signal2 = "hey 2"
|
||||
const signalHash2 = genSignalHash(signal2)
|
||||
const signal3 = "hey 3"
|
||||
const signalHash3 = genSignalHash(signal3)
|
||||
const signal4 = "hey 4"
|
||||
const signalHash4 = genSignalHash(signal4)
|
||||
|
||||
const epoch = genExternalNullifier("test-epoch")
|
||||
const rlnIdentifier = NRLN.genIdentifier()
|
||||
|
||||
const [y1] = NRLN.calculateOutput(identitySecret, BigInt(epoch), signalHash1, SPAM_TRESHOLD, rlnIdentifier)
|
||||
const [y2] = NRLN.calculateOutput(identitySecret, BigInt(epoch), signalHash2, SPAM_TRESHOLD, rlnIdentifier)
|
||||
const [y3] = NRLN.calculateOutput(identitySecret, BigInt(epoch), signalHash3, SPAM_TRESHOLD, rlnIdentifier)
|
||||
const [y4] = NRLN.calculateOutput(identitySecret, BigInt(epoch), signalHash4, SPAM_TRESHOLD, rlnIdentifier)
|
||||
|
||||
const retrievedSecret = NRLN.retrieveSecret(
|
||||
[signalHash1, signalHash2, signalHash3, signalHash4],
|
||||
[y1, y2, y3, y4]
|
||||
)
|
||||
|
||||
expect(retrievedSecret).toEqual(poseidon(identitySecret))
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SecretType, ZkIdentity } from "@zk-kit/identity"
|
||||
import { ZkIdentity } from "@zk-kit/identity"
|
||||
import { getCurveFromName } from "ffjavascript"
|
||||
import * as fs from "fs"
|
||||
import * as path from "path"
|
||||
@@ -18,7 +18,7 @@ describe("RLN", () => {
|
||||
|
||||
for (let i = 0; i < numberOfLeaves; i += 1) {
|
||||
const identity = new ZkIdentity()
|
||||
const identityCommitment = identity.genIdentityCommitment(SecretType.MULTIPART)
|
||||
const identityCommitment = identity.genIdentityCommitment()
|
||||
|
||||
identityCommitments.push(identityCommitment)
|
||||
}
|
||||
@@ -32,7 +32,7 @@ describe("RLN", () => {
|
||||
it("Should generate rln witness", () => {
|
||||
const identity = new ZkIdentity()
|
||||
const identityCommitment = identity.genIdentityCommitment()
|
||||
const secretHash = identity.getMultipartSecretHash()
|
||||
const secretHash = identity.getSecretHash()
|
||||
|
||||
const leaves = Object.assign([], identityCommitments)
|
||||
leaves.push(identityCommitment)
|
||||
@@ -49,8 +49,8 @@ describe("RLN", () => {
|
||||
|
||||
it("Should generate rln proof and verify it", async () => {
|
||||
const identity = new ZkIdentity()
|
||||
const secretHash = identity.getMultipartSecretHash()
|
||||
const identityCommitment = identity.genIdentityCommitment(SecretType.MULTIPART)
|
||||
const secretHash = identity.getSecretHash()
|
||||
const identityCommitment = identity.genIdentityCommitment()
|
||||
|
||||
const leaves = Object.assign([], identityCommitments)
|
||||
leaves.push(identityCommitment)
|
||||
|
||||
1
types/zk-kit/index.d.ts
vendored
1
types/zk-kit/index.d.ts
vendored
@@ -40,5 +40,4 @@ export declare type SerializedIdentity = {
|
||||
identityNullifier: string
|
||||
identityTrapdoor: string
|
||||
secret: string[]
|
||||
multipartSecret: string[]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user