UNPKG

@cloudflare/zkp-ecdsa

Version:

zkp-ecdsa: A Typescript Implementation of ZKAttest

154 lines 6.88 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); }; 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