diff options
author | Florian Dold <florian.dold@gmail.com> | 2019-06-26 15:30:32 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2019-06-26 15:30:32 +0200 |
commit | cfa1df734315efc8e24a1a846e4d694abe2249ea (patch) | |
tree | be428e4179671a4b280fd7ba186befb44ce89354 /src/crypto | |
parent | 420a5ba23a83bb4e60a1b76e2605205e1c481551 (diff) |
add link signature to /refresh/reveal
Diffstat (limited to 'src/crypto')
-rw-r--r-- | src/crypto/cryptoApi.ts | 147 | ||||
-rw-r--r-- | src/crypto/cryptoWorker.ts | 299 | ||||
-rw-r--r-- | src/crypto/emscInterface.ts | 32 |
3 files changed, 314 insertions, 164 deletions
diff --git a/src/crypto/cryptoApi.ts b/src/crypto/cryptoApi.ts index 03c2a675b..43a3bc228 100644 --- a/src/crypto/cryptoApi.ts +++ b/src/crypto/cryptoApi.ts @@ -14,7 +14,6 @@ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ - /** * API to access the Taler crypto worker thread. * @author Florian Dold @@ -35,22 +34,14 @@ import { WireFee, } from "../dbTypes"; -import { - ContractTerms, - PaybackRequest, -} from "../talerTypes"; +import { ContractTerms, PaybackRequest } from "../talerTypes"; -import { - BenchmarkResult, - CoinWithDenom, - PayCoinInfo, -} from "../walletTypes"; +import { BenchmarkResult, CoinWithDenom, PayCoinInfo } from "../walletTypes"; import * as timer from "../timer"; import { startWorker } from "./startWorker"; - /** * State of a crypto worker. */ @@ -58,17 +49,17 @@ interface WorkerState { /** * The actual worker thread. */ - w: Worker|null; + w: Worker | null; /** * Work we're currently executing or null if not busy. */ - currentWorkItem: WorkItem|null; + currentWorkItem: WorkItem | null; /** * Timer to terminate the worker if it's not busy enough. */ - terminationTimerHandle: timer.TimerHandle|null; + terminationTimerHandle: timer.TimerHandle | null; } interface WorkItem { @@ -88,7 +79,6 @@ interface WorkItem { startTime: number; } - /** * Number of different priorities. Each priority p * must be 0 <= p < NUM_PRIO. @@ -151,8 +141,10 @@ export class CryptoApi { handleWorkerError(ws: WorkerState, e: ErrorEvent) { if (ws.currentWorkItem) { - console.error(`error in worker during ${ws.currentWorkItem!.operation}`, - e); + console.error( + `error in worker during ${ws.currentWorkItem!.operation}`, + e, + ); } else { console.error("error in worker", e); } @@ -201,7 +193,10 @@ export class CryptoApi { console.error(`RPC with id ${id} has no registry entry`); return; } - console.log(`rpc ${currentWorkItem.operation} took ${timer.performanceNow() - currentWorkItem.startTime}ms`); + console.log( + `rpc ${currentWorkItem.operation} took ${timer.performanceNow() - + currentWorkItem.startTime}ms`, + ); currentWorkItem.resolve(msg.data.result); } @@ -230,12 +225,21 @@ export class CryptoApi { } } - private doRpc<T>(operation: string, priority: number, - ...args: any[]): Promise<T> { - + private doRpc<T>( + operation: string, + priority: number, + ...args: any[] + ): Promise<T> { const p: Promise<T> = new Promise<T>((resolve, reject) => { const rpcId = this.nextRpcId++; - const workItem: WorkItem = {operation, args, resolve, reject, rpcId, startTime: 0}; + const workItem: WorkItem = { + operation, + args, + resolve, + reject, + rpcId, + startTime: 0, + }; if (this.numBusy === this.workers.length) { const q = this.workQueues[priority]; @@ -263,8 +267,10 @@ export class CryptoApi { }); } - - createPreCoin(denom: DenominationRecord, reserve: ReserveRecord): Promise<PreCoinRecord> { + createPreCoin( + denom: DenominationRecord, + reserve: ReserveRecord, + ): Promise<PreCoinRecord> { return this.doRpc<PreCoinRecord>("createPreCoin", 1, denom, reserve); } @@ -280,27 +286,48 @@ export class CryptoApi { return this.doRpc<string>("hashDenomPub", 1, denomPub); } - isValidDenom(denom: DenominationRecord, - masterPub: string): Promise<boolean> { + isValidDenom(denom: DenominationRecord, masterPub: string): Promise<boolean> { return this.doRpc<boolean>("isValidDenom", 2, denom, masterPub); } - isValidWireFee(type: string, wf: WireFee, masterPub: string): Promise<boolean> { + isValidWireFee( + type: string, + wf: WireFee, + masterPub: string, + ): Promise<boolean> { return this.doRpc<boolean>("isValidWireFee", 2, type, wf, masterPub); } - isValidPaymentSignature(sig: string, contractHash: string, merchantPub: string): Promise<boolean> { - return this.doRpc<boolean>("isValidPaymentSignature", 1, sig, contractHash, merchantPub); + isValidPaymentSignature( + sig: string, + contractHash: string, + merchantPub: string, + ): Promise<boolean> { + return this.doRpc<boolean>( + "isValidPaymentSignature", + 1, + sig, + contractHash, + merchantPub, + ); } - signDeposit(contractTerms: ContractTerms, - cds: CoinWithDenom[], - totalAmount: AmountJson): Promise<PayCoinInfo> { - return this.doRpc<PayCoinInfo>("signDeposit", 3, contractTerms, cds, totalAmount); + signDeposit( + contractTerms: ContractTerms, + cds: CoinWithDenom[], + totalAmount: AmountJson, + ): Promise<PayCoinInfo> { + return this.doRpc<PayCoinInfo>( + "signDeposit", + 3, + contractTerms, + cds, + totalAmount, + ); } - createEddsaKeypair(): Promise<{priv: string, pub: string}> { - return this.doRpc<{priv: string, pub: string}>("createEddsaKeypair", 1); + createEddsaKeypair(): Promise<{ priv: string; pub: string }> { + return this.doRpc<{ priv: string; pub: string }>("createEddsaKeypair", 1); } rsaUnblind(sig: string, bk: string, pk: string): Promise<string> { @@ -311,23 +338,43 @@ export class CryptoApi { return this.doRpc<PaybackRequest>("createPaybackRequest", 1, coin); } - createRefreshSession(exchangeBaseUrl: string, - kappa: number, - meltCoin: CoinRecord, - newCoinDenoms: DenominationRecord[], - meltFee: AmountJson): Promise<RefreshSessionRecord> { - return this.doRpc<RefreshSessionRecord>("createRefreshSession", - 4, - exchangeBaseUrl, - kappa, - meltCoin, - newCoinDenoms, - meltFee); + createRefreshSession( + exchangeBaseUrl: string, + kappa: number, + meltCoin: CoinRecord, + newCoinDenoms: DenominationRecord[], + meltFee: AmountJson, + ): Promise<RefreshSessionRecord> { + return this.doRpc<RefreshSessionRecord>( + "createRefreshSession", + 4, + exchangeBaseUrl, + kappa, + meltCoin, + newCoinDenoms, + meltFee, + ); + } + + signCoinLink( + oldCoinPriv: string, + newDenomHash: string, + oldCoinPub: string, + transferPub: string, + coinEv: string, + ): Promise<string> { + return this.doRpc<string>( + "signCoinLink", + 4, + oldCoinPriv, + newDenomHash, + oldCoinPub, + transferPub, + coinEv, + ); } benchmark(repetitions: number): Promise<BenchmarkResult> { - return this.doRpc<BenchmarkResult>("benchmark", - 1, - repetitions); + return this.doRpc<BenchmarkResult>("benchmark", 1, repetitions); } } diff --git a/src/crypto/cryptoWorker.ts b/src/crypto/cryptoWorker.ts index 5013e3acf..9c5263a6f 100644 --- a/src/crypto/cryptoWorker.ts +++ b/src/crypto/cryptoWorker.ts @@ -18,7 +18,6 @@ * Web worker for crypto operations. */ - /** * Imports. */ @@ -39,17 +38,9 @@ import { WireFee, } from "../dbTypes"; -import { - CoinPaySig, - ContractTerms, - PaybackRequest, -} from "../talerTypes"; +import { CoinPaySig, ContractTerms, PaybackRequest } from "../talerTypes"; -import { - BenchmarkResult, - CoinWithDenom, - PayCoinInfo, -} from "../walletTypes"; +import { BenchmarkResult, CoinWithDenom, PayCoinInfo } from "../walletTypes"; import { canonicalJson } from "../helpers"; @@ -64,15 +55,15 @@ import { } from "./emscInterface"; import * as native from "./emscInterface"; - namespace RpcFunctions { - /** * Create a pre-coin of the given denomination to be withdrawn from then given * reserve. */ - export function createPreCoin(denom: DenominationRecord, - reserve: ReserveRecord): PreCoinRecord { + export function createPreCoin( + denom: DenominationRecord, + reserve: ReserveRecord, + ): PreCoinRecord { const reservePriv = new native.EddsaPrivateKey(); reservePriv.loadCrock(reserve.reserve_priv); const reservePub = new native.EddsaPublicKey(); @@ -125,7 +116,6 @@ namespace RpcFunctions { return preCoin; } - /** * Create a planchet used for tipping, including the private keys. */ @@ -152,12 +142,14 @@ namespace RpcFunctions { coinPub: coinPub.toCrock(), coinValue: denom.value, denomPub: denomPub.encode().toCrock(), - denomPubHash: denomPub.encode().hash().toCrock(), + denomPubHash: denomPub + .encode() + .hash() + .toCrock(), }; return tipPlanchet; } - /** * Create and sign a message to request payback for a coin. */ @@ -165,7 +157,9 @@ namespace RpcFunctions { 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(), + h_denom_pub: native.RsaPublicKey.fromCrock(coin.denomPub) + .encode() + .hash(), }); const coinPriv = native.EddsaPrivateKey.fromCrock(coin.coinPriv); const coinSig = native.eddsaSign(p.toPurpose(), coinPriv); @@ -179,63 +173,83 @@ namespace RpcFunctions { return paybackRequest; } - /** * Check if a payment signature is valid. */ - export function isValidPaymentSignature(sig: string, contractHash: string, merchantPub: string): boolean { + export function isValidPaymentSignature( + sig: string, + contractHash: string, + merchantPub: string, + ): boolean { const p = new native.PaymentSignaturePS({ contract_hash: native.HashCode.fromCrock(contractHash), }); const nativeSig = new native.EddsaSignature(); nativeSig.loadCrock(sig); const nativePub = native.EddsaPublicKey.fromCrock(merchantPub); - return native.eddsaVerify(native.SignaturePurpose.MERCHANT_PAYMENT_OK, - p.toPurpose(), - nativeSig, - nativePub); + return native.eddsaVerify( + native.SignaturePurpose.MERCHANT_PAYMENT_OK, + p.toPurpose(), + nativeSig, + nativePub, + ); } /** * Check if a wire fee is correctly signed. */ - export function isValidWireFee(type: string, wf: WireFee, masterPub: string): boolean { + export function isValidWireFee( + type: string, + wf: WireFee, + masterPub: string, + ): boolean { const p = new native.MasterWireFeePS({ - closing_fee: (new native.Amount(wf.closingFee)).toNbo(), + 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), - wire_fee: (new native.Amount(wf.wireFee)).toNbo(), + wire_fee: new native.Amount(wf.wireFee).toNbo(), }); const nativeSig = new native.EddsaSignature(); nativeSig.loadCrock(wf.sig); const nativePub = native.EddsaPublicKey.fromCrock(masterPub); - return native.eddsaVerify(native.SignaturePurpose.MASTER_WIRE_FEES, - p.toPurpose(), - nativeSig, - nativePub); + return native.eddsaVerify( + native.SignaturePurpose.MASTER_WIRE_FEES, + p.toPurpose(), + nativeSig, + nativePub, + ); } - /** * Check if the signature of a denomination is valid. */ - export function isValidDenom(denom: DenominationRecord, - masterPub: string): boolean { + export function isValidDenom( + denom: DenominationRecord, + masterPub: string, + ): boolean { 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), - fee_deposit: (new native.Amount(denom.feeDeposit)).toNbo(), - fee_refresh: (new native.Amount(denom.feeRefresh)).toNbo(), - fee_refund: (new native.Amount(denom.feeRefund)).toNbo(), - fee_withdraw: (new native.Amount(denom.feeWithdraw)).toNbo(), + 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, + ), + fee_deposit: new native.Amount(denom.feeDeposit).toNbo(), + fee_refresh: new native.Amount(denom.feeRefresh).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(), + value: new native.Amount(denom.value).toNbo(), }); const nativeSig = new native.EddsaSignature(); @@ -243,42 +257,44 @@ namespace RpcFunctions { const nativePub = native.EddsaPublicKey.fromCrock(masterPub); - return native.eddsaVerify(native.SignaturePurpose.MASTER_DENOMINATION_KEY_VALIDITY, - p.toPurpose(), - nativeSig, - nativePub); - + return native.eddsaVerify( + native.SignaturePurpose.MASTER_DENOMINATION_KEY_VALIDITY, + p.toPurpose(), + nativeSig, + nativePub, + ); } - /** * Create a new EdDSA key pair. */ - export function createEddsaKeypair(): {priv: string, pub: string} { + export function createEddsaKeypair(): { priv: string; pub: string } { const priv = native.EddsaPrivateKey.create(); const pub = priv.getPublicKey(); - return {priv: priv.toCrock(), pub: pub.toCrock()}; + return { priv: priv.toCrock(), pub: pub.toCrock() }; } - /** * Unblind a blindly signed value. */ export function rsaUnblind(sig: string, bk: string, pk: string): string { - const denomSig = native.rsaUnblind(native.RsaSignature.fromCrock(sig), - native.RsaBlindingKeySecret.fromCrock(bk), - native.RsaPublicKey.fromCrock(pk)); + const denomSig = native.rsaUnblind( + native.RsaSignature.fromCrock(sig), + native.RsaBlindingKeySecret.fromCrock(bk), + native.RsaPublicKey.fromCrock(pk), + ); return denomSig.encode().toCrock(); } - /** * Generate updated coins (to store in the database) * and deposit permissions for each given coin. */ - export function signDeposit(contractTerms: ContractTerms, - cds: CoinWithDenom[], - totalAmount: AmountJson): PayCoinInfo { + export function signDeposit( + contractTerms: ContractTerms, + cds: CoinWithDenom[], + totalAmount: AmountJson, + ): PayCoinInfo { const ret: PayCoinInfo = { originalCoins: [], sigs: [], @@ -287,17 +303,21 @@ namespace RpcFunctions { const contractTermsHash = hashString(canonicalJson(contractTerms)); - const feeList: AmountJson[] = cds.map((x) => x.denom.feeDeposit); - let fees = Amounts.add(Amounts.getZero(feeList[0].currency), ...feeList).amount; + 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, Amounts.parseOrThrow(contractTerms.max_fee)).amount; + fees = Amounts.sub(fees, Amounts.parseOrThrow(contractTerms.max_fee)) + .amount; const total = Amounts.add(fees, totalAmount).amount; - const amountSpent = native.Amount.getZero(cds[0].coin.currentAmount.currency); + const amountSpent = native.Amount.getZero( + cds[0].coin.currentAmount.currency, + ); const amountRemaining = new native.Amount(total); for (const cd of cds) { let coinSpend: Amount; - const originalCoin = { ...(cd.coin) }; + const originalCoin = { ...cd.coin }; if (amountRemaining.value === 0 && amountRemaining.fraction === 0) { break; @@ -332,13 +352,20 @@ namespace RpcFunctions { h_contract: native.HashCode.fromCrock(contractTermsHash), h_wire: native.HashCode.fromCrock(contractTerms.H_wire), merchant: native.EddsaPublicKey.fromCrock(contractTerms.merchant_pub), - refund_deadline: native.AbsoluteTimeNbo.fromTalerString(contractTerms.refund_deadline), - timestamp: native.AbsoluteTimeNbo.fromTalerString(contractTerms.timestamp), + refund_deadline: native.AbsoluteTimeNbo.fromTalerString( + contractTerms.refund_deadline, + ), + timestamp: native.AbsoluteTimeNbo.fromTalerString( + contractTerms.timestamp, + ), }); - const coinSig = native.eddsaSign(d.toPurpose(), - native.EddsaPrivateKey.fromCrock(cd.coin.coinPriv)) - .toCrock(); + const coinSig = native + .eddsaSign( + d.toPurpose(), + native.EddsaPrivateKey.fromCrock(cd.coin.coinPriv), + ) + .toCrock(); const s: CoinPaySig = { coin_pub: cd.coin.coinPub, @@ -355,22 +382,21 @@ namespace RpcFunctions { return ret; } - /** * Create a new refresh session. */ - export function createRefreshSession(exchangeBaseUrl: string, - kappa: number, - meltCoin: CoinRecord, - newCoinDenoms: DenominationRecord[], - meltFee: AmountJson): RefreshSessionRecord { - + export function createRefreshSession( + exchangeBaseUrl: string, + kappa: number, + meltCoin: CoinRecord, + newCoinDenoms: DenominationRecord[], + meltFee: AmountJson, + ): RefreshSessionRecord { let valueWithFee = Amounts.getZero(newCoinDenoms[0].value.currency); for (const ncd of newCoinDenoms) { - valueWithFee = Amounts.add(valueWithFee, - ncd.value, - ncd.feeWithdraw).amount; + valueWithFee = Amounts.add(valueWithFee, ncd.value, ncd.feeWithdraw) + .amount; } // melt fee @@ -397,12 +423,11 @@ namespace RpcFunctions { } sessionHc.read(native.EddsaPublicKey.fromCrock(meltCoin.coinPub)); - sessionHc.read((new native.Amount(valueWithFee)).toNbo()); + sessionHc.read(new native.Amount(valueWithFee).toNbo()); for (let i = 0; i < kappa; i++) { const preCoins: RefreshPreCoinRecord[] = []; for (let j = 0; j < newCoinDenoms.length; j++) { - const transferPriv = native.EcdhePrivateKey.fromCrock(transferPrivs[i]); const oldCoinPub = native.EddsaPublicKey.fromCrock(meltCoin.coinPub); const transferSecret = native.ecdhEddsa(transferPriv, oldCoinPub); @@ -413,10 +438,10 @@ namespace RpcFunctions { 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); + 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?)"); } @@ -437,16 +462,18 @@ namespace RpcFunctions { sessionHc.finish(sessionHash); const confirmData = new RefreshMeltCoinAffirmationPS({ - amount_with_fee: (new Amount(valueWithFee)).toNbo(), + amount_with_fee: new Amount(valueWithFee).toNbo(), coin_pub: EddsaPublicKey.fromCrock(meltCoin.coinPub), - melt_fee: (new Amount(meltFee)).toNbo(), + melt_fee: new Amount(meltFee).toNbo(), session_hash: sessionHash, }); - - const confirmSig: string = native.eddsaSign(confirmData.toPurpose(), - native.EddsaPrivateKey.fromCrock( - meltCoin.coinPriv)).toCrock(); + const confirmSig: string = native + .eddsaSign( + confirmData.toPurpose(), + native.EddsaPrivateKey.fromCrock(meltCoin.coinPriv), + ) + .toCrock(); let valueOutput = Amounts.getZero(newCoinDenoms[0].value.currency); for (const denom of newCoinDenoms) { @@ -459,8 +486,8 @@ namespace RpcFunctions { finished: false, hash: sessionHash.toCrock(), meltCoinPub: meltCoin.coinPub, - newDenomHashes: newCoinDenoms.map((d) => d.denomPubHash), - newDenoms: newCoinDenoms.map((d) => d.denomPub), + newDenomHashes: newCoinDenoms.map(d => d.denomPubHash), + newDenoms: newCoinDenoms.map(d => d.denomPub), norevealIndex: undefined, preCoinsForGammas, transferPrivs, @@ -484,7 +511,33 @@ namespace RpcFunctions { * Hash a denomination public key. */ export function hashDenomPub(denomPub: string): string { - return native.RsaPublicKey.fromCrock(denomPub).encode().hash().toCrock(); + return native.RsaPublicKey.fromCrock(denomPub) + .encode() + .hash() + .toCrock(); + } + + export function signCoinLink( + oldCoinPriv: string, + newDenomHash: string, + oldCoinPub: string, + transferPub: string, + coinEv: string, + ): string { + const coinEvHash = native.ByteArray.fromCrock(coinEv).hash(); + + const coinLink = new native.CoinLinkSignaturePS({ + coin_envelope_hash: coinEvHash, + h_denom_pub: native.HashCode.fromCrock(newDenomHash), + old_coin_pub: native.EddsaPublicKey.fromCrock(oldCoinPub), + transfer_pub: native.EcdhePublicKey.fromCrock(transferPub), + }); + + const coinPriv = native.EddsaPrivateKey.fromCrock(oldCoinPriv); + + const sig = native.eddsaSign(coinLink.toPurpose(), coinPriv); + + return sig.toCrock(); } export function benchmark(repetitions: number): BenchmarkResult { @@ -500,7 +553,7 @@ namespace RpcFunctions { for (let i = 0; i < repetitions; i++) { ba.randomize(native.RandomQuality.WEAK); const start = timer.performanceNow(); - ba.hash(); + ba.hash(); time_hash_big += timer.performanceNow() - start; } @@ -508,7 +561,7 @@ namespace RpcFunctions { for (let i = 0; i < repetitions; i++) { const start = timer.performanceNow(); const priv: native.EddsaPrivateKey = native.EddsaPrivateKey.create(); - time_eddsa_create += timer.performanceNow() - start; + time_eddsa_create += timer.performanceNow() - start; priv.destroy(); } @@ -541,14 +594,15 @@ namespace RpcFunctions { priv.destroy(); } - let time_eddsa_verify = 0; for (let i = 0; i < repetitions; i++) { const start = timer.performanceNow(); - native.eddsaVerify(native.SignaturePurpose.MERCHANT_PAYMENT_OK, - p, - eddsaSig, - eddsaPub); + native.eddsaVerify( + native.SignaturePurpose.MERCHANT_PAYMENT_OK, + p, + eddsaSig, + eddsaPub, + ); time_eddsa_verify += timer.performanceNow() - start; } @@ -564,11 +618,18 @@ namespace RpcFunctions { time_rsa_2048_blind += timer.performanceNow() - start; } - const blindedMessage2048 = native.rsaBlind(h, blindingSecret2048, rsaPub2048); + const blindedMessage2048 = native.rsaBlind( + h, + blindingSecret2048, + rsaPub2048, + ); if (!blindedMessage2048) { throw Error("should not happen"); } - const rsaBlindSig2048 = native.rsaSignBlinded(rsaPriv2048, blindedMessage2048); + const rsaBlindSig2048 = native.rsaSignBlinded( + rsaPriv2048, + blindedMessage2048, + ); let time_rsa_2048_unblind = 0; for (let i = 0; i < repetitions; i++) { @@ -577,7 +638,11 @@ namespace RpcFunctions { time_rsa_2048_unblind += timer.performanceNow() - start; } - const unblindedSig2048 = native.rsaUnblind(rsaBlindSig2048, blindingSecret2048, rsaPub2048); + const unblindedSig2048 = native.rsaUnblind( + rsaBlindSig2048, + blindingSecret2048, + rsaPub2048, + ); let time_rsa_2048_verify = 0; for (let i = 0; i < repetitions; i++) { @@ -586,7 +651,6 @@ namespace RpcFunctions { time_rsa_2048_verify += timer.performanceNow() - start; } - /* rsa 4096 */ let time_rsa_4096_blind = 0; @@ -599,11 +663,18 @@ namespace RpcFunctions { time_rsa_4096_blind += timer.performanceNow() - start; } - const blindedMessage4096 = native.rsaBlind(h, blindingSecret4096, rsaPub4096); + const blindedMessage4096 = native.rsaBlind( + h, + blindingSecret4096, + rsaPub4096, + ); if (!blindedMessage4096) { throw Error("should not happen"); } - const rsaBlindSig4096 = native.rsaSignBlinded(rsaPriv4096, blindedMessage4096); + const rsaBlindSig4096 = native.rsaSignBlinded( + rsaPriv4096, + blindedMessage4096, + ); let time_rsa_4096_unblind = 0; for (let i = 0; i < repetitions; i++) { @@ -612,7 +683,11 @@ namespace RpcFunctions { time_rsa_4096_unblind += timer.performanceNow() - start; } - const unblindedSig4096 = native.rsaUnblind(rsaBlindSig4096, blindingSecret4096, rsaPub4096); + const unblindedSig4096 = native.rsaUnblind( + rsaBlindSig4096, + blindingSecret4096, + rsaPub4096, + ); let time_rsa_4096_verify = 0; for (let i = 0; i < repetitions; i++) { @@ -621,7 +696,6 @@ namespace RpcFunctions { time_rsa_4096_verify += timer.performanceNow() - start; } - return { repetitions, time: { @@ -637,12 +711,11 @@ namespace RpcFunctions { rsa_4096_blind: time_rsa_4096_blind, rsa_4096_unblind: time_rsa_4096_unblind, rsa_4096_verify: time_rsa_4096_verify, - } + }, }; } } - const worker: Worker = (self as any) as Worker; worker.onmessage = (msg: MessageEvent) => { @@ -665,7 +738,7 @@ worker.onmessage = (msg: MessageEvent) => { console.log("onmessage with", msg.data.operation); console.log("foo"); - emscLoader.getLib().then((p) => { + emscLoader.getLib().then(p => { const lib = p.lib; if (!native.isInitialized()) { console.log("initializing emscripten for then first time with lib"); diff --git a/src/crypto/emscInterface.ts b/src/crypto/emscInterface.ts index dcd16e633..2ddc15a37 100644 --- a/src/crypto/emscInterface.ts +++ b/src/crypto/emscInterface.ts @@ -223,6 +223,7 @@ export enum SignaturePurpose { MERCHANT_PAYMENT_OK = 1104, MASTER_WIRE_FEES = 1028, WALLET_COIN_PAYBACK = 1203, + WALLET_COIN_LINK = 1204, } @@ -970,7 +971,7 @@ abstract class SignatureStruct { throw Error(`Key ${name} not found`); } if (!(value instanceof typemap[name])) { - throw Error("Wrong type for ${name}"); + throw Error(`Wrong type for ${name}`); } this.members[name] = value; } @@ -1293,6 +1294,35 @@ export class DepositRequestPS extends SignatureStruct { } } + +interface CoinLinkSignaturePS_args { + h_denom_pub: HashCode; + old_coin_pub: EddsaPublicKey; + transfer_pub: EcdhePublicKey; + coin_envelope_hash: HashCode; +} + + +export class CoinLinkSignaturePS extends SignatureStruct { + constructor(w: CoinLinkSignaturePS_args) { + super(w); + } + + purpose() { + return SignaturePurpose.WALLET_COIN_LINK; + } + + fieldTypes() { + return [ + ["h_denom_pub", HashCode], + ["old_coin_pub", EddsaPublicKey], + ["transfer_pub", EcdhePublicKey], + ["coin_envelope_hash", HashCode], + ]; + } +} + + /** * Arguments for constuctor of [[DenominationKeyValidityPS]]. */ |