@cloudflare/zkp-ecdsa
Version:
zkp-ecdsa: A Typescript Implementation of ZKAttest
154 lines • 6.88 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);
};
var TEdwardsPoint_1;
import { fromBytes, invMod, posMod, serdeBigInt, toBytes, verifyPosRange } from '../bignum/big.js';
import { jsonMember, jsonObject, toJson } from 'typedjson';
import { Group } from './group.js';
let TEdwards = class TEdwards extends Group {
constructor(name, p, a, d, order, gen) {
super(name, p, order);
this.name = name;
this.p = p;
this.a = a;
this.d = d;
this.order = order;
this.gen = gen;
this._brandTEdwards = '';
verifyPosRange(a, p);
verifyPosRange(d, p);
verifyPosRange(gen[0], p);
verifyPosRange(gen[1], p);
const generator = this.generator();
if (!this.isOnGroup(generator)) {
throw new Error('generator not on group');
}
}
identity() {
return new TEdwardsPoint(this, BigInt(0), BigInt(1));
}
generator() {
return new TEdwardsPoint(this, this.gen[0], this.gen[1], posMod(this.gen[0] * this.gen[1], this.p), BigInt(1));
}
isOnGroup(pt) {
const { p, a, d } = this, { x, y, t, z } = pt, x2 = (x * x) % p, y2 = (y * y) % p, t2 = (t * t) % p, z2 = (z * z) % p, l0 = (a * x2 + y2) % p, r0 = (z2 + d * t2) % p, l1 = (x * y) % p, r1 = (z * t) % p;
return this.eq(pt.group) && posMod(l0 - r0, p) === BigInt(0) && posMod(l1 - r1, p) === BigInt(0);
}
sizePointBytes() {
return 1 + 2 * this.sizeFieldBytes();
}
deserializePoint(bytes) {
if (bytes.length === this.sizePointBytes() && bytes[0] === 0x04) {
const coordSize = this.sizeFieldBytes(), x = fromBytes(bytes.slice(1, 1 + coordSize)), y = fromBytes(bytes.slice(1 + coordSize));
verifyPosRange(x, this.p);
verifyPosRange(y, this.p);
const t = posMod(x * y, this.p), point = new TEdwardsPoint(this, x, y, t, BigInt(1));
if (!this.isOnGroup(point)) {
throw new Error(`point not on TEdwards group: ${this.name} `);
}
return point;
}
else {
throw new Error('error deserializing TEdwardsPoint');
}
}
};
TEdwards = __decorate([
toJson,
__metadata("design:paramtypes", [String, BigInt, BigInt, BigInt, BigInt, Array])
], TEdwards);
export { TEdwards };
let TEdwardsPoint = TEdwardsPoint_1 = class TEdwardsPoint extends Group.Point {
constructor(g, x, y, t, z) {
super();
this._brandTEdwardsPoint = '';
this.group = g;
this.x = x;
this.y = y;
this.t = typeof t !== 'undefined' ? t : x * y;
this.z = typeof z !== 'undefined' ? z : BigInt(1);
}
toString() {
return Group.Point.toStringCoords([
{ name: 'x', value: this.x },
{ name: 'y', value: this.y },
{ name: 't', value: this.t },
{ name: 'z', value: this.z },
]);
}
isIdentity() {
return (this.x === BigInt(0) &&
this.y !== BigInt(0) &&
this.t === BigInt(0) &&
this.z !== BigInt(0) &&
this.y === this.z);
}
eq(pt) {
const { group: g0, x: x0, y: y0, z: z0 } = this, { group: g1, x: x1, y: y1, z: z1 } = pt, x0z1 = posMod(x0 * z1, g0.p), x1z0 = posMod(x1 * z0, g0.p), y0z1 = posMod(y0 * z1, g0.p), y1z0 = posMod(y1 * z0, g0.p);
return g0.eq(g1) && x0z1 === x1z0 && y0z1 === y1z0;
}
neg() {
const x = posMod(-this.x, this.group.p), t = posMod(-this.t, this.group.p);
return new TEdwardsPoint_1(this.group, x, this.y, t, this.z);
}
dbl() {
const { x, y, z } = this, { p, a } = this.group, A = (x * x) % p, B = (y * y) % p, CC = z * z, C = (CC + CC) % p, D = (a * A) % p, EE = x + y, E = (EE * EE - A - B) % p, G = (D + B) % p, F = (G - C) % p, H = (D - B) % p, x3 = posMod(E * F, p), y3 = posMod(G * H, p), t3 = posMod(E * H, p), z3 = posMod(F * G, p);
return new TEdwardsPoint_1(this.group, x3, y3, t3, z3);
}
add(pt) {
this.isCompatPoint(pt);
const { x: x1, y: y1, t: t1, z: z1 } = this, { x: x2, y: y2, t: t2, z: z2 } = pt, { p, a, d } = this.group, A = (x1 * x2) % p, B = (y1 * y2) % p, C = (d * t1 * t2) % p, D = (z1 * z2) % p, E1 = (x1 + y1) % p, E2 = (x2 + y2) % p, E = (E1 * E2 - A - B) % p, F = (D - C) % p, G = (D + C) % p, H = (B - a * A) % p, x3 = posMod(E * F, p), y3 = posMod(G * H, p), t3 = posMod(E * H, p), z3 = posMod(F * G, p);
return new TEdwardsPoint_1(this.group, x3, y3, t3, z3);
}
toAffine() {
const zInv = invMod(this.z, this.group.p), x = posMod(this.x * zInv, this.group.p), y = posMod(this.y * zInv, this.group.p);
this.x = x;
this.y = y;
this.t = posMod(x * y, this.group.p);
this.z = BigInt(1);
return { x, y };
}
toBytes() {
const { x, y } = this.toAffine(), coordSize = this.group.sizeFieldBytes(), ret = new Uint8Array(this.group.sizePointBytes());
ret[0] = 0x04;
ret.set(toBytes(x, coordSize), 1);
ret.set(toBytes(y, coordSize), 1 + coordSize);
return ret;
}
afterJson() {
this.t = posMod(this.x * this.y, this.group.p);
if (!this.group.isOnGroup(this)) {
throw new Error(`point not on TEdwards group: ${this.group.name} `);
}
}
};
__decorate([
jsonMember({ constructor: Group, isRequired: true }),
__metadata("design:type", TEdwards)
], TEdwardsPoint.prototype, "group", void 0);
__decorate([
jsonMember(serdeBigInt),
__metadata("design:type", BigInt)
], TEdwardsPoint.prototype, "x", void 0);
__decorate([
jsonMember(serdeBigInt),
__metadata("design:type", BigInt)
], TEdwardsPoint.prototype, "y", void 0);
TEdwardsPoint = TEdwardsPoint_1 = __decorate([
jsonObject({
beforeSerialization: 'toAffine',
onDeserialized: 'afterJson',
}),
toJson,
__metadata("design:paramtypes", [TEdwards, BigInt, BigInt, BigInt, BigInt])
], TEdwardsPoint);
export { TEdwardsPoint };
jsonObject({ knownTypes: [TEdwards] })(Group);
jsonObject({ knownTypes: [TEdwardsPoint] })(Group.Point);
//# sourceMappingURL=edwards.js.map