Skip to content

Instantly share code, notes, and snippets.

@Yaffle
Created December 17, 2024 09:50
Show Gist options
  • Save Yaffle/74c3c9b0d675e304caa788d00208c346 to your computer and use it in GitHub Desktop.
Save Yaffle/74c3c9b0d675e304caa788d00208c346 to your computer and use it in GitHub Desktop.
const e = B2 >= 10**7 && d * d < 2**53 ? 2 : 1;
const dsP = scalePoint(curve, sP, Math.pow(d, e));
const range = function (n) {
const a = new Array(n);
for (let i = 0; i < n; i += 1) {
a[i] = i;
}
return a;
};
const multiScalePoint = function (curve, P, s) {
//console.time('chain');
const heap = new Heap(range(s.length).reverse(), function (a, b) {
return s[a] > s[b] ? 1 : 0;
});
const chain = [];
while (true) {
const max = heap.getMax();
const next = heap.getNextMax();
if (s[next] < 2) {
break;
}
s[max] -= s[next];
heap.updateMax();
chain.push(max);
chain.push(next);
}
//console.timeEnd('chain');
let additions = 0;
const res = s.map(function (i) {
return i === 0 ? null : (i === 1 ? P : scalePoint(curve, P, i));
});
while (chain.length >= 2) {
const next = chain.pop();
const max = chain.pop();
const b = s[next];
const a = s[max];
s[max] = a + b;
res[max] = a === 0 ? res[next] : (a === b ? curve.doublePoint(res[next]) : curve.addPoints(res[max], res[next]));
additions += a !== 0 ? 1 : 0;
}
//console.log('additions', additions, s.length, heap.swaps);
return res;
};
const pointsRange = function (curve, P, to, filter, e) {
const s = range(to + 1).map(i => (filter == null || filter(i)) && i !== 0 ? Math.pow(i, e) : null);
return restoreNulls(multiScalePoint(curve, P, s.filter(i => i != null)), s);
};
function Heap(data, cmpfn) {
this.data = data;
this.cmpfn = cmpfn;
this.swaps = 0;
}
Heap.prototype.getMax = function () {
if (this.data.length < 1) {
throw new RangeError();
}
return this.data[0];
};
Heap.prototype.getNextMax = function () {
if (this.data.length < 2) {
throw new RangeError();
}
if (this.data.length < 3) {
return this.data[1];
}
const left = this.data[1];
const right = this.data[2];
return this.cmpfn(left, right) > 0 ? left : right;
};
Heap.prototype.updateMax = function () {
let index = 0;
while (index !== -1) {
let largest = index;
const left = 2 * index + 1;
if (left < this.data.length && this.cmpfn(this.data[left], this.data[largest]) > 0) {
largest = left;
}
const right = 2 * index + 2;
if (right < this.data.length && this.cmpfn(this.data[right], this.data[largest]) > 0) {
largest = right;
}
if (largest !== index) {
const tmp = this.data[index];
this.data[index] = this.data[largest];
this.data[largest] = tmp;
index = largest;
this.swaps += 1;
} else {
index = -1;
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment