summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-core/src/crypto
diff options
context:
space:
mode:
authorFlorian Dold <florian@dold.me>2020-12-14 16:44:42 +0100
committerFlorian Dold <florian@dold.me>2020-12-14 16:44:42 +0100
commit12234083ecfe83de79eb2caf29808a0f17188e84 (patch)
tree2e369412845b51173ed0329bb08ee4dcaf48a3c6 /packages/taler-wallet-core/src/crypto
parent80a0fab1261fc06f79db4c32fd7a1a6d0cb0db0f (diff)
downloadwallet-core-12234083ecfe83de79eb2caf29808a0f17188e84.tar.gz
wallet-core-12234083ecfe83de79eb2caf29808a0f17188e84.tar.bz2
wallet-core-12234083ecfe83de79eb2caf29808a0f17188e84.zip
derive refresh info from secret seed
Diffstat (limited to 'packages/taler-wallet-core/src/crypto')
-rw-r--r--packages/taler-wallet-core/src/crypto/talerCrypto.ts16
-rw-r--r--packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts24
-rw-r--r--packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts95
3 files changed, 64 insertions, 71 deletions
diff --git a/packages/taler-wallet-core/src/crypto/talerCrypto.ts b/packages/taler-wallet-core/src/crypto/talerCrypto.ts
index 8713fc965..4faa523a0 100644
--- a/packages/taler-wallet-core/src/crypto/talerCrypto.ts
+++ b/packages/taler-wallet-core/src/crypto/talerCrypto.ts
@@ -389,3 +389,19 @@ export function setupRefreshPlanchet(
coinPub: eddsaGetPublic(coinPriv),
};
}
+
+export function setupRefreshTransferPub(
+ secretSeed: Uint8Array,
+ transferPubIndex: number,
+): EcdheKeyPair {
+ const info = stringToBytes("taler-transfer-pub-derivation");
+ const saltArrBuf = new ArrayBuffer(4);
+ const salt = new Uint8Array(saltArrBuf);
+ const saltDataView = new DataView(saltArrBuf);
+ saltDataView.setUint32(0, transferPubIndex);
+ const out = kdf(32, secretSeed, salt, info);
+ return {
+ ecdhePriv: out,
+ ecdhePub: ecdheGetPublic(out),
+ };
+}
diff --git a/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts b/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts
index 29f3b02b2..6a4264d2c 100644
--- a/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts
+++ b/packages/taler-wallet-core/src/crypto/workers/cryptoApi.ts
@@ -47,6 +47,10 @@ import {
import * as timer from "../../util/timer";
import { Logger } from "../../util/logging";
+import {
+ DerivedRefreshSession,
+ DeriveRefreshSessionRequest,
+} from "../../types/cryptoTypes";
const logger = new Logger("cryptoApi.ts");
@@ -417,22 +421,10 @@ export class CryptoApi {
return this.doRpc<RecoupRequest>("createRecoupRequest", 1, coin);
}
- createRefreshSession(
- exchangeBaseUrl: string,
- kappa: number,
- meltCoin: CoinRecord,
- newCoinDenoms: DenominationSelectionInfo,
- meltFee: AmountJson,
- ): Promise<RefreshSessionRecord> {
- return this.doRpc<RefreshSessionRecord>(
- "createRefreshSession",
- 4,
- exchangeBaseUrl,
- kappa,
- meltCoin,
- newCoinDenoms,
- meltFee,
- );
+ deriveRefreshSession(
+ req: DeriveRefreshSessionRequest,
+ ): Promise<DerivedRefreshSession> {
+ return this.doRpc<DerivedRefreshSession>("deriveRefreshSession", 4, req);
}
signCoinLink(
diff --git a/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts b/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts
index e55fa3d7b..d14f663e8 100644
--- a/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts
+++ b/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts
@@ -63,6 +63,8 @@ import {
keyExchangeEcdheEddsa,
setupRefreshPlanchet,
rsaVerify,
+ getRandomBytes,
+ setupRefreshTransferPub,
} from "../talerCrypto";
import { randomBytes } from "../primitives/nacl-fast";
import { kdf } from "../primitives/kdf";
@@ -73,6 +75,10 @@ import {
} from "../../util/time";
import { Logger } from "../../util/logging";
+import {
+ DerivedRefreshSession,
+ DeriveRefreshSessionRequest,
+} from "../../types/cryptoTypes";
const logger = new Logger("cryptoImplementation.ts");
@@ -375,21 +381,24 @@ export class CryptoImplementation {
return s;
}
- /**
- * Create a new refresh session.
- */
- createRefreshSession(
- exchangeBaseUrl: string,
- kappa: number,
- meltCoin: CoinRecord,
- newCoinDenoms: DenominationSelectionInfo,
- meltFee: AmountJson,
- ): RefreshSessionRecord {
- const currency = newCoinDenoms.selectedDenoms[0].denom.value.currency;
+ deriveRefreshSession(
+ req: DeriveRefreshSessionRequest,
+ ): DerivedRefreshSession {
+ const {
+ newCoinDenoms,
+ feeRefresh: meltFee,
+ kappa,
+ meltCoinDenomPubHash,
+ meltCoinPriv,
+ meltCoinPub,
+ sessionSecretSeed: refreshSessionSecretSeed,
+ } = req;
+
+ const currency = newCoinDenoms[0].value.currency;
let valueWithFee = Amounts.getZero(currency);
- for (const ncd of newCoinDenoms.selectedDenoms) {
- const t = Amounts.add(ncd.denom.value, ncd.denom.feeWithdraw).amount;
+ for (const ncd of newCoinDenoms) {
+ const t = Amounts.add(ncd.value, ncd.feeWithdraw).amount;
valueWithFee = Amounts.add(
valueWithFee,
Amounts.mult(t, ncd.count).amount,
@@ -409,7 +418,10 @@ export class CryptoImplementation {
logger.trace("starting RC computation");
for (let i = 0; i < kappa; i++) {
- const transferKeyPair = createEcdheKeyPair();
+ const transferKeyPair = setupRefreshTransferPub(
+ decodeCrock(refreshSessionSecretSeed),
+ i,
+ );
sessionHc.update(transferKeyPair.ecdhePub);
logger.trace(
`HASH transfer_pub ${encodeCrock(transferKeyPair.ecdhePub)}`,
@@ -418,16 +430,16 @@ export class CryptoImplementation {
transferPubs.push(encodeCrock(transferKeyPair.ecdhePub));
}
- for (const denomSel of newCoinDenoms.selectedDenoms) {
+ for (const denomSel of newCoinDenoms) {
for (let i = 0; i < denomSel.count; i++) {
- const r = decodeCrock(denomSel.denom.denomPub);
+ const r = decodeCrock(denomSel.denomPub);
sessionHc.update(r);
logger.trace(`HASH new_coins ${encodeCrock(r)}`);
}
}
- sessionHc.update(decodeCrock(meltCoin.coinPub));
- logger.trace(`HASH coin_pub ${meltCoin.coinPub}`);
+ sessionHc.update(decodeCrock(meltCoinPub));
+ logger.trace(`HASH coin_pub ${meltCoinPub}`);
sessionHc.update(amountToBuffer(valueWithFee));
logger.trace(
`HASH melt_amount ${encodeCrock(amountToBuffer(valueWithFee))}`,
@@ -435,12 +447,12 @@ export class CryptoImplementation {
for (let i = 0; i < kappa; i++) {
const planchets: RefreshPlanchet[] = [];
- for (let j = 0; j < newCoinDenoms.selectedDenoms.length; j++) {
- const denomSel = newCoinDenoms.selectedDenoms[j];
+ for (let j = 0; j < newCoinDenoms.length; j++) {
+ const denomSel = newCoinDenoms[j];
for (let k = 0; k < denomSel.count; k++) {
const coinNumber = planchets.length;
const transferPriv = decodeCrock(transferPrivs[i]);
- const oldCoinPub = decodeCrock(meltCoin.coinPub);
+ const oldCoinPub = decodeCrock(meltCoinPub);
const transferSecret = keyExchangeEcdheEddsa(
transferPriv,
oldCoinPub,
@@ -450,7 +462,7 @@ export class CryptoImplementation {
const coinPub = fresh.coinPub;
const blindingFactor = fresh.bks;
const pubHash = hash(coinPub);
- const denomPub = decodeCrock(denomSel.denom.denomPub);
+ const denomPub = decodeCrock(denomSel.denomPub);
const ev = rsaBlind(pubHash, blindingFactor, denomPub);
const planchet: RefreshPlanchet = {
blindingKey: encodeCrock(blindingFactor),
@@ -481,49 +493,22 @@ export class CryptoImplementation {
const confirmData = buildSigPS(SignaturePurpose.WALLET_COIN_MELT)
.put(sessionHash)
- .put(decodeCrock(meltCoin.denomPubHash))
+ .put(decodeCrock(meltCoinDenomPubHash))
.put(amountToBuffer(valueWithFee))
.put(amountToBuffer(meltFee))
- .put(decodeCrock(meltCoin.coinPub))
+ .put(decodeCrock(meltCoinPub))
.build();
- const confirmSig = eddsaSign(confirmData, decodeCrock(meltCoin.coinPriv));
-
- let valueOutput = Amounts.getZero(currency);
- for (const denomSel of newCoinDenoms.selectedDenoms) {
- const denom = denomSel.denom;
- for (let i = 0; i < denomSel.count; i++) {
- valueOutput = Amounts.add(valueOutput, denom.value).amount;
- }
- }
-
- const newDenoms: string[] = [];
- const newDenomHashes: string[] = [];
-
- for (const denomSel of newCoinDenoms.selectedDenoms) {
- const denom = denomSel.denom;
- for (let i = 0; i < denomSel.count; i++) {
- newDenoms.push(denom.denomPub);
- newDenomHashes.push(denom.denomPubHash);
- }
- }
+ const confirmSig = eddsaSign(confirmData, decodeCrock(meltCoinPriv));
- const refreshSession: RefreshSessionRecord = {
+ const refreshSession: DerivedRefreshSession = {
confirmSig: encodeCrock(confirmSig),
- exchangeBaseUrl,
hash: encodeCrock(sessionHash),
- meltCoinPub: meltCoin.coinPub,
- newDenomHashes,
- newDenoms,
- norevealIndex: undefined,
+ meltCoinPub: meltCoinPub,
planchetsForGammas: planchetsForGammas,
transferPrivs,
transferPubs,
- amountRefreshOutput: valueOutput,
- amountRefreshInput: valueWithFee,
- timestampCreated: getTimestampNow(),
- finishedTimestamp: undefined,
- lastError: undefined,
+ meltValueWithFee: valueWithFee,
};
return refreshSession;