UNPKG

@cloudflare/zkp-ecdsa

Version:

zkp-ecdsa: A Typescript Implementation of ZKAttest

208 lines 6.91 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 { fromBytes, posMod, rnd, serdeBigInt, toBytes, verifyPosRange } from '../bignum/big.js'; import { jsonMember, jsonObject, toJson } from 'typedjson'; export class Group { constructor(name, p, order) { this.p = p; this.order = order; this.name = name; } isCompatPoint(pt) { if (!this.eq(pt.group)) { throw new Error('points not compatible'); } return true; } isCompatScalar(s) { if (!this.eq(s.group)) { throw new Error('scalar not compatible'); } return true; } sizeFieldBytes() { const bitSize = this.p.toString(2).length; return Math.ceil(bitSize / 8); } eq(g) { return this.name === g.name; } newScalar(s) { return new Group.Scalar(this, s); } randomScalar() { return this.newScalar(rnd(this.order)); } deserializeScalar(a) { const s = fromBytes(a); verifyPosRange(s, this.order); return this.newScalar(s); } } __decorate([ jsonMember({ constructor: String, isRequired: true }), __metadata("design:type", String) ], Group.prototype, "name", void 0); (function (Group) { var Scalar_1; class Point { isCompatPoint(pt) { return this.group.isCompatPoint(pt); } isCompatScalar(s) { return this.group.isCompatScalar(s); } static toStringCoords(coords) { let s = ''; for (const { name, value } of coords) { s += `${name}:0x${value.toString(16)}\n`; } return s; } sub(pt) { return this.add(pt.neg()); } dblmul(s1, p2, s2) { this.isCompatScalar(s1); this.isCompatScalar(s2); this.isCompatPoint(p2); const digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'], mult1 = new Map(), mult2 = new Map(); let curr1 = this.group.identity(), curr2 = p2.group.identity(); for (const digit of digits) { mult1.set(digit, curr1); mult2.set(digit, curr2); curr1 = curr1.add(this); curr2 = curr2.add(p2); } let k1 = s1.base16(), k2 = s2.base16(); if (k1.length < k2.length) { k1 = k1.padStart(k2.length, '0'); } if (k2.length < k1.length) { k2 = k2.padStart(k1.length, '0'); } let q = this.group.identity(); for (let i = 0; i < k1.length; i++) { q = q.dbl(); q = q.dbl(); q = q.dbl(); q = q.dbl(); q = q.add(mult1.get(k1[i])); q = q.add(mult2.get(k2[i])); } return q; } mul(s) { this.isCompatScalar(s); const k = s.base16(); let q = this.group.identity(); const digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'], mults = new Map(); let curr = this.group.identity(); for (const digit of digits) { mults.set(digit, curr); curr = curr.add(this); } for (const ki of k) { q = q.dbl(); q = q.dbl(); q = q.dbl(); q = q.dbl(); q = q.add(mults.get(ki)); } return q; } } Group.Point = Point; let Scalar = Scalar_1 = class Scalar { constructor(group, s) { this.group = group; this.k = s ? posMod(s, group.order) : BigInt(0); } toString() { this.reduce(); return '0x' + this.k.toString(16); } bits() { this.reduce(); return this.k.toString(2); } base16() { return this.k.toString(16); } eq(s) { this.reduce(); s.reduce(); return this.group.eq(s.group) && this.k === s.k; } add(s) { return new Scalar_1(this.group, this.k + s.k); } sub(s) { return new Scalar_1(this.group, this.k - s.k); } mul(s) { return new Scalar_1(this.group, this.k * s.k); } neg() { return new Scalar_1(this.group, -this.k); } toBytes() { this.reduce(); return toBytes(this.k, this.group.sizeFieldBytes()); } isOne() { return this.k === BigInt(1); } isZero() { return this.k === BigInt(0); } cmp(s) { if (this.k < s.k) { return -1; } else if (this.k > s.k) { return 1; } else { return 0; } } reduce() { this.k = posMod(this.k, this.group.order); } }; __decorate([ jsonMember({ constructor: Group, isRequired: true }), __metadata("design:type", Group) ], Scalar.prototype, "group", void 0); __decorate([ jsonMember(serdeBigInt), __metadata("design:type", BigInt) ], Scalar.prototype, "k", void 0); Scalar = Scalar_1 = __decorate([ jsonObject({ beforeSerialization: 'reduce', }), toJson, __metadata("design:paramtypes", [Group, BigInt]) ], Scalar); Group.Scalar = Scalar; })(Group || (Group = {})); export async function hashPoints(hashID, points) { const bytesPoints = points.map((p) => p.toBytes()), size = bytesPoints.map((b) => b.length).reduce((sum, cur) => sum + cur), bytes = new Uint8Array(size); let offset = 0; for (const bP of bytesPoints) { bytes.set(bP, offset); offset += bP.length; } const buf = await crypto.subtle.digest(hashID, bytes), hash = new Uint8Array(buf); return fromBytes(hash.slice(0, 10)); } //# sourceMappingURL=group.js.map