epir
Version:
EllipticPIR client library (Node.js / TypeScript bindings).
74 lines • 3.23 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SelectorFactory = void 0;
const util_1 = require("./util");
const types_1 = require("./types");
const wasm_SelectorFactory_worker_ts_1 = __importDefault(require("./wasm.SelectorFactory.worker.ts"));
class SelectorFactory {
constructor(isFast, key,
/* istanbul ignore next */
capacities = types_1.DEFAULT_CAPACITIES, nThreads = navigator.hardwareConcurrency) {
this.isFast = isFast;
this.key = key;
this.capacities = capacities;
this.workers = [[], []];
this.ciphers = [[], []];
for (let i = 0; i < nThreads; i++) {
this.workers[0][i] = new wasm_SelectorFactory_worker_ts_1.default();
this.workers[1][i] = new wasm_SelectorFactory_worker_ts_1.default();
}
}
async fill() {
const promises = this.capacities.map((capacity, msg) => {
const needs = capacity - this.ciphers[msg].length;
const ciphersPerWorker = Math.floor(needs / this.workers[msg].length);
return Promise.all(this.workers[msg].map((worker, workerId) => {
const nCiphers = (workerId == this.workers[msg].length - 1 ?
needs - (this.workers[msg].length - 1) * ciphersPerWorker : ciphersPerWorker);
return new Promise((resolve) => {
if (nCiphers <= 0) {
resolve();
return;
}
worker.onmessage = (ev) => {
for (let i = 0; i * types_1.CIPHER_SIZE < ev.data.ciphers.byteLength; i++) {
this.ciphers[ev.data.msg].push(ev.data.ciphers.slice(i * types_1.CIPHER_SIZE, (i + 1) * types_1.CIPHER_SIZE));
}
resolve();
};
const random = util_1.getRandomScalarsConcat(nCiphers);
worker.postMessage({
isFast: this.isFast, key: this.key, msg: msg, count: nCiphers, random: random,
}, [random]);
});
}));
});
await Promise.all(promises);
}
create(indexCounts, idx, refill = true) {
let prod = indexCounts.reduce((acc, v) => acc * v, 1);
const ret = [];
for (let ic = 0; ic < indexCounts.length; ic++) {
const cols = indexCounts[ic];
prod /= cols;
const rows = Math.floor(idx / prod);
idx -= rows * prod;
for (let r = 0; r < cols; r++) {
const msg = (r == rows ? 1 : 0);
const cipher = this.ciphers[msg].pop();
if (!cipher)
throw new Error('Insufficient ciphers cache.');
ret.push(cipher);
}
}
const concat = util_1.arrayBufferConcat(ret);
if (refill)
this.fill();
return concat;
}
}
exports.SelectorFactory = SelectorFactory;
//# sourceMappingURL=wasm.SelectorFactory.js.map