UNPKG

epir

Version:

EllipticPIR client library (Node.js / TypeScript bindings).

129 lines (102 loc) 4.03 kB
/** * Node.js (TypeScript) bindings for Native C EllipticPIR library interface. */ import { EpirBase, EpirCreateFunction, DecryptionContextBase, DecryptionContextParameter, DecryptionContextCreateFunction, SelectorFactoryBase, DEFAULT_CAPACITIES, DEFAULT_MMAX } from './types'; import bindings from 'bindings'; const epir_napi = bindings('epir'); declare class DecryptionContext implements DecryptionContextBase { constructor(path: string); getMG(): ArrayBuffer; decryptCipher(privkey: ArrayBuffer, cipher: ArrayBuffer): number; decryptReply(privkey: ArrayBuffer, dimension: number, packing: number, reply: ArrayBuffer): Promise<ArrayBuffer>; } export const createDecryptionContext: DecryptionContextCreateFunction = async ( param?: DecryptionContextParameter, mmax: number = DEFAULT_MMAX) => { const napi = await new Promise<DecryptionContext>((resolve) => { if((typeof param === 'undefined') || (typeof param === 'string') || (param instanceof ArrayBuffer)) { resolve(new epir_napi.DecryptionContext(param, mmax)); } else { // We ensure that all the JS callbacks are called. const napi = new epir_napi.DecryptionContext({ cb: (points_computed: number) => { param.cb(points_computed); if(points_computed == mmax) { resolve(napi); } }, interval: param.interval }, mmax); } }); return napi; }; declare class SelectorFactoryNapi { constructor(isFast: boolean, key: ArrayBuffer, capacityZero: number, capacityOne: number); fill: () => Promise<void>; create: (indexCounts: number[], idx: number) => ArrayBuffer; } export class SelectorFactory extends SelectorFactoryBase { napi: SelectorFactoryNapi; constructor( public readonly isFast: boolean, public readonly key: ArrayBuffer, /* istanbul ignore next */ public readonly capacities: number[] = DEFAULT_CAPACITIES) { super(isFast, key, capacities); this.napi = new epir_napi.SelectorFactory(isFast, key, capacities[0], capacities[1]); } fill(): Promise<void> { return this.napi.fill(); } create(indexCounts: number[], idx: number, refill = true): ArrayBuffer { const selector = this.napi.create(indexCounts, idx); if(refill) this.fill(); return selector; } } export class Epir implements EpirBase { createPrivkey(): ArrayBuffer { return epir_napi.create_privkey(); } createPubkey(privkey: ArrayBuffer): ArrayBuffer { return epir_napi.pubkey_from_privkey(privkey); } encrypt(pubkey: ArrayBuffer, msg: number, r?: ArrayBuffer): ArrayBuffer { return r ? epir_napi.encrypt(pubkey, msg, r) : epir_napi.encrypt(pubkey, msg); } encryptFast(privkey: ArrayBuffer, msg: number, r?: ArrayBuffer): ArrayBuffer { return r ? epir_napi.encrypt_fast(privkey, msg, r) : epir_napi.encrypt_fast(privkey, msg); } ciphersCount(index_counts: number[]): number { return epir_napi.ciphers_count(index_counts); } elementsCount(index_counts: number[]): number { return epir_napi.elements_count(index_counts); } createSelector(pubkey: ArrayBuffer, index_counts: number[], idx: number, r?: ArrayBuffer): Promise<ArrayBuffer> { return epir_napi.selector_create(pubkey, index_counts, idx, r); } createSelectorFast(privkey: ArrayBuffer, index_counts: number[], idx: number, r?: ArrayBuffer): Promise<ArrayBuffer> { return epir_napi.selector_create_fast(privkey, index_counts, idx, r); } // For testing. computeReplySize(dimension: number, packing: number, elem_size: number): number { return epir_napi.reply_size(dimension, packing, elem_size); } computeReplyRCount(dimension: number, packing: number, elem_size: number): number { return epir_napi.reply_r_count(dimension, packing, elem_size); } computeReplyMock(pubkey: ArrayBuffer, dimension: number, packing: number, elem: ArrayBuffer, r?: ArrayBuffer): ArrayBuffer { return (r ? epir_napi.reply_mock(pubkey, dimension, packing, elem, r) : epir_napi.reply_mock(pubkey, dimension, packing, elem)); } } export const createEpir: EpirCreateFunction = async () => { return new Epir(); };