diff options
Diffstat (limited to 'src/crypto')
-rw-r--r-- | src/crypto/cryptoApi-test.ts | 126 | ||||
-rw-r--r-- | src/crypto/cryptoApi.ts | 67 | ||||
-rw-r--r-- | src/crypto/cryptoWorker.ts | 214 | ||||
-rw-r--r-- | src/crypto/emscInterface-test.ts | 109 | ||||
-rw-r--r-- | src/crypto/emscInterface.ts | 384 | ||||
-rw-r--r-- | src/crypto/emscLoader.d.ts | 12 | ||||
-rw-r--r-- | src/crypto/nodeWorker.ts | 5 | ||||
-rw-r--r-- | src/crypto/nodeWorkerEntry.ts | 38 |
8 files changed, 456 insertions, 499 deletions
diff --git a/src/crypto/cryptoApi-test.ts b/src/crypto/cryptoApi-test.ts index cc5d1156e..60bd44c90 100644 --- a/src/crypto/cryptoApi-test.ts +++ b/src/crypto/cryptoApi-test.ts @@ -1,80 +1,104 @@ -import {CryptoApi} from "./cryptoApi"; -import {ReserveRecord, DenominationRecord, DenominationStatus} from "../types"; +/* + This file is part of TALER + (C) 2017 Inria and GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +// tslint:disable:max-line-length + import {test} from "ava"; -let masterPub1: string = "CQQZ9DY3MZ1ARMN5K1VKDETS04Y2QCKMMCFHZSWJWWVN82BTTH00"; +import { + DenominationRecord, + DenominationStatus, + ReserveRecord, +} from "../types"; -let denomValid1: DenominationRecord = { - masterSig: "CJFJCQ48Q45PSGJ5KY94N6M2TPARESM2E15BSPBD95YVVPEARAEQ6V6G4Z2XBMS0QM0F3Y9EYVP276FCS90EQ1578ZC8JHFBZ3NGP3G", - stampStart: "/Date(1473148381)/", - stampExpireWithdraw: "/Date(2482300381)/", - stampExpireDeposit: "/Date(1851580381)/", +import {CryptoApi} from "./cryptoApi"; + +const masterPub1: string = "CQQZ9DY3MZ1ARMN5K1VKDETS04Y2QCKMMCFHZSWJWWVN82BTTH00"; + +const denomValid1: DenominationRecord = { denomPub: "51R7ARKCD5HJTTV5F4G0M818E9SP280A40G2GVH04CR30GHS84R3JHHP6GSM2D9Q6514CGT568R32C9J6CWM4DSH64TM4DSM851K0CA48CVKAC1P6H144C2160T46DHK8CVM4HJ274S38C1M6S338D9N6GWM8DT684T3JCT36S13EC9G88R3EGHQ8S0KJGSQ60SKGD216N33AGJ2651K2E9S60TMCD1N75244HHQ6X33EDJ570R3GGJ2651MACA38D130DA560VK4HHJ68WK2CA26GW3ECSH6D13EC9S88VK2GT66WVK8D9G750K0D9R8RRK4DHQ71332GHK8D23GE26710M2H9K6WVK8HJ38MVKEGA66N23AC9H88VKACT58MV3CCSJ6H1K4DT38GRK0C9M8N33CE1R60V4AHA38H1KECSH6S33JH9N8GRKGH1K68S36GH354520818CMG26C1H60R30C935452081918G2J2G0", - stampExpireLegal: "/Date(1567756381)/", - value: { - "currency": "PUDOS", - "value": 0, - "fraction": 100000 - }, - feeWithdraw: { - "currency": "PUDOS", - "value": 0, - "fraction": 10000 - }, + denomPubHash: "dummy", + exchangeBaseUrl: "https://exchange.example.com/", feeDeposit: { - "currency": "PUDOS", - "value": 0, - "fraction": 10000 + currency: "PUDOS", + fraction: 10000, + value: 0, }, feeRefresh: { - "currency": "PUDOS", - "value": 0, - "fraction": 10000 + currency: "PUDOS", + fraction: 10000, + value: 0, }, feeRefund: { - "currency": "PUDOS", - "value": 0, - "fraction": 10000 + currency: "PUDOS", + fraction: 10000, + value: 0, + }, + feeWithdraw: { + currency: "PUDOS", + fraction: 10000, + value: 0, }, - denomPubHash: "dummy", - status: DenominationStatus.Unverified, isOffered: true, - exchangeBaseUrl: "https://exchange.example.com/", + masterSig: "CJFJCQ48Q45PSGJ5KY94N6M2TPARESM2E15BSPBD95YVVPEARAEQ6V6G4Z2XBMS0QM0F3Y9EYVP276FCS90EQ1578ZC8JHFBZ3NGP3G", + stampExpireDeposit: "/Date(1851580381)/", + stampExpireLegal: "/Date(1567756381)/", + stampExpireWithdraw: "/Date(2482300381)/", + stampStart: "/Date(1473148381)/", + status: DenominationStatus.Unverified, + value: { + currency: "PUDOS", + fraction: 100000, + value: 0, + }, }; -let denomInvalid1 = JSON.parse(JSON.stringify(denomValid1)); +const denomInvalid1 = JSON.parse(JSON.stringify(denomValid1)); denomInvalid1.value.value += 1; -test("string hashing", async t => { - let crypto = new CryptoApi(); - let s = await crypto.hashString("hello taler"); - let sh = "8RDMADB3YNF3QZBS3V467YZVJAMC2QAQX0TZGVZ6Q5PFRRAJFT70HHN0QF661QR9QWKYMMC7YEMPD679D2RADXCYK8Y669A2A5MKQFR"; - t.true(s == sh); +test("string hashing", async (t) => { + const crypto = new CryptoApi(); + const s = await crypto.hashString("hello taler"); + const sh = "8RDMADB3YNF3QZBS3V467YZVJAMC2QAQX0TZGVZ6Q5PFRRAJFT70HHN0QF661QR9QWKYMMC7YEMPD679D2RADXCYK8Y669A2A5MKQFR"; + t.true(s === sh); t.pass(); }); -test("precoin creation", async t => { - let crypto = new CryptoApi(); - let {priv, pub} = await crypto.createEddsaKeypair(); - let r: ReserveRecord = { - reserve_pub: pub, - reserve_priv: priv, - hasPayback: false, - exchange_base_url: "https://example.com/exchange", +test("precoin creation", async (t) => { + const crypto = new CryptoApi(); + const {priv, pub} = await crypto.createEddsaKeypair(); + const r: ReserveRecord = { + confirmed: false, created: 0, - requested_amount: {currency: "PUDOS", value: 0, fraction: 0}, - precoin_amount: {currency: "PUDOS", value: 0, fraction: 0}, current_amount: null, - confirmed: false, + exchange_base_url: "https://example.com/exchange", + hasPayback: false, last_query: null, + precoin_amount: {currency: "PUDOS", value: 0, fraction: 0}, + requested_amount: {currency: "PUDOS", value: 0, fraction: 0}, + reserve_priv: priv, + reserve_pub: pub, }; - let precoin = await crypto.createPreCoin(denomValid1, r); + const precoin = await crypto.createPreCoin(denomValid1, r); t.pass(); }); -test("denom validation", async t => { - let crypto = new CryptoApi(); +test("denom validation", async (t) => { + const crypto = new CryptoApi(); let v: boolean; v = await crypto.isValidDenom(denomValid1, masterPub1); t.true(v); diff --git a/src/crypto/cryptoApi.ts b/src/crypto/cryptoApi.ts index b291cd17d..57f035a83 100644 --- a/src/crypto/cryptoApi.ts +++ b/src/crypto/cryptoApi.ts @@ -24,20 +24,22 @@ * Imports. */ import { - PreCoinRecord, - CoinRecord, - ReserveRecord, AmountJson, + CoinRecord, DenominationRecord, + PayCoinInfo, PaybackRequest, + PreCoinRecord, RefreshSessionRecord, + ReserveRecord, WireFee, - PayCoinInfo, } from "../types"; + import { - OfferRecord, CoinWithDenom, + OfferRecord, } from "../wallet"; + import * as timer from "../timer"; import { startWorker } from "./startWorker"; @@ -76,8 +78,6 @@ interface WorkItem { } - - /** * Number of different priorities. Each priority p * must be 0 <= p < NUM_PRIO. @@ -97,34 +97,35 @@ export class CryptoApi { * Start a worker (if not started) and set as busy. */ wake<T>(ws: WorkerState, work: WorkItem): void { - if (ws.currentWorkItem != null) { + if (ws.currentWorkItem !== null) { throw Error("assertion failed"); } ws.currentWorkItem = work; this.numBusy++; if (!ws.w) { - let w = startWorker(); + const w = startWorker(); w.onmessage = (m: MessageEvent) => this.handleWorkerMessage(ws, m); w.onerror = (e: ErrorEvent) => this.handleWorkerError(ws, e); ws.w = w; } - let msg: any = { - operation: work.operation, args: work.args, - id: work.rpcId + const msg: any = { + args: work.args, + id: work.rpcId, + operation: work.operation, }; this.resetWorkerTimeout(ws); ws.w!.postMessage(msg); } resetWorkerTimeout(ws: WorkerState) { - if (ws.terminationTimerHandle != null) { + if (ws.terminationTimerHandle !== null) { ws.terminationTimerHandle.clear(); ws.terminationTimerHandle = null; } - let destroy = () => { + const destroy = () => { // terminate worker if it's idle - if (ws.w && ws.currentWorkItem == null) { + if (ws.w && ws.currentWorkItem === null) { ws.w!.terminate(); ws.w = null; } @@ -146,7 +147,7 @@ export class CryptoApi { } catch (e) { console.error(e); } - if (ws.currentWorkItem != null) { + if (ws.currentWorkItem !== null) { ws.currentWorkItem.reject(e); ws.currentWorkItem = null; this.numBusy--; @@ -157,9 +158,9 @@ export class CryptoApi { findWork(ws: WorkerState) { // try to find more work for this worker for (let i = 0; i < NUM_PRIO; i++) { - let q = this.workQueues[NUM_PRIO - i - 1]; - if (q.length != 0) { - let work: WorkItem = q.shift()!; + const q = this.workQueues[NUM_PRIO - i - 1]; + if (q.length !== 0) { + const work: WorkItem = q.shift()!; this.wake(ws, work); return; } @@ -167,12 +168,12 @@ export class CryptoApi { } handleWorkerMessage(ws: WorkerState, msg: MessageEvent) { - let id = msg.data.id; + const id = msg.data.id; if (typeof id !== "number") { console.error("rpc id must be number"); return; } - let currentWorkItem = ws.currentWorkItem; + const currentWorkItem = ws.currentWorkItem; ws.currentWorkItem = null; this.numBusy--; this.findWork(ws); @@ -180,7 +181,7 @@ export class CryptoApi { console.error("unsolicited response from worker"); return; } - if (id != currentWorkItem.rpcId) { + if (id !== currentWorkItem.rpcId) { console.error(`RPC with id ${id} has no registry entry`); return; } @@ -191,6 +192,7 @@ export class CryptoApi { let concurrency = 2; try { // only works in the browser + // tslint:disable-next-line:no-string-literal concurrency = (navigator as any)["hardwareConcurrency"]; } catch (e) { // ignore @@ -199,9 +201,9 @@ export class CryptoApi { for (let i = 0; i < this.workers.length; i++) { this.workers[i] = { - w: null, - terminationTimerHandle: null, currentWorkItem: null, + terminationTimerHandle: null, + w: null, }; } this.workQueues = []; @@ -212,14 +214,14 @@ export class CryptoApi { private doRpc<T>(operation: string, priority: number, ...args: any[]): Promise<T> { - let start = timer.performanceNow(); + const start = timer.performanceNow(); - let p = new Promise((resolve, reject) => { - let rpcId = this.nextRpcId++; - let workItem: WorkItem = {operation, args, resolve, reject, rpcId}; + const p = new Promise((resolve, reject) => { + const rpcId = this.nextRpcId++; + const workItem: WorkItem = {operation, args, resolve, reject, rpcId}; - if (this.numBusy == this.workers.length) { - let q = this.workQueues[priority]; + if (this.numBusy === this.workers.length) { + const q = this.workQueues[priority]; if (!q) { throw Error("assertion failed"); } @@ -227,9 +229,8 @@ export class CryptoApi { return; } - for (let i = 0; i < this.workers.length; i++) { - let ws = this.workers[i]; - if (ws.currentWorkItem != null) { + for (const ws of this.workers) { + if (ws.currentWorkItem !== null) { continue; } diff --git a/src/crypto/cryptoWorker.ts b/src/crypto/cryptoWorker.ts index 36b3b924a..9541b7442 100644 --- a/src/crypto/cryptoWorker.ts +++ b/src/crypto/cryptoWorker.ts @@ -37,12 +37,11 @@ import { ReserveRecord, WireFee, } from "../types"; -import create = chrome.alarms.create; import { CoinWithDenom, OfferRecord, } from "../wallet"; -import * as native from "./emscInterface"; + import { Amount, EddsaPublicKey, @@ -50,6 +49,7 @@ import { HashContext, RefreshMeltCoinAffirmationPS, } from "./emscInterface"; +import * as native from "./emscInterface"; namespace RpcFunctions { @@ -60,18 +60,16 @@ namespace RpcFunctions { */ export function createPreCoin(denom: DenominationRecord, reserve: ReserveRecord): PreCoinRecord { - let reservePriv = new native.EddsaPrivateKey(); + const reservePriv = new native.EddsaPrivateKey(); reservePriv.loadCrock(reserve.reserve_priv); - let reservePub = new native.EddsaPublicKey(); + const reservePub = new native.EddsaPublicKey(); reservePub.loadCrock(reserve.reserve_pub); - let denomPub = native.RsaPublicKey.fromCrock(denom.denomPub); - let coinPriv = native.EddsaPrivateKey.create(); - let coinPub = coinPriv.getPublicKey(); - let blindingFactor = native.RsaBlindingKeySecret.create(); - let pubHash: native.HashCode = coinPub.hash(); - let ev = native.rsaBlind(pubHash, - blindingFactor, - denomPub); + const denomPub = native.RsaPublicKey.fromCrock(denom.denomPub); + const coinPriv = native.EddsaPrivateKey.create(); + const coinPub = coinPriv.getPublicKey(); + const blindingFactor = native.RsaBlindingKeySecret.create(); + const pubHash: native.HashCode = coinPub.hash(); + const ev = native.rsaBlind(pubHash, blindingFactor, denomPub); if (!ev) { throw Error("couldn't blind (malicious exchange key?)"); @@ -81,61 +79,61 @@ namespace RpcFunctions { throw Error("Field fee_withdraw missing"); } - let amountWithFee = new native.Amount(denom.value); + const amountWithFee = new native.Amount(denom.value); amountWithFee.add(new native.Amount(denom.feeWithdraw)); - let withdrawFee = new native.Amount(denom.feeWithdraw); + const withdrawFee = new native.Amount(denom.feeWithdraw); // Signature - let withdrawRequest = new native.WithdrawRequestPS({ - reserve_pub: reservePub, + const withdrawRequest = new native.WithdrawRequestPS({ amount_with_fee: amountWithFee.toNbo(), - withdraw_fee: withdrawFee.toNbo(), + h_coin_envelope: ev.hash(), h_denomination_pub: denomPub.encode().hash(), - h_coin_envelope: ev.hash() + reserve_pub: reservePub, + withdraw_fee: withdrawFee.toNbo(), }); - var sig = native.eddsaSign(withdrawRequest.toPurpose(), reservePriv); + const sig = native.eddsaSign(withdrawRequest.toPurpose(), reservePriv); - let preCoin: PreCoinRecord = { - reservePub: reservePub.toCrock(), + const preCoin: PreCoinRecord = { blindingKey: blindingFactor.toCrock(), - coinPub: coinPub.toCrock(), + coinEv: ev.toCrock(), coinPriv: coinPriv.toCrock(), + coinPub: coinPub.toCrock(), + coinValue: denom.value, denomPub: denomPub.encode().toCrock(), exchangeBaseUrl: reserve.exchange_base_url, + reservePub: reservePub.toCrock(), withdrawSig: sig.toCrock(), - coinEv: ev.toCrock(), - coinValue: denom.value }; return preCoin; } export function createPaybackRequest(coin: CoinRecord): PaybackRequest { - let p = new native.PaybackRequestPS({ + const p = new native.PaybackRequestPS({ + coin_blind: native.RsaBlindingKeySecret.fromCrock(coin.blindingKey), coin_pub: native.EddsaPublicKey.fromCrock(coin.coinPub), h_denom_pub: native.RsaPublicKey.fromCrock(coin.denomPub).encode().hash(), - coin_blind: native.RsaBlindingKeySecret.fromCrock(coin.blindingKey), }); - let coinPriv = native.EddsaPrivateKey.fromCrock(coin.coinPriv); - let coinSig = native.eddsaSign(p.toPurpose(), coinPriv); - let paybackRequest: PaybackRequest = { - denom_pub: coin.denomPub, - denom_sig: coin.denomSig, + const coinPriv = native.EddsaPrivateKey.fromCrock(coin.coinPriv); + const coinSig = native.eddsaSign(p.toPurpose(), coinPriv); + const paybackRequest: PaybackRequest = { coin_blind_key_secret: coin.blindingKey, coin_pub: coin.coinPub, coin_sig: coinSig.toCrock(), + denom_pub: coin.denomPub, + denom_sig: coin.denomSig, }; return paybackRequest; } export function isValidPaymentSignature(sig: string, contractHash: string, merchantPub: string): boolean { - let p = new native.PaymentSignaturePS({ + const p = new native.PaymentSignaturePS({ contract_hash: native.HashCode.fromCrock(contractHash), }); - let nativeSig = new native.EddsaSignature(); + const nativeSig = new native.EddsaSignature(); nativeSig.loadCrock(sig); - let nativePub = native.EddsaPublicKey.fromCrock(merchantPub); + const nativePub = native.EddsaPublicKey.fromCrock(merchantPub); return native.eddsaVerify(native.SignaturePurpose.MERCHANT_PAYMENT_OK, p.toPurpose(), nativeSig, @@ -143,17 +141,17 @@ namespace RpcFunctions { } export function isValidWireFee(type: string, wf: WireFee, masterPub: string): boolean { - let p = new native.MasterWireFeePS({ + const p = new native.MasterWireFeePS({ + closing_fee: (new native.Amount(wf.closingFee)).toNbo(), + end_date: native.AbsoluteTimeNbo.fromStampSeconds(wf.endStamp), h_wire_method: native.ByteArray.fromStringWithNull(type).hash(), start_date: native.AbsoluteTimeNbo.fromStampSeconds(wf.startStamp), - end_date: native.AbsoluteTimeNbo.fromStampSeconds(wf.endStamp), wire_fee: (new native.Amount(wf.wireFee)).toNbo(), - closing_fee: (new native.Amount(wf.closingFee)).toNbo(), }); - let nativeSig = new native.EddsaSignature(); + const nativeSig = new native.EddsaSignature(); nativeSig.loadCrock(wf.sig); - let nativePub = native.EddsaPublicKey.fromCrock(masterPub); + const nativePub = native.EddsaPublicKey.fromCrock(masterPub); return native.eddsaVerify(native.SignaturePurpose.MASTER_WIRE_FEES, p.toPurpose(), @@ -164,26 +162,24 @@ namespace RpcFunctions { export function isValidDenom(denom: DenominationRecord, masterPub: string): boolean { - let p = new native.DenominationKeyValidityPS({ - master: native.EddsaPublicKey.fromCrock(masterPub), - denom_hash: native.RsaPublicKey.fromCrock(denom.denomPub) - .encode() - .hash(), + const p = new native.DenominationKeyValidityPS({ + denom_hash: native.RsaPublicKey.fromCrock(denom.denomPub) .encode() .hash(), expire_legal: native.AbsoluteTimeNbo.fromTalerString(denom.stampExpireLegal), expire_spend: native.AbsoluteTimeNbo.fromTalerString(denom.stampExpireDeposit), expire_withdraw: native.AbsoluteTimeNbo.fromTalerString(denom.stampExpireWithdraw), - start: native.AbsoluteTimeNbo.fromTalerString(denom.stampStart), - value: (new native.Amount(denom.value)).toNbo(), fee_deposit: (new native.Amount(denom.feeDeposit)).toNbo(), fee_refresh: (new native.Amount(denom.feeRefresh)).toNbo(), - fee_withdraw: (new native.Amount(denom.feeWithdraw)).toNbo(), fee_refund: (new native.Amount(denom.feeRefund)).toNbo(), + fee_withdraw: (new native.Amount(denom.feeWithdraw)).toNbo(), + master: native.EddsaPublicKey.fromCrock(masterPub), + start: native.AbsoluteTimeNbo.fromTalerString(denom.stampStart), + value: (new native.Amount(denom.value)).toNbo(), }); - let nativeSig = new native.EddsaSignature(); + const nativeSig = new native.EddsaSignature(); nativeSig.loadCrock(denom.masterSig); - let nativePub = native.EddsaPublicKey.fromCrock(masterPub); + const nativePub = native.EddsaPublicKey.fromCrock(masterPub); return native.eddsaVerify(native.SignaturePurpose.MASTER_DENOMINATION_KEY_VALIDITY, p.toPurpose(), @@ -201,10 +197,10 @@ namespace RpcFunctions { export function rsaUnblind(sig: string, bk: string, pk: string): string { - let denomSig = native.rsaUnblind(native.RsaSignature.fromCrock(sig), + const denomSig = native.rsaUnblind(native.RsaSignature.fromCrock(sig), native.RsaBlindingKeySecret.fromCrock(bk), native.RsaPublicKey.fromCrock(pk)); - return denomSig.encode().toCrock() + return denomSig.encode().toCrock(); } @@ -214,21 +210,21 @@ namespace RpcFunctions { */ export function signDeposit(offer: OfferRecord, cds: CoinWithDenom[]): PayCoinInfo { - let ret: PayCoinInfo = []; + const ret: PayCoinInfo = []; - let feeList: AmountJson[] = cds.map((x) => x.denom.feeDeposit); + const feeList: AmountJson[] = cds.map((x) => x.denom.feeDeposit); let fees = Amounts.add(Amounts.getZero(feeList[0].currency), ...feeList).amount; // okay if saturates fees = Amounts.sub(fees, offer.contract.max_fee).amount; - let total = Amounts.add(fees, offer.contract.amount).amount; + const total = Amounts.add(fees, offer.contract.amount).amount; - let amountSpent = native.Amount.getZero(cds[0].coin.currentAmount.currency); - let amountRemaining = new native.Amount(total); - for (let cd of cds) { + const amountSpent = native.Amount.getZero(cds[0].coin.currentAmount.currency); + const amountRemaining = new native.Amount(total); + for (const cd of cds) { let coinSpend: Amount; - if (amountRemaining.value == 0 && amountRemaining.fraction == 0) { + if (amountRemaining.value === 0 && amountRemaining.fraction === 0) { break; } @@ -241,7 +237,7 @@ namespace RpcFunctions { amountSpent.add(coinSpend); amountRemaining.sub(coinSpend); - let feeDeposit: Amount = new native.Amount(cd.denom.feeDeposit); + const feeDeposit: Amount = new native.Amount(cd.denom.feeDeposit); // Give the merchant at least the deposit fee, otherwise it'll reject // the coin. @@ -249,32 +245,32 @@ namespace RpcFunctions { coinSpend = feeDeposit; } - let newAmount = new native.Amount(cd.coin.currentAmount); + const newAmount = new native.Amount(cd.coin.currentAmount); newAmount.sub(coinSpend); cd.coin.currentAmount = newAmount.toJson(); cd.coin.status = CoinStatus.TransactionPending; - let d = new native.DepositRequestPS({ - h_contract: native.HashCode.fromCrock(offer.H_contract), - h_wire: native.HashCode.fromCrock(offer.contract.H_wire), + const d = new native.DepositRequestPS({ amount_with_fee: coinSpend.toNbo(), coin_pub: native.EddsaPublicKey.fromCrock(cd.coin.coinPub), deposit_fee: new native.Amount(cd.denom.feeDeposit).toNbo(), + h_contract: native.HashCode.fromCrock(offer.H_contract), + h_wire: native.HashCode.fromCrock(offer.contract.H_wire), merchant: native.EddsaPublicKey.fromCrock(offer.contract.merchant_pub), refund_deadline: native.AbsoluteTimeNbo.fromTalerString(offer.contract.refund_deadline), timestamp: native.AbsoluteTimeNbo.fromTalerString(offer.contract.timestamp), }); - let coinSig = native.eddsaSign(d.toPurpose(), + const coinSig = native.eddsaSign(d.toPurpose(), native.EddsaPrivateKey.fromCrock(cd.coin.coinPriv)) .toCrock(); - let s: CoinPaySig = { - coin_sig: coinSig, + const s: CoinPaySig = { coin_pub: cd.coin.coinPub, - ub_sig: cd.coin.denomSig, + coin_sig: coinSig, denom_pub: cd.coin.denomPub, f: coinSpend.toJson(), + ub_sig: cd.coin.denomSig, }; ret.push({sig: s, updatedCoin: cd.coin}); } @@ -290,7 +286,7 @@ namespace RpcFunctions { let valueWithFee = Amounts.getZero(newCoinDenoms[0].value.currency); - for (let ncd of newCoinDenoms) { + for (const ncd of newCoinDenoms) { valueWithFee = Amounts.add(valueWithFee, ncd.value, ncd.feeWithdraw).amount; @@ -299,23 +295,23 @@ namespace RpcFunctions { // melt fee valueWithFee = Amounts.add(valueWithFee, meltFee).amount; - let sessionHc = new HashContext(); + const sessionHc = new HashContext(); - let transferPubs: string[] = []; - let transferPrivs: string[] = []; + const transferPubs: string[] = []; + const transferPrivs: string[] = []; - let preCoinsForGammas: RefreshPreCoinRecord[][] = []; + const preCoinsForGammas: RefreshPreCoinRecord[][] = []; for (let i = 0; i < kappa; i++) { - let t = native.EcdhePrivateKey.create(); - let pub = t.getPublicKey(); + const t = native.EcdhePrivateKey.create(); + const pub = t.getPublicKey(); sessionHc.read(pub); transferPrivs.push(t.toCrock()); transferPubs.push(pub.toCrock()); } - for (let i = 0; i < newCoinDenoms.length; i++) { - let r = native.RsaPublicKey.fromCrock(newCoinDenoms[i].denomPub); + for (const denom of newCoinDenoms) { + const r = native.RsaPublicKey.fromCrock(denom.denomPub); sessionHc.read(r.encode()); } @@ -323,31 +319,31 @@ namespace RpcFunctions { sessionHc.read((new native.Amount(valueWithFee)).toNbo()); for (let i = 0; i < kappa; i++) { - let preCoins: RefreshPreCoinRecord[] = []; + const preCoins: RefreshPreCoinRecord[] = []; for (let j = 0; j < newCoinDenoms.length; j++) { - let transferPriv = native.EcdhePrivateKey.fromCrock(transferPrivs[i]); - let oldCoinPub = native.EddsaPublicKey.fromCrock(meltCoin.coinPub); - let transferSecret = native.ecdhEddsa(transferPriv, oldCoinPub); + const transferPriv = native.EcdhePrivateKey.fromCrock(transferPrivs[i]); + const oldCoinPub = native.EddsaPublicKey.fromCrock(meltCoin.coinPub); + const transferSecret = native.ecdhEddsa(transferPriv, oldCoinPub); - let fresh = native.setupFreshCoin(transferSecret, j); + const fresh = native.setupFreshCoin(transferSecret, j); - let coinPriv = fresh.priv; - let coinPub = coinPriv.getPublicKey(); - let blindingFactor = fresh.blindingKey; - let pubHash: native.HashCode = coinPub.hash(); - let denomPub = native.RsaPublicKey.fromCrock(newCoinDenoms[j].denomPub); - let ev = native.rsaBlind(pubHash, + const coinPriv = fresh.priv; + const coinPub = coinPriv.getPublicKey(); + const blindingFactor = fresh.blindingKey; + const pubHash: native.HashCode = coinPub.hash(); + const denomPub = native.RsaPublicKey.fromCrock(newCoinDenoms[j].denomPub); + const ev = native.rsaBlind(pubHash, blindingFactor, denomPub); if (!ev) { throw Error("couldn't blind (malicious exchange key?)"); } - let preCoin: RefreshPreCoinRecord = { + const preCoin: RefreshPreCoinRecord = { blindingKey: blindingFactor.toCrock(), coinEv: ev.toCrock(), - publicKey: coinPub.toCrock(), privateKey: coinPriv.toCrock(), + publicKey: coinPub.toCrock(), }; preCoins.push(preCoin); sessionHc.read(ev); @@ -355,40 +351,40 @@ namespace RpcFunctions { preCoinsForGammas.push(preCoins); } - let sessionHash = new HashCode(); + const sessionHash = new HashCode(); sessionHash.alloc(); sessionHc.finish(sessionHash); - let confirmData = new RefreshMeltCoinAffirmationPS({ - coin_pub: EddsaPublicKey.fromCrock(meltCoin.coinPub), + const confirmData = new RefreshMeltCoinAffirmationPS({ amount_with_fee: (new Amount(valueWithFee)).toNbo(), + coin_pub: EddsaPublicKey.fromCrock(meltCoin.coinPub), + melt_fee: (new Amount(meltFee)).toNbo(), session_hash: sessionHash, - melt_fee: (new Amount(meltFee)).toNbo() }); - let confirmSig: string = native.eddsaSign(confirmData.toPurpose(), + const confirmSig: string = native.eddsaSign(confirmData.toPurpose(), native.EddsaPrivateKey.fromCrock( meltCoin.coinPriv)).toCrock(); let valueOutput = Amounts.getZero(newCoinDenoms[0].value.currency); - for (let denom of newCoinDenoms) { + for (const denom of newCoinDenoms) { valueOutput = Amounts.add(valueOutput, denom.value).amount; } - let refreshSession: RefreshSessionRecord = { - meltCoinPub: meltCoin.coinPub, - newDenoms: newCoinDenoms.map((d) => d.denomPub), + const refreshSession: RefreshSessionRecord = { confirmSig, - valueWithFee, - transferPubs, - preCoinsForGammas, + exchangeBaseUrl, + finished: false, hash: sessionHash.toCrock(), + meltCoinPub: meltCoin.coinPub, + newDenoms: newCoinDenoms.map((d) => d.denomPub), norevealIndex: undefined, - exchangeBaseUrl, + preCoinsForGammas, transferPrivs, - finished: false, + transferPubs, valueOutput, + valueWithFee, }; return refreshSession; @@ -408,24 +404,24 @@ namespace RpcFunctions { } -let worker: Worker = (self as any) as Worker; +const worker: Worker = (self as any) as Worker; worker.onmessage = (msg: MessageEvent) => { if (!Array.isArray(msg.data.args)) { console.error("args must be array"); return; } - if (typeof msg.data.id != "number") { + if (typeof msg.data.id !== "number") { console.error("RPC id must be number"); } - if (typeof msg.data.operation != "string") { + if (typeof msg.data.operation !== "string") { console.error("RPC operation must be string"); } - let f = (RpcFunctions as any)[msg.data.operation]; + const f = (RpcFunctions as any)[msg.data.operation]; if (!f) { console.error(`unknown operation: '${msg.data.operation}'`); return; } - let res = f(...msg.data.args); + const res = f(...msg.data.args); worker.postMessage({result: res, id: msg.data.id}); -} +}; diff --git a/src/crypto/emscInterface-test.ts b/src/crypto/emscInterface-test.ts index dc98308fb..789ac2509 100644 --- a/src/crypto/emscInterface-test.ts +++ b/src/crypto/emscInterface-test.ts @@ -1,101 +1,124 @@ +/* + This file is part of TALER + (C) 2017 Inria and GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +// tslint:disable:max-line-length + import {test} from "ava"; import * as native from "./emscInterface"; -test("string hashing", t => { - let x = native.ByteArray.fromStringWithNull("hello taler"); - let h = "8RDMADB3YNF3QZBS3V467YZVJAMC2QAQX0TZGVZ6Q5PFRRAJFT70HHN0QF661QR9QWKYMMC7YEMPD679D2RADXCYK8Y669A2A5MKQFR" - let hc = x.hash().toCrock(); +test("string hashing", (t) => { + const x = native.ByteArray.fromStringWithNull("hello taler"); + const h = "8RDMADB3YNF3QZBS3V467YZVJAMC2QAQX0TZGVZ6Q5PFRRAJFT70HHN0QF661QR9QWKYMMC7YEMPD679D2RADXCYK8Y669A2A5MKQFR"; + const hc = x.hash().toCrock(); console.log(`# hc ${hc}`); t.true(h === hc, "must equal"); t.pass(); }); -test("signing", t => { - let x = native.ByteArray.fromStringWithNull("hello taler"); - let priv = native.EddsaPrivateKey.create(); - let pub = priv.getPublicKey(); - let purpose = new native.EccSignaturePurpose(native.SignaturePurpose.TEST, x); - let sig = native.eddsaSign(purpose, priv); + +test("signing", (t) => { + const x = native.ByteArray.fromStringWithNull("hello taler"); + const priv = native.EddsaPrivateKey.create(); + const pub = priv.getPublicKey(); + const purpose = new native.EccSignaturePurpose(native.SignaturePurpose.TEST, x); + const sig = native.eddsaSign(purpose, priv); t.true(native.eddsaVerify(native.SignaturePurpose.TEST, purpose, sig, pub)); t.pass(); }); -test("signing-fixed-data", t => { - let x = native.ByteArray.fromStringWithNull("hello taler"); - let purpose = new native.EccSignaturePurpose(native.SignaturePurpose.TEST, x); + +test("signing-fixed-data", (t) => { + const x = native.ByteArray.fromStringWithNull("hello taler"); + const purpose = new native.EccSignaturePurpose(native.SignaturePurpose.TEST, x); const privStr = "G9R8KRRCAFKPD0KW7PW48CC2T03VQ8K2AN9J6J6K2YW27J5MHN90"; const pubStr = "YHCZB442FQFJ0ET20MWA8YJ53M61EZGJ6QKV1KTJZMRNXDY45WT0"; const sigStr = "7V6XY4QGC1406GPMT305MZQ1HDCR7R0S5BP02GTGDQFPSXB6YD2YDN5ZS7NJQCNP61Y39MRHXNXQ1Z15JY4CJY4CPDA6CKQ3313WG38"; - let priv = native.EddsaPrivateKey.fromCrock(privStr); - t.true(privStr == priv.toCrock()) - let pub = priv.getPublicKey(); - t.true(pubStr == pub.toCrock()); - let sig = native.EddsaSignature.fromCrock(sigStr); - t.true(sigStr == sig.toCrock()) - let sig2 = native.eddsaSign(purpose, priv); - t.true(sig.toCrock() == sig2.toCrock()); + const priv = native.EddsaPrivateKey.fromCrock(privStr); + t.true(privStr === priv.toCrock()); + const pub = priv.getPublicKey(); + t.true(pubStr === pub.toCrock()); + const sig = native.EddsaSignature.fromCrock(sigStr); + t.true(sigStr === sig.toCrock()); + const sig2 = native.eddsaSign(purpose, priv); + t.true(sig.toCrock() === sig2.toCrock()); t.true(native.eddsaVerify(native.SignaturePurpose.TEST, purpose, sig, pub)); t.pass(); }); + const denomPubStr1 = "51R7ARKCD5HJTTV5F4G0M818E9SP280A40G2GVH04CR30G9R64VK6HHS6MW42DSN8MVKJGHK6WR3CGT18MWMCDSM75138E1K8S0MADSQ68W34DHH6MW4CHA270W4CG9J6GW48DHG8MVK4E9S7523GEA56H0K4E1Q891KCCSG752KGC1M88VMCDSQ6D23CHHG8H33AGHG6MSK8GT26CRKAC1M64V3JCJ56CVKCC228MWMCHA26MS30H1J8MVKEDHJ70TMADHK892KJC1H60TKJDHM710KGGT584T38H9K851KCDHG60W30HJ28CT4CC1G8CR3JGJ28H236DJ28H330H9S890M2D9S8S14AGA369344GA36S248CHS70RKEDSS6MWKGDJ26D136GT465348CSS8S232CHM6GS34C9N8CS3GD9H60W36H1R8MSK2GSQ8MSM6C9R70SKCHHN6MW3ACJ28N0K2CA58RS3GCA26MV42G9P891KAG9Q8N0KGD9M850KEHJ16S130CA27124AE1G852KJCHR6S1KGDSJ8RTKED1S8RR3CCHP68W4CH9Q6GT34GT18GS36EA46N24AGSP6933GCHM60VMAE1S8GV3EHHN74W3GC1J651KEH9N8MSK0CSG6S2KEEA460R32C1M8D144GSR6RWKEC218S0KEGJ4611KEEA36CSKJC2564TM4CSJ6H230E1N74TM8C1P61342CSG60WKCGHH64VK2G9S8CRKAHHK88W30HJ388R3CH1Q6X2K2DHK8GSM4D1Q74WM4HA461146H9S6D33JDJ26D234C9Q6923ECSS60RM6CT46CSKCH1M6S13EH9J8S33GCSN4CMGM81051JJ08SG64R30C1H4CMGM81054520A8A00"; -test("rsa-encode", t => { - const pubHashStr = "JM63YM5X7X547164QJ3MGJZ4WDD47GEQR5DW5SH35G4JFZXEJBHE5JBNZM5K8XN5C4BRW25BE6GSVAYBF790G2BZZ13VW91D41S4DS0" - let denomPub = native.RsaPublicKey.fromCrock(denomPubStr1); - let pubHash = denomPub.encode().hash(); - t.true(pubHashStr == pubHash.toCrock()); + +test("rsa-encode", (t) => { + const pubHashStr = "JM63YM5X7X547164QJ3MGJZ4WDD47GEQR5DW5SH35G4JFZXEJBHE5JBNZM5K8XN5C4BRW25BE6GSVAYBF790G2BZZ13VW91D41S4DS0"; + const denomPub = native.RsaPublicKey.fromCrock(denomPubStr1); + const pubHash = denomPub.encode().hash(); + t.true(pubHashStr === pubHash.toCrock()); t.pass(); }); -test("withdraw-request", t => { +test("withdraw-request", (t) => { const reservePrivStr = "G9R8KRRCAFKPD0KW7PW48CC2T03VQ8K2AN9J6J6K2YW27J5MHN90"; const reservePriv = native.EddsaPrivateKey.fromCrock(reservePrivStr); const reservePub = reservePriv.getPublicKey(); const amountWithFee = new native.Amount({currency: "KUDOS", value: 1, fraction: 10000}); amountWithFee.add(new native.Amount({currency: "KUDOS", value: 0, fraction: 20000})); - const withdrawFee = new native.Amount({currency: "KUDOS", value: 0, fraction: 20000}) + const withdrawFee = new native.Amount({currency: "KUDOS", value: 0, fraction: 20000}); const denomPub = native.RsaPublicKey.fromCrock(denomPubStr1); const ev = native.ByteArray.fromStringWithNull("hello, world"); - // Signature - let withdrawRequest = new native.WithdrawRequestPS({ - reserve_pub: reservePub, + const withdrawRequest = new native.WithdrawRequestPS({ amount_with_fee: amountWithFee.toNbo(), - withdraw_fee: withdrawFee.toNbo(), + h_coin_envelope: ev.hash(), h_denomination_pub: denomPub.encode().hash(), - h_coin_envelope: ev.hash() + reserve_pub: reservePub, + withdraw_fee: withdrawFee.toNbo(), }); - var sigStr = "AD3T8W44NV193J19RAN3NAJHPP6RVB0R3NWV7ZK5G8Q946YDK0B6F8YJBNRRBXSPVTKY31S7BVZPJFFTJJRMY61DH51X4JSXK677428"; + const sigStr = "AD3T8W44NV193J19RAN3NAJHPP6RVB0R3NWV7ZK5G8Q946YDK0B6F8YJBNRRBXSPVTKY31S7BVZPJFFTJJRMY61DH51X4JSXK677428"; - var sig = native.eddsaSign(withdrawRequest.toPurpose(), reservePriv); + const sig = native.eddsaSign(withdrawRequest.toPurpose(), reservePriv); t.true(native.eddsaVerify(native.SignaturePurpose.RESERVE_WITHDRAW, withdrawRequest.toPurpose(), sig, reservePub)); - t.true(sig.toCrock() == sigStr); + t.true(sig.toCrock() === sigStr); t.pass(); }); -test("withdraw-request", t => { + +test("withdraw-request", (t) => { const a1 = new native.Amount({currency: "KUDOS", value: 1, fraction: 50000000}); const a2 = new native.Amount({currency: "KUDOS", value: 1, fraction: 50000000}); a1.add(a2); - let x = a1.toJson(); - t.true(x.currency == "KUDOS"); - t.true(x.fraction == 0); - t.true(x.value == 3); + const x = a1.toJson(); + t.true(x.currency === "KUDOS"); + t.true(x.fraction === 0); + t.true(x.value === 3); t.pass(); }); -test("ecdsa", t => { +test("ecdsa", (t) => { const priv = native.EcdsaPrivateKey.create(); const pub1 = priv.getPublicKey(); t.pass(); }); -test("ecdhe", t => { + +test("ecdhe", (t) => { const priv = native.EcdhePrivateKey.create(); const pub = priv.getPublicKey(); t.pass(); diff --git a/src/crypto/emscInterface.ts b/src/crypto/emscInterface.ts index 52c6c965e..e00e67a84 100644 --- a/src/crypto/emscInterface.ts +++ b/src/crypto/emscInterface.ts @@ -27,8 +27,8 @@ * Imports. */ import {AmountJson} from "../types"; -import {getLib, EmscFunGen} from "./emscLoader"; +import {EmscFunGen, getLib} from "./emscLoader"; const emscLib = getLib(); @@ -51,7 +51,7 @@ const GNUNET_SYSERR = -1; const getEmsc: EmscFunGen = (name: string, ret: any, argTypes: any[]) => { return (...args: any[]) => { return emscLib.ccall(name, ret, argTypes, args); - } + }; }; @@ -59,84 +59,32 @@ const getEmsc: EmscFunGen = (name: string, ret: any, argTypes: any[]) => { * Wrapped emscripten functions that do not allocate any memory. */ const emsc = { + amount_add: getEmsc("TALER_amount_add", "number", ["number", "number", "number"]), + amount_cmp: getEmsc("TALER_amount_cmp", "number", ["number", "number"]), + amount_get_zero: getEmsc("TALER_amount_get_zero", "number", ["string", "number"]), + amount_hton: getEmsc("TALER_amount_hton", "void", ["number", "number"]), + amount_normalize: getEmsc("TALER_amount_normalize", "void", ["number"]), + amount_ntoh: getEmsc("TALER_amount_ntoh", "void", ["number", "number"]), + amount_subtract: getEmsc("TALER_amount_subtract", "number", ["number", "number", "number"]), + ecdh_eddsa: getEmsc("GNUNET_CRYPTO_ecdh_eddsa", "number", ["number", "number", "number"]), + eddsa_sign: getEmsc("GNUNET_CRYPTO_eddsa_sign", "number", ["number", "number", "number"]), + eddsa_verify: getEmsc("GNUNET_CRYPTO_eddsa_verify", "number", ["number", "number", "number", "number"]), free: (ptr: number) => emscLib._free(ptr), - get_value: getEmsc("TALER_WR_get_value", - "number", - ["number"]), - get_fraction: getEmsc("TALER_WR_get_fraction", - "number", - ["number"]), - get_currency: getEmsc("TALER_WR_get_currency", - "string", - ["number"]), - amount_add: getEmsc("TALER_amount_add", - "number", - ["number", "number", "number"]), - amount_subtract: getEmsc("TALER_amount_subtract", - "number", - ["number", "number", "number"]), - amount_normalize: getEmsc("TALER_amount_normalize", - "void", - ["number"]), - amount_get_zero: getEmsc("TALER_amount_get_zero", - "number", - ["string", "number"]), - amount_cmp: getEmsc("TALER_amount_cmp", - "number", - ["number", "number"]), - amount_hton: getEmsc("TALER_amount_hton", - "void", - ["number", "number"]), - amount_ntoh: getEmsc("TALER_amount_ntoh", - "void", - ["number", "number"]), - hash: getEmsc("GNUNET_CRYPTO_hash", - "void", - ["number", "number", "number"]), - memmove: getEmsc("memmove", - "number", - ["number", "number", "number"]), - rsa_public_key_free: getEmsc("GNUNET_CRYPTO_rsa_public_key_free", - "void", - ["number"]), - rsa_signature_free: getEmsc("GNUNET_CRYPTO_rsa_signature_free", - "void", - ["number"]), - string_to_data: getEmsc("GNUNET_STRINGS_string_to_data", - "number", - ["number", "number", "number", "number"]), - eddsa_sign: getEmsc("GNUNET_CRYPTO_eddsa_sign", - "number", - ["number", "number", "number"]), - eddsa_verify: getEmsc("GNUNET_CRYPTO_eddsa_verify", - "number", - ["number", "number", "number", "number"]), - hash_create_random: getEmsc("GNUNET_CRYPTO_hash_create_random", - "void", - ["number", "number"]), - rsa_blinding_key_destroy: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_free", - "void", - ["number"]), - random_block: getEmsc("GNUNET_CRYPTO_random_block", - "void", - ["number", "number", "number"]), - hash_context_abort: getEmsc("GNUNET_CRYPTO_hash_context_abort", - "void", - ["number"]), - hash_context_read: getEmsc("GNUNET_CRYPTO_hash_context_read", - "void", - ["number", "number", "number"]), - hash_context_finish: getEmsc("GNUNET_CRYPTO_hash_context_finish", - "void", - ["number", "number"]), - ecdh_eddsa: getEmsc("GNUNET_CRYPTO_ecdh_eddsa", - "number", - ["number", "number", "number"]), - - setup_fresh_coin: getEmsc( - "TALER_setup_fresh_coin", - "void", - ["number", "number", "number"]), + get_currency: getEmsc("TALER_WR_get_currency", "string", ["number"]), + get_fraction: getEmsc("TALER_WR_get_fraction", "number", ["number"]), + get_value: getEmsc("TALER_WR_get_value", "number", ["number"]), + hash: getEmsc("GNUNET_CRYPTO_hash", "void", ["number", "number", "number"]), + hash_context_abort: getEmsc("GNUNET_CRYPTO_hash_context_abort", "void", ["number"]), + hash_context_finish: getEmsc("GNUNET_CRYPTO_hash_context_finish", "void", ["number", "number"]), + hash_context_read: getEmsc("GNUNET_CRYPTO_hash_context_read", "void", ["number", "number", "number"]), + hash_create_random: getEmsc("GNUNET_CRYPTO_hash_create_random", "void", ["number", "number"]), + memmove: getEmsc("memmove", "number", ["number", "number", "number"]), + random_block: getEmsc("GNUNET_CRYPTO_random_block", "void", ["number", "number", "number"]), + rsa_blinding_key_destroy: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_free", "void", ["number"]), + rsa_public_key_free: getEmsc("GNUNET_CRYPTO_rsa_public_key_free", "void", ["number"]), + rsa_signature_free: getEmsc("GNUNET_CRYPTO_rsa_signature_free", "void", ["number"]), + setup_fresh_coin: getEmsc( "TALER_setup_fresh_coin", "void", ["number", "number", "number"]), + string_to_data: getEmsc("GNUNET_STRINGS_string_to_data", "number", ["number", "number", "number", "number"]), }; @@ -144,64 +92,26 @@ const emsc = { * Emscripten functions that allocate memory. */ const emscAlloc = { - get_amount: getEmsc("TALER_WRALL_get_amount", - "number", - ["number", "number", "number", "string"]), - eddsa_key_create: getEmsc("GNUNET_CRYPTO_eddsa_key_create", - "number", []), - ecdsa_key_create: getEmsc("GNUNET_CRYPTO_ecdsa_key_create", - "number", []), - ecdhe_key_create: getEmsc("GNUNET_CRYPTO_ecdhe_key_create", - "number", []), - eddsa_public_key_from_private: getEmsc( - "TALER_WRALL_eddsa_public_key_from_private", - "number", - ["number"]), - ecdsa_public_key_from_private: getEmsc( - "TALER_WRALL_ecdsa_public_key_from_private", - "number", - ["number"]), - ecdhe_public_key_from_private: getEmsc( - "TALER_WRALL_ecdhe_public_key_from_private", - "number", - ["number"]), - data_to_string_alloc: getEmsc("GNUNET_STRINGS_data_to_string_alloc", - "number", - ["number", "number"]), - purpose_create: getEmsc("TALER_WRALL_purpose_create", - "number", - ["number", "number", "number"]), - rsa_blind: getEmsc("GNUNET_CRYPTO_rsa_blind", - "number", - ["number", "number", "number", "number", "number"]), - rsa_blinding_key_create: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_create", - "number", - ["number"]), - rsa_blinding_key_encode: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_encode", - "number", - ["number", "number"]), - rsa_signature_encode: getEmsc("GNUNET_CRYPTO_rsa_signature_encode", - "number", - ["number", "number"]), - rsa_blinding_key_decode: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_decode", - "number", - ["number", "number"]), - rsa_public_key_decode: getEmsc("GNUNET_CRYPTO_rsa_public_key_decode", - "number", - ["number", "number"]), - rsa_signature_decode: getEmsc("GNUNET_CRYPTO_rsa_signature_decode", - "number", - ["number", "number"]), - rsa_public_key_encode: getEmsc("GNUNET_CRYPTO_rsa_public_key_encode", - "number", - ["number", "number"]), - rsa_unblind: getEmsc("GNUNET_CRYPTO_rsa_unblind", - "number", - ["number", "number", "number"]), - hash_context_start: getEmsc("GNUNET_CRYPTO_hash_context_start", - "number", - []), + data_to_string_alloc: getEmsc("GNUNET_STRINGS_data_to_string_alloc", "number", ["number", "number"]), + ecdhe_key_create: getEmsc("GNUNET_CRYPTO_ecdhe_key_create", "number", []), + ecdhe_public_key_from_private: getEmsc( "TALER_WRALL_ecdhe_public_key_from_private", "number", ["number"]), + ecdsa_key_create: getEmsc("GNUNET_CRYPTO_ecdsa_key_create", "number", []), + ecdsa_public_key_from_private: getEmsc( "TALER_WRALL_ecdsa_public_key_from_private", "number", ["number"]), + eddsa_key_create: getEmsc("GNUNET_CRYPTO_eddsa_key_create", "number", []), + eddsa_public_key_from_private: getEmsc( "TALER_WRALL_eddsa_public_key_from_private", "number", ["number"]), + get_amount: getEmsc("TALER_WRALL_get_amount", "number", ["number", "number", "number", "string"]), + hash_context_start: getEmsc("GNUNET_CRYPTO_hash_context_start", "number", []), malloc: (size: number) => emscLib._malloc(size), + purpose_create: getEmsc("TALER_WRALL_purpose_create", "number", ["number", "number", "number"]), + rsa_blind: getEmsc("GNUNET_CRYPTO_rsa_blind", "number", ["number", "number", "number", "number", "number"]), + rsa_blinding_key_create: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_create", "number", ["number"]), + rsa_blinding_key_decode: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_decode", "number", ["number", "number"]), + rsa_blinding_key_encode: getEmsc("GNUNET_CRYPTO_rsa_blinding_key_encode", "number", ["number", "number"]), + rsa_public_key_decode: getEmsc("GNUNET_CRYPTO_rsa_public_key_decode", "number", ["number", "number"]), + rsa_public_key_encode: getEmsc("GNUNET_CRYPTO_rsa_public_key_encode", "number", ["number", "number"]), + rsa_signature_decode: getEmsc("GNUNET_CRYPTO_rsa_signature_decode", "number", ["number", "number"]), + rsa_signature_encode: getEmsc("GNUNET_CRYPTO_rsa_signature_encode", "number", ["number", "number"]), + rsa_unblind: getEmsc("GNUNET_CRYPTO_rsa_unblind", "number", ["number", "number", "number"]), }; @@ -226,7 +136,7 @@ export enum SignaturePurpose { export enum RandomQuality { WEAK = 0, STRONG = 1, - NONCE = 2 + NONCE = 2, } @@ -301,8 +211,8 @@ abstract class MallocArenaObject implements ArenaObject { constructor(arena?: Arena) { if (!arena) { - if (arenaStack.length == 0) { - throw Error("No arena available") + if (arenaStack.length === 0) { + throw Error("No arena available"); } arena = arenaStack[arenaStack.length - 1]; } @@ -349,7 +259,7 @@ interface Arena { * Arena that must be manually destroyed. */ class SimpleArena implements Arena { - heap: Array<ArenaObject>; + heap: ArenaObject[]; constructor() { this.heap = []; @@ -360,10 +270,10 @@ class SimpleArena implements Arena { } destroy() { - for (let obj of this.heap) { + for (const obj of this.heap) { obj.destroy(); } - this.heap = [] + this.heap = []; } } @@ -396,7 +306,7 @@ class SyncArena extends SimpleArena { } } -let arenaStack: Arena[] = []; +const arenaStack: Arena[] = []; arenaStack.push(new SyncArena()); @@ -417,9 +327,9 @@ export class Amount extends MallocArenaObject { } static getZero(currency: string, a?: Arena): Amount { - let am = new Amount(undefined, a); - let r = emsc.amount_get_zero(currency, am.nativePtr); - if (r != GNUNET_OK) { + const am = new Amount(undefined, a); + const r = emsc.amount_get_zero(currency, am.nativePtr); + if (r !== GNUNET_OK) { throw Error("invalid currency"); } return am; @@ -427,7 +337,7 @@ export class Amount extends MallocArenaObject { toNbo(a?: Arena): AmountNbo { - let x = new AmountNbo(a); + const x = new AmountNbo(a); x.alloc(); emsc.amount_hton(x.nativePtr, this.nativePtr); return x; @@ -445,15 +355,15 @@ export class Amount extends MallocArenaObject { return emsc.get_fraction(this.nativePtr); } - get currency(): String { + get currency(): string { return emsc.get_currency(this.nativePtr); } toJson(): AmountJson { return { - value: emsc.get_value(this.nativePtr), + currency: emsc.get_currency(this.nativePtr), fraction: emsc.get_fraction(this.nativePtr), - currency: emsc.get_currency(this.nativePtr) + value: emsc.get_value(this.nativePtr), }; } @@ -461,7 +371,7 @@ export class Amount extends MallocArenaObject { * Add an amount to this amount. */ add(a: Amount) { - let res = emsc.amount_add(this.nativePtr, a.nativePtr, this.nativePtr); + const res = emsc.amount_add(this.nativePtr, a.nativePtr, this.nativePtr); if (res < 1) { // Overflow return false; @@ -474,8 +384,8 @@ export class Amount extends MallocArenaObject { */ sub(a: Amount) { // this = this - a - let res = emsc.amount_subtract(this.nativePtr, this.nativePtr, a.nativePtr); - if (res == 0) { + const res = emsc.amount_subtract(this.nativePtr, this.nativePtr, a.nativePtr); + if (res === 0) { // Underflow return false; } @@ -503,10 +413,10 @@ export class Amount extends MallocArenaObject { * Count the UTF-8 characters in a JavaScript string. */ function countUtf8Bytes(str: string): number { - var s = str.length; + let s = str.length; // JavaScript strings are UTF-16 arrays for (let i = str.length - 1; i >= 0; i--) { - var code = str.charCodeAt(i); + const code = str.charCodeAt(i); if (code > 0x7f && code <= 0x7ff) { // We need an extra byte in utf-8 here s++; @@ -540,8 +450,8 @@ abstract class PackedArenaObject extends MallocArenaObject { } toCrock(): string { - var d = emscAlloc.data_to_string_alloc(this.nativePtr, this.size()); - var s = emscLib.Pointer_stringify(d); + const d = emscAlloc.data_to_string_alloc(this.nativePtr, this.size()); + const s = emscLib.Pointer_stringify(d); emsc.free(d); return s; } @@ -557,8 +467,8 @@ abstract class PackedArenaObject extends MallocArenaObject { this.alloc(); // We need to get the javascript string // to the emscripten heap first. - let buf = ByteArray.fromStringWithNull(s); - let res = emsc.string_to_data(buf.nativePtr, + const buf = ByteArray.fromStringWithNull(s); + const res = emsc.string_to_data(buf.nativePtr, s.length, this.nativePtr, this.size()); @@ -576,20 +486,20 @@ abstract class PackedArenaObject extends MallocArenaObject { } hash(): HashCode { - var x = new HashCode(); + const x = new HashCode(); x.alloc(); emsc.hash(this.nativePtr, this.size(), x.nativePtr); return x; } hexdump() { - let bytes: string[] = []; + const bytes: string[] = []; for (let i = 0; i < this.size(); i++) { let b = emscLib.getValue(this.nativePtr + i, "i8"); b = (b + 256) % 256; bytes.push("0".concat(b.toString(16)).slice(-2)); } - let lines: string[] = []; + const lines: string[] = []; for (let i = 0; i < bytes.length; i += 8) { lines.push(bytes.slice(i, i + 8).join(",")); } @@ -607,10 +517,10 @@ export class AmountNbo extends PackedArenaObject { } toJson(): any { - let a = new SimpleArena(); - let am = new Amount(undefined, a); + const a = new SimpleArena(); + const am = new Amount(undefined, a); am.fromNbo(this); - let json = am.toJson(); + const json = am.toJson(); a.destroy(); return json; } @@ -621,7 +531,7 @@ export class AmountNbo extends PackedArenaObject { * Create a packed arena object from the base32 crockford encoding. */ function fromCrock<T extends PackedArenaObject>(s: string, ctor: Ctor<T>): T { - let x: T = new ctor(); + const x: T = new ctor(); x.alloc(); x.loadCrock(s); return x; @@ -632,9 +542,11 @@ function fromCrock<T extends PackedArenaObject>(s: string, ctor: Ctor<T>): T { * Create a packed arena object from the base32 crockford encoding for objects * that have a special decoding function. */ -function fromCrockDecoded<T extends MallocArenaObject>(s: string, ctor: Ctor<T>, decodeFn: (p: number, s: number) => number): T { - let obj = new ctor(); - let buf = ByteArray.fromCrock(s); +function fromCrockDecoded<T extends MallocArenaObject>(s: string, + ctor: Ctor<T>, + decodeFn: (p: number, s: number) => number): T { + const obj = new ctor(); + const buf = ByteArray.fromCrock(s); obj.nativePtr = decodeFn(buf.nativePtr, buf.size()); buf.destroy(); return obj; @@ -645,10 +557,10 @@ function fromCrockDecoded<T extends MallocArenaObject>(s: string, ctor: Ctor<T>, * Encode an object using a special encoding function. */ function encode<T extends MallocArenaObject>(obj: T, encodeFn: any, arena?: Arena): ByteArray { - let ptr = emscAlloc.malloc(PTR_SIZE); - let len = encodeFn(obj.nativePtr, ptr); - let res = new ByteArray(len, undefined, arena); - res.nativePtr = emscLib.getValue(ptr, '*'); + const ptr = emscAlloc.malloc(PTR_SIZE); + const len = encodeFn(obj.nativePtr, ptr); + const res = new ByteArray(len, undefined, arena); + res.nativePtr = emscLib.getValue(ptr, "*"); emsc.free(ptr); return res; } @@ -659,7 +571,7 @@ function encode<T extends MallocArenaObject>(obj: T, encodeFn: any, arena?: Aren */ export class EddsaPrivateKey extends PackedArenaObject { static create(a?: Arena): EddsaPrivateKey { - let obj = new EddsaPrivateKey(a); + const obj = new EddsaPrivateKey(a); obj.nativePtr = emscAlloc.eddsa_key_create(); return obj; } @@ -669,7 +581,7 @@ export class EddsaPrivateKey extends PackedArenaObject { } getPublicKey(a?: Arena): EddsaPublicKey { - let obj = new EddsaPublicKey(a); + const obj = new EddsaPublicKey(a); obj.nativePtr = emscAlloc.eddsa_public_key_from_private(this.nativePtr); return obj; } @@ -682,7 +594,7 @@ export class EddsaPrivateKey extends PackedArenaObject { export class EcdsaPrivateKey extends PackedArenaObject { static create(a?: Arena): EcdsaPrivateKey { - let obj = new EcdsaPrivateKey(a); + const obj = new EcdsaPrivateKey(a); obj.nativePtr = emscAlloc.ecdsa_key_create(); return obj; } @@ -692,7 +604,7 @@ export class EcdsaPrivateKey extends PackedArenaObject { } getPublicKey(a?: Arena): EcdsaPublicKey { - let obj = new EcdsaPublicKey(a); + const obj = new EcdsaPublicKey(a); obj.nativePtr = emscAlloc.ecdsa_public_key_from_private(this.nativePtr); return obj; } @@ -705,7 +617,7 @@ export class EcdsaPrivateKey extends PackedArenaObject { export class EcdhePrivateKey extends PackedArenaObject { static create(a?: Arena): EcdhePrivateKey { - let obj = new EcdhePrivateKey(a); + const obj = new EcdhePrivateKey(a); obj.nativePtr = emscAlloc.ecdhe_key_create(); return obj; } @@ -715,7 +627,7 @@ export class EcdhePrivateKey extends PackedArenaObject { } getPublicKey(a?: Arena): EcdhePublicKey { - let obj = new EcdhePublicKey(a); + const obj = new EcdhePublicKey(a); obj.nativePtr = emscAlloc.ecdhe_public_key_from_private(this.nativePtr); return obj; } @@ -730,7 +642,7 @@ export class EcdhePrivateKey extends PackedArenaObject { * Constructor for a given type. */ interface Ctor<T> { - new(): T + new(): T; } @@ -774,7 +686,7 @@ export class RsaBlindingKeySecret extends PackedArenaObject { * Create a random blinding key secret. */ static create(a?: Arena): RsaBlindingKeySecret { - let o = new RsaBlindingKeySecret(a); + const o = new RsaBlindingKeySecret(a); o.alloc(); o.randomize(); return o; @@ -821,16 +733,16 @@ export class ByteArray extends PackedArenaObject { static fromStringWithoutNull(s: string, a?: Arena): ByteArray { // UTF-8 bytes, including 0-terminator - let terminatedByteLength = countUtf8Bytes(s) + 1; - let hstr = emscAlloc.malloc(terminatedByteLength); + const terminatedByteLength = countUtf8Bytes(s) + 1; + const hstr = emscAlloc.malloc(terminatedByteLength); emscLib.stringToUTF8(s, hstr, terminatedByteLength); return new ByteArray(terminatedByteLength - 1, hstr, a); } static fromStringWithNull(s: string, a?: Arena): ByteArray { // UTF-8 bytes, including 0-terminator - let terminatedByteLength = countUtf8Bytes(s) + 1; - let hstr = emscAlloc.malloc(terminatedByteLength); + const terminatedByteLength = countUtf8Bytes(s) + 1; + const hstr = emscAlloc.malloc(terminatedByteLength); emscLib.stringToUTF8(s, hstr, terminatedByteLength); return new ByteArray(terminatedByteLength, hstr, a); } @@ -838,14 +750,14 @@ export class ByteArray extends PackedArenaObject { static fromCrock(s: string, a?: Arena): ByteArray { // this one is a bit more complicated than the other fromCrock functions, // since we don't have a fixed size - let byteLength = countUtf8Bytes(s); - let hstr = emscAlloc.malloc(byteLength + 1); + const byteLength = countUtf8Bytes(s); + const hstr = emscAlloc.malloc(byteLength + 1); emscLib.stringToUTF8(s, hstr, byteLength + 1); - let decodedLen = Math.floor((byteLength * 5) / 8); - let ba = new ByteArray(decodedLen, undefined, a); - let res = emsc.string_to_data(hstr, byteLength, ba.nativePtr, decodedLen); + const decodedLen = Math.floor((byteLength * 5) / 8); + const ba = new ByteArray(decodedLen, undefined, a); + const res = emsc.string_to_data(hstr, byteLength, ba.nativePtr, decodedLen); emsc.free(hstr); - if (res != GNUNET_OK) { + if (res !== GNUNET_OK) { throw Error("decoding failed"); } return ba; @@ -877,60 +789,60 @@ export class EccSignaturePurpose extends PackedArenaObject { abstract class SignatureStruct { - abstract fieldTypes(): Array<any>; + abstract fieldTypes(): any[]; abstract purpose(): SignaturePurpose; private members: any = {}; constructor(x: { [name: string]: any }) { - for (let k in x) { + for (const k in x) { this.set(k, x[k]); } } toPurpose(a?: Arena): EccSignaturePurpose { let totalSize = 0; - for (let f of this.fieldTypes()) { - let name = f[0]; - let member = this.members[name]; + for (const f of this.fieldTypes()) { + const name = f[0]; + const member = this.members[name]; if (!member) { throw Error(`Member ${name} not set`); } totalSize += member.size(); } - let buf = emscAlloc.malloc(totalSize); + const buf = emscAlloc.malloc(totalSize); let ptr = buf; - for (let f of this.fieldTypes()) { - let name = f[0]; - let member = this.members[name]; - let size = member.size(); + for (const f of this.fieldTypes()) { + const name = f[0]; + const member = this.members[name]; + const size = member.size(); emsc.memmove(ptr, member.nativePtr, size); ptr += size; } - let ba = new ByteArray(totalSize, buf, a); + const ba = new ByteArray(totalSize, buf, a); return new EccSignaturePurpose(this.purpose(), ba); } toJson() { - let res: any = {}; - for (let f of this.fieldTypes()) { - let name = f[0]; - let member = this.members[name]; + const res: any = {}; + for (const f of this.fieldTypes()) { + const name = f[0]; + const member = this.members[name]; if (!member) { throw Error(`Member ${name} not set`); } res[name] = member.toJson(); } - res["purpose"] = this.purpose(); + res.purpose = this.purpose(); return res; } protected set(name: string, value: PackedArenaObject) { - let typemap: any = {}; - for (let f of this.fieldTypes()) { + const typemap: any = {}; + for (const f of this.fieldTypes()) { typemap[f[0]] = f[1]; } if (!(name in typemap)) { @@ -969,7 +881,7 @@ export class WithdrawRequestPS extends SignatureStruct { ["amount_with_fee", AmountNbo], ["withdraw_fee", AmountNbo], ["h_denomination_pub", HashCode], - ["h_coin_envelope", HashCode] + ["h_coin_envelope", HashCode], ]; } } @@ -1023,7 +935,7 @@ export class RefreshMeltCoinAffirmationPS extends SignatureStruct { ["session_hash", HashCode], ["amount_with_fee", AmountNbo], ["melt_fee", AmountNbo], - ["coin_pub", EddsaPublicKey] + ["coin_pub", EddsaPublicKey], ]; } } @@ -1060,21 +972,21 @@ export class MasterWireFeePS extends SignatureStruct { export class AbsoluteTimeNbo extends PackedArenaObject { static fromTalerString(s: string): AbsoluteTimeNbo { - let x = new AbsoluteTimeNbo(); + const x = new AbsoluteTimeNbo(); x.alloc(); - let r = /Date\(([0-9]+)\)/; - let m = r.exec(s); - if (!m || m.length != 2) { + const r = /Date\(([0-9]+)\)/; + const m = r.exec(s); + if (!m || m.length !== 2) { throw Error(); } - let n = parseInt(m[1]) * 1000000; + const n = parseInt(m[1], 10) * 1000000; // XXX: This only works up to 54 bit numbers. set64(x.nativePtr, n); return x; } static fromStampSeconds(stamp: number): AbsoluteTimeNbo { - let x = new AbsoluteTimeNbo(); + const x = new AbsoluteTimeNbo(); x.alloc(); // XXX: This only works up to 54 bit numbers. set64(x.nativePtr, stamp * 1000000); @@ -1107,7 +1019,7 @@ function set32(p: number, n: number) { export class UInt64 extends PackedArenaObject { static fromNumber(n: number): UInt64 { - let x = new UInt64(); + const x = new UInt64(); x.alloc(); set64(x.nativePtr, n); return x; @@ -1121,7 +1033,7 @@ export class UInt64 extends PackedArenaObject { export class UInt32 extends PackedArenaObject { static fromNumber(n: number): UInt64 { - let x = new UInt32(); + const x = new UInt32(); x.alloc(); set32(x.nativePtr, n); return x; @@ -1204,7 +1116,7 @@ export class DenominationKeyValidityPS extends SignatureStruct { ["fee_deposit", AmountNbo], ["fee_refresh", AmountNbo], ["fee_refund", AmountNbo], - ["denom_hash", HashCode] + ["denom_hash", HashCode], ]; } } @@ -1283,18 +1195,18 @@ export function rsaBlind(hashCode: HashCode, blindingKey: RsaBlindingKeySecret, pkey: RsaPublicKey, arena?: Arena): ByteArray|null { - let buf_ptr_out = emscAlloc.malloc(PTR_SIZE); - let buf_size_out = emscAlloc.malloc(PTR_SIZE); - let res = emscAlloc.rsa_blind(hashCode.nativePtr, + const buf_ptr_out = emscAlloc.malloc(PTR_SIZE); + const buf_size_out = emscAlloc.malloc(PTR_SIZE); + const res = emscAlloc.rsa_blind(hashCode.nativePtr, blindingKey.nativePtr, pkey.nativePtr, buf_ptr_out, buf_size_out); - let buf_ptr = emscLib.getValue(buf_ptr_out, '*'); - let buf_size = emscLib.getValue(buf_size_out, '*'); + const buf_ptr = emscLib.getValue(buf_ptr_out, "*"); + const buf_size = emscLib.getValue(buf_size_out, "*"); emsc.free(buf_ptr_out); emsc.free(buf_size_out); - if (res != GNUNET_OK) { + if (res !== GNUNET_OK) { // malicious key return null; } @@ -1308,9 +1220,9 @@ export function rsaBlind(hashCode: HashCode, export function eddsaSign(purpose: EccSignaturePurpose, priv: EddsaPrivateKey, a?: Arena): EddsaSignature { - let sig = new EddsaSignature(a); + const sig = new EddsaSignature(a); sig.alloc(); - let res = emsc.eddsa_sign(priv.nativePtr, purpose.nativePtr, sig.nativePtr); + const res = emsc.eddsa_sign(priv.nativePtr, purpose.nativePtr, sig.nativePtr); if (res < 1) { throw Error("EdDSA signing failed"); } @@ -1326,7 +1238,7 @@ export function eddsaVerify(purposeNum: number, sig: EddsaSignature, pub: EddsaPublicKey, a?: Arena): boolean { - let r = emsc.eddsa_verify(purposeNum, + const r = emsc.eddsa_verify(purposeNum, verify.nativePtr, sig.nativePtr, pub.nativePtr); @@ -1341,7 +1253,7 @@ export function rsaUnblind(sig: RsaSignature, bk: RsaBlindingKeySecret, pk: RsaPublicKey, a?: Arena): RsaSignature { - let x = new RsaSignature(a); + const x = new RsaSignature(a); x.nativePtr = emscAlloc.rsa_unblind(sig.nativePtr, bk.nativePtr, pk.nativePtr); @@ -1362,10 +1274,10 @@ export interface FreshCoin { */ export function ecdhEddsa(priv: EcdhePrivateKey, pub: EddsaPublicKey): HashCode { - let h = new HashCode(); + const h = new HashCode(); h.alloc(); - let res = emsc.ecdh_eddsa(priv.nativePtr, pub.nativePtr, h.nativePtr); - if (res != GNUNET_OK) { + const res = emsc.ecdh_eddsa(priv.nativePtr, pub.nativePtr, h.nativePtr); + if (res !== GNUNET_OK) { throw Error("ecdh_eddsa failed"); } return h; @@ -1377,11 +1289,11 @@ export function ecdhEddsa(priv: EcdhePrivateKey, */ export function setupFreshCoin(secretSeed: TransferSecretP, coinIndex: number): FreshCoin { - let priv = new EddsaPrivateKey(); + const priv = new EddsaPrivateKey(); priv.isWeak = true; - let blindingKey = new RsaBlindingKeySecret(); + const blindingKey = new RsaBlindingKeySecret(); blindingKey.isWeak = true; - let buf = new ByteArray(priv.size() + blindingKey.size()); + const buf = new ByteArray(priv.size() + blindingKey.size()); emsc.setup_fresh_coin(secretSeed.nativePtr, coinIndex, buf.nativePtr); diff --git a/src/crypto/emscLoader.d.ts b/src/crypto/emscLoader.d.ts index e46ed7f13..aac4116b5 100644 --- a/src/crypto/emscLoader.d.ts +++ b/src/crypto/emscLoader.d.ts @@ -20,25 +20,25 @@ declare function getLib(): EmscLib; export interface EmscFunGen { (name: string, ret: string, - args: string[]): ((...x: (number|string)[]) => any); + args: string[]): ((...x: Array<number|string>) => any); (name: string, ret: "number", - args: string[]): ((...x: (number|string)[]) => number); + args: string[]): ((...x: Array<number|string>) => number); (name: string, ret: "void", - args: string[]): ((...x: (number|string)[]) => void); + args: string[]): ((...x: Array<number|string>) => void); (name: string, ret: "string", - args: string[]): ((...x: (number|string)[]) => string); + args: string[]): ((...x: Array<number|string>) => string); } interface EmscLib { cwrap: EmscFunGen; - ccall(name: string, ret:"number"|"string", argTypes: any[], args: any[]): any + ccall(name: string, ret: "number"|"string", argTypes: any[], args: any[]): any; - stringToUTF8(s: string, addr: number, maxLength: number): void + stringToUTF8(s: string, addr: number, maxLength: number): void; _free(ptr: number): void; diff --git a/src/crypto/nodeWorker.ts b/src/crypto/nodeWorker.ts index afa2930a8..4352b66c2 100644 --- a/src/crypto/nodeWorker.ts +++ b/src/crypto/nodeWorker.ts @@ -14,6 +14,9 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ + +// tslint:disable:no-var-requires + const path = require("path"); const fork = require("child_process").fork; @@ -49,7 +52,7 @@ export class Worker { } }); - this.child.send({scriptFilename,cwd: process.cwd()}); + this.child.send({scriptFilename, cwd: process.cwd()}); } addEventListener(event: "message" | "error", fn: (x: any) => void): void { diff --git a/src/crypto/nodeWorkerEntry.ts b/src/crypto/nodeWorkerEntry.ts index aa6f57599..ff7f8766b 100644 --- a/src/crypto/nodeWorkerEntry.ts +++ b/src/crypto/nodeWorkerEntry.ts @@ -15,6 +15,8 @@ */ +// tslint:disable:no-var-requires + const fs = require("fs"); const vm = require("vm"); @@ -22,57 +24,53 @@ process.once("message", (obj: any) => { const g: any = global as any; (g as any).self = { + addEventListener: (event: "error" | "message", fn: (x: any) => void) => { + if (event === "error") { + g.onerror = fn; + } else if (event === "message") { + g.onmessage = fn; + } + }, close: () => { process.exit(0); }, - postMessage: (msg: any) => { - const str: string = JSON.stringify({data: msg}); + onerror: (err: any) => { + const str: string = JSON.stringify({error: err.message, stack: err.stack}); if (process.send) { process.send(str); } }, onmessage: undefined, - onerror: (err: any) => { - const str: string = JSON.stringify({error: err.message, stack: err.stack}); + postMessage: (msg: any) => { + const str: string = JSON.stringify({data: msg}); if (process.send) { process.send(str); } }, - addEventListener: (event: "error" | "message", fn: (x: any) => void) => { - if (event == "error") { - g.onerror = fn; - } else if (event == "message") { - g.onmessage = fn; - } - }, }; g.__dirname = obj.cwd; g.__filename = __filename; - //g.require = require; - //g.module = module; - //g.exports = module.exports; - g.importScripts = (...files: string[]) => { if (files.length > 0) { - vm.createScript(files.map(file => fs.readFileSync(file, "utf8")).join("\n")).runInThisContext(); + vm.createScript(files.map((file) => fs.readFileSync(file, "utf8")).join("\n")).runInThisContext(); } }; - Object.keys(g.self).forEach(key => { + Object.keys(g.self).forEach((key) => { g[key] = g.self[key]; }); process.on("message", (msg: any) => { try { - (g.onmessage || g.self.onmessage || (() => {}))(JSON.parse(msg)); + (g.onmessage || g.self.onmessage || (() => undefined))(JSON.parse(msg)); } catch (err) { - (g.onerror || g.self.onerror || (() => {}))(err); + (g.onerror || g.self.onerror || (() => undefined))(err); } }); process.on("error", (err: any) => { - (g.onerror || g.self.onerror || (() => {}))(err); + (g.onerror || g.self.onerror || (() => undefined))(err); }); require(obj.scriptFilename); |