UNPKG

@cloudflare/zkp-ecdsa

Version:

zkp-ecdsa: A Typescript Implementation of ZKAttest

230 lines 10.1 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; import { Group, hashPoints } from '../curves/group.js'; import { MultiMult, Relation } from '../curves/multimult.js'; import { PointAddProof, aggregatePointAdd, provePointAdd } from './pointAdd.js'; import { isOdd, rndRange } from '../bignum/big.js'; import { jsonMember, jsonObject, toJson } from 'typedjson'; let ExpProof = class ExpProof { constructor(A, Tx, Ty, alpha, beta1, beta2, beta3, z, z2, proof, r1, r2) { this.A = A; this.Tx = Tx; this.Ty = Ty; this.alpha = alpha; this.beta1 = beta1; this.beta2 = beta2; this.beta3 = beta3; this.z = z; this.z2 = z2; this.proof = proof; this.r1 = r1; this.r2 = r2; } eq(o) { const c0 = this.A.eq(o.A) && this.Tx.eq(o.Tx) && this.Ty.eq(o.Ty), r0 = (this.alpha && o.alpha ? this.alpha.eq(o.alpha) : false) && (this.beta1 && o.beta1 ? this.beta1.eq(o.beta1) : false) && (this.beta2 && o.beta2 ? this.beta2.eq(o.beta2) : false) && (this.beta3 && o.beta3 ? this.beta3.eq(o.beta3) : false), r1 = (this.z && o.z ? this.z.eq(o.z) : false) && (this.z2 && o.z2 ? this.z2.eq(o.z2) : false) && (this.proof && o.proof ? this.proof.eq(o.proof) : false) && (this.r1 && o.r1 ? this.r1.eq(o.r1) : false) && (this.r2 && o.r2 ? this.r2.eq(o.r2) : false); return c0 && (r0 || r1); } }; __decorate([ jsonMember({ constructor: Group.Point, isRequired: true }), __metadata("design:type", Group.Point) ], ExpProof.prototype, "A", void 0); __decorate([ jsonMember({ constructor: Group.Point, isRequired: true }), __metadata("design:type", Group.Point) ], ExpProof.prototype, "Tx", void 0); __decorate([ jsonMember({ constructor: Group.Point, isRequired: true }), __metadata("design:type", Group.Point) ], ExpProof.prototype, "Ty", void 0); __decorate([ jsonMember({ constructor: Group.Scalar }), __metadata("design:type", Group.Scalar) ], ExpProof.prototype, "alpha", void 0); __decorate([ jsonMember({ constructor: Group.Scalar }), __metadata("design:type", Group.Scalar) ], ExpProof.prototype, "beta1", void 0); __decorate([ jsonMember({ constructor: Group.Scalar }), __metadata("design:type", Group.Scalar) ], ExpProof.prototype, "beta2", void 0); __decorate([ jsonMember({ constructor: Group.Scalar }), __metadata("design:type", Group.Scalar) ], ExpProof.prototype, "beta3", void 0); __decorate([ jsonMember({ constructor: Group.Scalar }), __metadata("design:type", Group.Scalar) ], ExpProof.prototype, "z", void 0); __decorate([ jsonMember({ constructor: Group.Scalar }), __metadata("design:type", Group.Scalar) ], ExpProof.prototype, "z2", void 0); __decorate([ jsonMember({ constructor: PointAddProof }), __metadata("design:type", PointAddProof) ], ExpProof.prototype, "proof", void 0); __decorate([ jsonMember({ constructor: Group.Scalar }), __metadata("design:type", Group.Scalar) ], ExpProof.prototype, "r1", void 0); __decorate([ jsonMember({ constructor: Group.Scalar }), __metadata("design:type", Group.Scalar) ], ExpProof.prototype, "r2", void 0); ExpProof = __decorate([ jsonObject, toJson, __metadata("design:paramtypes", [Group.Point, Group.Point, Group.Point, Group.Scalar, Group.Scalar, Group.Scalar, Group.Scalar, Group.Scalar, Group.Scalar, PointAddProof, Group.Scalar, Group.Scalar]) ], ExpProof); export { ExpProof }; function paddedBits(val, length) { const ret = []; for (let i = 0; i < length; i++) { ret[i] = val % BigInt(2) == BigInt(1); val >>= BigInt(1); } return ret; } function generateIndices(indnum, limit) { const ret = []; for (let i = 0; i < limit; i++) { ret[i] = i; } for (let i = 0; i < limit - 2; i++) { const j = Number(rndRange(BigInt(i), BigInt(limit - 1))), k = ret[i]; ret[i] = ret[j]; ret[j] = k; } ret.slice(indnum); return ret; } export async function proveExp(paramsNIST, paramsWario, s, Cs, P, Px, Py, secparam, Q) { const alpha = new Array(secparam), r = new Array(secparam), T = new Array(secparam), A = new Array(secparam), Tx = new Array(secparam), Ty = new Array(secparam); for (let i = 0; i < secparam; i++) { alpha[i] = paramsNIST.c.randomScalar(); r[i] = paramsNIST.c.randomScalar(); T[i] = paramsNIST.g.mul(alpha[i]); A[i] = T[i].add(paramsNIST.h.mul(r[i])); const coordT = T[i].toAffine(); if (!coordT) { throw new Error('T[i] is at infinity'); } const { x, y } = coordT; Tx[i] = paramsWario.commit(x); Ty[i] = paramsWario.commit(y); } const arr = [Px.p, Py.p]; for (let i = 0; i < secparam; i++) { arr.push(A[i]); arr.push(Tx[i].p); arr.push(Ty[i].p); } let challenge = await hashPoints('SHA-256', arr); const allProofs = new Array(secparam); let proof; for (let i = 0; i < secparam; i++) { if (isOdd(challenge)) { proof = new ExpProof(A[i], Tx[i].p, Ty[i].p, alpha[i], r[i], Tx[i].r, Ty[i].r, undefined, undefined, undefined, undefined, undefined); } else { const z = alpha[i].sub(paramsNIST.c.newScalar(s)); let T1 = paramsNIST.g.mul(z); if (Q) { T1 = T1.add(Q); } const coordT1 = T1.toAffine(); if (!coordT1) { throw new Error('T1 is at infinity'); } const { x, y } = coordT1, T1x = paramsWario.commit(x), T1y = paramsWario.commit(y), pointAddProof = await provePointAdd(paramsWario, T1, P, T[i], T1x, T1y, Px, Py, Tx[i], Ty[i]); proof = new ExpProof(A[i], Tx[i].p, Ty[i].p, undefined, undefined, undefined, undefined, z, r[i].sub(Cs.r), pointAddProof, T1x.r, T1y.r); } allProofs[i] = proof; challenge >>= BigInt(1); } return allProofs; } export async function verifyExp(paramsNIST, paramsWario, Clambda, Px, Py, pi, secparam, Q) { if (secparam > pi.length) { throw new Error('security level not achieved'); } const multiW = new MultiMult(paramsWario.c), multiN = new MultiMult(paramsNIST.c); multiW.addKnown(paramsWario.g); multiW.addKnown(paramsWario.h); multiN.addKnown(paramsNIST.g); multiN.addKnown(paramsNIST.h); multiN.addKnown(Clambda); const arr = [Px, Py]; for (let i = 0; i < pi.length; i++) { arr.push(pi[i].A); arr.push(pi[i].Tx); arr.push(pi[i].Ty); } const challenge = await hashPoints('SHA-256', arr), indices = generateIndices(secparam, pi.length), challengeBits = paddedBits(challenge, pi.length); for (let j = 0; j < secparam; j++) { const i = indices[j]; if (challengeBits[i]) { const { alpha, beta1, beta2, beta3 } = pi[i]; if (!(alpha && beta1 && beta2 && beta3)) { throw new Error('params not found'); } const resp = { alpha, beta1, beta2, beta3 }, T = paramsNIST.g.mul(resp.alpha), relA = new Relation(paramsNIST.c); relA.insertM([T, paramsNIST.h, pi[i].A.neg()], [paramsNIST.c.newScalar(BigInt(1)), resp.beta1, paramsNIST.c.newScalar(BigInt(1))]); relA.drain(multiN); const coordT = T.toAffine(); if (!coordT) { throw new Error('T is at infinity'); } const sx = paramsWario.c.newScalar(coordT.x), sy = paramsWario.c.newScalar(coordT.y), relTx = new Relation(paramsWario.c), relTy = new Relation(paramsWario.c); relTx.insertM([paramsWario.g, paramsWario.h, pi[i].Tx.neg()], [sx, resp.beta2, paramsWario.c.newScalar(BigInt(1))]); relTy.insertM([paramsWario.g, paramsWario.h, pi[i].Ty.neg()], [sy, resp.beta3, paramsWario.c.newScalar(BigInt(1))]); relTx.drain(multiW); relTy.drain(multiW); } else { const { z, z2, proof, r1, r2 } = pi[i]; if (!(z && z2 && proof && r1 && r2)) { throw new Error('params not found'); } const resp = { z, z2, proof, r1, r2 }; let T1 = paramsNIST.g.mul(resp.z); const relA = new Relation(paramsNIST.c); relA.insertM([T1, Clambda, pi[i].A.neg(), paramsNIST.h], [ paramsNIST.c.newScalar(BigInt(1)), paramsNIST.c.newScalar(BigInt(1)), paramsNIST.c.newScalar(BigInt(1)), resp.z2, ]); relA.drain(multiN); if (Q) { T1 = T1.add(Q); } const coordT1 = T1.toAffine(); if (!coordT1) { throw new Error('T1 is at infinity'); } const sx = paramsWario.c.newScalar(coordT1.x), sy = paramsWario.c.newScalar(coordT1.y), T1x = paramsWario.g.dblmul(sx, paramsWario.h, resp.r1), T1y = paramsWario.g.dblmul(sy, paramsWario.h, resp.r2); if (!(await aggregatePointAdd(paramsWario, T1x, T1y, Px, Py, pi[i].Tx, pi[i].Ty, resp.proof, multiW))) { return false; } } } return multiW.evaluate().isIdentity() && multiN.evaluate().isIdentity(); } //# sourceMappingURL=exp.js.map