UNPKG

@cloudflare/zkp-ecdsa

Version:

zkp-ecdsa: A Typescript Implementation of ZKAttest

132 lines 3.73 kB
class Pair { constructor(pt, scalar) { this.pt = pt; this.scalar = scalar; } cmp(b) { return this.scalar.cmp(b.scalar); } } export class MultiMult { constructor(g) { this.group = g; this.pairs = []; this.known = []; } addKnown(pt) { this.group.isCompatPoint(pt); if (!this.known.some((x) => pt.eq(x.pt))) { const newlen = this.pairs.push(new Pair(pt, this.group.newScalar(BigInt(0)))); this.known.push({ pt: pt, idx: newlen - 1 }); } } insert(pt, s) { this.group.isCompatPoint(pt); this.group.isCompatScalar(s); const match = this.known.find((x) => pt.eq(x.pt)); if (match != undefined) { this.pairs[match.idx].scalar = this.pairs[match.idx].scalar.add(s); } else { this.pairs.push(new Pair(pt, s)); } } evaluate() { if (this.pairs.length === 0) { return this.group.identity(); } if (this.pairs.length === 1) { const a = this.pairs[0]; return a.pt.mul(a.scalar); } heapify(this.pairs); while (true) { if (this.pairs.length === 1) { const a = this.pairs[0]; return a.pt.mul(a.scalar); } const a = extractMax(this.pairs), b = this.pairs[0]; if (b.scalar.isZero()) { return a.pt.mul(a.scalar); } const c = new Pair(a.pt, a.scalar.sub(b.scalar)), d = new Pair(b.pt.add(a.pt), b.scalar); this.pairs[0] = d; if (!c.scalar.isZero()) { this.pairs.push(c); bubbleup(this.pairs, this.pairs.length); } } } } function extractMax(arr) { const t = arr[0]; arr[0] = arr[arr.length - 1]; arr[arr.length - 1] = t; const max = arr.pop(); if (max == undefined) { throw new Error('heap underflow'); } pushdown(arr, 1); return max; } function heapify(arr) { for (let i = 0; i < arr.length; i++) { bubbleup(arr, i + 1); } } function bubbleup(arr, index) { if (index == 0 || index == 1) { return; } const parent = Math.floor(index / 2); if (arr[parent - 1].cmp(arr[index - 1]) < 0) { const t = arr[index - 1]; arr[index - 1] = arr[parent - 1]; arr[parent - 1] = t; bubbleup(arr, parent); } } function pushdown(arr, parent) { const son = 2 * parent, daughter = 2 * parent + 1; if (son > arr.length) { return; } let child = son; if (daughter <= arr.length) { if (arr[daughter - 1].cmp(arr[son - 1]) > 0) { child = daughter; } } if (arr[parent - 1].cmp(arr[child - 1]) < 0) { const t = arr[child - 1]; arr[child - 1] = arr[parent - 1]; arr[parent - 1] = t; pushdown(arr, child); } } export class Relation { constructor(g) { this.group = g; this.pairs = []; } insertM(pts, scalars) { if (pts.length !== scalars.length) { throw new Error('arrays are not the same length'); } for (let i = 0; i < pts.length; i++) { this.insert(pts[i], scalars[i]); } } insert(pt, s) { this.group.isCompatPoint(pt); this.group.isCompatScalar(s); this.pairs.push(new Pair(pt, s)); } drain(m) { const randomizer = this.group.randomScalar(); for (let i = 0; i < this.pairs.length; i++) { m.insert(this.pairs[i].pt, this.pairs[i].scalar.mul(randomizer)); } } } //# sourceMappingURL=multimult.js.map