gnunet-svn
[Top][All Lists]
Advanced

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

[taler-exchange] branch master updated: centralize exchange online signa


From: gnunet
Subject: [taler-exchange] branch master updated: centralize exchange online signature logic
Date: Tue, 29 Mar 2022 15:24:08 +0200

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

grothoff pushed a commit to branch master
in repository exchange.

The following commit(s) were added to refs/heads/master by this push:
     new 074ea750 centralize exchange online signature logic
074ea750 is described below

commit 074ea7502e93b290f9300974f5a349a8de4f4753
Author: Christian Grothoff <grothoff@gnunet.org>
AuthorDate: Tue Mar 29 15:21:49 2022 +0200

    centralize exchange online signature logic
---
 .../taler-auditor-httpd_deposit-confirmation.c     |   23 +-
 src/exchange/taler-exchange-httpd_deposit.c        |   53 +-
 src/exchange/taler-exchange-httpd_deposits_get.c   |   40 +-
 src/exchange/taler-exchange-httpd_keys.c           |   21 +-
 src/exchange/taler-exchange-httpd_keys.h           |    4 +-
 src/exchange/taler-exchange-httpd_kyc-check.c      |   16 +-
 src/exchange/taler-exchange-httpd_melt.c           |   15 +-
 src/exchange/taler-exchange-httpd_refund.c         |   22 +-
 src/exchange/taler-exchange-httpd_responses.c      |  196 ++--
 src/exchange/taler-exchange-httpd_transfers_get.c  |   47 +-
 src/include/taler_crypto_lib.h                     |  672 +++++++++++-
 src/include/taler_signatures.h                     |  761 -------------
 src/lib/auditor_api_deposit_confirmation.c         |   23 +-
 src/lib/exchange_api_common.c                      |  169 ++-
 src/lib/exchange_api_deposit.c                     |   23 +-
 src/lib/exchange_api_deposits_get.c                |   66 +-
 src/lib/exchange_api_handle.c                      |   18 +-
 src/lib/exchange_api_kyc_check.c                   |   18 +-
 src/lib/exchange_api_melt.c                        |    2 +-
 src/lib/exchange_api_refund.c                      |  107 +-
 src/lib/exchange_api_transfers_get.c               |   61 +-
 src/util/auditor_signatures.c                      |   83 ++
 src/util/exchange_signatures.c                     | 1125 +++++++++++++++++++-
 src/util/secmod_signatures.c                       |   66 ++
 24 files changed, 2326 insertions(+), 1305 deletions(-)

