@cloudflare/zkp-ecdsa
Version:
zkp-ecdsa: A Typescript Implementation of ZKAttest
230 lines • 10.1 kB
JavaScript
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