gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 02/02: derive refresh info from secret seed


From: gnunet
Subject: [taler-wallet-core] 02/02: derive refresh info from secret seed
Date: Mon, 14 Dec 2020 16:44:54 +0100

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

commit 12234083ecfe83de79eb2caf29808a0f17188e84
Author: Florian Dold <florian@dold.me>
AuthorDate: Mon Dec 14 16:44:42 2020 +0100

    derive refresh info from secret seed
---
 .../taler-wallet-core/src/crypto/talerCrypto.ts    |  16 ++
 .../src/crypto/workers/cryptoApi.ts                |  24 +--
 .../src/crypto/workers/cryptoImplementation.ts     |  95 ++++-----
 .../taler-wallet-core/src/operations/refresh.ts    | 236 ++++++++++++++-------
 .../taler-wallet-core/src/types/cryptoTypes.ts     | 111 ++++++++++
 packages/taler-wallet-core/src/types/dbTypes.ts    |  76 ++-----
 6 files changed, 350 insertions(+), 208 deletions(-)

diff --git a/packages/taler-wallet-core/src/crypto/talerCrypto.ts 
b/packages/taler-wallet-core/src/crypto/talerCrypto.ts
index 8713fc96..4faa523a 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 29f3b02b..6a4264d2 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 e55fa3d7..d14f663e 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;
diff --git a/packages/taler-wallet-core/src/operations/refresh.ts 
b/packages/taler-wallet-core/src/operations/refresh.ts
index 21c884d4..16b691ec 100644
--- a/packages/taler-wallet-core/src/operations/refresh.ts
+++ b/packages/taler-wallet-core/src/operations/refresh.ts
@@ -60,6 +60,8 @@ import {
 import { URL } from "../util/url";
 import { checkDbInvariant } from "../util/invariants";
 import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries";
+import { WALLET_EXCHANGE_PROTOCOL_VERSION } from "./versions";
+import { RefreshNewDenomInfo } from "../types/cryptoTypes";
 
 const logger = new Logger("refresh.ts");
 
@@ -182,13 +184,7 @@ async function refreshCreateSession(
     return;
   }
 
-  const refreshSession: RefreshSessionRecord = await 
ws.cryptoApi.createRefreshSession(
-    exchange.baseUrl,
-    3,
-    coin,
-    newCoinDenoms,
-    oldDenom.feeRefresh,
-  );
+  const sessionSecretSeed = encodeCrock(getRandomBytes(64));
 
   // Store refresh session for this coin in the database.
   await ws.db.runWithWriteTransaction(
@@ -201,7 +197,15 @@ async function refreshCreateSession(
       if (rg.refreshSessionPerCoin[coinIndex]) {
         return;
       }
-      rg.refreshSessionPerCoin[coinIndex] = refreshSession;
+      rg.refreshSessionPerCoin[coinIndex] = {
+        norevealIndex: undefined,
+        sessionSecretSeed: sessionSecretSeed,
+        newDenoms: newCoinDenoms.selectedDenoms.map((x) => ({
+          count: x.count,
+          denomPubHash: x.denom.denomPubHash,
+        })),
+        amountRefreshOutput: newCoinDenoms.totalCoinValue,
+      };
       await tx.put(Stores.refreshGroups, rg);
     },
   );
@@ -232,24 +236,57 @@ async function refreshMelt(
     return;
   }
 
-  const coin = await ws.db.get(Stores.coins, refreshSession.meltCoinPub);
+  const oldCoin = await ws.db.get(
+    Stores.coins,
+    refreshGroup.oldCoinPubs[coinIndex],
+  );
+  checkDbInvariant(!!oldCoin, "melt coin doesn't exist");
+  const oldDenom = await ws.db.get(Stores.denominations, [
+    oldCoin.exchangeBaseUrl,
+    oldCoin.denomPubHash,
+  ]);
+  checkDbInvariant(!!oldDenom, "denomination for melted coin doesn't exist");
 
-  if (!coin) {
-    console.error("can't melt coin, it does not exist");
-    return;
+  const newCoinDenoms: RefreshNewDenomInfo[] = [];
+
+  for (const dh of refreshSession.newDenoms) {
+    const newDenom = await ws.db.get(Stores.denominations, [
+      oldCoin.exchangeBaseUrl,
+      dh.denomPubHash,
+    ]);
+    checkDbInvariant(
+      !!newDenom,
+      "new denomination for refresh not in database",
+    );
+    newCoinDenoms.push({
+      count: dh.count,
+      denomPub: newDenom.denomPub,
+      feeWithdraw: newDenom.feeWithdraw,
+      value: newDenom.value,
+    });
   }
 
+  const derived = await ws.cryptoApi.deriveRefreshSession({
+    kappa: 3,
+    meltCoinDenomPubHash: oldCoin.denomPubHash,
+    meltCoinPriv: oldCoin.coinPriv,
+    meltCoinPub: oldCoin.coinPub,
+    feeRefresh: oldDenom.feeRefresh,
+    newCoinDenoms,
+    sessionSecretSeed: refreshSession.sessionSecretSeed,
+  });
+
   const reqUrl = new URL(
-    `coins/${coin.coinPub}/melt`,
-    refreshSession.exchangeBaseUrl,
+    `coins/${oldCoin.coinPub}/melt`,
+    oldCoin.exchangeBaseUrl,
   );
   const meltReq = {
-    coin_pub: coin.coinPub,
-    confirm_sig: refreshSession.confirmSig,
-    denom_pub_hash: coin.denomPubHash,
-    denom_sig: coin.denomSig,
-    rc: refreshSession.hash,
-    value_with_fee: Amounts.stringify(refreshSession.amountRefreshInput),
+    coin_pub: oldCoin.coinPub,
+    confirm_sig: derived.confirmSig,
+    denom_pub_hash: oldCoin.denomPubHash,
+    denom_sig: oldCoin.denomSig,
+    rc: derived.hash,
+    value_with_fee: Amounts.stringify(derived.meltValueWithFee),
   };
   logger.trace(`melt request for coin:`, meltReq);
 
@@ -270,13 +307,13 @@ async function refreshMelt(
 
   await ws.db.mutate(Stores.refreshGroups, refreshGroupId, (rg) => {
     const rs = rg.refreshSessionPerCoin[coinIndex];
-    if (!rs) {
+    if (rg.timestampFinished) {
       return;
     }
-    if (rs.norevealIndex !== undefined) {
+    if (!rs) {
       return;
     }
-    if (rs.finishedTimestamp) {
+    if (rs.norevealIndex !== undefined) {
       return;
     }
     rs.norevealIndex = norevealIndex;
@@ -305,48 +342,95 @@ async function refreshReveal(
   if (norevealIndex === undefined) {
     throw Error("can't reveal without melting first");
   }
-  const privs = Array.from(refreshSession.transferPrivs);
+
+  const oldCoin = await ws.db.get(
+    Stores.coins,
+    refreshGroup.oldCoinPubs[coinIndex],
+  );
+  checkDbInvariant(!!oldCoin, "melt coin doesn't exist");
+  const oldDenom = await ws.db.get(Stores.denominations, [
+    oldCoin.exchangeBaseUrl,
+    oldCoin.denomPubHash,
+  ]);
+  checkDbInvariant(!!oldDenom, "denomination for melted coin doesn't exist");
+
+  const newCoinDenoms: RefreshNewDenomInfo[] = [];
+
+  for (const dh of refreshSession.newDenoms) {
+    const newDenom = await ws.db.get(Stores.denominations, [
+      oldCoin.exchangeBaseUrl,
+      dh.denomPubHash,
+    ]);
+    checkDbInvariant(
+      !!newDenom,
+      "new denomination for refresh not in database",
+    );
+    newCoinDenoms.push({
+      count: dh.count,
+      denomPub: newDenom.denomPub,
+      feeWithdraw: newDenom.feeWithdraw,
+      value: newDenom.value,
+    });
+  }
+
+  const derived = await ws.cryptoApi.deriveRefreshSession({
+    kappa: 3,
+    meltCoinDenomPubHash: oldCoin.denomPubHash,
+    meltCoinPriv: oldCoin.coinPriv,
+    meltCoinPub: oldCoin.coinPub,
+    feeRefresh: oldDenom.feeRefresh,
+    newCoinDenoms,
+    sessionSecretSeed: refreshSession.sessionSecretSeed,
+  });
+
+  const privs = Array.from(derived.transferPrivs);
   privs.splice(norevealIndex, 1);
 
-  const planchets = refreshSession.planchetsForGammas[norevealIndex];
+  const planchets = derived.planchetsForGammas[norevealIndex];
   if (!planchets) {
     throw Error("refresh index error");
   }
 
   const meltCoinRecord = await ws.db.get(
     Stores.coins,
-    refreshSession.meltCoinPub,
+    refreshGroup.oldCoinPubs[coinIndex],
   );
   if (!meltCoinRecord) {
     throw Error("inconsistent database");
   }
 
   const evs = planchets.map((x: RefreshPlanchet) => x.coinEv);
-
+  const newDenomsFlat: string[] = [];
   const linkSigs: string[] = [];
+
   for (let i = 0; i < refreshSession.newDenoms.length; i++) {
-    const linkSig = await ws.cryptoApi.signCoinLink(
-      meltCoinRecord.coinPriv,
-      refreshSession.newDenomHashes[i],
-      refreshSession.meltCoinPub,
-      refreshSession.transferPubs[norevealIndex],
-      planchets[i].coinEv,
-    );
-    linkSigs.push(linkSig);
+    const dsel = refreshSession.newDenoms[i];
+    for (let j = 0; j < dsel.count; j++) {
+      const newCoinIndex = linkSigs.length;
+      const linkSig = await ws.cryptoApi.signCoinLink(
+        meltCoinRecord.coinPriv,
+        dsel.denomPubHash,
+        meltCoinRecord.coinPub,
+        derived.transferPubs[norevealIndex],
+        planchets[newCoinIndex].coinEv,
+      );
+      linkSigs.push(linkSig);
+      newDenomsFlat.push(dsel.denomPubHash);
+    }
   }
 
   const req = {
     coin_evs: evs,
-    new_denoms_h: refreshSession.newDenomHashes,
-    rc: refreshSession.hash,
+    new_denoms_h: newDenomsFlat,
+    rc: derived.hash,
     transfer_privs: privs,
-    transfer_pub: refreshSession.transferPubs[norevealIndex],
+    transfer_pub: derived.transferPubs[norevealIndex],
     link_sigs: linkSigs,
   };
 
   const reqUrl = new URL(
-    `refreshes/${refreshSession.hash}/reveal`,
-    refreshSession.exchangeBaseUrl,
+    `refreshes/${derived.hash}/reveal`,
+    oldCoin.exchangeBaseUrl,
   );
 
   const resp = await ws.runSequentialized([EXCHANGE_COINS_LOCK], async () => {
@@ -362,39 +446,42 @@ async function refreshReveal(
 
   const coins: CoinRecord[] = [];
 
-  for (let i = 0; i < reveal.ev_sigs.length; i++) {
-    const denom = await ws.db.get(Stores.denominations, [
-      refreshSession.exchangeBaseUrl,
-      refreshSession.newDenomHashes[i],
-    ]);
-    if (!denom) {
-      console.error("denom not found");
-      continue;
+  for (let i = 0; i < refreshSession.newDenoms.length; i++) {
+    for (let j = 0; j < refreshSession.newDenoms[i].count; j++) {
+      const newCoinIndex = coins.length;
+      const denom = await ws.db.get(Stores.denominations, [
+        oldCoin.exchangeBaseUrl,
+        refreshSession.newDenoms[i].denomPubHash,
+      ]);
+      if (!denom) {
+        console.error("denom not found");
+        continue;
+      }
+      const pc = derived.planchetsForGammas[norevealIndex][newCoinIndex];
+      const denomSig = await ws.cryptoApi.rsaUnblind(
+        reveal.ev_sigs[newCoinIndex].ev_sig,
+        pc.blindingKey,
+        denom.denomPub,
+      );
+      const coin: CoinRecord = {
+        blindingKey: pc.blindingKey,
+        coinPriv: pc.privateKey,
+        coinPub: pc.publicKey,
+        currentAmount: denom.value,
+        denomPub: denom.denomPub,
+        denomPubHash: denom.denomPubHash,
+        denomSig,
+        exchangeBaseUrl: oldCoin.exchangeBaseUrl,
+        status: CoinStatus.Fresh,
+        coinSource: {
+          type: CoinSourceType.Refresh,
+          oldCoinPub: refreshGroup.oldCoinPubs[coinIndex],
+        },
+        suspended: false,
+      };
+
+      coins.push(coin);
     }
-    const pc = refreshSession.planchetsForGammas[norevealIndex][i];
-    const denomSig = await ws.cryptoApi.rsaUnblind(
-      reveal.ev_sigs[i].ev_sig,
-      pc.blindingKey,
-      denom.denomPub,
-    );
-    const coin: CoinRecord = {
-      blindingKey: pc.blindingKey,
-      coinPriv: pc.privateKey,
-      coinPub: pc.publicKey,
-      currentAmount: denom.value,
-      denomPub: denom.denomPub,
-      denomPubHash: denom.denomPubHash,
-      denomSig,
-      exchangeBaseUrl: refreshSession.exchangeBaseUrl,
-      status: CoinStatus.Fresh,
-      coinSource: {
-        type: CoinSourceType.Refresh,
-        oldCoinPub: refreshSession.meltCoinPub,
-      },
-      suspended: false,
-    };
-
-    coins.push(coin);
   }
 
   await ws.db.runWithWriteTransaction(
@@ -409,11 +496,6 @@ async function refreshReveal(
       if (!rs) {
         return;
       }
-      if (rs.finishedTimestamp) {
-        logger.warn("refresh session already finished");
-        return;
-      }
-      rs.finishedTimestamp = getTimestampNow();
       rg.finishedPerCoin[coinIndex] = true;
       let allDone = true;
       for (const f of rg.finishedPerCoin) {
diff --git a/packages/taler-wallet-core/src/types/cryptoTypes.ts 
b/packages/taler-wallet-core/src/types/cryptoTypes.ts
new file mode 100644
index 00000000..a7f51ab5
--- /dev/null
+++ b/packages/taler-wallet-core/src/types/cryptoTypes.ts
@@ -0,0 +1,111 @@
+/*
+ This file is part of GNU Taler
+ (C) 2020 Taler Systems SA
+
+ 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/>
+ */
+
+/**
+ * Types used by the wallet crypto worker.
+ *
+ * These types are defined in a separate file make tree shaking easier, since
+ * some components use these types (via RPC) but do not depend on the wallet
+ * code directly.
+ *
+ * @author Florian Dold <dold@taler.net>
+ */
+
+/**
+ * Imports.
+ */
+import { AmountJson } from "../util/amounts";
+
+export interface RefreshNewDenomInfo {
+  count: number;
+  value: AmountJson;
+  feeWithdraw: AmountJson;
+  denomPub: string;
+}
+
+/**
+ * Request to derive a refresh session from the refresh session
+ * secret seed.
+ */
+export interface DeriveRefreshSessionRequest {
+  sessionSecretSeed: string;
+  kappa: number;
+  meltCoinPub: string;
+  meltCoinPriv: string;
+  meltCoinDenomPubHash: string;
+  newCoinDenoms: RefreshNewDenomInfo[];
+  feeRefresh: AmountJson;
+}
+
+/**
+ *
+ */
+export interface DerivedRefreshSession {
+  /**
+   * Public key that's being melted in this session.
+   */
+  meltCoinPub: string;
+
+  /**
+   * Signature to confirm the melting.
+   */
+  confirmSig: string;
+
+  /**
+   * Planchets for each cut-and-choose instance.
+   */
+  planchetsForGammas: {
+    /**
+     * Public key for the coin.
+     */
+    publicKey: string;
+
+    /**
+     * Private key for the coin.
+     */
+    privateKey: string;
+
+    /**
+     * Blinded public key.
+     */
+    coinEv: string;
+
+    /**
+     * Blinding key used.
+     */
+    blindingKey: string;
+  }[][];
+
+  /**
+   * The transfer keys, kappa of them.
+   */
+  transferPubs: string[];
+
+  /**
+   * Private keys for the transfer public keys.
+   */
+  transferPrivs: string[];
+
+  /**
+   * Hash of the session.
+   */
+  hash: string;
+
+  /**
+   * Exact value that is being melted.
+   */
+  meltValueWithFee: AmountJson;
+}
diff --git a/packages/taler-wallet-core/src/types/dbTypes.ts 
b/packages/taler-wallet-core/src/types/dbTypes.ts
index a4f14ff0..18a1102b 100644
--- a/packages/taler-wallet-core/src/types/dbTypes.ts
+++ b/packages/taler-wallet-core/src/types/dbTypes.ts
@@ -557,7 +557,7 @@ export interface ExchangeRecord {
 
   /**
    * Terms of service text or undefined if not downloaded yet.
-   * 
+   *
    * This is just used as a cache of the last downloaded ToS.
    */
   termsOfServiceText: string | undefined;
@@ -664,14 +664,17 @@ export interface RefreshPlanchet {
    * Public key for the coin.
    */
   publicKey: string;
+
   /**
    * Private key for the coin.
    */
   privateKey: string;
+
   /**
    * Blinded public key.
    */
   coinEv: string;
+
   /**
    * Blinding key used.
    */
@@ -991,18 +994,14 @@ export interface RefreshGroupRecord {
  * Ongoing refresh
  */
 export interface RefreshSessionRecord {
-  lastError: TalerErrorDetails | undefined;
-
   /**
-   * Public key that's being melted in this session.
-   */
-  meltCoinPub: string;
-
-  /**
-   * How much of the coin's value is melted away
-   * with this refresh session?
+   * 512-bit secret that can be used to derive
+   * the other cryptographic material for the refresh session.
+   *
+   * FIXME:  We currently store the derived material, but
+   * should always derive it.
    */
-  amountRefreshInput: AmountJson;
+  sessionSecretSeed: string;
 
   /**
    * Sum of the value of denominations we want
@@ -1011,59 +1010,17 @@ export interface RefreshSessionRecord {
   amountRefreshOutput: AmountJson;
 
   /**
-   * Signature to confirm the melting.
+   * Hashed denominations of the newly requested coins.
    */
-  confirmSig: string;
-
-  /**
-   * Hased denominations of the newly requested coins.
-   */
-  newDenomHashes: string[];
-
-  /**
-   * Denominations of the newly requested coins.
-   */
-  newDenoms: string[];
-
-  /**
-   * Planchets for each cut-and-choose instance.
-   */
-  planchetsForGammas: RefreshPlanchet[][];
-
-  /**
-   * The transfer keys, kappa of them.
-   */
-  transferPubs: string[];
-
-  /**
-   * Private keys for the transfer public keys.
-   */
-  transferPrivs: string[];
+  newDenoms: {
+    denomPubHash: string;
+    count: number;
+  }[];
 
   /**
    * The no-reveal-index after we've done the melting.
    */
   norevealIndex?: number;
-
-  /**
-   * Hash of the session.
-   */
-  hash: string;
-
-  /**
-   * Timestamp when the refresh session finished.
-   */
-  finishedTimestamp: Timestamp | undefined;
-
-  /**
-   * When has this refresh session been created?
-   */
-  timestampCreated: Timestamp;
-
-  /**
-   * Base URL for the exchange we're doing the refresh with.
-   */
-  exchangeBaseUrl: string;
 }
 
 /**
@@ -1602,7 +1559,7 @@ class PurchasesStore extends Store<"purchases", 
PurchaseRecord> {
     string,
     PurchaseRecord
   >(this, "fulfillmentUrlIndex", "contractData.fulfillmentUrl");
-  
+
   orderIdIndex = new Index<"purchases", "orderIdIndex", string, 
PurchaseRecord>(
     this,
     "orderIdIndex",
@@ -1712,7 +1669,6 @@ class BankWithdrawUrisStore extends Store<
   }
 }
 
-
 /**
  */
 class BackupProvidersStore extends Store<

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]