diff --git a/src/auditor/taler-auditor-httpd_deposit-confirmation.c 
b/src/auditor/taler-auditor-httpd_deposit-confirmation.c
index 7f4d4286..6042b740 100644
--- a/src/auditor/taler-auditor-httpd_deposit-confirmation.c
+++ b/src/auditor/taler-auditor-httpd_deposit-confirmation.c
@@ -182,17 +182,18 @@ verify_and_execute_deposit_confirmation (
 
   /* check deposit confirmation signature */
   if (GNUNET_OK !=
-      TALER_exchange_deposit_confirm_verify (&dc->h_contract_terms,
-                                             &dc->h_wire,
-                                             NULL /* h_extensions! */,
-                                             dc->exchange_timestamp,
-                                             dc->wire_deadline,
-                                             dc->refund_deadline,
-                                             &dc->amount_without_fee,
-                                             &dc->coin_pub,
-                                             &dc->merchant,
-                                             &dc->exchange_pub,
-                                             &dc->exchange_sig))
+      TALER_exchange_online_deposit_confirmation_verify (
+        &dc->h_contract_terms,
+        &dc->h_wire,
+        NULL /* h_extensions! */,
+        dc->exchange_timestamp,
+        dc->wire_deadline,
+        dc->refund_deadline,
+        &dc->amount_without_fee,
+        &dc->coin_pub,
+        &dc->merchant,
+        &dc->exchange_pub,
+        &dc->exchange_sig))
   {
     TALER_LOG_WARNING (
       "Invalid signature on /deposit-confirmation request\n");
diff --git a/src/exchange/taler-exchange-httpd_deposit.c 
b/src/exchange/taler-exchange-httpd_deposit.c
index 00353a40..59d25904 100644
--- a/src/exchange/taler-exchange-httpd_deposit.c
+++ b/src/exchange/taler-exchange-httpd_deposit.c
@@ -57,41 +57,36 @@
  * @return MHD result code
  */
 static MHD_RESULT
-reply_deposit_success (struct MHD_Connection *connection,
-                       const struct TALER_CoinSpendPublicKeyP *coin_pub,
-                       const struct TALER_MerchantWireHashP *h_wire,
-                       const struct TALER_ExtensionContractHashP *h_extensions,
-                       const struct
-                       TALER_PrivateContractHashP *h_contract_terms,
-                       struct GNUNET_TIME_Timestamp exchange_timestamp,
-                       struct GNUNET_TIME_Timestamp refund_deadline,
-                       struct GNUNET_TIME_Timestamp wire_deadline,
-                       const struct TALER_MerchantPublicKeyP *merchant,
-                       const struct TALER_Amount *amount_without_fee)
+reply_deposit_success (
+  struct MHD_Connection *connection,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_MerchantWireHashP *h_wire,
+  const struct TALER_ExtensionContractHashP *h_extensions,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  struct GNUNET_TIME_Timestamp exchange_timestamp,
+  struct GNUNET_TIME_Timestamp refund_deadline,
+  struct GNUNET_TIME_Timestamp wire_deadline,
+  const struct TALER_MerchantPublicKeyP *merchant,
+  const struct TALER_Amount *amount_without_fee)
 {
   struct TALER_ExchangePublicKeyP pub;
   struct TALER_ExchangeSignatureP sig;
-  struct TALER_DepositConfirmationPS dc = {
-    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
-    .purpose.size = htonl (sizeof (dc)),
-    .h_contract_terms = *h_contract_terms,
-    .h_wire = *h_wire,
-    .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
-    .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
-    .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
-    .coin_pub = *coin_pub,
-    .merchant_pub = *merchant
-  };
   enum TALER_ErrorCode ec;
 
-  if (NULL != h_extensions)
-    dc.h_extensions = *h_extensions;
-  TALER_amount_hton (&dc.amount_without_fee,
-                     amount_without_fee);
   if (TALER_EC_NONE !=
-      (ec = TEH_keys_exchange_sign (&dc,
-                                    &pub,
-                                    &sig)))
+      (ec = TALER_exchange_online_deposit_confirmation_sign (
+         &TEH_keys_exchange_sign_,
+         h_contract_terms,
+         h_wire,
+         h_extensions,
+         exchange_timestamp,
+         wire_deadline,
+         refund_deadline,
+         amount_without_fee,
+         coin_pub,
+         merchant,
+         &pub,
+         &sig)))
   {
     return TALER_MHD_reply_with_ec (connection,
                                     ec,
diff --git a/src/exchange/taler-exchange-httpd_deposits_get.c 
b/src/exchange/taler-exchange-httpd_deposits_get.c
index c88026fc..72657d16 100644
--- a/src/exchange/taler-exchange-httpd_deposits_get.c
+++ b/src/exchange/taler-exchange-httpd_deposits_get.c
@@ -46,34 +46,30 @@
  * @return MHD result code
  */
 static MHD_RESULT
-reply_deposit_details (struct MHD_Connection *connection,
-                       const struct
-                       TALER_PrivateContractHashP *h_contract_terms,
-                       const struct TALER_MerchantWireHashP *h_wire,
-                       const struct TALER_CoinSpendPublicKeyP *coin_pub,
-                       const struct TALER_Amount *coin_contribution,
-                       const struct TALER_WireTransferIdentifierRawP *wtid,
-                       struct GNUNET_TIME_Timestamp exec_time)
+reply_deposit_details (
+  struct MHD_Connection *connection,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const struct TALER_MerchantWireHashP *h_wire,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_Amount *coin_contribution,
+  const struct TALER_WireTransferIdentifierRawP *wtid,
+  struct GNUNET_TIME_Timestamp exec_time)
 {
   struct TALER_ExchangePublicKeyP pub;
   struct TALER_ExchangeSignatureP sig;
-  struct TALER_ConfirmWirePS cw = {
-    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE),
-    .purpose.size = htonl (sizeof (cw)),
-    .h_wire = *h_wire,
-    .h_contract_terms = *h_contract_terms,
-    .wtid = *wtid,
-    .coin_pub = *coin_pub,
-    .execution_time = GNUNET_TIME_timestamp_hton (exec_time)
-  };
   enum TALER_ErrorCode ec;
 
-  TALER_amount_hton (&cw.coin_contribution,
-                     coin_contribution);
   if (TALER_EC_NONE !=
-      (ec = TEH_keys_exchange_sign (&cw,
-                                    &pub,
-                                    &sig)))
+      (ec = TALER_exchange_online_confirm_wire_sign (
+         &TEH_keys_exchange_sign_,
+         h_wire,
+         h_contract_terms,
+         wtid,
+         coin_pub,
+         exec_time,
+         coin_contribution,
+         &pub,
+         &sig)))
   {
     return TALER_MHD_reply_with_ec (connection,
                                     ec,
diff --git a/src/exchange/taler-exchange-httpd_keys.c 
b/src/exchange/taler-exchange-httpd_keys.c
index 658e5a34..e0ca24a6 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -1797,19 +1797,17 @@ create_krd (struct TEH_KeyStateHandle *ksh,
               GNUNET_TIME_timestamp2s (last_cpd));
   /* Sign hash over denomination keys */
   {
-    struct TALER_ExchangeKeySetPS ks = {
-      .purpose.size = htonl (sizeof (ks)),
-      .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
-      .list_issue_date = GNUNET_TIME_timestamp_hton (last_cpd),
-      .hc = *denom_keys_hash
-    };
     enum TALER_ErrorCode ec;
 
     if (TALER_EC_NONE !=
-        (ec = TEH_keys_exchange_sign2 (ksh,
-                                       &ks,
-                                       &exchange_pub,
-                                       &exchange_sig)))
+        (ec =
+           TALER_exchange_online_key_set_sign (
+             &TEH_keys_exchange_sign2_,
+             ksh,
+             last_cpd,
+             denom_keys_hash,
+             &exchange_pub,
+             &exchange_sig)))
     {
       GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                   "Could not create key response data: cannot sign (%s)\n",
@@ -2770,11 +2768,12 @@ TEH_keys_exchange_sign_ (
 
 enum TALER_ErrorCode
 TEH_keys_exchange_sign2_ (
-  struct TEH_KeyStateHandle *ksh,
+  void *cls,
   const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
   struct TALER_ExchangePublicKeyP *pub,
   struct TALER_ExchangeSignatureP *sig)
 {
+  struct TEH_KeyStateHandle *ksh = cls;
   enum TALER_ErrorCode ec;
 
   TEH_METRICS_num_signatures[TEH_MT_SIGNATURE_EDDSA]++;
diff --git a/src/exchange/taler-exchange-httpd_keys.h 
b/src/exchange/taler-exchange-httpd_keys.h
index 732ee032..544906ad 100644
--- a/src/exchange/taler-exchange-httpd_keys.h
+++ b/src/exchange/taler-exchange-httpd_keys.h
@@ -367,7 +367,7 @@ TEH_keys_exchange_sign_ (
  * number of bytes of the data structure, including its header.  Use
  * #TEH_keys_exchange_sign() instead of calling this function directly!
  *
- * @param ksh key state state to look in
+ * @param cls key state state to look in
  * @param purpose the message to sign
  * @param[out] pub set to the current public signing key of the exchange
  * @param[out] sig signature over purpose using current signing key
@@ -375,7 +375,7 @@ TEH_keys_exchange_sign_ (
  */
 enum TALER_ErrorCode
 TEH_keys_exchange_sign2_ (
-  struct TEH_KeyStateHandle *ksh,
+  void *cls,
   const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
   struct TALER_ExchangePublicKeyP *pub,
   struct TALER_ExchangeSignatureP *sig);
diff --git a/src/exchange/taler-exchange-httpd_kyc-check.c 
b/src/exchange/taler-exchange-httpd_kyc-check.c
index d6b16d21..62ecbaab 100644
--- a/src/exchange/taler-exchange-httpd_kyc-check.c
+++ b/src/exchange/taler-exchange-httpd_kyc-check.c
@@ -414,19 +414,15 @@ TEH_handler_kyc_check (
   {
     struct TALER_ExchangePublicKeyP pub;
     struct TALER_ExchangeSignatureP sig;
-    struct TALER_ExchangeAccountSetupSuccessPS as = {
-      .purpose.purpose = htonl (
-        TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS),
-      .purpose.size = htonl (sizeof (as)),
-      .h_payto = kyp->h_payto,
-      .timestamp = GNUNET_TIME_timestamp_hton (now)
-    };
     enum TALER_ErrorCode ec;
 
     if (TALER_EC_NONE !=
-        (ec = TEH_keys_exchange_sign (&as,
-                                      &pub,
-                                      &sig)))
+        (ec = TALER_exchange_online_account_setup_success_sign (
+           &TEH_keys_exchange_sign_,
+           &kyp->h_payto,
+           now,
+           &pub,
+           &sig)))
     {
       return TALER_MHD_reply_with_ec (rc->connection,
                                       ec,
diff --git a/src/exchange/taler-exchange-httpd_melt.c 
b/src/exchange/taler-exchange-httpd_melt.c
index 531209c1..6fe97c8f 100644
--- a/src/exchange/taler-exchange-httpd_melt.c
+++ b/src/exchange/taler-exchange-httpd_melt.c
@@ -48,18 +48,15 @@ reply_melt_success (struct MHD_Connection *connection,
 {
   struct TALER_ExchangePublicKeyP pub;
   struct TALER_ExchangeSignatureP sig;
-  struct TALER_RefreshMeltConfirmationPS body = {
-    .purpose.size = htonl (sizeof (body)),
-    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
-    .rc = *rc,
-    .noreveal_index = htonl (noreveal_index)
-  };
   enum TALER_ErrorCode ec;
 
   if (TALER_EC_NONE !=
-      (ec = TEH_keys_exchange_sign (&body,
-                                    &pub,
-                                    &sig)))
+      (ec = TALER_exchange_online_melt_confirmation_sign (
+         &TEH_keys_exchange_sign_,
+         rc,
+         noreveal_index,
+         &pub,
+         &sig)))
   {
     return TALER_MHD_reply_with_ec (connection,
                                     ec,
diff --git a/src/exchange/taler-exchange-httpd_refund.c 
b/src/exchange/taler-exchange-httpd_refund.c
index 84b60bcd..3718fded 100644
--- a/src/exchange/taler-exchange-httpd_refund.c
+++ b/src/exchange/taler-exchange-httpd_refund.c
@@ -50,22 +50,18 @@ reply_refund_success (struct MHD_Connection *connection,
 {
   struct TALER_ExchangePublicKeyP pub;
   struct TALER_ExchangeSignatureP sig;
-  struct TALER_RefundConfirmationPS rc = {
-    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND),
-    .purpose.size = htonl (sizeof (rc)),
-    .h_contract_terms = refund->h_contract_terms,
-    .coin_pub = *coin_pub,
-    .merchant = refund->merchant_pub,
-    .rtransaction_id = GNUNET_htonll (refund->rtransaction_id)
-  };
   enum TALER_ErrorCode ec;
 
-  TALER_amount_hton (&rc.refund_amount,
-                     &refund->refund_amount);
   if (TALER_EC_NONE !=
-      (ec = TEH_keys_exchange_sign (&rc,
-                                    &pub,
-                                    &sig)))
+      (ec = TALER_exchange_online_refund_confirmation_sign (
+         &TEH_keys_exchange_sign_,
+         &refund->h_contract_terms,
+         coin_pub,
+         &refund->merchant_pub,
+         refund->rtransaction_id,
+         &refund->refund_amount,
+         &pub,
+         &sig)))
   {
     return TALER_MHD_reply_with_ec (connection,
                                     ec,
diff --git a/src/exchange/taler-exchange-httpd_responses.c 
b/src/exchange/taler-exchange-httpd_responses.c
index ee8c902d..725e08d9 100644
--- a/src/exchange/taler-exchange-httpd_responses.c
+++ b/src/exchange/taler-exchange-httpd_responses.c
@@ -241,21 +241,16 @@ TEH_RESPONSE_compile_transaction_history (
           pos->details.old_coin_recoup;
         struct TALER_ExchangePublicKeyP epub;
         struct TALER_ExchangeSignatureP esig;
-        struct TALER_RecoupRefreshConfirmationPS pc = {
-          .purpose.purpose = htonl (
-            TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
-          .purpose.size = htonl (sizeof (pc)),
-          .timestamp = GNUNET_TIME_timestamp_hton (pr->timestamp),
-          .coin_pub = pr->coin.coin_pub,
-          .old_coin_pub = pr->old_coin_pub
-        };
-
-        TALER_amount_hton (&pc.recoup_amount,
-                           &pr->value);
+
         if (TALER_EC_NONE !=
-            TEH_keys_exchange_sign (&pc,
-                                    &epub,
-                                    &esig))
+            TALER_exchange_online_confirm_recoup_refresh_sign (
+              &TEH_keys_exchange_sign_,
+              pr->timestamp,
+              &pr->value,
+              &pr->coin.coin_pub,
+              &pr->old_coin_pub,
+              &epub,
+              &esig))
         {
           GNUNET_break (0);
           json_decref (history);
@@ -295,20 +290,16 @@ TEH_RESPONSE_compile_transaction_history (
           pos->details.recoup;
         struct TALER_ExchangePublicKeyP epub;
         struct TALER_ExchangeSignatureP esig;
-        struct TALER_RecoupConfirmationPS pc = {
-          .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
-          .purpose.size = htonl (sizeof (pc)),
-          .timestamp = GNUNET_TIME_timestamp_hton (recoup->timestamp),
-          .coin_pub = *coin_pub,
-          .reserve_pub = recoup->reserve_pub
-        };
-
-        TALER_amount_hton (&pc.recoup_amount,
-                           &recoup->value);
+
         if (TALER_EC_NONE !=
-            TEH_keys_exchange_sign (&pc,
-                                    &epub,
-                                    &esig))
+            TALER_exchange_online_confirm_recoup_sign (
+              &TEH_keys_exchange_sign_,
+              recoup->timestamp,
+              &recoup->value,
+              coin_pub,
+              &recoup->reserve_pub,
+              &epub,
+              &esig))
         {
           GNUNET_break (0);
           json_decref (history);
@@ -351,21 +342,16 @@ TEH_RESPONSE_compile_transaction_history (
           pos->details.recoup_refresh;
         struct TALER_ExchangePublicKeyP epub;
         struct TALER_ExchangeSignatureP esig;
-        struct TALER_RecoupRefreshConfirmationPS pc = {
-          .purpose.purpose = htonl (
-            TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
-          .purpose.size = htonl (sizeof (pc)),
-          .timestamp = GNUNET_TIME_timestamp_hton (pr->timestamp),
-          .coin_pub = *coin_pub,
-          .old_coin_pub = pr->old_coin_pub
-        };
-
-        TALER_amount_hton (&pc.recoup_amount,
-                           &pr->value);
+
         if (TALER_EC_NONE !=
-            TEH_keys_exchange_sign (&pc,
-                                    &epub,
-                                    &esig))
+            TALER_exchange_online_confirm_recoup_refresh_sign (
+              &TEH_keys_exchange_sign_,
+              pr->timestamp,
+              &pr->value,
+              coin_pub,
+              &pr->old_coin_pub,
+              &epub,
+              &esig))
         {
           GNUNET_break (0);
           json_decref (history);
@@ -424,18 +410,12 @@ TEH_RESPONSE_reply_unknown_denom_pub_hash (
   enum TALER_ErrorCode ec;
 
   now = GNUNET_TIME_timestamp_get ();
-  {
-    struct TALER_DenominationUnknownAffirmationPS dua = {
-      .purpose.size = htonl (sizeof (dua)),
-      .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
-      .timestamp = GNUNET_TIME_timestamp_hton (now),
-      .h_denom_pub = *dph,
-    };
-
-    ec = TEH_keys_exchange_sign (&dua,
-                                 &epub,
-                                 &esig);
-  }
+  ec = TALER_exchange_online_denomination_unknown_sign (
+    &TEH_keys_exchange_sign_,
+    now,
+    dph,
+    &epub,
+    &esig);
   if (TALER_EC_NONE != ec)
   {
     GNUNET_break (0);
@@ -471,22 +451,14 @@ TEH_RESPONSE_reply_expired_denom_pub_hash (
   enum TALER_ErrorCode ecr;
   struct GNUNET_TIME_Timestamp now
     = GNUNET_TIME_timestamp_get ();
-  struct TALER_DenominationExpiredAffirmationPS dua = {
-    .purpose.size = htonl (sizeof (dua)),
-    .purpose.purpose = htonl (
-      TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
-    .timestamp = GNUNET_TIME_timestamp_hton (now),
-    .h_denom_pub = *dph,
-  };
-
-  /* strncpy would create a compiler warning */
-  memcpy (dua.operation,
-          oper,
-          GNUNET_MIN (sizeof (dua.operation),
-                      strlen (oper)));
-  ecr = TEH_keys_exchange_sign (&dua,
-                                &epub,
-                                &esig);
+
+  ecr = TALER_exchange_online_denomination_expired_sign (
+    &TEH_keys_exchange_sign_,
+    now,
+    dph,
+    oper,
+    &epub,
+    &esig);
   if (TALER_EC_NONE != ecr)
   {
     GNUNET_break (0);
@@ -523,18 +495,12 @@ TEH_RESPONSE_reply_invalid_denom_cipher_for_operation (
   enum TALER_ErrorCode ec;
 
   now = GNUNET_TIME_timestamp_get ();
-  {
-    struct TALER_DenominationUnknownAffirmationPS dua = {
-      .purpose.size = htonl (sizeof (dua)),
-      .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
-      .timestamp = GNUNET_TIME_timestamp_hton (now),
-      .h_denom_pub = *dph,
-    };
-
-    ec = TEH_keys_exchange_sign (&dua,
-                                 &epub,
-                                 &esig);
-  }
+  ec = TALER_exchange_online_denomination_unknown_sign (
+    &TEH_keys_exchange_sign_,
+    now,
+    dph,
+    &epub,
+    &esig);
   if (TALER_EC_NONE != ec)
   {
     GNUNET_break (0);
@@ -679,26 +645,19 @@ TEH_RESPONSE_compile_reserve_history (
         struct TALER_ExchangePublicKeyP pub;
         struct TALER_ExchangeSignatureP sig;
 
+        if (TALER_EC_NONE !=
+            TALER_exchange_online_confirm_recoup_sign (
+              &TEH_keys_exchange_sign_,
+              recoup->timestamp,
+              &recoup->value,
+              &recoup->coin.coin_pub,
+              &recoup->reserve_pub,
+              &pub,
+              &sig))
         {
-          struct TALER_RecoupConfirmationPS pc = {
-            .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
-            .purpose.size = htonl (sizeof (pc)),
-            .timestamp = GNUNET_TIME_timestamp_hton (recoup->timestamp),
-            .coin_pub = recoup->coin.coin_pub,
-            .reserve_pub = recoup->reserve_pub
-          };
-
-          TALER_amount_hton (&pc.recoup_amount,
-                             &recoup->value);
-          if (TALER_EC_NONE !=
-              TEH_keys_exchange_sign (&pc,
-                                      &pub,
-                                      &sig))
-          {
-            GNUNET_break (0);
-            json_decref (json_history);
-            return NULL;
-          }
+          GNUNET_break (0);
+          json_decref (json_history);
+          return NULL;
         }
 
         if (0 !=
@@ -731,30 +690,21 @@ TEH_RESPONSE_compile_reserve_history (
         struct TALER_ExchangePublicKeyP pub;
         struct TALER_ExchangeSignatureP sig;
 
+        if (TALER_EC_NONE !=
+            TALER_exchange_online_reserve_closed_sign (
+              &TEH_keys_exchange_sign_,
+              closing->execution_date,
+              &closing->amount,
+              &closing->closing_fee,
+              closing->receiver_account_details,
+              &closing->wtid,
+              &pos->details.closing->reserve_pub,
+              &pub,
+              &sig))
         {
-          struct TALER_ReserveCloseConfirmationPS rcc = {
-            .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED),
-            .purpose.size = htonl (sizeof (rcc)),
-            .timestamp = GNUNET_TIME_timestamp_hton (closing->execution_date),
-            .reserve_pub = pos->details.closing->reserve_pub,
-            .wtid = closing->wtid
-          };
-
-          TALER_amount_hton (&rcc.closing_amount,
-                             &closing->amount);
-          TALER_amount_hton (&rcc.closing_fee,
-                             &closing->closing_fee);
-          TALER_payto_hash (closing->receiver_account_details,
-                            &rcc.h_payto);
-          if (TALER_EC_NONE !=
-              TEH_keys_exchange_sign (&rcc,
-                                      &pub,
-                                      &sig))
-          {
-            GNUNET_break (0);
-            json_decref (json_history);
-            return NULL;
-          }
+          GNUNET_break (0);
+          json_decref (json_history);
+          return NULL;
         }
         if (0 !=
             json_array_append_new (
diff --git a/src/exchange/taler-exchange-httpd_transfers_get.c 
b/src/exchange/taler-exchange-httpd_transfers_get.c
index 3f87f370..0a994d8e 100644
--- a/src/exchange/taler-exchange-httpd_transfers_get.c
+++ b/src/exchange/taler-exchange-httpd_transfers_get.c
@@ -93,11 +93,11 @@ reply_transfer_details (struct MHD_Connection *connection,
                         const struct AggregatedDepositDetail *wdd_head)
 {
   json_t *deposits;
-  struct TALER_WireDepositDetailP dd;
   struct GNUNET_HashContext *hash_context;
-  struct TALER_WireDepositDataPS wdp;
+  struct GNUNET_HashCode h_details;
   struct TALER_ExchangePublicKeyP pub;
   struct TALER_ExchangeSignatureP sig;
+  struct TALER_PaytoHashP h_payto;
 
   deposits = json_array ();
   GNUNET_assert (NULL != deposits);
@@ -106,16 +106,12 @@ reply_transfer_details (struct MHD_Connection *connection,
        NULL != wdd_pos;
        wdd_pos = wdd_pos->next)
   {
-    dd.h_contract_terms = wdd_pos->h_contract_terms;
-    dd.execution_time = GNUNET_TIME_timestamp_hton (exec_time);
-    dd.coin_pub = wdd_pos->coin_pub;
-    TALER_amount_hton (&dd.deposit_value,
-                       &wdd_pos->deposit_value);
-    TALER_amount_hton (&dd.deposit_fee,
-                       &wdd_pos->deposit_fee);
-    GNUNET_CRYPTO_hash_context_read (hash_context,
-                                     &dd,
-                                     sizeof (struct TALER_WireDepositDetailP));
+    TALER_exchange_online_wire_deposit_append (hash_context,
+                                               &wdd_pos->h_contract_terms,
+                                               exec_time,
+                                               &wdd_pos->coin_pub,
+                                               &wdd_pos->deposit_value,
+                                               &wdd_pos->deposit_fee);
     if (0 !=
         json_array_append_new (
           deposits,
@@ -137,24 +133,21 @@ reply_transfer_details (struct MHD_Connection *connection,
                                          "json_array_append_new() failed");
     }
   }
-  wdp.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT);
-  wdp.purpose.size = htonl (sizeof (struct TALER_WireDepositDataPS));
-  TALER_amount_hton (&wdp.total,
-                     total);
-  TALER_amount_hton (&wdp.wire_fee,
-                     wire_fee);
-  wdp.merchant_pub = *merchant_pub;
-  TALER_payto_hash (payto_uri,
-                    &wdp.h_payto);
   GNUNET_CRYPTO_hash_context_finish (hash_context,
-                                     &wdp.h_details);
+                                     &h_details);
   {
     enum TALER_ErrorCode ec;
 
     if (TALER_EC_NONE !=
-        (ec = TEH_keys_exchange_sign (&wdp,
-                                      &pub,
-                                      &sig)))
+        (ec = TALER_exchange_online_wire_deposit_sign (
+           &TEH_keys_exchange_sign_,
+           total,
+           wire_fee,
+           merchant_pub,
+           payto_uri,
+           &h_details,
+           &pub,
+           &sig)))
     {
       json_decref (deposits);
       return TALER_MHD_reply_with_ec (connection,
@@ -163,6 +156,8 @@ reply_transfer_details (struct MHD_Connection *connection,
     }
   }
 
+  TALER_payto_hash (payto_uri,
+                    &h_payto);
   return TALER_MHD_REPLY_JSON_PACK (
     connection,
     MHD_HTTP_OK,
@@ -173,7 +168,7 @@ reply_transfer_details (struct MHD_Connection *connection,
     GNUNET_JSON_pack_data_auto ("merchant_pub",
                                 merchant_pub),
     GNUNET_JSON_pack_data_auto ("h_payto",
-                                &wdp.h_payto),
+                                &h_payto),
     GNUNET_JSON_pack_timestamp ("execution_time",
                                 exec_time),
     GNUNET_JSON_pack_array_steal ("deposits",
diff --git a/src/include/taler_crypto_lib.h b/src/include/taler_crypto_lib.h
index cc489e2c..9276ab14 100644
--- a/src/include/taler_crypto_lib.h
+++ b/src/include/taler_crypto_lib.h
@@ -1455,6 +1455,132 @@ struct TALER_ExchangeWithdrawValues
 };
 
 
+/**
+ * @brief Information about a signing key of the exchange.  Signing keys are 
used
+ * to sign exchange messages other than coins, i.e. to confirm that a
+ * deposit was successful or that a refresh was accepted.
+ *
+ * FIXME: remove this from the public API...
+ */
+struct TALER_ExchangeSigningKeyValidityPS
+{
+
+  /**
+   * Purpose is #TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY.
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * When does this signing key begin to be valid?
+   */
+  struct GNUNET_TIME_TimestampNBO start;
+
+  /**
+   * When does this signing key expire? Note: This is currently when
+   * the Exchange will definitively stop using it.  Signatures made with
+   * the key remain valid until @e end.  When checking validity periods,
+   * clients should allow for some overlap between keys and tolerate
+   * the use of either key during the overlap time (due to the
+   * possibility of clock skew).
+   */
+  struct GNUNET_TIME_TimestampNBO expire;
+
+  /**
+   * When do signatures with this signing key become invalid?  After
+   * this point, these signatures cannot be used in (legal) disputes
+   * anymore, as the Exchange is then allowed to destroy its side of the
+   * evidence.  @e end is expected to be significantly larger than @e
+   * expire (by a year or more).
+   */
+  struct GNUNET_TIME_TimestampNBO end;
+
+  /**
+   * The public online signing key that the exchange will use
+   * between @e start and @e expire.
+   */
+  struct TALER_ExchangePublicKeyP signkey_pub;
+};
+
+
+/**
+ * @brief Information about a denomination key. Denomination keys
+ * are used to sign coins of a certain value into existence.
+ *
+ * FIXME: remove this from the public API...
+ */
+struct TALER_DenominationKeyValidityPS
+{
+
+  /**
+   * Purpose is #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY.
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * The long-term offline master key of the exchange that was
+   * used to create @e signature.
+   */
+  struct TALER_MasterPublicKeyP master;
+
+  /**
+   * Start time of the validity period for this key.
+   */
+  struct GNUNET_TIME_TimestampNBO start;
+
+  /**
+   * The exchange will sign fresh coins between @e start and this time.
+   * @e expire_withdraw will be somewhat larger than @e start to
+   * ensure a sufficiently large anonymity set, while also allowing
+   * the Exchange to limit the financial damage in case of a key being
+   * compromised.  Thus, exchanges with low volume are expected to have a
+   * longer withdraw period (@e expire_withdraw - @e start) than exchanges
+   * with high transaction volume.  The period may also differ between
+   * types of coins.  A exchange may also have a few denomination keys
+   * with the same value with overlapping validity periods, to address
+   * issues such as clock skew.
+   */
+  struct GNUNET_TIME_TimestampNBO expire_withdraw;
+
+  /**
+   * Coins signed with the denomination key must be spent or refreshed
+   * between @e start and this expiration time.  After this time, the
+   * exchange will refuse transactions involving this key as it will
+   * "drop" the table with double-spending information (shortly after)
+   * this time.  Note that wallets should refresh coins significantly
+   * before this time to be on the safe side.  @e expire_deposit must be
+   * significantly larger than @e expire_withdraw (by months or even
+   * years).
+   */
+  struct GNUNET_TIME_TimestampNBO expire_deposit;
+
+  /**
+   * When do signatures with this denomination key become invalid?
+   * After this point, these signatures cannot be used in (legal)
+   * disputes anymore, as the Exchange is then allowed to destroy its side
+   * of the evidence.  @e expire_legal is expected to be significantly
+   * larger than @e expire_deposit (by a year or more).
+   */
+  struct GNUNET_TIME_TimestampNBO expire_legal;
+
+  /**
+   * The value of the coins signed with this denomination key.
+   */
+  struct TALER_AmountNBO value;
+
+  /**
+   * Fees for the coin.
+   */
+  struct TALER_DenomFeeSetNBOP fees;
+
+  /**
+   * Hash code of the denomination public key. (Used to avoid having
+   * the variable-size RSA key in this struct.)
+   */
+  struct TALER_DenominationHashP denom_hash GNUNET_PACKED;
+
+};
+
+
 /**
  * Free internals of @a denom_pub, but not @a denom_pub itself.
  *
@@ -2678,40 +2804,6 @@ TALER_CRYPTO_helper_esign_disconnect (
   struct TALER_CRYPTO_ExchangeSignHelper *esh);
 
 
-/* ********************* exchange signing ************************** */
-
-
-/**
- * Verify a deposit confirmation.
- *
- * @param h_contract_terms hash of the contact of the merchant with the 
customer (further details are never disclosed to the exchange)
- * @param h_wire hash of the merchant’s account details
- * @param h_extensions hash over the extensions, can be NULL
- * @param exchange_timestamp timestamp when the contract was finalized, must 
not be too far off
- * @param wire_deadline date until which the exchange should wire the funds
- * @param refund_deadline date until which the merchant can issue a refund to 
the customer via the exchange (can be zero if refunds are not allowed); must 
not be after the @a wire_deadline
- * @param amount_without_fee the amount to be deposited after fees
- * @param coin_pub public key of the deposited coin
- * @param merchant_pub the public key of the merchant (used to identify the 
merchant for refund requests)
- * @param exchange_pub exchange's online signing public key
- * @param exchange_sig the signature made with purpose 
#TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT
- * @return #GNUNET_OK if the signature is valid
- */
-enum GNUNET_GenericReturnValue
-TALER_exchange_deposit_confirm_verify (
-  const struct TALER_PrivateContractHashP *h_contract_terms,
-  const struct TALER_MerchantWireHashP *h_wire,
-  const struct TALER_ExtensionContractHashP *h_extensions,
-  struct GNUNET_TIME_Timestamp exchange_timestamp,
-  struct GNUNET_TIME_Timestamp wire_deadline,
-  struct GNUNET_TIME_Timestamp refund_deadline,
-  const struct TALER_Amount *amount_without_fee,
-  const struct TALER_CoinSpendPublicKeyP *coin_pub,
-  const struct TALER_MerchantPublicKeyP *merchant_pub,
-  const struct TALER_ExchangePublicKeyP *exchange_pub,
-  const struct TALER_ExchangeSignatureP *exchange_sig);
-
-
 /* ********************* wallet signing ************************** */
 
 
@@ -3333,6 +3425,518 @@ TALER_merchant_refund_verify (
   const struct TALER_MerchantSignatureP *merchant_sig);
 
 
+/* ********************* exchange online signing ************************** */
+
+
+/**
+ * Signature of a function that signs the message in @a purpose with the
+ * exchange's signing key.
+ *
+ * The @a purpose data is the beginning of the data of which the signature is
+ * to be created. The `size` field in @a purpose must correctly indicate the
+ * number of bytes of the data structure, including its header. *
+ * @param purpose the message to sign
+ * @param[out] pub set to the current public signing key of the exchange
+ * @param[out] sig signature over purpose using current signing key
+ * @return #TALER_EC_NONE on success
+ */
+typedef enum TALER_ErrorCode
+(*TALER_ExchangeSignCallback)(
+  const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Signature of a function that signs the message in @a purpose with the
+ * exchange's signing key.
+ *
+ * The @a purpose data is the beginning of the data of which the signature is
+ * to be created. The `size` field in @a purpose must correctly indicate the
+ * number of bytes of the data structure, including its header. *
+ * @param cls closure
+ * @param purpose the message to sign
+ * @param[out] pub set to the current public signing key of the exchange
+ * @param[out] sig signature over purpose using current signing key
+ * @return #TALER_EC_NONE on success
+ */
+typedef enum TALER_ErrorCode
+(*TALER_ExchangeSignCallback2)(
+  void *cls,
+  const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create deposit confirmation signature.
+ *
+ * @param scb function to call to create the signature
+ * @param h_contract_terms hash of the contact of the merchant with the 
customer (further details are never disclosed to the exchange)
+ * @param h_wire hash of the merchant’s account details
+ * @param h_extensions hash over the extensions, can be NULL
+ * @param exchange_timestamp timestamp when the contract was finalized, must 
not be too far off
+ * @param wire_deadline date until which the exchange should wire the funds
+ * @param refund_deadline date until which the merchant can issue a refund to 
the customer via the exchange (can be zero if refunds are not allowed); must 
not be after the @a wire_deadline
+ * @param amount_without_fee the amount to be deposited after fees
+ * @param coin_pub public key of the deposited coin
+ * @param merchant_pub the public key of the merchant (used to identify the 
merchant for refund requests)
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_deposit_confirmation_sign (
+  TALER_ExchangeSignCallback scb,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const struct TALER_MerchantWireHashP *h_wire,
+  const struct TALER_ExtensionContractHashP *h_extensions,
+  struct GNUNET_TIME_Timestamp exchange_timestamp,
+  struct GNUNET_TIME_Timestamp wire_deadline,
+  struct GNUNET_TIME_Timestamp refund_deadline,
+  const struct TALER_Amount *amount_without_fee,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_MerchantPublicKeyP *merchant_pub,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify deposit confirmation signature.
+ *
+ * @param h_contract_terms hash of the contact of the merchant with the 
customer (further details are never disclosed to the exchange)
+ * @param h_wire hash of the merchant’s account details
+ * @param h_extensions hash over the extensions, can be NULL
+ * @param exchange_timestamp timestamp when the contract was finalized, must 
not be too far off
+ * @param wire_deadline date until which the exchange should wire the funds
+ * @param refund_deadline date until which the merchant can issue a refund to 
the customer via the exchange (can be zero if refunds are not allowed); must 
not be after the @a wire_deadline
+ * @param amount_without_fee the amount to be deposited after fees
+ * @param coin_pub public key of the deposited coin
+ * @param merchant_pub the public key of the merchant (used to identify the 
merchant for refund requests)
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_deposit_confirmation_verify (
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const struct TALER_MerchantWireHashP *h_wire,
+  const struct TALER_ExtensionContractHashP *h_extensions,
+  struct GNUNET_TIME_Timestamp exchange_timestamp,
+  struct GNUNET_TIME_Timestamp wire_deadline,
+  struct GNUNET_TIME_Timestamp refund_deadline,
+  const struct TALER_Amount *amount_without_fee,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_MerchantPublicKeyP *merchant_pub,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create refund confirmation signature.
+ *
+ * @param scb function to call to create the signature
+ * @param XXX wire transfer subject used
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_refund_confirmation_sign (
+  TALER_ExchangeSignCallback scb,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_MerchantPublicKeyP *merchant,
+  uint64_t rtransaction_id,
+  const struct TALER_Amount *refund_amount,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify refund confirmation signature.
+ *
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_refund_confirmation_verify (
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_MerchantPublicKeyP *merchant,
+  uint64_t rtransaction_id,
+  const struct TALER_Amount *refund_amount,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create refresh melt confirmation signature.
+ *
+ * @param scb function to call to create the signature
+ * @param XXX
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_melt_confirmation_sign (
+  TALER_ExchangeSignCallback scb,
+  const struct TALER_RefreshCommitmentP *rc,
+  uint32_t noreveal_index,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify refresh melt confirmation signature.
+ *
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_melt_confirmation_verify (
+  const struct TALER_RefreshCommitmentP *rc,
+  uint32_t noreveal_index,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create exchange key set signature.
+ *
+ * @param scb function to call to create the signature
+ * @param timestamp time when the key set was issued
+ * @param hc hash over all the keys
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_key_set_sign (
+  TALER_ExchangeSignCallback2 scb,
+  void *cls,
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct GNUNET_HashCode *hc,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify key set signature.
+ *
+ * @param timestamp time when the key set was issued
+ * @param hc hash over all the keys
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_key_set_verify (
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct GNUNET_HashCode *hc,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create account setup success signature.
+ *
+ * @param scb function to call to create the signature
+ * @param h_payto target of the KYC account
+ * @param timestamp time when the KYC was confirmed
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_account_setup_success_sign (
+  TALER_ExchangeSignCallback scb,
+  const struct TALER_PaytoHashP *h_payto,
+  struct GNUNET_TIME_Timestamp timestamp,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify account setup success signature.
+ *
+ * @param h_payto target of the KYC account
+ * @param timestamp time when the KYC was confirmed
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_account_setup_success_verify (
+  const struct TALER_PaytoHashP *h_payto,
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig);
+
+
+void
+TALER_exchange_online_wire_deposit_append (
+  struct GNUNET_HashContext *hash_context,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  struct GNUNET_TIME_Timestamp execution_time,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_Amount *deposit_value,
+  const struct TALER_Amount *deposit_fee);
+
+
+/**
+ * Create wire deposit signature.
+ *
+ * @param scb function to call to create the signature
+ * @param XXX
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_wire_deposit_sign (
+  TALER_ExchangeSignCallback scb,
+  const struct TALER_Amount *total,
+  const struct TALER_Amount *wire_fee,
+  const struct TALER_MerchantPublicKeyP *merchant_pub,
+  const char *payto,
+  const struct GNUNET_HashCode *h_details,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify wire deposit signature.
+ *
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_wire_deposit_verify (
+  const struct TALER_Amount *total,
+  const struct TALER_Amount *wire_fee,
+  const struct TALER_MerchantPublicKeyP *merchant_pub,
+  const struct TALER_PaytoHashP *h_payto,
+  const struct GNUNET_HashCode *h_details,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create wire confirmation signature.
+ *
+ * @param scb function to call to create the signature
+ * @param XXX
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_confirm_wire_sign (
+  TALER_ExchangeSignCallback scb,
+  const struct TALER_MerchantWireHashP *h_wire,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const struct TALER_WireTransferIdentifierRawP *wtid,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  struct GNUNET_TIME_Timestamp execution_time,
+  const struct TALER_Amount *coin_contribution,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify confirm wire signature.
+ *
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_confirm_wire_verify (
+  const struct TALER_MerchantWireHashP *h_wire,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const struct TALER_WireTransferIdentifierRawP *wtid,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  struct GNUNET_TIME_Timestamp execution_time,
+  const struct TALER_Amount *coin_contribution,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create confirm recoup signature.
+ *
+ * @param scb function to call to create the signature
+ * @param XXX
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_confirm_recoup_sign (
+  TALER_ExchangeSignCallback scb,
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_Amount *recoup_amount,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_ReservePublicKeyP *reserve_pub,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify confirm recoup signature.
+ *
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_confirm_recoup_verify (
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_Amount *recoup_amount,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_ReservePublicKeyP *reserve_pub,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create confirm recoup refresh signature.
+ *
+ * @param scb function to call to create the signature
+ * @param XXX
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_confirm_recoup_refresh_sign (
+  TALER_ExchangeSignCallback scb,
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_Amount *recoup_amount,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify confirm recoup refresh signature.
+ *
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_confirm_recoup_refresh_verify (
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_Amount *recoup_amount,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create denomination unknown signature.
+ *
+ * @param scb function to call to create the signature
+ * @param XXX
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_denomination_unknown_sign (
+  TALER_ExchangeSignCallback scb,
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_DenominationHashP *h_denom_pub,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify denomination unknown signature.
+ *
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_denomination_unknown_verify (
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_DenominationHashP *h_denom_pub,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create denomination expired signature.
+ *
+ * @param scb function to call to create the signature
+ * @param XXX
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_denomination_expired_sign (
+  TALER_ExchangeSignCallback scb,
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_DenominationHashP *h_denom_pub,
+  const char *op,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify denomination expired signature.
+ *
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_denomination_expired_verify (
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_DenominationHashP *h_denom_pub,
+  const char *op,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Create reserve closure signature.
+ *
+ * @param scb function to call to create the signature
+ * @param timestamp time when the reserve was closed
+ * @param closing_amount amount left in the reserve
+ * @param closing_fee closing fee charged
+ * @param payto target of the wire transfer
+ * @param wtid wire transfer subject used
+ * @param reserve_pub public key of the closed reserve
+ * @param[out] pub where to write the public key
+ * @param[out] sig where to write the signature
+ */
+enum TALER_ErrorCode
+TALER_exchange_online_reserve_closed_sign (
+  TALER_ExchangeSignCallback scb,
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_Amount *closing_amount,
+  const struct TALER_Amount *closing_fee,
+  const char *payto,
+  const struct TALER_WireTransferIdentifierRawP *wtid,
+  const struct TALER_ReservePublicKeyP *reserve_pub,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig);
+
+
+/**
+ * Verify reserve closure signature.
+ *
+ * @param timestamp time when the reserve was closed
+ * @param closing_amount amount left in the reserve
+ * @param closing_fee closing fee charged
+ * @param payto target of the wire transfer
+ * @param wtid wire transfer subject used
+ * @param reserve_pub public key of the closed reserve
+ * @param pub where to write the public key
+ * @param sig where to write the signature
+ */
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_reserve_closed_verify (
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_Amount *closing_amount,
+  const struct TALER_Amount *closing_fee,
+  const char *payto,
+  const struct TALER_WireTransferIdentifierRawP *wtid,
+  const struct TALER_ReservePublicKeyP *reserve_pub,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig);
+
+
 /* ********************* offline signing ************************** */
 
 
diff --git a/src/include/taler_signatures.h b/src/include/taler_signatures.h
index 775947ac..52c294ce 100644
--- a/src/include/taler_signatures.h
+++ b/src/include/taler_signatures.h
@@ -369,467 +369,6 @@
 
 GNUNET_NETWORK_STRUCT_BEGIN
 
-/**
- * @brief format used by the denomination crypto helper when affirming
- *        that it created a denomination key.
- */
-struct TALER_DenominationKeyAnnouncementPS
-{
-
-  /**
-   * Purpose must be #TALER_SIGNATURE_SM_RSA_DENOMINATION_KEY.
-   * Used with an EdDSA signature of a `struct TALER_SecurityModulePublicKeyP`.
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * Hash of the denomination public key.
-   */
-  struct TALER_DenominationHashP h_denom;
-
-  /**
-   * Hash of the section name in the configuration of this denomination.
-   */
-  struct GNUNET_HashCode h_section_name;
-
-  /**
-   * When does the key become available?
-   */
-  struct GNUNET_TIME_TimestampNBO anchor_time;
-
-  /**
-   * How long is the key available after @e anchor_time?
-   */
-  struct GNUNET_TIME_RelativeNBO duration_withdraw;
-
-};
-
-
-/**
- * @brief format used by the signing crypto helper when affirming
- *        that it created an exchange signing key.
- */
-struct TALER_SigningKeyAnnouncementPS
-{
-
-  /**
-   * Purpose must be #TALER_SIGNATURE_SM_SIGNING_KEY.
-   * Used with an EdDSA signature of a `struct TALER_SecurityModulePublicKeyP`.
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * Public signing key of the exchange this is about.
-   */
-  struct TALER_ExchangePublicKeyP exchange_pub;
-
-  /**
-   * When does the key become available?
-   */
-  struct GNUNET_TIME_TimestampNBO anchor_time;
-
-  /**
-   * How long is the key available after @e anchor_time?
-   */
-  struct GNUNET_TIME_RelativeNBO duration;
-
-};
-
-
-/**
- * @brief Format used to generate the signature on a confirmation
- * from the exchange that a deposit request succeeded.
- */
-struct TALER_DepositConfirmationPS
-{
-  /**
-   * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT.  Signed
-   * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * Hash over the contract for which this deposit is made.
-   */
-  struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
-
-  /**
-   * Hash over the wiring information of the merchant.
-   */
-  struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
-
-  /**
-   * Hash over the extension options of the deposit, 0 if there
-   * were not extension options.
-   */
-  struct TALER_ExtensionContractHashP h_extensions GNUNET_PACKED;
-
-  /**
-   * Time when this confirmation was generated / when the exchange received
-   * the deposit request.
-   */
-  struct GNUNET_TIME_TimestampNBO exchange_timestamp;
-
-  /**
-   * By when does the exchange expect to pay the merchant
-   * (as per the merchant's request).
-   */
-  struct GNUNET_TIME_TimestampNBO wire_deadline;
-
-  /**
-   * How much time does the @e merchant have to issue a refund
-   * request?  Zero if refunds are not allowed.  After this time, the
-   * coin cannot be refunded.  Note that the wire transfer will not be
-   * performed by the exchange until the refund deadline.  This value
-   * is taken from the original deposit request.
-   */
-  struct GNUNET_TIME_TimestampNBO refund_deadline;
-
-  /**
-   * Amount to be deposited, excluding fee.  Calculated from the
-   * amount with fee and the fee from the deposit request.
-   */
-  struct TALER_AmountNBO amount_without_fee;
-
-  /**
-   * The public key of the coin that was deposited.
-   */
-  struct TALER_CoinSpendPublicKeyP coin_pub;
-
-  /**
-   * The Merchant's public key.  Allows the merchant to later refund
-   * the transaction or to inquire about the wire transfer identifier.
-   */
-  struct TALER_MerchantPublicKeyP merchant_pub;
-
-};
-
-
-/**
- * @brief Format used to generate the signature on a request to refund
- * a coin into the account of the customer.
- */
-struct TALER_RefundConfirmationPS
-{
-  /**
-   * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND.
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * Hash over the proposal data to identify the contract
-   * which is being refunded.
-   */
-  struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
-
-  /**
-   * The coin's public key.  This is the value that must have been
-   * signed (blindly) by the Exchange.
-   */
-  struct TALER_CoinSpendPublicKeyP coin_pub;
-
-  /**
-   * The Merchant's public key.  Allows the merchant to later refund
-   * the transaction or to inquire about the wire transfer identifier.
-   */
-  struct TALER_MerchantPublicKeyP merchant;
-
-  /**
-   * Merchant-generated transaction ID for the refund.
-   */
-  uint64_t rtransaction_id GNUNET_PACKED;
-
-  /**
-   * Amount to be refunded, including refund fee charged by the
-   * exchange to the customer.
-   */
-  struct TALER_AmountNBO refund_amount;
-};
-
-
-/**
- * @brief Format of the block signed by the Exchange in response to a 
successful
- * "/refresh/melt" request.  Hereby the exchange affirms that all of the
- * coins were successfully melted.  This also commits the exchange to a
- * particular index to not be revealed during the refresh.
- */
-struct TALER_RefreshMeltConfirmationPS
-{
-  /**
-   * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT.   Signed
-   * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * Commitment made in the /refresh/melt.
-   */
-  struct TALER_RefreshCommitmentP rc GNUNET_PACKED;
-
-  /**
-   * Index that the client will not have to reveal, in NBO.
-   * Must be smaller than #TALER_CNC_KAPPA.
-   */
-  uint32_t noreveal_index GNUNET_PACKED;
-
-};
-
-
-/**
- * @brief Signature made by the exchange over the full set of keys, used
- * to detect cheating exchanges that give out different sets to
- * different users.
- */
-struct TALER_ExchangeKeySetPS
-{
-
-  /**
-   * Purpose is #TALER_SIGNATURE_EXCHANGE_KEY_SET.   Signed
-   * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * Time of the key set issue.
-   */
-  struct GNUNET_TIME_TimestampNBO list_issue_date;
-
-  /**
-   * Hash over the various denomination signing keys returned.
-   */
-  struct GNUNET_HashCode hc GNUNET_PACKED;
-};
-
-
-/**
- * @brief Signature by which an exchange affirms that an account
- * successfully passed the KYC checks.
- */
-struct TALER_ExchangeAccountSetupSuccessPS
-{
-  /**
-   * Purpose is #TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS.  Signed by a
-   * `struct TALER_ExchangePublicKeyP` using EdDSA.
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * Hash over the payto for which the signature was
-   * made.
-   */
-  struct TALER_PaytoHashP h_payto;
-
-  /**
-   * When was the signature made.
-   */
-  struct GNUNET_TIME_TimestampNBO timestamp;
-};
-
-
-/**
- * @brief Information about a signing key of the exchange.  Signing keys are 
used
- * to sign exchange messages other than coins, i.e. to confirm that a
- * deposit was successful or that a refresh was accepted.
- */
-struct TALER_ExchangeSigningKeyValidityPS
-{
-
-  /**
-   * Purpose is #TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY.
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * When does this signing key begin to be valid?
-   */
-  struct GNUNET_TIME_TimestampNBO start;
-
-  /**
-   * When does this signing key expire? Note: This is currently when
-   * the Exchange will definitively stop using it.  Signatures made with
-   * the key remain valid until @e end.  When checking validity periods,
-   * clients should allow for some overlap between keys and tolerate
-   * the use of either key during the overlap time (due to the
-   * possibility of clock skew).
-   */
-  struct GNUNET_TIME_TimestampNBO expire;
-
-  /**
-   * When do signatures with this signing key become invalid?  After
-   * this point, these signatures cannot be used in (legal) disputes
-   * anymore, as the Exchange is then allowed to destroy its side of the
-   * evidence.  @e end is expected to be significantly larger than @e
-   * expire (by a year or more).
-   */
-  struct GNUNET_TIME_TimestampNBO end;
-
-  /**
-   * The public online signing key that the exchange will use
-   * between @e start and @e expire.
-   */
-  struct TALER_ExchangePublicKeyP signkey_pub;
-};
-
-
-/**
- * @brief Information about a denomination key. Denomination keys
- * are used to sign coins of a certain value into existence.
- */
-struct TALER_DenominationKeyValidityPS
-{
-
-  /**
-   * Purpose is #TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY.
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * The long-term offline master key of the exchange that was
-   * used to create @e signature.
-   */
-  struct TALER_MasterPublicKeyP master;
-
-  /**
-   * Start time of the validity period for this key.
-   */
-  struct GNUNET_TIME_TimestampNBO start;
-
-  /**
-   * The exchange will sign fresh coins between @e start and this time.
-   * @e expire_withdraw will be somewhat larger than @e start to
-   * ensure a sufficiently large anonymity set, while also allowing
-   * the Exchange to limit the financial damage in case of a key being
-   * compromised.  Thus, exchanges with low volume are expected to have a
-   * longer withdraw period (@e expire_withdraw - @e start) than exchanges
-   * with high transaction volume.  The period may also differ between
-   * types of coins.  A exchange may also have a few denomination keys
-   * with the same value with overlapping validity periods, to address
-   * issues such as clock skew.
-   */
-  struct GNUNET_TIME_TimestampNBO expire_withdraw;
-
-  /**
-   * Coins signed with the denomination key must be spent or refreshed
-   * between @e start and this expiration time.  After this time, the
-   * exchange will refuse transactions involving this key as it will
-   * "drop" the table with double-spending information (shortly after)
-   * this time.  Note that wallets should refresh coins significantly
-   * before this time to be on the safe side.  @e expire_deposit must be
-   * significantly larger than @e expire_withdraw (by months or even
-   * years).
-   */
-  struct GNUNET_TIME_TimestampNBO expire_deposit;
-
-  /**
-   * When do signatures with this denomination key become invalid?
-   * After this point, these signatures cannot be used in (legal)
-   * disputes anymore, as the Exchange is then allowed to destroy its side
-   * of the evidence.  @e expire_legal is expected to be significantly
-   * larger than @e expire_deposit (by a year or more).
-   */
-  struct GNUNET_TIME_TimestampNBO expire_legal;
-
-  /**
-   * The value of the coins signed with this denomination key.
-   */
-  struct TALER_AmountNBO value;
-
-  /**
-   * Fees for the coin.
-   */
-  struct TALER_DenomFeeSetNBOP fees;
-
-  /**
-   * Hash code of the denomination public key. (Used to avoid having
-   * the variable-size RSA key in this struct.)
-   */
-  struct TALER_DenominationHashP denom_hash GNUNET_PACKED;
-
-};
-
-
-/**
- * @brief Information signed by an auditor affirming
- * the master public key and the denomination keys
- * of a exchange.
- */
-struct TALER_ExchangeKeyValidityPS
-{
-
-  /**
-   * Purpose is #TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS.
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * Hash of the auditor's URL (including 0-terminator).
-   */
-  struct GNUNET_HashCode auditor_url_hash;
-
-  /**
-   * The long-term offline master key of the exchange, affirmed by the
-   * auditor.
-   */
-  struct TALER_MasterPublicKeyP master;
-
-  /**
-   * Start time of the validity period for this key.
-   */
-  struct GNUNET_TIME_TimestampNBO start;
-
-  /**
-   * The exchange will sign fresh coins between @e start and this time.
-   * @e expire_withdraw will be somewhat larger than @e start to
-   * ensure a sufficiently large anonymity set, while also allowing
-   * the Exchange to limit the financial damage in case of a key being
-   * compromised.  Thus, exchanges with low volume are expected to have a
-   * longer withdraw period (@e expire_withdraw - @e start) than exchanges
-   * with high transaction volume.  The period may also differ between
-   * types of coins.  A exchange may also have a few denomination keys
-   * with the same value with overlapping validity periods, to address
-   * issues such as clock skew.
-   */
-  struct GNUNET_TIME_TimestampNBO expire_withdraw;
-
-  /**
-   * Coins signed with the denomination key must be spent or refreshed
-   * between @e start and this expiration time.  After this time, the
-   * exchange will refuse transactions involving this key as it will
-   * "drop" the table with double-spending information (shortly after)
-   * this time.  Note that wallets should refresh coins significantly
-   * before this time to be on the safe side.  @e expire_deposit must be
-   * significantly larger than @e expire_withdraw (by months or even
-   * years).
-   */
-  struct GNUNET_TIME_TimestampNBO expire_deposit;
-
-  /**
-   * When do signatures with this denomination key become invalid?
-   * After this point, these signatures cannot be used in (legal)
-   * disputes anymore, as the Exchange is then allowed to destroy its side
-   * of the evidence.  @e expire_legal is expected to be significantly
-   * larger than @e expire_deposit (by a year or more).
-   */
-  struct GNUNET_TIME_TimestampNBO expire_legal;
-
-  /**
-   * The value of the coins signed with this denomination key.
-   */
-  struct TALER_AmountNBO value;
-
-  /**
-   * Fees for the coin.
-   */
-  struct TALER_DenomFeeSetNBOP fees;
-
-  /**
-   * Hash code of the denomination public key. (Used to avoid having
-   * the variable-size RSA key in this struct.)
-   */
-  struct TALER_DenominationHashP denom_hash GNUNET_PACKED;
-
-};
-
 
 /**
  * @brief Format used to generate the signature on a request to obtain
@@ -867,81 +406,6 @@ struct TALER_DepositTrackPS
 };
 
 
-/**
- * @brief Format internally used for packing the detailed information
- * to generate the signature for /track/transfer signatures.
- */
-struct TALER_WireDepositDetailP
-{
-
-  /**
-   * Hash of the contract
-   */
-  struct TALER_PrivateContractHashP h_contract_terms;
-
-  /**
-   * Time when the wire transfer was performed by the exchange.
-   */
-  struct GNUNET_TIME_TimestampNBO execution_time;
-
-  /**
-   * Coin's public key.
-   */
-  struct TALER_CoinSpendPublicKeyP coin_pub;
-
-  /**
-   * Total value of the coin.
-   */
-  struct TALER_AmountNBO deposit_value;
-
-  /**
-   * Fees charged by the exchange for the deposit.
-   */
-  struct TALER_AmountNBO deposit_fee;
-
-};
-
-
-/**
- * @brief Format used to generate the signature for /wire/deposit
- * replies.
- */
-struct TALER_WireDepositDataPS
-{
-  /**
-   * Purpose header for the signature over the contract with
-   * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT.
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * Total amount that was transferred.
-   */
-  struct TALER_AmountNBO total;
-
-  /**
-   * Wire fee that was charged.
-   */
-  struct TALER_AmountNBO wire_fee;
-
-  /**
-   * Public key of the merchant (for all aggregated transactions).
-   */
-  struct TALER_MerchantPublicKeyP merchant_pub;
-
-  /**
-   * Hash of bank account of the merchant.
-   */
-  struct TALER_PaytoHashP h_payto;
-
-  /**
-   * Hash of the individual deposits that were aggregated,
-   * each in the format of a `struct TALER_WireDepositDetailP`.
-   */
-  struct GNUNET_HashCode h_details;
-
-};
-
 /**
  * The contract sent by the merchant to the wallet.
  */
@@ -979,231 +443,6 @@ struct TALER_PaymentResponsePS
 };
 
 
-/**
- * Details affirmed by the exchange about a wire transfer the exchange
- * claims to have done with respect to a deposit operation.
- */
-struct TALER_ConfirmWirePS
-{
-  /**
-   * Purpose header for the signature over the contract with
-   * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE.
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * Hash over the wiring information of the merchant.
-   */
-  struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
-
-  /**
-   * Hash over the contract for which this deposit is made.
-   */
-  struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
-
-  /**
-   * Raw value (binary encoding) of the wire transfer subject.
-   */
-  struct TALER_WireTransferIdentifierRawP wtid;
-
-  /**
-   * The coin's public key.  This is the value that must have been
-   * signed (blindly) by the Exchange.
-   */
-  struct TALER_CoinSpendPublicKeyP coin_pub;
-
-  /**
-   * When did the exchange execute this transfer? Note that the
-   * timestamp may not be exactly the same on the wire, i.e.
-   * because the wire has a different timezone or resolution.
-   */
-  struct GNUNET_TIME_TimestampNBO execution_time;
-
-  /**
-   * The contribution of @e coin_pub to the total transfer volume.
-   * This is the value of the deposit minus the fee.
-   */
-  struct TALER_AmountNBO coin_contribution;
-
-};
-
-
-/**
- * Response by which the exchange affirms that it will
- * refund a coin as part of the emergency /recoup
- * protocol.  The recoup will go back to the bank
- * account that created the reserve.
- */
-struct TALER_RecoupConfirmationPS
-{
-
-  /**
-   * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * When did the exchange receive the recoup request?
-   * Indirectly determines when the wire transfer is (likely)
-   * to happen.
-   */
-  struct GNUNET_TIME_TimestampNBO timestamp;
-
-  /**
-   * How much of the coin's value will the exchange transfer?
-   * (Needed in case the coin was partially spent.)
-   */
-  struct TALER_AmountNBO recoup_amount;
-
-  /**
-   * Public key of the coin.
-   */
-  struct TALER_CoinSpendPublicKeyP coin_pub;
-
-  /**
-   * Public key of the reserve that will receive the recoup.
-   */
-  struct TALER_ReservePublicKeyP reserve_pub;
-};
-
-
-/**
- * Response by which the exchange affirms that it will refund a refreshed coin
- * as part of the emergency /recoup protocol.  The recoup will go back to the
- * old coin's balance.
- */
-struct TALER_RecoupRefreshConfirmationPS
-{
-
-  /**
-   * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * When did the exchange receive the recoup request?
-   * Indirectly determines when the wire transfer is (likely)
-   * to happen.
-   */
-  struct GNUNET_TIME_TimestampNBO timestamp;
-
-  /**
-   * How much of the coin's value will the exchange transfer?
-   * (Needed in case the coin was partially spent.)
-   */
-  struct TALER_AmountNBO recoup_amount;
-
-  /**
-   * Public key of the refreshed coin.
-   */
-  struct TALER_CoinSpendPublicKeyP coin_pub;
-
-  /**
-   * Public key of the old coin that will receive the recoup.
-   */
-  struct TALER_CoinSpendPublicKeyP old_coin_pub;
-};
-
-
-/**
- * Response by which the exchange affirms that it does not
- * currently know a denomination by the given hash.
- */
-struct TALER_DenominationUnknownAffirmationPS
-{
-
-  /**
-   * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * When did the exchange sign this message.
-   */
-  struct GNUNET_TIME_TimestampNBO timestamp;
-
-  /**
-   * Hash of the public denomination key we do not know.
-   */
-  struct TALER_DenominationHashP h_denom_pub;
-};
-
-
-/**
- * Response by which the exchange affirms that it does not
- * currently consider the given denomination to be valid
- * for the requested operation.
- */
-struct TALER_DenominationExpiredAffirmationPS
-{
-
-  /**
-   * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * When did the exchange sign this message.
-   */
-  struct GNUNET_TIME_TimestampNBO timestamp;
-
-  /**
-   * Name of the operation that is not allowed at this time.  Might NOT be 
0-terminated, but is padded with 0s.
-   */
-  char operation[8];
-
-  /**
-   * Hash of the public denomination key we do not know.
-   */
-  struct TALER_DenominationHashP h_denom_pub;
-
-};
-
-
-/**
- * Response by which the exchange affirms that it has
- * closed a reserve and send back the funds.
- */
-struct TALER_ReserveCloseConfirmationPS
-{
-
-  /**
-   * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED
-   */
-  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
-
-  /**
-   * When did the exchange initiate the wire transfer.
-   */
-  struct GNUNET_TIME_TimestampNBO timestamp;
-
-  /**
-   * How much did the exchange send?
-   */
-  struct TALER_AmountNBO closing_amount;
-
-  /**
-   * How much did the exchange charge for closing the reserve?
-   */
-  struct TALER_AmountNBO closing_fee;
-
-  /**
-   * Public key of the reserve that received the recoup.
-   */
-  struct TALER_ReservePublicKeyP reserve_pub;
-
-  /**
-   * Hash of the receiver's bank account.
-   */
-  struct TALER_PaytoHashP h_payto;
-
-  /**
-   * Wire transfer subject.
-   */
-  struct TALER_WireTransferIdentifierRawP wtid;
-};
-
-
 GNUNET_NETWORK_STRUCT_END
 
 #endif
diff --git a/src/lib/auditor_api_deposit_confirmation.c 
b/src/lib/auditor_api_deposit_confirmation.c
index 2c5bd2b4..be981eb9 100644
--- a/src/lib/auditor_api_deposit_confirmation.c
+++ b/src/lib/auditor_api_deposit_confirmation.c
@@ -188,17 +188,18 @@ verify_signatures (const struct TALER_MerchantWireHashP 
*h_wire,
                    const struct TALER_MasterSignatureP *master_sig)
 {
   if (GNUNET_OK !=
-      TALER_exchange_deposit_confirm_verify (h_contract_terms,
-                                             h_wire,
-                                             h_extensions,
-                                             exchange_timestamp,
-                                             wire_deadline,
-                                             refund_deadline,
-                                             amount_without_fee,
-                                             coin_pub,
-                                             merchant_pub,
-                                             exchange_pub,
-                                             exchange_sig))
+      TALER_exchange_online_deposit_confirmation_verify (
+        h_contract_terms,
+        h_wire,
+        h_extensions,
+        exchange_timestamp,
+        wire_deadline,
+        refund_deadline,
+        amount_without_fee,
+        coin_pub,
+        merchant_pub,
+        exchange_pub,
+        exchange_sig))
   {
     GNUNET_break_op (0);
     TALER_LOG_WARNING (
diff --git a/src/lib/exchange_api_common.c b/src/lib/exchange_api_common.c
index 1da36fe8..df1c43e4 100644
--- a/src/lib/exchange_api_common.c
+++ b/src/lib/exchange_api_common.c
@@ -219,18 +219,16 @@ TALER_EXCHANGE_parse_reserve_history (
     else if (0 == strcasecmp (type,
                               "RECOUP"))
     {
-      struct TALER_RecoupConfirmationPS pc;
-      struct GNUNET_TIME_Timestamp timestamp;
       const struct TALER_EXCHANGE_Keys *key_state;
       struct GNUNET_JSON_Specification recoup_spec[] = {
         GNUNET_JSON_spec_fixed_auto ("coin_pub",
-                                     &pc.coin_pub),
+                                     &rh->details.recoup_details.coin_pub),
         GNUNET_JSON_spec_fixed_auto ("exchange_sig",
                                      &rh->details.recoup_details.exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
                                      &rh->details.recoup_details.exchange_pub),
-        GNUNET_JSON_spec_timestamp_nbo ("timestamp",
-                                        &pc.timestamp),
+        GNUNET_JSON_spec_timestamp ("timestamp",
+                                    &rh->details.recoup_details.timestamp),
         GNUNET_JSON_spec_end ()
       };
 
@@ -244,15 +242,6 @@ TALER_EXCHANGE_parse_reserve_history (
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      rh->details.recoup_details.coin_pub = pc.coin_pub;
-      TALER_amount_hton (&pc.recoup_amount,
-                         &amount);
-      pc.purpose.size = htonl (sizeof (pc));
-      pc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP);
-      pc.reserve_pub = *reserve_pub;
-      timestamp = GNUNET_TIME_timestamp_ntoh (pc.timestamp);
-      rh->details.recoup_details.timestamp = timestamp;
-
       key_state = TALER_EXCHANGE_get_keys (exchange);
       if (GNUNET_OK !=
           TALER_EXCHANGE_test_signing_key (key_state,
@@ -263,11 +252,13 @@ TALER_EXCHANGE_parse_reserve_history (
         return GNUNET_SYSERR;
       }
       if (GNUNET_OK !=
-          GNUNET_CRYPTO_eddsa_verify (
-            TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP,
-            &pc,
-            &rh->details.recoup_details.exchange_sig.eddsa_signature,
-            &rh->details.recoup_details.exchange_pub.eddsa_pub))
+          TALER_exchange_online_confirm_recoup_verify (
+            rh->details.recoup_details.timestamp,
+            &amount,
+            &rh->details.recoup_details.coin_pub,
+            reserve_pub,
+            &rh->details.recoup_details.exchange_pub,
+            &rh->details.recoup_details.exchange_sig))
       {
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
@@ -287,8 +278,6 @@ TALER_EXCHANGE_parse_reserve_history (
                               "CLOSING"))
     {
       const struct TALER_EXCHANGE_Keys *key_state;
-      struct TALER_ReserveCloseConfirmationPS rcc;
-      struct GNUNET_TIME_Timestamp timestamp;
       struct GNUNET_JSON_Specification closing_spec[] = {
         GNUNET_JSON_spec_string (
           "receiver_account_details",
@@ -299,10 +288,10 @@ TALER_EXCHANGE_parse_reserve_history (
                                      &rh->details.close_details.exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
                                      &rh->details.close_details.exchange_pub),
-        TALER_JSON_spec_amount_any_nbo ("closing_fee",
-                                        &rcc.closing_fee),
-        GNUNET_JSON_spec_timestamp_nbo ("timestamp",
-                                        &rcc.timestamp),
+        TALER_JSON_spec_amount_any ("closing_fee",
+                                    &rh->details.close_details.fee),
+        GNUNET_JSON_spec_timestamp ("timestamp",
+                                    &rh->details.close_details.timestamp),
         GNUNET_JSON_spec_end ()
       };
 
@@ -316,33 +305,26 @@ TALER_EXCHANGE_parse_reserve_history (
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      TALER_amount_hton (&rcc.closing_amount,
-                         &amount);
-      TALER_payto_hash (rh->details.close_details.receiver_account_details,
-                        &rcc.h_payto);
-      rcc.wtid = rh->details.close_details.wtid;
-      rcc.purpose.size = htonl (sizeof (rcc));
-      rcc.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED);
-      rcc.reserve_pub = *reserve_pub;
-      timestamp = GNUNET_TIME_timestamp_ntoh (rcc.timestamp);
-      rh->details.close_details.timestamp = timestamp;
-      TALER_amount_ntoh (&rh->details.close_details.fee,
-                         &rcc.closing_fee);
+
       key_state = TALER_EXCHANGE_get_keys (exchange);
       if (GNUNET_OK !=
-          TALER_EXCHANGE_test_signing_key (key_state,
-                                           &rh->details.close_details.
-                                           exchange_pub))
+          TALER_EXCHANGE_test_signing_key (
+            key_state,
+            &rh->details.close_details.exchange_pub))
       {
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
       if (GNUNET_OK !=
-          GNUNET_CRYPTO_eddsa_verify (
-            TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED,
-            &rcc,
-            &rh->details.close_details.exchange_sig.eddsa_signature,
-            &rh->details.close_details.exchange_pub.eddsa_pub))
+          TALER_exchange_online_reserve_closed_verify (
+            rh->details.close_details.timestamp,
+            &amount,
+            &rh->details.close_details.fee,
+            rh->details.close_details.receiver_account_details,
+            &rh->details.close_details.wtid,
+            reserve_pub,
+            &rh->details.close_details.exchange_pub,
+            &rh->details.close_details.exchange_sig))
       {
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
@@ -671,35 +653,29 @@ TALER_EXCHANGE_verify_coin_history (
     else if (0 == strcasecmp (type,
                               "RECOUP"))
     {
-      struct TALER_RecoupConfirmationPS pc = {
-        .purpose.size = htonl (sizeof (pc)),
-        .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
-        .coin_pub = *coin_pub
-      };
+      struct TALER_ReservePublicKeyP reserve_pub;
+      struct GNUNET_TIME_Timestamp timestamp;
       union TALER_DenominationBlindingKeyP coin_bks;
-      struct TALER_Amount recoup_amount;
       struct TALER_ExchangePublicKeyP exchange_pub;
       struct TALER_ExchangeSignatureP exchange_sig;
       struct TALER_CoinSpendSignatureP coin_sig;
       struct GNUNET_JSON_Specification spec[] = {
-        TALER_JSON_spec_amount_any_nbo ("amount",
-                                        &pc.recoup_amount),
         TALER_JSON_spec_amount_any ("amount",
-                                    &recoup_amount),
+                                    &amount),
         GNUNET_JSON_spec_fixed_auto ("exchange_sig",
                                      &exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
                                      &exchange_pub),
         GNUNET_JSON_spec_fixed_auto ("reserve_pub",
-                                     &pc.reserve_pub),
+                                     &reserve_pub),
         GNUNET_JSON_spec_fixed_auto ("coin_sig",
                                      &coin_sig),
         GNUNET_JSON_spec_fixed_auto ("coin_blind",
                                      &coin_bks),
         GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
                                      h_denom_pub),
-        GNUNET_JSON_spec_timestamp_nbo ("timestamp",
-                                        &pc.timestamp),
+        GNUNET_JSON_spec_timestamp ("timestamp",
+                                    &timestamp),
         GNUNET_JSON_spec_end ()
       };
 
@@ -711,13 +687,14 @@ TALER_EXCHANGE_verify_coin_history (
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      TALER_amount_hton (&pc.recoup_amount,
-                         &amount);
       if (GNUNET_OK !=
-          GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP,
-                                      &pc,
-                                      &exchange_sig.eddsa_signature,
-                                      &exchange_pub.eddsa_pub))
+          TALER_exchange_online_confirm_recoup_verify (
+            timestamp,
+            &amount,
+            coin_pub,
+            &reserve_pub,
+            &exchange_pub,
+            &exchange_sig))
       {
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
@@ -738,22 +715,16 @@ TALER_EXCHANGE_verify_coin_history (
     {
       /* This is the coin that was subjected to a recoup,
          the value being credited to the old coin. */
-      struct TALER_RecoupRefreshConfirmationPS pc = {
-        .purpose.size = htonl (sizeof (pc)),
-        .purpose.purpose = htonl (
-          TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
-        .coin_pub = *coin_pub
-      };
+      struct TALER_CoinSpendPublicKeyP old_coin_pub;
       union TALER_DenominationBlindingKeyP coin_bks;
-      struct TALER_Amount recoup_amount;
+      struct TALER_Amount amount;
+      struct GNUNET_TIME_Timestamp timestamp;
       struct TALER_ExchangePublicKeyP exchange_pub;
       struct TALER_ExchangeSignatureP exchange_sig;
       struct TALER_CoinSpendSignatureP coin_sig;
       struct GNUNET_JSON_Specification spec[] = {
-        TALER_JSON_spec_amount_any_nbo ("amount",
-                                        &pc.recoup_amount),
         TALER_JSON_spec_amount_any ("amount",
-                                    &recoup_amount),
+                                    &amount),
         GNUNET_JSON_spec_fixed_auto ("exchange_sig",
                                      &exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
@@ -761,13 +732,13 @@ TALER_EXCHANGE_verify_coin_history (
         GNUNET_JSON_spec_fixed_auto ("coin_sig",
                                      &coin_sig),
         GNUNET_JSON_spec_fixed_auto ("old_coin_pub",
-                                     &pc.old_coin_pub),
+                                     &old_coin_pub),
         GNUNET_JSON_spec_fixed_auto ("coin_blind",
                                      &coin_bks),
         GNUNET_JSON_spec_fixed_auto ("h_denom_pub",
                                      h_denom_pub),
-        GNUNET_JSON_spec_timestamp_nbo ("timestamp",
-                                        &pc.timestamp),
+        GNUNET_JSON_spec_timestamp ("timestamp",
+                                    &timestamp),
         GNUNET_JSON_spec_end ()
       };
 
@@ -779,14 +750,14 @@ TALER_EXCHANGE_verify_coin_history (
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      TALER_amount_hton (&pc.recoup_amount,
-                         &amount);
       if (GNUNET_OK !=
-          GNUNET_CRYPTO_eddsa_verify (
-            TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH,
-            &pc,
-            &exchange_sig.eddsa_signature,
-            &exchange_pub.eddsa_pub))
+          TALER_exchange_online_confirm_recoup_refresh_verify (
+            timestamp,
+            &amount,
+            coin_pub,
+            &old_coin_pub,
+            &exchange_pub,
+            &exchange_sig))
       {
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
@@ -807,25 +778,21 @@ TALER_EXCHANGE_verify_coin_history (
     {
       /* This is the coin that was credited in a recoup,
          the value being credited to the this coin. */
-      struct TALER_RecoupRefreshConfirmationPS pc = {
-        .purpose.size = htonl (sizeof (pc)),
-        .purpose.purpose = htonl (
-          TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
-        .old_coin_pub = *coin_pub
-      };
       struct TALER_ExchangePublicKeyP exchange_pub;
       struct TALER_ExchangeSignatureP exchange_sig;
+      struct TALER_CoinSpendPublicKeyP new_coin_pub;
+      struct GNUNET_TIME_Timestamp timestamp;
       struct GNUNET_JSON_Specification spec[] = {
-        TALER_JSON_spec_amount_any_nbo ("amount",
-                                        &pc.recoup_amount),
+        TALER_JSON_spec_amount_any ("amount",
+                                    &amount),
         GNUNET_JSON_spec_fixed_auto ("exchange_sig",
                                      &exchange_sig),
         GNUNET_JSON_spec_fixed_auto ("exchange_pub",
                                      &exchange_pub),
         GNUNET_JSON_spec_fixed_auto ("coin_pub",
-                                     &pc.coin_pub),
-        GNUNET_JSON_spec_timestamp_nbo ("timestamp",
-                                        &pc.timestamp),
+                                     &new_coin_pub),
+        GNUNET_JSON_spec_timestamp ("timestamp",
+                                    &timestamp),
         GNUNET_JSON_spec_end ()
       };
 
@@ -837,14 +804,14 @@ TALER_EXCHANGE_verify_coin_history (
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
       }
-      TALER_amount_hton (&pc.recoup_amount,
-                         &amount);
       if (GNUNET_OK !=
-          GNUNET_CRYPTO_eddsa_verify (
-            TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH,
-            &pc,
-            &exchange_sig.eddsa_signature,
-            &exchange_pub.eddsa_pub))
+          TALER_exchange_online_confirm_recoup_refresh_verify (
+            timestamp,
+            &amount,
+            &new_coin_pub,
+            coin_pub,
+            &exchange_pub,
+            &exchange_sig))
       {
         GNUNET_break_op (0);
         return GNUNET_SYSERR;
diff --git a/src/lib/exchange_api_deposit.c b/src/lib/exchange_api_deposit.c
index a08a6f42..947a4256 100644
--- a/src/lib/exchange_api_deposit.c
+++ b/src/lib/exchange_api_deposit.c
@@ -361,17 +361,18 @@ handle_deposit_finished (void *cls,
       }
 
       if (GNUNET_OK !=
-          TALER_exchange_deposit_confirm_verify (&dh->h_contract_terms,
-                                                 &dh->h_wire,
-                                                 &dh->h_extensions,
-                                                 dh->exchange_timestamp,
-                                                 dh->wire_deadline,
-                                                 dh->refund_deadline,
-                                                 &dh->amount_without_fee,
-                                                 &dh->coin_pub,
-                                                 &dh->merchant_pub,
-                                                 &dh->exchange_pub,
-                                                 &dh->exchange_sig))
+          TALER_exchange_online_deposit_confirmation_verify (
+            &dh->h_contract_terms,
+            &dh->h_wire,
+            &dh->h_extensions,
+            dh->exchange_timestamp,
+            dh->wire_deadline,
+            dh->refund_deadline,
+            &dh->amount_without_fee,
+            &dh->coin_pub,
+            &dh->merchant_pub,
+            &dh->exchange_pub,
+            &dh->exchange_sig))
       {
         GNUNET_break_op (0);
         dr.hr.http_status = 0;
diff --git a/src/lib/exchange_api_deposits_get.c 
b/src/lib/exchange_api_deposits_get.c
index 5d069d5c..32c60f1f 100644
--- a/src/lib/exchange_api_deposits_get.c
+++ b/src/lib/exchange_api_deposits_get.c
@@ -70,10 +70,38 @@ struct TALER_EXCHANGE_DepositGetHandle
   void *cb_cls;
 
   /**
-   * Information the exchange should sign in response.
-   * (with pre-filled fields from the request).
+   * Hash over the wiring information of the merchant.
    */
-  struct TALER_ConfirmWirePS depconf;
+  struct TALER_MerchantWireHashP h_wire;
+
+  /**
+   * Hash over the contract for which this deposit is made.
+   */
+  struct TALER_PrivateContractHashP h_contract_terms;
+
+  /**
+   * Raw value (binary encoding) of the wire transfer subject.
+   */
+  struct TALER_WireTransferIdentifierRawP wtid;
+
+  /**
+   * The coin's public key.  This is the value that must have been
+   * signed (blindly) by the Exchange.
+   */
+  struct TALER_CoinSpendPublicKeyP coin_pub;
+
+  /**
+   * When did the exchange execute this transfer? Note that the
+   * timestamp may not be exactly the same on the wire, i.e.
+   * because the wire has a different timezone or resolution.
+   */
+  struct GNUNET_TIME_Timestamp execution_time;
+
+  /**
+   * The contribution of @e coin_pub to the total transfer volume.
+   * This is the value of the deposit minus the fee.
+   */
+  struct TALER_Amount coin_contribution;
 
 };
 
@@ -87,6 +115,7 @@ struct TALER_EXCHANGE_DepositGetHandle
  * @param exchange_sig the exchange's signature
  * @return #GNUNET_OK if the signature is valid, #GNUNET_SYSERR if not
  */
+// FIXME: inline...
 static enum GNUNET_GenericReturnValue
 verify_deposit_wtid_signature_ok (
   const struct TALER_EXCHANGE_DepositGetHandle *dwh,
@@ -104,10 +133,15 @@ verify_deposit_wtid_signature_ok (
     return GNUNET_SYSERR;
   }
   if (GNUNET_OK !=
-      GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE,
-                                  &dwh->depconf,
-                                  &exchange_sig->eddsa_signature,
-                                  &exchange_pub->eddsa_pub))
+      TALER_exchange_online_confirm_wire_verify (
+        &dwh->h_wire,
+        &dwh->h_contract_terms,
+        &dwh->wtid,
+        &dwh->coin_pub,
+        dwh->execution_time,
+        &dwh->coin_contribution,
+        exchange_pub,
+        exchange_sig))
   {
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
@@ -168,11 +202,10 @@ handle_deposit_wtid_finished (void *cls,
         dr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
         break;
       }
-      dwh->depconf.execution_time = GNUNET_TIME_timestamp_hton (
-        dr.details.success.execution_time);
-      dwh->depconf.wtid = dr.details.success.wtid;
-      TALER_amount_hton (&dwh->depconf.coin_contribution,
-                         &dr.details.success.coin_contribution);
+      // FIXME: remove once we inline function below...
+      dwh->execution_time = dr.details.success.execution_time;
+      dwh->wtid = dr.details.success.wtid;
+      dwh->coin_contribution = dr.details.success.coin_contribution;
       if (GNUNET_OK !=
           verify_deposit_wtid_signature_ok (dwh,
                                             &dr.details.success.exchange_pub,
@@ -285,6 +318,7 @@ TALER_EXCHANGE_deposits_get (
     GNUNET_break (0);
     return NULL;
   }
+  // FIXME: move to helper!
   dtp.purpose.purpose = htonl (TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION);
   dtp.purpose.size = htonl (sizeof (dtp));
   dtp.h_contract_terms = *h_contract_terms;
@@ -351,11 +385,9 @@ TALER_EXCHANGE_deposits_get (
     GNUNET_free (dwh);
     return NULL;
   }
-  dwh->depconf.purpose.size = htonl (sizeof (struct TALER_ConfirmWirePS));
-  dwh->depconf.purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE);
-  dwh->depconf.h_wire = *h_wire;
-  dwh->depconf.h_contract_terms = *h_contract_terms;
-  dwh->depconf.coin_pub = *coin_pub;
+  dwh->h_wire = *h_wire;
+  dwh->h_contract_terms = *h_contract_terms;
+  dwh->coin_pub = *coin_pub;
 
   eh = TALER_EXCHANGE_curl_easy_get_ (dwh->url);
   if (NULL == eh)
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
index e0fcd2b9..feab4ac4 100644
--- a/src/lib/exchange_api_handle.c
+++ b/src/lib/exchange_api_handle.c
@@ -1136,11 +1136,7 @@ decode_keys_json (const json_t *resp_obj,
 
   if (check_sig)
   {
-    struct TALER_ExchangeKeySetPS ks = {
-      .purpose.size = htonl (sizeof (ks)),
-      .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
-      .list_issue_date = GNUNET_TIME_timestamp_hton (key_data->list_issue_date)
-    };
+    struct GNUNET_HashCode hc;
 
     /* If we had any age restricted denominations, add their hash to the end of
      * the normal denominations. */
@@ -1160,16 +1156,18 @@ decode_keys_json (const json_t *resp_obj,
     }
 
     GNUNET_CRYPTO_hash_context_finish (hash_context,
-                                       &ks.hc);
+                                       &hc);
     hash_context = NULL;
     EXITIF (GNUNET_OK !=
             TALER_EXCHANGE_test_signing_key (key_data,
                                              &pub));
+
     EXITIF (GNUNET_OK !=
-            GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_KEY_SET,
-                                        &ks,
-                                        &sig.eddsa_signature,
-                                        &pub.eddsa_pub));
+            TALER_exchange_online_key_set_verify (
+              key_data->list_issue_date,
+              &hc,
+              &pub,
+              &sig));
   }
   return GNUNET_OK;
 EXITIF_exit:
diff --git a/src/lib/exchange_api_kyc_check.c b/src/lib/exchange_api_kyc_check.c
index 303368ea..1f9f3b16 100644
--- a/src/lib/exchange_api_kyc_check.c
+++ b/src/lib/exchange_api_kyc_check.c
@@ -105,12 +105,6 @@ handle_kyc_check_finished (void *cls,
         GNUNET_JSON_spec_end ()
       };
       const struct TALER_EXCHANGE_Keys *key_state;
-      struct TALER_ExchangeAccountSetupSuccessPS kyc_purpose = {
-        .purpose.size = htonl (sizeof (kyc_purpose)),
-        .purpose.purpose = htonl (
-          TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS),
-        .h_payto = kch->h_payto
-      };
 
       if (GNUNET_OK !=
           GNUNET_JSON_parse (j,
@@ -122,8 +116,6 @@ handle_kyc_check_finished (void *cls,
         ks.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
         break;
       }
-      kyc_purpose.timestamp = GNUNET_TIME_timestamp_hton (
-        ks.details.kyc_ok.timestamp);
       key_state = TALER_EXCHANGE_get_keys (kch->exchange);
       if (GNUNET_OK !=
           TALER_EXCHANGE_test_signing_key (key_state,
@@ -137,11 +129,11 @@ handle_kyc_check_finished (void *cls,
       }
 
       if (GNUNET_OK !=
-          GNUNET_CRYPTO_eddsa_verify (
-            TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS,
-            &kyc_purpose,
-            &ks.details.kyc_ok.exchange_sig.eddsa_signature,
-            &ks.details.kyc_ok.exchange_pub.eddsa_pub))
+          TALER_exchange_online_account_setup_success_verify (
+            &kch->h_payto,
+            ks.details.kyc_ok.timestamp,
+            &ks.details.kyc_ok.exchange_pub,
+            &ks.details.kyc_ok.exchange_sig))
       {
         GNUNET_break_op (0);
         ks.http_status = 0;
diff --git a/src/lib/exchange_api_melt.c b/src/lib/exchange_api_melt.c
index 96e8c8e2..80c75970 100644
--- a/src/lib/exchange_api_melt.c
+++ b/src/lib/exchange_api_melt.c
@@ -170,7 +170,7 @@ verify_melt_signature_ok (struct TALER_EXCHANGE_MeltHandle 
*mh,
   }
 
   if (GNUNET_OK !=
-      TALER_exchange_melt_confirmation_verify (
+      TALER_exchange_online_melt_confirmation_verify (
         &mh->md.rc,
         mh->noreveal_index,
         exchange_pub,
diff --git a/src/lib/exchange_api_refund.c b/src/lib/exchange_api_refund.c
index 9ae907dc..6369a5bd 100644
--- a/src/lib/exchange_api_refund.c
+++ b/src/lib/exchange_api_refund.c
@@ -70,9 +70,33 @@ struct TALER_EXCHANGE_RefundHandle
   void *cb_cls;
 
   /**
-   * Information the exchange should sign in response.
+   * Hash over the proposal data to identify the contract
+   * which is being refunded.
    */
-  struct TALER_RefundConfirmationPS depconf;
+  struct TALER_PrivateContractHashP h_contract_terms;
+
+  /**
+   * The coin's public key.  This is the value that must have been
+   * signed (blindly) by the Exchange.
+   */
+  struct TALER_CoinSpendPublicKeyP coin_pub;
+
+  /**
+   * The Merchant's public key.  Allows the merchant to later refund
+   * the transaction or to inquire about the wire transfer identifier.
+   */
+  struct TALER_MerchantPublicKeyP merchant;
+
+  /**
+   * Merchant-generated transaction ID for the refund.
+   */
+  uint64_t rtransaction_id;
+
+  /**
+   * Amount to be refunded, including refund fee charged by the
+   * exchange to the customer.
+   */
+  struct TALER_Amount refund_amount;
 
 };
 
@@ -119,10 +143,14 @@ verify_refund_signature_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
     return GNUNET_SYSERR;
   }
   if (GNUNET_OK !=
-      GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND,
-                                  &rh->depconf,
-                                  &exchange_sig->eddsa_signature,
-                                  &exchange_pub->eddsa_pub))
+      TALER_exchange_online_refund_confirmation_verify (
+        &rh->h_contract_terms,
+        &rh->coin_pub,
+        &rh->merchant,
+        rh->rtransaction_id,
+        &rh->refund_amount,
+        exchange_pub,
+        exchange_sig))
   {
     GNUNET_break_op (0);
     return GNUNET_SYSERR;
@@ -253,16 +281,16 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
                                        wallet_timestamp,
                                        &merchant_pub,
                                        refund_deadline,
-                                       &rh->depconf.coin_pub,
+                                       &rh->coin_pub,
                                        &sig))
       {
         GNUNET_break_op (0);
         GNUNET_JSON_parse_free (spec);
         return GNUNET_SYSERR;
       }
-      if ( (0 != GNUNET_memcmp (&rh->depconf.h_contract_terms,
+      if ( (0 != GNUNET_memcmp (&rh->h_contract_terms,
                                 &h_contract_terms)) ||
-           (0 != GNUNET_memcmp (&rh->depconf.merchant,
+           (0 != GNUNET_memcmp (&rh->merchant,
                                 &merchant_pub)) )
       {
         /* deposit information is about a different merchant/contract */
@@ -334,7 +362,7 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
         return GNUNET_SYSERR;
       }
       if (GNUNET_OK !=
-          TALER_merchant_refund_verify (&rh->depconf.coin_pub,
+          TALER_merchant_refund_verify (&rh->coin_pub,
                                         &h_contract_terms,
                                         rtransaction_id,
                                         &sig_amount,
@@ -345,9 +373,9 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
         GNUNET_JSON_parse_free (spec);
         return GNUNET_SYSERR;
       }
-      if ( (0 != GNUNET_memcmp (&rh->depconf.h_contract_terms,
+      if ( (0 != GNUNET_memcmp (&rh->h_contract_terms,
                                 &h_contract_terms)) ||
-           (0 != GNUNET_memcmp (&rh->depconf.merchant,
+           (0 != GNUNET_memcmp (&rh->merchant,
                                 &merchant_pub)) )
       {
         /* refund is about a different merchant/contract */
@@ -355,7 +383,7 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
         GNUNET_JSON_parse_free (spec);
         return GNUNET_SYSERR;
       }
-      if (rtransaction_id == rh->depconf.rtransaction_id)
+      if (rtransaction_id == rh->rtransaction_id)
       {
         /* Eh, this shows either a dependency failure or idempotency,
            but must not happen in a conflict reply. Fail! */
@@ -398,16 +426,12 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
   }
 
   {
-    struct TALER_Amount amount;
-
-    TALER_amount_ntoh (&amount,
-                       &rh->depconf.refund_amount);
     if (have_refund)
     {
       if (0 >
           TALER_amount_add (&rtotal,
                             &rtotal,
-                            &amount))
+                            &rh->refund_amount))
       {
         GNUNET_break (0);
         GNUNET_JSON_parse_free (spec);
@@ -416,7 +440,7 @@ verify_conflict_history_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
     }
     else
     {
-      rtotal = amount;
+      rtotal = rh->refund_amount;
     }
   }
   if (-1 == TALER_amount_cmp (&dtotal,
@@ -472,7 +496,6 @@ verify_failed_dependency_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
   e = json_array_get (h, 0);
   {
     struct TALER_Amount amount;
-    struct TALER_Amount depconf_amount;
     const char *type;
     struct TALER_MerchantSignatureP sig;
     struct TALER_Amount refund_fee;
@@ -507,7 +530,7 @@ verify_failed_dependency_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
       return GNUNET_SYSERR;
     }
     if (GNUNET_OK !=
-        TALER_merchant_refund_verify (&rh->depconf.coin_pub,
+        TALER_merchant_refund_verify (&rh->coin_pub,
                                       &h_contract_terms,
                                       rtransaction_id,
                                       &amount,
@@ -518,14 +541,12 @@ verify_failed_dependency_ok (struct 
TALER_EXCHANGE_RefundHandle *rh,
       GNUNET_JSON_parse_free (spec);
       return GNUNET_SYSERR;
     }
-    TALER_amount_ntoh (&depconf_amount,
-                       &rh->depconf.refund_amount);
-    if ( (rtransaction_id != rh->depconf.rtransaction_id) ||
-         (0 != GNUNET_memcmp (&rh->depconf.h_contract_terms,
+    if ( (rtransaction_id != rh->rtransaction_id) ||
+         (0 != GNUNET_memcmp (&rh->h_contract_terms,
                               &h_contract_terms)) ||
-         (0 != GNUNET_memcmp (&rh->depconf.merchant,
+         (0 != GNUNET_memcmp (&rh->merchant,
                               &merchant_pub)) ||
-         (0 == TALER_amount_cmp (&depconf_amount,
+         (0 == TALER_amount_cmp (&rh->refund_amount,
                                  &amount)) )
     {
       GNUNET_break_op (0);
@@ -669,15 +690,15 @@ handle_refund_finished (void *cls,
 
 
 struct TALER_EXCHANGE_RefundHandle *
-TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange,
-                       const struct TALER_Amount *amount,
-                       const struct
-                       TALER_PrivateContractHashP *h_contract_terms,
-                       const struct TALER_CoinSpendPublicKeyP *coin_pub,
-                       uint64_t rtransaction_id,
-                       const struct TALER_MerchantPrivateKeyP *merchant_priv,
-                       TALER_EXCHANGE_RefundCallback cb,
-                       void *cb_cls)
+TALER_EXCHANGE_refund (
+  struct TALER_EXCHANGE_Handle *exchange,
+  const struct TALER_Amount *amount,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  uint64_t rtransaction_id,
+  const struct TALER_MerchantPrivateKeyP *merchant_priv,
+  TALER_EXCHANGE_RefundCallback cb,
+  void *cb_cls)
 {
   struct TALER_MerchantPublicKeyP merchant_pub;
   struct TALER_MerchantSignatureP merchant_sig;
@@ -735,15 +756,11 @@ TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle 
*exchange,
     GNUNET_free (rh);
     return NULL;
   }
-  rh->depconf.purpose.size = htonl (sizeof (struct 
TALER_RefundConfirmationPS));
-  rh->depconf.purpose.purpose = htonl 
(TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND);
-  rh->depconf.h_contract_terms = *h_contract_terms;
-  rh->depconf.coin_pub = *coin_pub;
-  rh->depconf.merchant = merchant_pub;
-  rh->depconf.rtransaction_id = GNUNET_htonll (rtransaction_id);
-  TALER_amount_hton (&rh->depconf.refund_amount,
-                     amount);
-
+  rh->h_contract_terms = *h_contract_terms;
+  rh->coin_pub = *coin_pub;
+  rh->merchant = merchant_pub;
+  rh->rtransaction_id = rtransaction_id;
+  rh->refund_amount = *amount;
   eh = TALER_EXCHANGE_curl_easy_get_ (rh->url);
   if ( (NULL == eh) ||
        (GNUNET_OK !=
diff --git a/src/lib/exchange_api_transfers_get.c 
b/src/lib/exchange_api_transfers_get.c
index b9a9db94..23a0ee76 100644
--- a/src/lib/exchange_api_transfers_get.c
+++ b/src/lib/exchange_api_transfers_get.c
@@ -177,43 +177,29 @@ check_transfers_get_response_ok (
         return GNUNET_SYSERR;
       }
       /* build up big hash for signature checking later */
-      {
-        struct TALER_WireDepositDetailP dd;
-
-        dd.h_contract_terms = detail->h_contract_terms;
-        dd.execution_time = GNUNET_TIME_timestamp_hton (td.execution_time);
-        dd.coin_pub = detail->coin_pub;
-        TALER_amount_hton (&dd.deposit_value,
-                           &detail->coin_value);
-        TALER_amount_hton (&dd.deposit_fee,
-                           &detail->coin_fee);
-        GNUNET_CRYPTO_hash_context_read (hash_context,
-                                         &dd,
-                                         sizeof (dd));
-      }
+      TALER_exchange_online_wire_deposit_append (
+        hash_context,
+        &detail->h_contract_terms,
+        td.execution_time,
+        &detail->coin_pub,
+        &detail->coin_value,
+        &detail->coin_fee);
     }
     /* Check signature */
     {
-      struct TALER_WireDepositDataPS wdp = {
-        .purpose.purpose = htonl (
-          TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT),
-        .purpose.size = htonl (sizeof (wdp)),
-        .merchant_pub = merchant_pub,
-        .h_payto = td.h_payto
-      };
+      struct GNUNET_HashCode h_details;
 
-      TALER_amount_hton (&wdp.total,
-                         &td.total_amount);
-      TALER_amount_hton (&wdp.wire_fee,
-                         &td.wire_fee);
       GNUNET_CRYPTO_hash_context_finish (hash_context,
-                                         &wdp.h_details);
+                                         &h_details);
       if (GNUNET_OK !=
-          GNUNET_CRYPTO_eddsa_verify (
-            TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT,
-            &wdp,
-            &td.exchange_sig.eddsa_signature,
-            &td.exchange_pub.eddsa_pub))
+          TALER_exchange_online_wire_deposit_verify (
+            &td.total_amount,
+            &td.wire_fee,
+            &merchant_pub,
+            &td.h_payto,
+            &h_details,
+            &td.exchange_pub,
+            &td.exchange_sig))
       {
         GNUNET_break_op (0);
         GNUNET_JSON_parse_free (spec);
@@ -330,16 +316,6 @@ handle_transfers_get_finished (void *cls,
 }
 
 
-/**
- * Query the exchange about which transactions were combined
- * to create a wire transfer.
- *
- * @param exchange exchange to query
- * @param wtid raw wire transfer identifier to get information about
- * @param cb callback to call
- * @param cb_cls closure for @a cb
- * @return handle to cancel operation
- */
 struct TALER_EXCHANGE_TransfersGetHandle *
 TALER_EXCHANGE_transfers_get (
   struct TALER_EXCHANGE_Handle *exchange,
@@ -369,8 +345,7 @@ TALER_EXCHANGE_transfers_get (
     char *end;
 
     end = GNUNET_STRINGS_data_to_string (wtid,
-                                         sizeof (struct
-                                                 
TALER_WireTransferIdentifierRawP),
+                                         sizeof (wtid),
                                          wtid_str,
                                          sizeof (wtid_str));
     *end = '\0';
diff --git a/src/util/auditor_signatures.c b/src/util/auditor_signatures.c
index 77db296c..c35b6f19 100644
--- a/src/util/auditor_signatures.c
+++ b/src/util/auditor_signatures.c
@@ -23,6 +23,89 @@
 #include "taler_signatures.h"
 
 
+/**
+ * @brief Information signed by an auditor affirming
+ * the master public key and the denomination keys
+ * of a exchange.
+ */
+struct TALER_ExchangeKeyValidityPS
+{
+
+  /**
+   * Purpose is #TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS.
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * Hash of the auditor's URL (including 0-terminator).
+   */
+  struct GNUNET_HashCode auditor_url_hash;
+
+  /**
+   * The long-term offline master key of the exchange, affirmed by the
+   * auditor.
+   */
+  struct TALER_MasterPublicKeyP master;
+
+  /**
+   * Start time of the validity period for this key.
+   */
+  struct GNUNET_TIME_TimestampNBO start;
+
+  /**
+   * The exchange will sign fresh coins between @e start and this time.
+   * @e expire_withdraw will be somewhat larger than @e start to
+   * ensure a sufficiently large anonymity set, while also allowing
+   * the Exchange to limit the financial damage in case of a key being
+   * compromised.  Thus, exchanges with low volume are expected to have a
+   * longer withdraw period (@e expire_withdraw - @e start) than exchanges
+   * with high transaction volume.  The period may also differ between
+   * types of coins.  A exchange may also have a few denomination keys
+   * with the same value with overlapping validity periods, to address
+   * issues such as clock skew.
+   */
+  struct GNUNET_TIME_TimestampNBO expire_withdraw;
+
+  /**
+   * Coins signed with the denomination key must be spent or refreshed
+   * between @e start and this expiration time.  After this time, the
+   * exchange will refuse transactions involving this key as it will
+   * "drop" the table with double-spending information (shortly after)
+   * this time.  Note that wallets should refresh coins significantly
+   * before this time to be on the safe side.  @e expire_deposit must be
+   * significantly larger than @e expire_withdraw (by months or even
+   * years).
+   */
+  struct GNUNET_TIME_TimestampNBO expire_deposit;
+
+  /**
+   * When do signatures with this denomination key become invalid?
+   * After this point, these signatures cannot be used in (legal)
+   * disputes anymore, as the Exchange is then allowed to destroy its side
+   * of the evidence.  @e expire_legal is expected to be significantly
+   * larger than @e expire_deposit (by a year or more).
+   */
+  struct GNUNET_TIME_TimestampNBO expire_legal;
+
+  /**
+   * The value of the coins signed with this denomination key.
+   */
+  struct TALER_AmountNBO value;
+
+  /**
+   * Fees for the coin.
+   */
+  struct TALER_DenomFeeSetNBOP fees;
+
+  /**
+   * Hash code of the denomination public key. (Used to avoid having
+   * the variable-size RSA key in this struct.)
+   */
+  struct TALER_DenominationHashP denom_hash GNUNET_PACKED;
+
+};
+
+
 void
 TALER_auditor_denom_validity_sign (
   const char *auditor_url,
diff --git a/src/util/exchange_signatures.c b/src/util/exchange_signatures.c
index b4a1f9d7..4890ca20 100644
--- a/src/util/exchange_signatures.c
+++ b/src/util/exchange_signatures.c
@@ -23,8 +23,114 @@
 #include "taler_signatures.h"
 
 
+/**
+ * @brief Format used to generate the signature on a confirmation
+ * from the exchange that a deposit request succeeded.
+ */
+struct TALER_DepositConfirmationPS
+{
+  /**
+   * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT.  Signed
+   * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * Hash over the contract for which this deposit is made.
+   */
+  struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
+
+  /**
+   * Hash over the wiring information of the merchant.
+   */
+  struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
+
+  /**
+   * Hash over the extension options of the deposit, 0 if there
+   * were not extension options.
+   */
+  struct TALER_ExtensionContractHashP h_extensions GNUNET_PACKED;
+
+  /**
+   * Time when this confirmation was generated / when the exchange received
+   * the deposit request.
+   */
+  struct GNUNET_TIME_TimestampNBO exchange_timestamp;
+
+  /**
+   * By when does the exchange expect to pay the merchant
+   * (as per the merchant's request).
+   */
+  struct GNUNET_TIME_TimestampNBO wire_deadline;
+
+  /**
+   * How much time does the @e merchant have to issue a refund
+   * request?  Zero if refunds are not allowed.  After this time, the
+   * coin cannot be refunded.  Note that the wire transfer will not be
+   * performed by the exchange until the refund deadline.  This value
+   * is taken from the original deposit request.
+   */
+  struct GNUNET_TIME_TimestampNBO refund_deadline;
+
+  /**
+   * Amount to be deposited, excluding fee.  Calculated from the
+   * amount with fee and the fee from the deposit request.
+   */
+  struct TALER_AmountNBO amount_without_fee;
+
+  /**
+   * The public key of the coin that was deposited.
+   */
+  struct TALER_CoinSpendPublicKeyP coin_pub;
+
+  /**
+   * The Merchant's public key.  Allows the merchant to later refund
+   * the transaction or to inquire about the wire transfer identifier.
+   */
+  struct TALER_MerchantPublicKeyP merchant_pub;
+
+};
+
+
+enum TALER_ErrorCode
+TALER_exchange_online_deposit_confirmation_sign (
+  TALER_ExchangeSignCallback scb,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const struct TALER_MerchantWireHashP *h_wire,
+  const struct TALER_ExtensionContractHashP *h_extensions,
+  struct GNUNET_TIME_Timestamp exchange_timestamp,
+  struct GNUNET_TIME_Timestamp wire_deadline,
+  struct GNUNET_TIME_Timestamp refund_deadline,
+  const struct TALER_Amount *amount_without_fee,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_MerchantPublicKeyP *merchant_pub,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_DepositConfirmationPS dcs = {
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
+    .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
+    .h_contract_terms = *h_contract_terms,
+    .h_wire = *h_wire,
+    .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
+    .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
+    .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
+    .coin_pub = *coin_pub,
+    .merchant_pub = *merchant_pub
+  };
+
+  if (NULL != h_extensions)
+    dcs.h_extensions = *h_extensions;
+  TALER_amount_hton (&dcs.amount_without_fee,
+                     amount_without_fee);
+  return scb (&dcs.purpose,
+              pub,
+              sig);
+}
+
+
 enum GNUNET_GenericReturnValue
-TALER_exchange_deposit_confirm_verify (
+TALER_exchange_online_deposit_confirmation_verify (
   const struct TALER_PrivateContractHashP *h_contract_terms,
   const struct TALER_MerchantWireHashP *h_wire,
   const struct TALER_ExtensionContractHashP *h_extensions,
@@ -66,8 +172,161 @@ TALER_exchange_deposit_confirm_verify (
 }
 
 
+/**
+ * @brief Format used to generate the signature on a request to refund
+ * a coin into the account of the customer.
+ */
+struct TALER_RefundConfirmationPS
+{
+  /**
+   * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND.
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * Hash over the proposal data to identify the contract
+   * which is being refunded.
+   */
+  struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
+
+  /**
+   * The coin's public key.  This is the value that must have been
+   * signed (blindly) by the Exchange.
+   */
+  struct TALER_CoinSpendPublicKeyP coin_pub;
+
+  /**
+   * The Merchant's public key.  Allows the merchant to later refund
+   * the transaction or to inquire about the wire transfer identifier.
+   */
+  struct TALER_MerchantPublicKeyP merchant;
+
+  /**
+   * Merchant-generated transaction ID for the refund.
+   */
+  uint64_t rtransaction_id GNUNET_PACKED;
+
+  /**
+   * Amount to be refunded, including refund fee charged by the
+   * exchange to the customer.
+   */
+  struct TALER_AmountNBO refund_amount;
+};
+
+
+enum TALER_ErrorCode
+TALER_exchange_online_refund_confirmation_sign (
+  TALER_ExchangeSignCallback scb,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_MerchantPublicKeyP *merchant,
+  uint64_t rtransaction_id,
+  const struct TALER_Amount *refund_amount,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_RefundConfirmationPS rc = {
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND),
+    .purpose.size = htonl (sizeof (rc)),
+    .h_contract_terms = *h_contract_terms,
+    .coin_pub = *coin_pub,
+    .merchant = *merchant,
+    .rtransaction_id = GNUNET_htonll (rtransaction_id)
+  };
+
+  TALER_amount_hton (&rc.refund_amount,
+                     refund_amount);
+  return scb (&rc.purpose,
+              pub,
+              sig);
+}
+
+
 enum GNUNET_GenericReturnValue
-TALER_exchange_melt_confirmation_verify (
+TALER_exchange_online_refund_confirmation_verify (
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_MerchantPublicKeyP *merchant,
+  uint64_t rtransaction_id,
+  const struct TALER_Amount *refund_amount,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_RefundConfirmationPS rc = {
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND),
+    .purpose.size = htonl (sizeof (rc)),
+    .h_contract_terms = *h_contract_terms,
+    .coin_pub = *coin_pub,
+    .merchant = *merchant,
+    .rtransaction_id = GNUNET_htonll (rtransaction_id)
+  };
+
+  TALER_amount_hton (&rc.refund_amount,
+                     refund_amount);
+  if (GNUNET_OK !=
+      GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND,
+                                  &rc,
+                                  &sig->eddsa_signature,
+                                  &pub->eddsa_pub))
+  {
+    GNUNET_break_op (0);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * @brief Format of the block signed by the Exchange in response to a 
successful
+ * "/refresh/melt" request.  Hereby the exchange affirms that all of the
+ * coins were successfully melted.  This also commits the exchange to a
+ * particular index to not be revealed during the refresh.
+ */
+struct TALER_RefreshMeltConfirmationPS
+{
+  /**
+   * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT.   Signed
+   * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * Commitment made in the /refresh/melt.
+   */
+  struct TALER_RefreshCommitmentP rc GNUNET_PACKED;
+
+  /**
+   * Index that the client will not have to reveal, in NBO.
+   * Must be smaller than #TALER_CNC_KAPPA.
+   */
+  uint32_t noreveal_index GNUNET_PACKED;
+
+};
+
+
+enum TALER_ErrorCode
+TALER_exchange_online_melt_confirmation_sign (
+  TALER_ExchangeSignCallback scb,
+  const struct TALER_RefreshCommitmentP *rc,
+  uint32_t noreveal_index,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_RefreshMeltConfirmationPS confirm = {
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
+    .purpose.size = htonl (sizeof (confirm)),
+    .rc = *rc,
+    .noreveal_index = htonl (noreveal_index)
+  };
+
+  return scb (&confirm.purpose,
+              pub,
+              sig);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_melt_confirmation_verify (
   const struct TALER_RefreshCommitmentP *rc,
   uint32_t noreveal_index,
   const struct TALER_ExchangePublicKeyP *exchange_pub,
@@ -88,4 +347,866 @@ TALER_exchange_melt_confirmation_verify (
 }
 
 
+/**
+ * @brief Signature made by the exchange over the full set of keys, used
+ * to detect cheating exchanges that give out different sets to
+ * different users.
+ */
+struct TALER_ExchangeKeySetPS
+{
+
+  /**
+   * Purpose is #TALER_SIGNATURE_EXCHANGE_KEY_SET.   Signed
+   * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * Time of the key set issue.
+   */
+  struct GNUNET_TIME_TimestampNBO list_issue_date;
+
+  /**
+   * Hash over the various denomination signing keys returned.
+   */
+  struct GNUNET_HashCode hc GNUNET_PACKED;
+};
+
+
+enum TALER_ErrorCode
+TALER_exchange_online_key_set_sign (
+  TALER_ExchangeSignCallback2 scb,
+  void *cls,
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct GNUNET_HashCode *hc,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_ExchangeKeySetPS ks = {
+    .purpose.size = htonl (sizeof (ks)),
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
+    .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp),
+    .hc = *hc
+  };
+
+  return scb (cls,
+              &ks.purpose,
+              pub,
+              sig);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_key_set_verify (
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct GNUNET_HashCode *hc,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_ExchangeKeySetPS ks = {
+    .purpose.size = htonl (sizeof (ks)),
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
+    .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp),
+    .hc = *hc
+  };
+
+  return
+    GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_KEY_SET,
+                                &ks,
+                                &sig->eddsa_signature,
+                                &pub->eddsa_pub);
+}
+
+
+/**
+ * @brief Signature by which an exchange affirms that an account
+ * successfully passed the KYC checks.
+ */
+struct TALER_ExchangeAccountSetupSuccessPS
+{
+  /**
+   * Purpose is #TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS.  Signed by a
+   * `struct TALER_ExchangePublicKeyP` using EdDSA.
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * Hash over the payto for which the signature was
+   * made.
+   */
+  struct TALER_PaytoHashP h_payto;
+
+  /**
+   * When was the signature made.
+   */
+  struct GNUNET_TIME_TimestampNBO timestamp;
+};
+
+
+enum TALER_ErrorCode
+TALER_exchange_online_account_setup_success_sign (
+  TALER_ExchangeSignCallback scb,
+  const struct TALER_PaytoHashP *h_payto,
+  struct GNUNET_TIME_Timestamp timestamp,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_ExchangeAccountSetupSuccessPS kyc_purpose = {
+    .purpose.size = htonl (sizeof (kyc_purpose)),
+    .purpose.purpose = htonl (
+      TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS),
+    .h_payto = *h_payto,
+    .timestamp = GNUNET_TIME_timestamp_hton (
+      timestamp)
+  };
+
+  return scb (&kyc_purpose.purpose,
+              pub,
+              sig);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_account_setup_success_verify (
+  const struct TALER_PaytoHashP *h_payto,
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_ExchangeAccountSetupSuccessPS kyc_purpose = {
+    .purpose.size = htonl (sizeof (kyc_purpose)),
+    .purpose.purpose = htonl (
+      TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS),
+    .h_payto = *h_payto,
+    .timestamp = GNUNET_TIME_timestamp_hton (
+      timestamp)
+  };
+
+  return
+    GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_ACCOUNT_SETUP_SUCCESS,
+                                &kyc_purpose,
+                                &sig->eddsa_signature,
+                                &pub->eddsa_pub);
+}
+
+
+/**
+ * @brief Format internally used for packing the detailed information
+ * to generate the signature for /track/transfer signatures.
+ */
+struct TALER_WireDepositDetailP
+{
+
+  /**
+   * Hash of the contract
+   */
+  struct TALER_PrivateContractHashP h_contract_terms;
+
+  /**
+   * Time when the wire transfer was performed by the exchange.
+   */
+  struct GNUNET_TIME_TimestampNBO execution_time;
+
+  /**
+   * Coin's public key.
+   */
+  struct TALER_CoinSpendPublicKeyP coin_pub;
+
+  /**
+   * Total value of the coin.
+   */
+  struct TALER_AmountNBO deposit_value;
+
+  /**
+   * Fees charged by the exchange for the deposit.
+   */
+  struct TALER_AmountNBO deposit_fee;
+
+};
+
+
+void
+TALER_exchange_online_wire_deposit_append (
+  struct GNUNET_HashContext *hash_context,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  struct GNUNET_TIME_Timestamp execution_time,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_Amount *deposit_value,
+  const struct TALER_Amount *deposit_fee)
+{
+  struct TALER_WireDepositDetailP dd = {
+    .h_contract_terms = *h_contract_terms,
+    .execution_time = GNUNET_TIME_timestamp_hton (execution_time),
+    .coin_pub = *coin_pub
+  };
+  TALER_amount_hton (&dd.deposit_value,
+                     deposit_value);
+  TALER_amount_hton (&dd.deposit_fee,
+                     deposit_fee);
+  GNUNET_CRYPTO_hash_context_read (hash_context,
+                                   &dd,
+                                   sizeof (dd));
+}
+
+
+/**
+ * @brief Format used to generate the signature for /wire/deposit
+ * replies.
+ */
+struct TALER_WireDepositDataPS
+{
+  /**
+   * Purpose header for the signature over the contract with
+   * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT.
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * Total amount that was transferred.
+   */
+  struct TALER_AmountNBO total;
+
+  /**
+   * Wire fee that was charged.
+   */
+  struct TALER_AmountNBO wire_fee;
+
+  /**
+   * Public key of the merchant (for all aggregated transactions).
+   */
+  struct TALER_MerchantPublicKeyP merchant_pub;
+
+  /**
+   * Hash of bank account of the merchant.
+   */
+  struct TALER_PaytoHashP h_payto;
+
+  /**
+   * Hash of the individual deposits that were aggregated,
+   * each in the format of a `struct TALER_WireDepositDetailP`.
+   */
+  struct GNUNET_HashCode h_details;
+
+};
+
+
+enum TALER_ErrorCode
+TALER_exchange_online_wire_deposit_sign (
+  TALER_ExchangeSignCallback scb,
+  const struct TALER_Amount *total,
+  const struct TALER_Amount *wire_fee,
+  const struct TALER_MerchantPublicKeyP *merchant_pub,
+  const char *payto,
+  const struct GNUNET_HashCode *h_details,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_WireDepositDataPS wdp = {
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT),
+    .purpose.size = htonl (sizeof (wdp)),
+    .merchant_pub = *merchant_pub,
+    .h_details = *h_details
+  };
+
+  TALER_amount_hton (&wdp.total,
+                     total);
+  TALER_amount_hton (&wdp.wire_fee,
+                     wire_fee);
+  TALER_payto_hash (payto,
+                    &wdp.h_payto);
+  return scb (&wdp.purpose,
+              pub,
+              sig);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_wire_deposit_verify (
+  const struct TALER_Amount *total,
+  const struct TALER_Amount *wire_fee,
+  const struct TALER_MerchantPublicKeyP *merchant_pub,
+  const struct TALER_PaytoHashP *h_payto,
+  const struct GNUNET_HashCode *h_details,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_WireDepositDataPS wdp = {
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT),
+    .purpose.size = htonl (sizeof (wdp)),
+    .merchant_pub = *merchant_pub,
+    .h_details = *h_details,
+    .h_payto = *h_payto
+  };
+
+  TALER_amount_hton (&wdp.total,
+                     total);
+  TALER_amount_hton (&wdp.wire_fee,
+                     wire_fee);
+  return
+    GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT,
+                                &wdp,
+                                &sig->eddsa_signature,
+                                &pub->eddsa_pub);
+}
+
+
+/**
+ * Details affirmed by the exchange about a wire transfer the exchange
+ * claims to have done with respect to a deposit operation.
+ */
+struct TALER_ConfirmWirePS
+{
+  /**
+   * Purpose header for the signature over the contract with
+   * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE.
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * Hash over the wiring information of the merchant.
+   */
+  struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
+
+  /**
+   * Hash over the contract for which this deposit is made.
+   */
+  struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
+
+  /**
+   * Raw value (binary encoding) of the wire transfer subject.
+   */
+  struct TALER_WireTransferIdentifierRawP wtid;
+
+  /**
+   * The coin's public key.  This is the value that must have been
+   * signed (blindly) by the Exchange.
+   */
+  struct TALER_CoinSpendPublicKeyP coin_pub;
+
+  /**
+   * When did the exchange execute this transfer? Note that the
+   * timestamp may not be exactly the same on the wire, i.e.
+   * because the wire has a different timezone or resolution.
+   */
+  struct GNUNET_TIME_TimestampNBO execution_time;
+
+  /**
+   * The contribution of @e coin_pub to the total transfer volume.
+   * This is the value of the deposit minus the fee.
+   */
+  struct TALER_AmountNBO coin_contribution;
+
+};
+
+
+enum TALER_ErrorCode
+TALER_exchange_online_confirm_wire_sign (
+  TALER_ExchangeSignCallback scb,
+  const struct TALER_MerchantWireHashP *h_wire,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const struct TALER_WireTransferIdentifierRawP *wtid,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  struct GNUNET_TIME_Timestamp execution_time,
+  const struct TALER_Amount *coin_contribution,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig)
+
+{
+  struct TALER_ConfirmWirePS cw = {
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE),
+    .purpose.size = htonl (sizeof (cw)),
+    .h_wire = *h_wire,
+    .h_contract_terms = *h_contract_terms,
+    .wtid = *wtid,
+    .coin_pub = *coin_pub,
+    .execution_time = GNUNET_TIME_timestamp_hton (execution_time)
+  };
+
+  TALER_amount_hton (&cw.coin_contribution,
+                     coin_contribution);
+  return scb (&cw.purpose,
+              pub,
+              sig);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_confirm_wire_verify (
+  const struct TALER_MerchantWireHashP *h_wire,
+  const struct TALER_PrivateContractHashP *h_contract_terms,
+  const struct TALER_WireTransferIdentifierRawP *wtid,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  struct GNUNET_TIME_Timestamp execution_time,
+  const struct TALER_Amount *coin_contribution,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_ConfirmWirePS cw = {
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE),
+    .purpose.size = htonl (sizeof (cw)),
+    .h_wire = *h_wire,
+    .h_contract_terms = *h_contract_terms,
+    .wtid = *wtid,
+    .coin_pub = *coin_pub,
+    .execution_time = GNUNET_TIME_timestamp_hton (execution_time)
+  };
+
+  TALER_amount_hton (&cw.coin_contribution,
+                     coin_contribution);
+  return
+    GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE,
+                                &cw,
+                                &sig->eddsa_signature,
+                                &pub->eddsa_pub);
+}
+
+
+/**
+ * Response by which the exchange affirms that it will
+ * refund a coin as part of the emergency /recoup
+ * protocol.  The recoup will go back to the bank
+ * account that created the reserve.
+ */
+struct TALER_RecoupConfirmationPS
+{
+
+  /**
+   * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * When did the exchange receive the recoup request?
+   * Indirectly determines when the wire transfer is (likely)
+   * to happen.
+   */
+  struct GNUNET_TIME_TimestampNBO timestamp;
+
+  /**
+   * How much of the coin's value will the exchange transfer?
+   * (Needed in case the coin was partially spent.)
+   */
+  struct TALER_AmountNBO recoup_amount;
+
+  /**
+   * Public key of the coin.
+   */
+  struct TALER_CoinSpendPublicKeyP coin_pub;
+
+  /**
+   * Public key of the reserve that will receive the recoup.
+   */
+  struct TALER_ReservePublicKeyP reserve_pub;
+};
+
+
+enum TALER_ErrorCode
+TALER_exchange_online_confirm_recoup_sign (
+  TALER_ExchangeSignCallback scb,
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_Amount *recoup_amount,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_ReservePublicKeyP *reserve_pub,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_RecoupConfirmationPS pc = {
+    .purpose.size = htonl (sizeof (pc)),
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
+    .reserve_pub = *reserve_pub,
+    .coin_pub = *coin_pub
+  };
+
+  TALER_amount_hton (&pc.recoup_amount,
+                     recoup_amount);
+  return scb (&pc.purpose,
+              pub,
+              sig);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_confirm_recoup_verify (
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_Amount *recoup_amount,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_ReservePublicKeyP *reserve_pub,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_RecoupConfirmationPS pc = {
+    .purpose.size = htonl (sizeof (pc)),
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
+    .reserve_pub = *reserve_pub,
+    .coin_pub = *coin_pub
+  };
+
+  TALER_amount_hton (&pc.recoup_amount,
+                     recoup_amount);
+  return
+    GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP,
+                                &pc,
+                                &sig->eddsa_signature,
+                                &pub->eddsa_pub);
+}
+
+
+/**
+ * Response by which the exchange affirms that it will refund a refreshed coin
+ * as part of the emergency /recoup protocol.  The recoup will go back to the
+ * old coin's balance.
+ */
+struct TALER_RecoupRefreshConfirmationPS
+{
+
+  /**
+   * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * When did the exchange receive the recoup request?
+   * Indirectly determines when the wire transfer is (likely)
+   * to happen.
+   */
+  struct GNUNET_TIME_TimestampNBO timestamp;
+
+  /**
+   * How much of the coin's value will the exchange transfer?
+   * (Needed in case the coin was partially spent.)
+   */
+  struct TALER_AmountNBO recoup_amount;
+
+  /**
+   * Public key of the refreshed coin.
+   */
+  struct TALER_CoinSpendPublicKeyP coin_pub;
+
+  /**
+   * Public key of the old coin that will receive the recoup.
+   */
+  struct TALER_CoinSpendPublicKeyP old_coin_pub;
+};
+
+
+enum TALER_ErrorCode
+TALER_exchange_online_confirm_recoup_refresh_sign (
+  TALER_ExchangeSignCallback scb,
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_Amount *recoup_amount,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_RecoupRefreshConfirmationPS pc = {
+    .purpose.purpose = htonl (
+      TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
+    .purpose.size = htonl (sizeof (pc)),
+    .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
+    .coin_pub = *coin_pub,
+    .old_coin_pub = *old_coin_pub
+  };
+
+  TALER_amount_hton (&pc.recoup_amount,
+                     recoup_amount);
+  return scb (&pc.purpose,
+              pub,
+              sig);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_confirm_recoup_refresh_verify (
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_Amount *recoup_amount,
+  const struct TALER_CoinSpendPublicKeyP *coin_pub,
+  const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_RecoupRefreshConfirmationPS pc = {
+    .purpose.purpose = htonl (
+      TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
+    .purpose.size = htonl (sizeof (pc)),
+    .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
+    .coin_pub = *coin_pub,
+    .old_coin_pub = *old_coin_pub
+  };
+
+  TALER_amount_hton (&pc.recoup_amount,
+                     recoup_amount);
+
+  return
+    GNUNET_CRYPTO_eddsa_verify 
(TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH,
+                                &pc,
+                                &sig->eddsa_signature,
+                                &pub->eddsa_pub);
+}
+
+
+/**
+ * Response by which the exchange affirms that it does not
+ * currently know a denomination by the given hash.
+ */
+struct TALER_DenominationUnknownAffirmationPS
+{
+
+  /**
+   * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * When did the exchange sign this message.
+   */
+  struct GNUNET_TIME_TimestampNBO timestamp;
+
+  /**
+   * Hash of the public denomination key we do not know.
+   */
+  struct TALER_DenominationHashP h_denom_pub;
+};
+
+
+enum TALER_ErrorCode
+TALER_exchange_online_denomination_unknown_sign (
+  TALER_ExchangeSignCallback scb,
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_DenominationHashP *h_denom_pub,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_DenominationUnknownAffirmationPS dua = {
+    .purpose.size = htonl (sizeof (dua)),
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
+    .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
+    .h_denom_pub = *h_denom_pub,
+  };
+
+  return scb (&dua.purpose,
+              pub,
+              sig);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_denomination_unknown_verify (
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_DenominationHashP *h_denom_pub,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_DenominationUnknownAffirmationPS dua = {
+    .purpose.size = htonl (sizeof (dua)),
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
+    .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
+    .h_denom_pub = *h_denom_pub,
+  };
+
+  return
+    GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN,
+                                &dua,
+                                &sig->eddsa_signature,
+                                &pub->eddsa_pub);
+}
+
+
+/**
+ * Response by which the exchange affirms that it does not
+ * currently consider the given denomination to be valid
+ * for the requested operation.
+ */
+struct TALER_DenominationExpiredAffirmationPS
+{
+
+  /**
+   * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * When did the exchange sign this message.
+   */
+  struct GNUNET_TIME_TimestampNBO timestamp;
+
+  /**
+   * Name of the operation that is not allowed at this time.  Might NOT be 
0-terminated, but is padded with 0s.
+   */
+  char operation[8];
+
+  /**
+   * Hash of the public denomination key we do not know.
+   */
+  struct TALER_DenominationHashP h_denom_pub;
+
+};
+
+
+enum TALER_ErrorCode
+TALER_exchange_online_denomination_expired_sign (
+  TALER_ExchangeSignCallback scb,
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_DenominationHashP *h_denom_pub,
+  const char *op,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_DenominationExpiredAffirmationPS dua = {
+    .purpose.size = htonl (sizeof (dua)),
+    .purpose.purpose = htonl (
+      TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
+    .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
+    .h_denom_pub = *h_denom_pub,
+  };
+
+  /* strncpy would create a compiler warning */
+  memcpy (dua.operation,
+          op,
+          GNUNET_MIN (sizeof (dua.operation),
+                      strlen (op)));
+  return scb (&dua.purpose,
+              pub,
+              sig);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_denomination_expired_verify (
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_DenominationHashP *h_denom_pub,
+  const char *op,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_DenominationExpiredAffirmationPS dua = {
+    .purpose.size = htonl (sizeof (dua)),
+    .purpose.purpose = htonl (
+      TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
+    .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
+    .h_denom_pub = *h_denom_pub,
+  };
+
+  /* strncpy would create a compiler warning */
+  memcpy (dua.operation,
+          op,
+          GNUNET_MIN (sizeof (dua.operation),
+                      strlen (op)));
+  return
+    GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED,
+                                &dua,
+                                &sig->eddsa_signature,
+                                &pub->eddsa_pub);
+}
+
+
+/**
+ * Response by which the exchange affirms that it has
+ * closed a reserve and send back the funds.
+ */
+struct TALER_ReserveCloseConfirmationPS
+{
+
+  /**
+   * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * When did the exchange initiate the wire transfer.
+   */
+  struct GNUNET_TIME_TimestampNBO timestamp;
+
+  /**
+   * How much did the exchange send?
+   */
+  struct TALER_AmountNBO closing_amount;
+
+  /**
+   * How much did the exchange charge for closing the reserve?
+   */
+  struct TALER_AmountNBO closing_fee;
+
+  /**
+   * Public key of the reserve that was closed.
+   */
+  struct TALER_ReservePublicKeyP reserve_pub;
+
+  /**
+   * Hash of the receiver's bank account.
+   */
+  struct TALER_PaytoHashP h_payto;
+
+  /**
+   * Wire transfer subject.
+   */
+  struct TALER_WireTransferIdentifierRawP wtid;
+};
+
+
+enum TALER_ErrorCode
+TALER_exchange_online_reserve_closed_sign (
+  TALER_ExchangeSignCallback scb,
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_Amount *closing_amount,
+  const struct TALER_Amount *closing_fee,
+  const char *payto,
+  const struct TALER_WireTransferIdentifierRawP *wtid,
+  const struct TALER_ReservePublicKeyP *reserve_pub,
+  struct TALER_ExchangePublicKeyP *pub,
+  struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_ReserveCloseConfirmationPS rcc = {
+    .purpose.size = htonl (sizeof (rcc)),
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED),
+    .wtid = *wtid,
+    .reserve_pub = *reserve_pub,
+    .timestamp = GNUNET_TIME_timestamp_hton (timestamp)
+  };
+
+  TALER_amount_hton (&rcc.closing_amount,
+                     closing_amount);
+  TALER_amount_hton (&rcc.closing_fee,
+                     closing_fee);
+  TALER_payto_hash (payto,
+                    &rcc.h_payto);
+  return scb (&rcc.purpose,
+              pub,
+              sig);
+}
+
+
+enum GNUNET_GenericReturnValue
+TALER_exchange_online_reserve_closed_verify (
+  struct GNUNET_TIME_Timestamp timestamp,
+  const struct TALER_Amount *closing_amount,
+  const struct TALER_Amount *closing_fee,
+  const char *payto,
+  const struct TALER_WireTransferIdentifierRawP *wtid,
+  const struct TALER_ReservePublicKeyP *reserve_pub,
+  const struct TALER_ExchangePublicKeyP *pub,
+  const struct TALER_ExchangeSignatureP *sig)
+{
+  struct TALER_ReserveCloseConfirmationPS rcc = {
+    .purpose.size = htonl (sizeof (rcc)),
+    .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED),
+    .wtid = *wtid,
+    .reserve_pub = *reserve_pub,
+    .timestamp = GNUNET_TIME_timestamp_hton (timestamp)
+  };
+
+  TALER_amount_hton (&rcc.closing_amount,
+                     closing_amount);
+  TALER_amount_hton (&rcc.closing_fee,
+                     closing_fee);
+  TALER_payto_hash (payto,
+                    &rcc.h_payto);
+  return
+    GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED,
+                                &rcc,
+                                &sig->eddsa_signature,
+                                &pub->eddsa_pub);
+}
+
+
 /* end of exchange_signatures.c */
diff --git a/src/util/secmod_signatures.c b/src/util/secmod_signatures.c
index 8e629ebb..3b539d5f 100644
--- a/src/util/secmod_signatures.c
+++ b/src/util/secmod_signatures.c
@@ -23,6 +23,37 @@
 #include "taler_signatures.h"
 
 
+/**
+ * @brief format used by the signing crypto helper when affirming
+ *        that it created an exchange signing key.
+ */
+struct TALER_SigningKeyAnnouncementPS
+{
+
+  /**
+   * Purpose must be #TALER_SIGNATURE_SM_SIGNING_KEY.
+   * Used with an EdDSA signature of a `struct TALER_SecurityModulePublicKeyP`.
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * Public signing key of the exchange this is about.
+   */
+  struct TALER_ExchangePublicKeyP exchange_pub;
+
+  /**
+   * When does the key become available?
+   */
+  struct GNUNET_TIME_TimestampNBO anchor_time;
+
+  /**
+   * How long is the key available after @e anchor_time?
+   */
+  struct GNUNET_TIME_RelativeNBO duration;
+
+};
+
+
 void
 TALER_exchange_secmod_eddsa_sign (
   const struct TALER_ExchangePublicKeyP *exchange_pub,
@@ -69,6 +100,41 @@ TALER_exchange_secmod_eddsa_verify (
 }
 
 
+/**
+ * @brief format used by the denomination crypto helper when affirming
+ *        that it created a denomination key.
+ */
+struct TALER_DenominationKeyAnnouncementPS
+{
+
+  /**
+   * Purpose must be #TALER_SIGNATURE_SM_RSA_DENOMINATION_KEY.
+   * Used with an EdDSA signature of a `struct TALER_SecurityModulePublicKeyP`.
+   */
+  struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+  /**
+   * Hash of the denomination public key.
+   */
+  struct TALER_DenominationHashP h_denom;
+
+  /**
+   * Hash of the section name in the configuration of this denomination.
+   */
+  struct GNUNET_HashCode h_section_name;
+
+  /**
+   * When does the key become available?
+   */
+  struct GNUNET_TIME_TimestampNBO anchor_time;
+
+  /**
+   * How long is the key available after @e anchor_time?
+   */
+  struct GNUNET_TIME_RelativeNBO duration_withdraw;
+
+};
+
 void
 TALER_exchange_secmod_rsa_sign (
   const struct TALER_RsaPubHashP *h_rsa,

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