gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] branch master updated: export complete backup, deriv


From: gnunet
Subject: [taler-wallet-core] branch master updated: export complete backup, derive planchets in withdrawal
Date: Thu, 17 Dec 2020 12:21:08 +0100

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

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

The following commit(s) were added to refs/heads/master by this push:
     new 84d5b5e5 export complete backup, derive planchets in withdrawal
84d5b5e5 is described below

commit 84d5b5e5ef34f7289256c6fd301206cda19be694
Author: Florian Dold <florian@dold.me>
AuthorDate: Thu Dec 17 12:21:03 2020 +0100

    export complete backup, derive planchets in withdrawal
---
 .../taler-wallet-core/src/crypto/talerCrypto.ts    | 19 ++++++++++
 .../src/crypto/workers/cryptoImplementation.ts     | 22 +++++------
 .../taler-wallet-core/src/operations/backup.ts     | 44 +++++++++++++++-------
 .../taler-wallet-core/src/operations/reserves.ts   |  1 +
 packages/taler-wallet-core/src/operations/tip.ts   |  8 ++--
 .../taler-wallet-core/src/operations/withdraw.ts   |  2 +
 .../taler-wallet-core/src/types/backupTypes.ts     | 13 +++----
 packages/taler-wallet-core/src/types/dbTypes.ts    |  5 +++
 .../taler-wallet-core/src/types/walletTypes.ts     |  2 +
 packages/taler-wallet-core/src/util/invariants.ts  | 10 +++++
 10 files changed, 91 insertions(+), 35 deletions(-)

diff --git a/packages/taler-wallet-core/src/crypto/talerCrypto.ts 
b/packages/taler-wallet-core/src/crypto/talerCrypto.ts
index 09595798..d28f1117 100644
--- a/packages/taler-wallet-core/src/crypto/talerCrypto.ts
+++ b/packages/taler-wallet-core/src/crypto/talerCrypto.ts
@@ -390,6 +390,25 @@ export function setupRefreshPlanchet(
   };
 }
 
