@cloudflare/zkp-ecdsa
Advanced tools
Comparing version 0.2.1 to 0.2.2
@@ -1,6 +0,4 @@ | ||
export * from './rsaAccumulator.js'; | ||
export * from './zkpAttestAcc.js'; | ||
export * from './serde.js'; | ||
export * from './curves/instances.js'; | ||
export * from './zkpAttestList.js'; | ||
export * from './util.js'; | ||
export { p256, war256 } from './ec.js'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,6 +0,4 @@ | ||
export * from './rsaAccumulator.js'; | ||
export * from './zkpAttestAcc.js'; | ||
export * from './serde.js'; | ||
export * from './curves/instances.js'; | ||
export * from './zkpAttestList.js'; | ||
export * from './util.js'; | ||
export { p256, war256 } from './ec.js'; | ||
//# sourceMappingURL=index.js.map |
@@ -1,11 +0,5 @@ | ||
import * as typedjsonESM from 'typedjson'; | ||
export declare const jsonMember: typeof typedjsonESM.jsonMember; | ||
export declare const jsonArrayMember: typeof typedjsonESM.jsonArrayMember; | ||
export declare const toJson: typeof typedjsonESM.toJson; | ||
export declare const jsonObject: typeof typedjsonESM.jsonObject; | ||
export declare type Newable<T> = new (...args: any[]) => T; | ||
export declare function readJson<T>(type: Newable<T>, text: string): T; | ||
export declare function cmpArray<T extends { | ||
eq(o: T): boolean; | ||
}>(x: Array<T>, y: Array<T>): boolean; | ||
export declare type Comparable<T> = { | ||
eq(_: T): boolean; | ||
}; | ||
export declare function cmpArray<T extends Comparable<T>>(x: Array<T>, y: Array<T>): boolean; | ||
//# sourceMappingURL=util.d.ts.map |
@@ -1,30 +0,4 @@ | ||
import * as typedjsonESM from 'typedjson'; | ||
import typedjsonCJS from 'typedjson'; | ||
const typedjson = typedjsonCJS ? typedjsonCJS : typedjsonESM, TypedJSON = typedjson.TypedJSON; | ||
export const jsonMember = typedjson.jsonMember; | ||
export const jsonArrayMember = typedjson.jsonArrayMember; | ||
export const toJson = typedjson.toJson; | ||
export const jsonObject = typedjson.jsonObject; | ||
export function readJson(type, text) { | ||
const ser = new TypedJSON(type, { | ||
errorHandler: (e) => { | ||
throw e; | ||
}, | ||
}), obj = ser.parse(text); | ||
if (obj) { | ||
return obj; | ||
} | ||
throw new Error('bad parsing'); | ||
} | ||
export function cmpArray(x, y) { | ||
if (x.length != y.length) { | ||
return false; | ||
} | ||
for (let i = 0; i < x.length; i++) { | ||
if (!x[i].eq(y[i])) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
return x.length === y.length && x.every((xi, i) => xi.eq(y[i])); | ||
} | ||
//# sourceMappingURL=util.js.map |
@@ -1,13 +0,13 @@ | ||
import { ExpProof } from './exp.js'; | ||
import { GKProof } from './gk.js'; | ||
import { PedersenParams } from './pedersen.js'; | ||
import { Point } from './ec.js'; | ||
import { ExpProof } from './exp/exp.js'; | ||
import { GKProof } from './proofGK/gk.js'; | ||
import { PedersenParams } from './commit/pedersen.js'; | ||
import { Group } from './curves/group.js'; | ||
export declare class SignatureProofList { | ||
R: Point; | ||
comS1: Point; | ||
keyXcom: Point; | ||
keyYcom: Point; | ||
R: Group.Point; | ||
comS1: Group.Point; | ||
keyXcom: Group.Point; | ||
keyYcom: Group.Point; | ||
expProof: ExpProof[]; | ||
membershipProof: GKProof; | ||
constructor(R: Point, comS1: Point, keyXcom: Point, keyYcom: Point, expProof: ExpProof[], membershipProof: GKProof); | ||
constructor(R: Group.Point, comS1: Group.Point, keyXcom: Group.Point, keyYcom: Group.Point, expProof: ExpProof[], membershipProof: GKProof); | ||
eq(o: SignatureProofList): boolean; | ||
@@ -17,5 +17,5 @@ } | ||
NistGroup: PedersenParams; | ||
WarioGroup: PedersenParams; | ||
ProofGroup: PedersenParams; | ||
SecLevel: number; | ||
constructor(NistGroup: PedersenParams, WarioGroup: PedersenParams, SecLevel: number); | ||
constructor(NistGroup: PedersenParams, ProofGroup: PedersenParams, SecLevel: number); | ||
eq(o: SystemParametersList): boolean; | ||
@@ -22,0 +22,0 @@ } |
@@ -10,8 +10,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { | ||
}; | ||
import { ExpProof, proveExp, verifyExp } from './exp.js'; | ||
import { GKProof, proveMembership, verifyMembership } from './gk.js'; | ||
import { PedersenParams, generatePedersenParams } from './pedersen.js'; | ||
import { Point, p256, serdePoint, war256 } from './ec.js'; | ||
import { bitLen, fromBytes, invMod, posMod } from './big.js'; | ||
import { cmpArray, jsonArrayMember, jsonMember, jsonObject, toJson } from './util.js'; | ||
import { ExpProof, proveExp, verifyExp } from './exp/exp.js'; | ||
import { GKProof, proveMembership, verifyMembership } from './proofGK/gk.js'; | ||
import { PedersenParams, generatePedersenParams } from './commit/pedersen.js'; | ||
import { bitLen, fromBytes, invMod, posMod } from './bignum/big.js'; | ||
import { jsonArrayMember, jsonMember, jsonObject, toJson } from 'typedjson'; | ||
import { p256, tomEdwards256 } from './curves/instances.js'; | ||
import { Group } from './curves/group.js'; | ||
import { cmpArray } from './util.js'; | ||
let SignatureProofList = class SignatureProofList { | ||
@@ -36,16 +38,16 @@ constructor(R, comS1, keyXcom, keyYcom, expProof, membershipProof) { | ||
__decorate([ | ||
jsonMember(serdePoint), | ||
__metadata("design:type", Point) | ||
jsonMember({ constructor: Group.Point, isRequired: true }), | ||
__metadata("design:type", Group.Point) | ||
], SignatureProofList.prototype, "R", void 0); | ||
__decorate([ | ||
jsonMember(serdePoint), | ||
__metadata("design:type", Point) | ||
jsonMember({ constructor: Group.Point, isRequired: true }), | ||
__metadata("design:type", Group.Point) | ||
], SignatureProofList.prototype, "comS1", void 0); | ||
__decorate([ | ||
jsonMember(serdePoint), | ||
__metadata("design:type", Point) | ||
jsonMember({ constructor: Group.Point, isRequired: true }), | ||
__metadata("design:type", Group.Point) | ||
], SignatureProofList.prototype, "keyXcom", void 0); | ||
__decorate([ | ||
jsonMember(serdePoint), | ||
__metadata("design:type", Point) | ||
jsonMember({ constructor: Group.Point, isRequired: true }), | ||
__metadata("design:type", Group.Point) | ||
], SignatureProofList.prototype, "keyYcom", void 0); | ||
@@ -63,18 +65,13 @@ __decorate([ | ||
toJson, | ||
__metadata("design:paramtypes", [Point, | ||
Point, | ||
Point, | ||
Point, Array, GKProof]) | ||
__metadata("design:paramtypes", [Group.Point, Group.Point, Group.Point, Group.Point, Array, GKProof]) | ||
], SignatureProofList); | ||
export { SignatureProofList }; | ||
let SystemParametersList = class SystemParametersList { | ||
constructor(NistGroup, WarioGroup, SecLevel) { | ||
constructor(NistGroup, ProofGroup, SecLevel) { | ||
this.NistGroup = NistGroup; | ||
this.WarioGroup = WarioGroup; | ||
this.ProofGroup = ProofGroup; | ||
this.SecLevel = SecLevel; | ||
} | ||
eq(o) { | ||
return (this.NistGroup.eq(o.NistGroup) && | ||
this.WarioGroup.eq(o.WarioGroup) && | ||
this.SecLevel == o.SecLevel); | ||
return this.NistGroup.eq(o.NistGroup) && this.ProofGroup.eq(o.ProofGroup) && this.SecLevel == o.SecLevel; | ||
} | ||
@@ -89,3 +86,3 @@ }; | ||
__metadata("design:type", PedersenParams) | ||
], SystemParametersList.prototype, "WarioGroup", void 0); | ||
], SystemParametersList.prototype, "ProofGroup", void 0); | ||
__decorate([ | ||
@@ -109,4 +106,4 @@ jsonMember({ constructor: Number, isRequired: true }), | ||
export function generateParamsList(secLevel = 80) { | ||
const nistGroup = generatePedersenParams(p256), warioGroup = generatePedersenParams(war256); | ||
return new SystemParametersList(nistGroup, warioGroup, secLevel); | ||
const nistGroup = generatePedersenParams(p256), proofGroup = generatePedersenParams(tomEdwards256); | ||
return new SystemParametersList(nistGroup, proofGroup, secLevel); | ||
} | ||
@@ -125,19 +122,18 @@ export async function keyToInt(publicKey) { | ||
} | ||
const len = sigBytes.length; | ||
if (len !== 2 * Math.ceil(p256.bitSize / 8)) { | ||
throw new Error('invalid signature size'); | ||
} | ||
const groupOrder = ec.r, z = truncateToN(fromBytes(msgHash), groupOrder), r = fromBytes(sigBytes.slice(0, len / 2)), s = fromBytes(sigBytes.slice(len / 2)), sinv = invMod(s, groupOrder), u1 = posMod(sinv * z, groupOrder), u2 = posMod(sinv * r, groupOrder), R = ec.g.mul(ec.newScalar(u1)).add(pkPoint.mul(ec.newScalar(u2))), rinv = invMod(r, groupOrder), s1 = posMod(rinv * s, groupOrder), z1 = posMod(rinv * z, groupOrder), Q = ec.g.mul(ec.newScalar(z1)), paramsSigExp = new PedersenParams(p256, R, params.NistGroup.h), comS1 = paramsSigExp.commit(s1), pkX = params.WarioGroup.commit(pkCoords.x), pkY = params.WarioGroup.commit(pkCoords.y), sigProof = await proveExp(paramsSigExp, params.WarioGroup, s1, comS1, pkPoint, pkX, pkY, params.SecLevel, Q), membershipProof = await proveMembership(params.WarioGroup, pkX, which, keys); | ||
const len = sigBytes.length, groupOrder = ec.order, z = truncateToN(fromBytes(msgHash), groupOrder), r = fromBytes(sigBytes.slice(0, len / 2)), s = fromBytes(sigBytes.slice(len / 2)), sinv = invMod(s, groupOrder), u1 = posMod(sinv * z, groupOrder), u2 = posMod(sinv * r, groupOrder), R = ec | ||
.generator() | ||
.mul(ec.newScalar(u1)) | ||
.add(pkPoint.mul(ec.newScalar(u2))), rinv = invMod(r, groupOrder), s1 = posMod(rinv * s, groupOrder), z1 = posMod(rinv * z, groupOrder), Q = ec.generator().mul(ec.newScalar(z1)), paramsSigExp = new PedersenParams(p256, R, params.NistGroup.h), comS1 = paramsSigExp.commit(s1), pkX = params.ProofGroup.commit(pkCoords.x), pkY = params.ProofGroup.commit(pkCoords.y), sigProof = await proveExp(paramsSigExp, params.ProofGroup, s1, comS1, pkPoint, pkX, pkY, params.SecLevel, Q), membershipProof = await proveMembership(params.ProofGroup, pkX, which, keys); | ||
return new SignatureProofList(R, comS1.p, pkX.p, pkY.p, sigProof, membershipProof); | ||
} | ||
export async function verifySignatureList(params, msgHash, keys, proof) { | ||
const ec = p256, groupOrder = ec.r, z = truncateToN(fromBytes(msgHash), groupOrder), R = proof.R, coordR = R.toAffine(); | ||
const ec = p256, groupOrder = ec.order, z = truncateToN(fromBytes(msgHash), groupOrder), R = proof.R, coordR = R.toAffine(); | ||
if (!coordR) { | ||
throw new Error('R is at infinity'); | ||
} | ||
const rinv = invMod(coordR.x, groupOrder), paramsSigExp = new PedersenParams(p256, R, params.NistGroup.h), z1 = posMod(rinv * z, groupOrder), Q = ec.g.mul(ec.newScalar(z1)); | ||
if (!(await verifyMembership(params.WarioGroup, proof.keyXcom, keys, proof.membershipProof))) { | ||
const rinv = invMod(coordR.x, groupOrder), paramsSigExp = new PedersenParams(p256, R, params.NistGroup.h), z1 = posMod(rinv * z, groupOrder), Q = ec.generator().mul(ec.newScalar(z1)); | ||
if (!(await verifyMembership(params.ProofGroup, proof.keyXcom, keys, proof.membershipProof))) { | ||
return false; | ||
} | ||
if (!(await verifyExp(paramsSigExp, params.WarioGroup, proof.comS1, proof.keyXcom, proof.keyYcom, proof.expProof, 20, Q))) { | ||
if (!(await verifyExp(paramsSigExp, params.ProofGroup, proof.comS1, proof.keyXcom, proof.keyYcom, proof.expProof, 20, Q))) { | ||
return false; | ||
@@ -144,0 +140,0 @@ } |
{ | ||
"name": "@cloudflare/zkp-ecdsa", | ||
"version": "0.2.1", | ||
"version": "0.2.2", | ||
"description": "Zero-Knowledge Proof for ECDSA", | ||
@@ -28,10 +28,10 @@ "contributors": [ | ||
"@types/benchmark": "^1.0.33", | ||
"@types/node": "^14.14.31", | ||
"@types/node": "^15.0.1", | ||
"@typescript-eslint/eslint-plugin": "^3.9.1", | ||
"@typescript-eslint/parser": "^3.9.1", | ||
"benchmark": "^2.1.4", | ||
"eslint": "^7.21.0", | ||
"eslint": "^7.25.0", | ||
"eslint-config-pedant": "^1.0.1", | ||
"eslint-config-prettier": "^6.15.0", | ||
"eslint-plugin-prettier": "^3.3.1", | ||
"eslint-plugin-prettier": "^3.4.0", | ||
"eslint-plugin-security": "^1.4.0", | ||
@@ -41,3 +41,3 @@ "node-webcrypto-shim": "0.0.1", | ||
"pvutils": "^1.0.17", | ||
"typescript": "^4.2.2" | ||
"typescript": "^4.2.4" | ||
}, | ||
@@ -53,3 +53,3 @@ "scripts": { | ||
"flame": "tsc -b bench && 0x --output-dir flames ./lib/bench/flamegraph.js", | ||
"format": "prettier './(src|test)/*.ts' --write" | ||
"format": "prettier './(src|test|bench)/**/*.ts' --write" | ||
}, | ||
@@ -56,0 +56,0 @@ "dependencies": { |
## zkp-ecdsa | ||
This is a TypeScript library for Zero-Knowledge proof for ECDSA. | ||
This is a TypeScript library for Zero-Knowledge proof for ECDSA signatures. | ||
It enables proving knowledge of a ECDSA-P256 signature under one of many | ||
public keys that are stored in an accumulator or in a list. | ||
public keys that are stored in a list. | ||
@@ -53,40 +53,2 @@ ## Specification | ||
## Proof using RSA Accumulators. | ||
```ts | ||
import { | ||
SignatureProofAccumulator, | ||
SystemParametersAccumulator, | ||
addKeyToAccumulator, | ||
generateParamsAccumulator, | ||
proveSignatureAccumulator, | ||
verifySignatureAccumulator | ||
} from '../src/zkpAttestAcc.js' | ||
import { Accumulator } from '../src/rsaAccumulator.js' | ||
const keyPair = await crypto.subtle.generateKey( | ||
{ name: 'ECDSA', namedCurve: 'P-256' }, | ||
true, | ||
[ 'sign', 'verify']), | ||
enc = new TextEncoder(), | ||
msg = enc.encode('kilroy was here'), | ||
msgHash = new Uint8Array(await crypto.subtle.digest('SHA-256', msg)), | ||
signature = new Uint8Array( | ||
await crypto.subtle.sign({ name: 'ECDSA', hash: 'SHA-256' }, keyPair.privateKey, msg) | ||
) | ||
const { system: params, accumulator: initAcc } = generateParamsAccumulator(), | ||
{ j, acc, witness } = await addKeyToAccumulator(params, initAcc, keyPair.publicKey), | ||
proof = await proveSignatureAccumulator( | ||
params, | ||
msgHash, | ||
signature, | ||
keyPair.publicKey, | ||
j, | ||
witness, | ||
acc | ||
), | ||
success = await verifySignatureAccumulator(params, msgHash, acc, proof) | ||
``` | ||
--- | ||
@@ -114,4 +76,2 @@ | ||
--- | ||
@@ -118,0 +78,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
345485
72
5757
112