add link signature to /refresh/reveal

This commit is contained in:
Florian Dold 2019-06-26 15:30:32 +02:00
parent 420a5ba23a
commit cfa1df7343
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
4 changed files with 1217 additions and 695 deletions

View File

@ -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);
}
}

View File

@ -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");

View File

@ -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]].
*/

File diff suppressed because it is too large Load Diff