+export function setupWithdrawPlanchet(
+  secretSeed: Uint8Array,
+  coinNumber: number,
+): FreshCoin {
+  const info = stringToBytes("taler-withdrawal-coin-derivation");
+  const saltArrBuf = new ArrayBuffer(4);
+  const salt = new Uint8Array(saltArrBuf);
+  const saltDataView = new DataView(saltArrBuf);
+  saltDataView.setUint32(0, coinNumber);
+  const out = kdf(64, secretSeed, salt, info);
+  const coinPriv = out.slice(0, 32);
+  const bks = out.slice(32, 64);
+  return {
+    bks,
+    coinPriv,
+    coinPub: eddsaGetPublic(coinPriv),
+  };
+}
+
 export function setupTipPlanchet(
   secretSeed: Uint8Array,
   coinNumber: number,
diff --git 
a/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts 
b/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts
index 4f553c50..fc8b53eb 100644
--- a/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts
+++ b/packages/taler-wallet-core/src/crypto/workers/cryptoImplementation.ts
@@ -61,13 +61,11 @@ import {
   rsaVerify,
   setupRefreshTransferPub,
   setupTipPlanchet,
+  setupWithdrawPlanchet,
 } from "../talerCrypto";
 import { randomBytes } from "../primitives/nacl-fast";
 import { kdf } from "../primitives/kdf";
-import {
-  Timestamp,
-  timestampTruncateToSecond,
-} from "../../util/time";
+import { Timestamp, timestampTruncateToSecond } from "../../util/time";
 
 import { Logger } from "../../util/logging";
 import {
@@ -161,10 +159,12 @@ export class CryptoImplementation {
     const reservePub = decodeCrock(req.reservePub);
     const reservePriv = decodeCrock(req.reservePriv);
     const denomPub = decodeCrock(req.denomPub);
-    const coinKeyPair = createEddsaKeyPair();
-    const blindingFactor = createBlindingKeySecret();
-    const coinPubHash = hash(coinKeyPair.eddsaPub);
-    const ev = rsaBlind(coinPubHash, blindingFactor, denomPub);
+    const derivedPlanchet = setupWithdrawPlanchet(
+      decodeCrock(req.secretSeed),
+      req.coinIndex,
+    );
+    const coinPubHash = hash(derivedPlanchet.coinPub);
+    const ev = rsaBlind(coinPubHash, derivedPlanchet.bks, denomPub);
     const amountWithFee = Amounts.add(req.value, req.feeWithdraw).amount;
     const denomPubHash = hash(denomPub);
     const evHash = hash(ev);
@@ -179,10 +179,10 @@ export class CryptoImplementation {
     const sig = eddsaSign(withdrawRequest, reservePriv);
 
     const planchet: PlanchetCreationResult = {
-      blindingKey: encodeCrock(blindingFactor),
+      blindingKey: encodeCrock(derivedPlanchet.bks),
       coinEv: encodeCrock(ev),
-      coinPriv: encodeCrock(coinKeyPair.eddsaPriv),
-      coinPub: encodeCrock(coinKeyPair.eddsaPub),
+      coinPriv: encodeCrock(derivedPlanchet.coinPriv),
+      coinPub: encodeCrock(derivedPlanchet.coinPub),
       coinValue: req.value,
       denomPub: encodeCrock(denomPub),
       denomPubHash: encodeCrock(denomPubHash),
diff --git a/packages/taler-wallet-core/src/operations/backup.ts 
b/packages/taler-wallet-core/src/operations/backup.ts
index 1e5aa542..f071b6d0 100644
--- a/packages/taler-wallet-core/src/operations/backup.ts
+++ b/packages/taler-wallet-core/src/operations/backup.ts
@@ -198,17 +198,17 @@ export async function exportBackup(
         const withdrawalGroups = (withdrawalGroupsByReserve[
           wg.reservePub
         ] ??= []);
-        // FIXME: finish!
-        // withdrawalGroups.push({
-        //   raw_withdrawal_amount: Amounts.stringify(wg.rawWithdrawalAmount),
-        //   selected_denoms: wg.denomsSel.selectedDenoms.map((x) => ({
-        //     count: x.count,
-        //     denom_pub_hash: x.denomPubHash,
-        //   })),
-        //   timestamp_start: wg.timestampStart,
-        //   timestamp_finish: wg.timestampFinish,
-        //   withdrawal_group_id: wg.withdrawalGroupId,
-        // });
+        withdrawalGroups.push({
+          raw_withdrawal_amount: Amounts.stringify(wg.rawWithdrawalAmount),
+          selected_denoms: wg.denomsSel.selectedDenoms.map((x) => ({
+            count: x.count,
+            denom_pub_hash: x.denomPubHash,
+          })),
+          timestamp_start: wg.timestampStart,
+          timestamp_finish: wg.timestampFinish,
+          withdrawal_group_id: wg.withdrawalGroupId,
+          secret_seed: wg.secretSeed
+        });
       });
 
       await tx.iter(Stores.reserves).forEach((reserve) => {
@@ -572,11 +572,29 @@ export async function encryptBackup(
   throw Error("not implemented");
 }
 
-export function importBackup(
+export async function importBackup(
   ws: InternalWalletState,
   backupRequest: BackupRequest,
 ): Promise<void> {
-  throw Error("not implemented");
+  await provideBackupState(ws);
+  return ws.db.runWithWriteTransaction(
+    [
+      Stores.config,
+      Stores.exchanges,
+      Stores.coins,
+      Stores.denominations,
+      Stores.purchases,
+      Stores.proposals,
+      Stores.refreshGroups,
+      Stores.backupProviders,
+      Stores.tips,
+      Stores.recoupGroups,
+      Stores.reserves,
+      Stores.withdrawalGroups,
+    ],
+    async (tx) => {
+
+    });
 }
 
 function deriveAccountKeyPair(
diff --git a/packages/taler-wallet-core/src/operations/reserves.ts 
b/packages/taler-wallet-core/src/operations/reserves.ts
index 95c38120..4e4db1fc 100644
--- a/packages/taler-wallet-core/src/operations/reserves.ts
+++ b/packages/taler-wallet-core/src/operations/reserves.ts
@@ -623,6 +623,7 @@ async function updateReserve(
           retryInfo: initRetryInfo(),
           lastError: undefined,
           denomsSel: denomSelectionInfoToState(denomSelInfo),
+          secretSeed: encodeCrock(getRandomBytes(64)),
         };
 
         newReserve.lastError = undefined;
diff --git a/packages/taler-wallet-core/src/operations/tip.ts 
b/packages/taler-wallet-core/src/operations/tip.ts
index f47f7662..f683999b 100644
--- a/packages/taler-wallet-core/src/operations/tip.ts
+++ b/packages/taler-wallet-core/src/operations/tip.ts
@@ -48,7 +48,7 @@ import {
 } from "../util/http";
 import { URL } from "../util/url";
 import { Logger } from "../util/logging";
-import { checkDbInvariant } from "../util/invariants";
+import { checkDbInvariant, checkLogicInvariant } from "../util/invariants";
 import { TalerErrorCode } from "../TalerErrorCode";
 import { initRetryInfo, updateRetryInfoTimeout } from "../util/retries";
 import { j2s } from "../util/helpers";
@@ -221,13 +221,13 @@ async function processTipImpl(
       dh.denomPubHash,
     ]);
     checkDbInvariant(!!denom, "denomination should be in database");
-    denomForPlanchet[planchets.length] = denom;
     for (let i = 0; i < dh.count; i++) {
       const p = await ws.cryptoApi.createTipPlanchet({
-        denomPub: dh.denomPubHash,
+        denomPub: denom.denomPub,
         planchetIndex: planchets.length,
         secretSeed: tipRecord.secretSeed,
       });
+      denomForPlanchet[planchets.length] = denom;
       planchets.push(p);
       planchetsDetail.push({
         coin_ev: p.coinEv,
@@ -275,7 +275,9 @@ async function processTipImpl(
     const blindedSig = response.blind_sigs[i].blind_sig;
 
     const denom = denomForPlanchet[i];
+    checkLogicInvariant(!!denom);
     const planchet = planchets[i];
+    checkLogicInvariant(!!planchet);
 
     const denomSig = await ws.cryptoApi.rsaUnblind(
       blindedSig,
diff --git a/packages/taler-wallet-core/src/operations/withdraw.ts 
b/packages/taler-wallet-core/src/operations/withdraw.ts
index 758b8078..c2dfcd1c 100644
--- a/packages/taler-wallet-core/src/operations/withdraw.ts
+++ b/packages/taler-wallet-core/src/operations/withdraw.ts
@@ -284,6 +284,8 @@ async function processPlanchetGenerate(
       reservePriv: reserve.reservePriv,
       reservePub: reserve.reservePub,
       value: denom.value,
+      coinIndex: coinIdx,
+      secretSeed: withdrawalGroup.secretSeed,
     });
     const newPlanchet: PlanchetRecord = {
       blindingKey: r.blindingKey,
diff --git a/packages/taler-wallet-core/src/types/backupTypes.ts 
b/packages/taler-wallet-core/src/types/backupTypes.ts
index a3261ae3..d40d4fa6 100644
--- a/packages/taler-wallet-core/src/types/backupTypes.ts
+++ b/packages/taler-wallet-core/src/types/backupTypes.ts
@@ -625,6 +625,11 @@ export interface BackupRefreshGroup {
 export interface BackupWithdrawalGroup {
   withdrawal_group_id: string;
 
+  /**
+   * Secret seed to derive the planchets.
+   */
+  secret_seed: string;
+
   /**
    * When was the withdrawal operation started started?
    * Timestamp in milliseconds.
@@ -653,14 +658,6 @@ export interface BackupWithdrawalGroup {
     denom_pub_hash: string;
     count: number;
   }[];
-
-  /**
-   * One planchet/coin for each selected denomination.
-   */
-  planchets: {
-    blinding_key: string;
-    coin_priv: string;
-  }[];
 }
 
 export enum BackupRefundState {
diff --git a/packages/taler-wallet-core/src/types/dbTypes.ts 
b/packages/taler-wallet-core/src/types/dbTypes.ts
index 71a59131..7ba3b860 100644
--- a/packages/taler-wallet-core/src/types/dbTypes.ts
+++ b/packages/taler-wallet-core/src/types/dbTypes.ts
@@ -1322,6 +1322,11 @@ export interface DenomSelectionState {
 export interface WithdrawalGroupRecord {
   withdrawalGroupId: string;
 
+  /**
+   * Secret seed used to derive planchets.
+   */
+  secretSeed: string;
+
   reservePub: string;
 
   exchangeBaseUrl: string;
diff --git a/packages/taler-wallet-core/src/types/walletTypes.ts 
b/packages/taler-wallet-core/src/types/walletTypes.ts
index 7dc675b3..1b962e1c 100644
--- a/packages/taler-wallet-core/src/types/walletTypes.ts
+++ b/packages/taler-wallet-core/src/types/walletTypes.ts
@@ -557,6 +557,8 @@ export interface PlanchetCreationResult {
 }
 
 export interface PlanchetCreationRequest {
+  secretSeed: string;
+  coinIndex: number;
   value: AmountJson;
   feeWithdraw: AmountJson;
   denomPub: string;
diff --git a/packages/taler-wallet-core/src/util/invariants.ts 
b/packages/taler-wallet-core/src/util/invariants.ts
index fa381d33..b788d044 100644
--- a/packages/taler-wallet-core/src/util/invariants.ts
+++ b/packages/taler-wallet-core/src/util/invariants.ts
@@ -27,3 +27,13 @@ export function checkDbInvariant(b: boolean, m?: string): 
asserts b {
     }
   }
 }
+
+export function checkLogicInvariant(b: boolean, m?: string): asserts b {
+  if (!b) {
+    if (m) {
+      throw Error(`BUG: logic invariant failed (${m})`);
+    } else {
+      throw Error("BUG: logic invariant failed");
+    }
+  }
+}

-- 
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]