From dbfc599540b21da399d94a966ac85b00b339b31a Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 9 Dec 2021 10:39:50 +0100 Subject: [PATCH] wallet-core: use crypto worker for eddsa signing --- packages/taler-wallet-cli/src/bench1.ts | 23 ++++---- .../crypto/workers/cryptoImplementation.ts | 59 ++++++++++++++----- .../src/crypto/workers/synchronousWorker.ts | 10 ++++ packages/taler-wallet-core/src/wallet.ts | 2 +- 4 files changed, 68 insertions(+), 26 deletions(-) diff --git a/packages/taler-wallet-cli/src/bench1.ts b/packages/taler-wallet-cli/src/bench1.ts index 3f3f752c2..c239a3623 100644 --- a/packages/taler-wallet-cli/src/bench1.ts +++ b/packages/taler-wallet-cli/src/bench1.ts @@ -38,7 +38,6 @@ import { * set up its own services. */ export async function runBench1(configJson: any): Promise { - const logger = new Logger("Bench1"); // Validate the configuration file for this benchmark. @@ -53,26 +52,29 @@ export async function runBench1(configJson: any): Promise { const withdrawAmount = (numDeposits + 1) * 10; - logger.info(`Starting Benchmark iterations=${numIter} deposits=${numDeposits}`); + logger.info( + `Starting Benchmark iterations=${numIter} deposits=${numDeposits}`, + ); let wallet = {} as Wallet; for (let i = 0; i < numIter; i++) { - // Create a new wallet in each iteration - // otherwise the TPS go down - // my assumption is that the in-memory db file gets too large + // Create a new wallet in each iteration + // otherwise the TPS go down + // my assumption is that the in-memory db file gets too large if (i % restartWallet == 0) { if (Object.keys(wallet).length !== 0) { - wallet.stop(); + wallet.stop(); } wallet = await getDefaultNodeWallet({ // No persistent DB storage. persistentStoragePath: undefined, httpLib: myHttpLib, }); + wallet.setInsecureTrustExchange(); await wallet.client.call(WalletApiOperation.InitWallet, {}); } - + logger.trace(`Starting withdrawal amount=${withdrawAmount}`); let start = Date.now(); @@ -86,12 +88,13 @@ export async function runBench1(configJson: any): Promise { stopWhenDone: true, }); - logger.info(`Finished withdrawal amount=${withdrawAmount} time=${Date.now() - start}`); + logger.info( + `Finished withdrawal amount=${withdrawAmount} time=${Date.now() - start}`, + ); for (let i = 0; i < numDeposits; i++) { - logger.trace(`Starting deposit amount=10`); - start = Date.now() + start = Date.now(); await wallet.client.call(WalletApiOperation.CreateDepositGroup, { amount: b1conf.currency + ":10", diff --git a/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts index 621105b63..b5569fadd 100644 --- a/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts +++ b/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts @@ -142,6 +142,21 @@ export interface PrimitiveWorker { sig: string; pub: string; }): Promise<{ valid: boolean }>; + + eddsaSign(req: { msg: string; priv: string }): Promise<{ sig: string }>; +} + +async function myEddsaSign( + primitiveWorker: PrimitiveWorker | undefined, + req: { msg: string; priv: string }, +): Promise<{ sig: string }> { + if (primitiveWorker) { + return primitiveWorker.eddsaSign(req); + } + const sig = eddsaSign(decodeCrock(req.msg), decodeCrock(req.priv)); + return { + sig: encodeCrock(sig), + }; } export class CryptoImplementation { @@ -153,13 +168,14 @@ export class CryptoImplementation { * Create a pre-coin of the given denomination to be withdrawn from then given * reserve. */ - createPlanchet(req: PlanchetCreationRequest): PlanchetCreationResult { + async createPlanchet( + req: PlanchetCreationRequest, + ): Promise { if ( req.denomPub.cipher === DenomKeyType.Rsa || req.denomPub.cipher === DenomKeyType.LegacyRsa ) { const reservePub = decodeCrock(req.reservePub); - const reservePriv = decodeCrock(req.reservePriv); const denomPubRsa = decodeCrock(req.denomPub.rsa_public_key); const derivedPlanchet = setupWithdrawPlanchet( decodeCrock(req.secretSeed), @@ -180,7 +196,10 @@ export class CryptoImplementation { .put(evHash) .build(); - const sig = eddsaSign(withdrawRequest, reservePriv); + const sigResult = await myEddsaSign(this.primitiveWorker, { + msg: encodeCrock(withdrawRequest), + priv: req.reservePriv, + }); const planchet: PlanchetCreationResult = { blindingKey: encodeCrock(derivedPlanchet.bks), @@ -194,7 +213,7 @@ export class CryptoImplementation { }, denomPubHash: encodeCrock(denomPubHash), reservePub: encodeCrock(reservePub), - withdrawSig: encodeCrock(sig), + withdrawSig: sigResult.sig, coinEvHash: encodeCrock(evHash), }; return planchet; @@ -427,7 +446,9 @@ export class CryptoImplementation { * Generate updated coins (to store in the database) * and deposit permissions for each given coin. */ - signDepositPermission(depositInfo: DepositInfo): CoinDepositPermission { + async signDepositPermission( + depositInfo: DepositInfo, + ): Promise { // FIXME: put extensions here if used const hExt = new Uint8Array(64); let d: Uint8Array; @@ -460,12 +481,15 @@ export class CryptoImplementation { } else { throw Error("unsupported exchange protocol version"); } - const coinSig = eddsaSign(d, decodeCrock(depositInfo.coinPriv)); + const coinSigRes = await myEddsaSign(this.primitiveWorker, { + msg: encodeCrock(d), + priv: depositInfo.coinPriv, + }); if (depositInfo.denomKeyType === DenomKeyType.Rsa) { const s: CoinDepositPermission = { coin_pub: depositInfo.coinPub, - coin_sig: encodeCrock(coinSig), + coin_sig: coinSigRes.sig, contribution: Amounts.stringify(depositInfo.spendAmount), h_denom: depositInfo.denomPubHash, exchange_url: depositInfo.exchangeBaseUrl, @@ -478,7 +502,7 @@ export class CryptoImplementation { } else if (depositInfo.denomKeyType === DenomKeyType.LegacyRsa) { const s: CoinDepositPermission = { coin_pub: depositInfo.coinPub, - coin_sig: encodeCrock(coinSig), + coin_sig: coinSigRes.sig, contribution: Amounts.stringify(depositInfo.spendAmount), h_denom: depositInfo.denomPubHash, exchange_url: depositInfo.exchangeBaseUrl, @@ -611,10 +635,13 @@ export class CryptoImplementation { .put(decodeCrock(meltCoinPub)) .build(); - const confirmSig = eddsaSign(confirmData, decodeCrock(meltCoinPriv)); + const confirmSigResp = await myEddsaSign(this.primitiveWorker, { + msg: encodeCrock(confirmData), + priv: meltCoinPriv, + }); const refreshSession: DerivedRefreshSession = { - confirmSig: encodeCrock(confirmSig), + confirmSig: confirmSigResp.sig, hash: encodeCrock(sessionHash), meltCoinPub: meltCoinPub, planchetsForGammas: planchetsForGammas, @@ -641,22 +668,24 @@ export class CryptoImplementation { return encodeCrock(hash(decodeCrock(encodedBytes))); } - signCoinLink( + async signCoinLink( oldCoinPriv: string, newDenomHash: string, oldCoinPub: string, transferPub: string, coinEv: string, - ): string { + ): Promise { const coinEvHash = hash(decodeCrock(coinEv)); const coinLink = buildSigPS(TalerSignaturePurpose.WALLET_COIN_LINK) .put(decodeCrock(newDenomHash)) .put(decodeCrock(transferPub)) .put(coinEvHash) .build(); - const coinPriv = decodeCrock(oldCoinPriv); - const sig = eddsaSign(coinLink, coinPriv); - return encodeCrock(sig); + const sig = await myEddsaSign(this.primitiveWorker, { + msg: encodeCrock(coinLink), + priv: oldCoinPriv, + }); + return sig.sig; } benchmark(repetitions: number): BenchmarkResult { diff --git a/packages/taler-wallet-core/src/crypto/workers/synchronousWorker.ts b/packages/taler-wallet-core/src/crypto/workers/synchronousWorker.ts index ae8442efd..bfc7ee7a5 100644 --- a/packages/taler-wallet-core/src/crypto/workers/synchronousWorker.ts +++ b/packages/taler-wallet-core/src/crypto/workers/synchronousWorker.ts @@ -114,6 +114,16 @@ class MyPrimitiveWorker implements PrimitiveWorker { args: req, }); } + + async eddsaSign(req: { + msg: string; + priv: string; + }): Promise<{ sig: string }> { + return this.queueRequest({ + op: "eddsa_sign", + args: req, + }); + } } /** diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index 1d809afa8..7e7980795 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -942,7 +942,7 @@ async function dispatchRequestInternal( } const components = pt.targetPath.split("/"); const creditorAcct = components[components.length - 1]; - logger.info(`making testbank transfer to '${creditorAcct}''`); + logger.info(`making testbank transfer to '${creditorAcct}'`); const fbReq = await ws.http.postJson( new URL(`${creditorAcct}/admin/add-incoming`, req.bank).href, {