mte/src/binary_formats.ml
2025-10-17 17:30:02 +02:00

1091 lines
29 KiB
OCaml
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(* https://docs.taler.net/core/api-common.html#binary-formats
- numeric values are in network byte order (big endian) *)
(* structs that are packed and do not contain pointers and are
thus suitable for hashing or similar operations are distinguished
by adding a “P” at the end of the name. (NEW) Note that this convention
does not hold for the GNUnet-structs (yet).
structs that are used with a purpose for signatures,
additionally get an “S” at the end of the name.
(from https://docs.taler.net/taler-developer-manual.html) *)
(* TODO
- check that our struct are well packed
- it looks like Bin only define packed structs
- we don't need to worry about struct having "P" suffix
remove them
- test them
- some purpose (`TALER_SIGNATURE_XXX`) are missing
exchange and gana master branch are not in sync
and we should use a specific git tag instead
- clean up functor mess
don't have not hash thing be HashCode like
- have a make function for wrapped HashCode structs
make it take the relevant type *)
module Taler_signatures = Include.Taler_signatures
(* -- Crypto keys -- *)
module RsaPublicKey = struct
(* libgnuutil format:
https://docs.gnunet.org/doxygen/d9/dbe/structGNUNET__CRYPTO__RsaPublicKeyHeaderP.html
https://docs.gnunet.org/doxygen/d6/d70/group__libgnunetutil.html#ga9c99a81e8cd649c1c925d23211a0738f
https://www.gnupg.org/documentation/manuals/gcrypt/MPI-formats.html
format:
- rsa header
- modulus
- public_exponent
integer in big-endian format (MSB first).
Leading zeroes are stripped unless they are required to keep a value positive.
*)
type header = {
n_len: int;
e_len: int;
}
type t = {
header: header;
n: Z.t;
e: Z.t;
}
(* need to strip leading zeros or something? *)
let z_to_bigendian_bits v =
let s = Z.to_bits v in
let len = String.length s in
let s = String.init len (fun i -> s.[len - 1 - i]) in
s
let header_bin =
let open Bin in
record (fun n_len e_len -> { n_len; e_len })
|+ field beint16 (fun t -> t.n_len)
|+ field beint16 (fun t -> t.e_len)
|> sealr
let bin =
let open Bin in
record (fun header n e ->
let n = Z.of_bits n in
let e = Z.of_bits e in
{ header; n; e })
|+ field header_bin (fun t -> t.header)
(* TODO
Z.to_bits is in little endian but we need it in big endian *)
|+ field cstring (fun t -> z_to_bigendian_bits t.n)
|+ field cstring (fun t -> z_to_bigendian_bits t.e)
|> sealr
end
let int32_size = 4
let int64_size = 8
(* -- Time -- *)
(* microseconds since the UNIX Epoch. UINT64_MAX represents "never" *)
module MK_TIME () = struct
type t = { v: int64 }
(* not BE (?) *)
let bin =
let open Bin in
record (fun v -> { v }) |+ field neint64 (fun t -> t.v) |> sealr
end
module MK_TIME_NBO () = struct
type t = { v: int64 }
let bin =
let open Bin in
record (fun v -> { v }) |+ field beint64 (fun t -> t.v) |> sealr
end
module TimeAbsolute = MK_TIME ()
module TimeAbsoluteNBO = MK_TIME_NBO ()
module TimeRelative = MK_TIME ()
module TimeRelativeNBO = MK_TIME_NBO ()
module Timestamp = MK_TIME ()
module TimestampNBO = MK_TIME_NBO ()
(* -- Cryptographic primitives -- *)
(* MK_BASIC_XX functor for structs like:
struct Foo { uint8t bar[XX]; } *)
module MKMK_BASIC (S : sig
val v : int
end) =
struct
type t = { v: string }
let bin =
let open Bin in
record (fun v -> { v }) |+ field (bytes S.v) (fun t -> t.v) |> sealr
end
module SIZE_32 = struct
let v = 32
end
module SIZE_64 = struct
let v = 64
end
module MK_BASIC_32 () = MKMK_BASIC (SIZE_32)
module MK_BASIC_64 () = MKMK_BASIC (SIZE_64)
(* MK_XX functor for structs like:
struct FooWrap { struct Foo { uint8t bar[XX]; } } *)
module MKMK (S : sig
val v : int
end) =
struct
module H = MKMK_BASIC (S)
type t = { v: H.t }
let bin =
let open Bin in
record (fun v -> { v }) |+ field H.bin (fun t -> t.v) |> sealr
end
module MK_32 () = MKMK (SIZE_32)
module MK_64 () = MKMK (SIZE_64)
(* - *)
module ShortHashCode = MK_BASIC_32 ()
module HashCode = MK_BASIC_64 ()
module DenominationHash = MK_64 ()
module PrivateContractHash = MK_64 ()
module ExtensionsPolicyHash = MK_64 ()
module MerchantWireHash = MK_64 ()
(* Hash over a full payto://-URI, including receiver-name
(and possibly BIC and other optional fields). *)
module FullPaytoHash = MK_32 ()
(* Hash over a normalized payto://-URI, including all optional
fields and also with account-part canonicalized (so no BIC). *)
module NormalizedPaytoHash = MK_32 ()
(* TODO Taler doc: missing *)
module AgeCommitmentHash = MK_64 ()
(* TODO Taler doc: missing *)
module PublicRefreshCoinNonceP = MK_64 ()
(* TODO Taler doc: missing *)
module PursePublicKey = MK_32 ()
(* TODO Taler doc: missing *)
module AuditorPublicKeyP = MK_32 ()
(* TODO
// Secret for blinding/unblinding.
// An RSA blinding secret, which is basically
// a 256-bit nonce, converted to Crockford `Base32`.
type DenominationBlindingKeyP = string;
*)
module DenominationBlindingKeyP = MK_64 ()
(* Hash over:
a) the hash of the denomination's public key,
b) an enum value identifying the cipher, and
c) cipher-dependant blinded information.
See implementation of `TALER_CoinEvHash`
in libtalerexchange for details. *)
module BlindedCoinHash = MK_64 ()
(* -- *)
module CoinPubHash = MK_64 ()
module OutputCommitmentHash = MK_64 ()
module ReservePublicKeyP = MK_32 ()
module ReservePrivateKeyP = MK_32 ()
module ReserveSignatureP = MK_64 ()
module MerchantPublicKeyP = MK_32 ()
module MerchantPrivateKeyP = MK_32 ()
(*module MerchantSignatureP = MK_64 () *)
module TransferPublicKeyP = MK_32 ()
module TransferPrivateKeyP = MK_32 ()
(*
enum TALER_AmlDecisionState {
NORMAL, PENDING, FROZEN
};
*)
module AmlOfficerPublicKeyP = MK_32 ()
module AmlOfficerPrivateKeyP = MK_32 ()
module ExchangePublicKeyP = MK_32 ()
module ExchangePrivateKeyP = MK_32 ()
module ExchangeSignatureP = MK_64 ()
module MasterPublicKeyP = MK_32 ()
module MasterPrivateKeyP = MK_32 ()
module MasterSignatureP = MK_64 ()
module WireTransferIdentifierRawP = MK_BASIC_32 ()
module UUID = struct
(* uint32t value[4]; *)
type t = { value: string }
let size = 4 * int32_size
let bin =
let open Bin in
record (fun value -> { value })
|+ field (bytes size) (fun t -> t.value)
|> sealr
end
module WadId = struct
(* uint32t value[6]; *)
type t = { raw: string }
let size = 6 * int32_size
let bin =
let open Bin in
record (fun raw -> { raw }) |+ field (bytes size) (fun t -> t.raw) |> sealr
end
(* TODO not sure what to do of union, probably not needed *)
(*
union TALER_CoinSpendPublicKeyP {
uint8t eddsaPub[32];
uint8t ecdhePub[32];
};
union TALER_CoinSpendPrivateKeyP {
uint8t eddsaPriv[32];
uint8t ecdhePriv[32];
};
*)
module CoinSpendPublicKeyP = MK_32 ()
module CoinSpendPrivateKeyP = MK_32 ()
module CoinSpendSignatureP = MK_64 ()
(* TODO padding: sizeof used here (assume no padding for now) *)
(*
struct TALER_TransferSecretP {
uint8t key[sizeof (struct HashCode)];
};
uint8t key[sizeof (struct HashCode)];
};
struct TALER_EncryptedLinkSecretP {
uint8t enc[sizeof (struct TALER_LinkSecretP)];
};
*)
module TransferSecretP = MK_64 ()
module LinkSecretP = MK_64 ()
module EncryptedLinkSecretP = MK_64 ()
(*
union TALER_TokenPublicKeyP {
uint8t eddsaPub[32];
uint8t ecdhePub[32];
};
*)
module TokenPublicKeyP = MK_32 ()
(* -- Signatures -- *)
(* EccSignaturePurpose *)
module Purpose = struct
type t = {
(* This field equals the number of bytes being signed,
namely 'sizeof (struct Data)'. *)
size: int32;
(* This field is used to express the context in
which the signature is made, ensuring that a
signature cannot be lifted from one part of the protocol
to another. *)
purpose: int32;
}
let bin =
let open Bin in
record (fun size purpose -> { size; purpose })
|+ field beint32 (fun t -> t.size)
|+ field beint32 (fun t -> t.purpose)
|> sealr
let make ~size purpose = { size= Int32.of_int size; purpose }
let dummy = make ~size:0 0_l
(* helper function to make ['signature Bin.t] *)
let make_bin =
let get_size f =
let open Bin in
match Size.of_value (Size.size_of (f dummy)) with
| Dynamic _ | Unknown ->
Fmt.failwith "size_of failure: size is not Static"
| Static n -> n
in
fun code f -> make ~size:(get_size f) code |> f
let field purpose = Bin.field bin (fun _t -> purpose)
end
(* This is the running SHA512-hash over all
`TALER_BlindedCoinHashP` values of an array of coins.
Note that each `TALER_BlindedCoinHashP` itself
captures the hash of the corresponding denomination's
public key. *)
module HashPlanchetsP = MK_64 ()
module AgeMask = struct
type t = { mask: int32 }
let bin =
let open Bin in
record (fun mask -> { mask }) |+ field beint32 (fun t -> t.mask) |> sealr
end
(* TODO
- why is the non-NBO version only used in TALER_WithdrawRequestPS? *)
(* Number of characters (plus 1 for 0-termination) for currency names.
typically an ISO 4217 currency code when an alphanumeric 3-digit code is used.
For regional currencies, the first character should be a "*" followed
by a region-specific name (i.e. "*BRETAGNEFR").
Currency string, left adjusted and padded with zeros. All zeros
for "invalid" values. *)
let currency_len = 12
(* TODO Taler doc: missing
found in src/include/taler/taler_amount_lib.h *)
module Amount = struct
type t = {
value: int64;
fraction: int32;
currency: string;
}
(* TODO BE here? *)
let bin =
let open Bin in
record (fun value fraction currency -> { value; fraction; currency })
|+ field beint64 (fun t -> t.value)
|+ field beint32 (fun t -> t.fraction)
|+ field (bytes currency_len) (fun t -> t.currency)
|> sealr
end
module AmountNBO = struct
type t = {
value: int64;
fraction: int32;
currency: string;
}
let bin =
let open Bin in
record (fun value fraction currency -> { value; fraction; currency })
|+ field beint64 (fun t -> t.value)
|+ field beint32 (fun t -> t.fraction)
|+ field (bytes currency_len) (fun t -> t.currency)
|> sealr
end
module BlindingMasterSeed = MK_BASIC_32 ()
module WithdrawRequestPS = struct
(* Purpose is #TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW *)
type t = {
amount: Amount.t;
fee: Amount.t;
h_planchets: HashPlanchetsP.t;
(* TODO TALER doc
`TALER_BlindingMasterSecretP` in doc, but probably TALER_BlindingMasterSeed *)
blinding_seed: BlindingMasterSeed.t;
max_age_group: int32;
mask: AgeMask.t;
}
let bin =
let open Bin in
Purpose.make_bin Taler_signatures.wallet_reserve_withdraw @@ fun purpose ->
record
(fun _purpose amount fee h_planchets blinding_seed max_age_group mask ->
{ amount; fee; h_planchets; blinding_seed; max_age_group; mask })
|+ Purpose.field purpose
|+ field Amount.bin (fun t -> t.amount)
|+ field Amount.bin (fun t -> t.fee)
|+ field HashPlanchetsP.bin (fun t -> t.h_planchets)
|+ field BlindingMasterSeed.bin (fun t -> t.blinding_seed)
|+ field beint32 (fun t -> t.max_age_group)
|+ field AgeMask.bin (fun t -> t.mask)
|> sealr
end
module WithdrawConfirmationPS = struct
(* Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW.
Signed by a `struct TALER_ExchangePrivateKeyP` using EdDSA. *)
type t = {
(* TODO TALER doc
missing TALER_HashBlindedPlanchetsP*)
h_planchets: HashPlanchetsP.t;
noreveal_index: int32;
}
let bin =
let open Bin in
Purpose.make_bin Taler_signatures.exchange_confirm_withdraw
@@ fun purpose ->
record (fun _purpose h_planchets noreveal_index ->
{ h_planchets; noreveal_index })
|+ Purpose.field purpose
|+ field HashPlanchetsP.bin (fun t -> t.h_planchets)
|+ field beint32 (fun t -> t.noreveal_index)
|> sealr
end
module DenominationKeyAnnouncementPS = struct
(* TODO taler_signatures purpose
we use TALER_SIGNATURE_SM_RSA_DENOMINATION_KEY instead here *)
(* purpose.purpose = TALER_SIGNATURE_SM_DENOMINATION_KEY *)
type t = {
h_denom_pub: DenominationHash.t;
h_section_name: HashCode.t;
anchor_time: TimeAbsoluteNBO.t;
duration_withdraw: TimeRelativeNBO.t;
}
let bin =
let open Bin in
Purpose.make_bin Taler_signatures.sm_rsa_denomination_key @@ fun purpose ->
record
(fun _purpose h_denom_pub h_section_name anchor_time duration_withdraw ->
{ h_denom_pub; h_section_name; anchor_time; duration_withdraw })
|+ Purpose.field purpose
|+ field DenominationHash.bin (fun t -> t.h_denom_pub)
|+ field HashCode.bin (fun t -> t.h_section_name)
|+ field TimeAbsoluteNBO.bin (fun t -> t.anchor_time)
|+ field TimeRelativeNBO.bin (fun t -> t.duration_withdraw)
|> sealr
end
module SigningKeyAnnouncementPS = struct
(* purpose.purpose = TALER_SIGNATURE_SM_SIGNING_KEY *)
type t = {
exchange_pub: ExchangePublicKeyP.t;
anchor_time: TimeAbsoluteNBO.t;
duration: TimeRelativeNBO.t;
}
let bin =
let open Bin in
Purpose.make_bin Taler_signatures.sm_signing_key @@ fun purpose ->
record (fun _purpose exchange_pub anchor_time duration ->
{ exchange_pub; anchor_time; duration })
|+ Purpose.field purpose
|+ field ExchangePublicKeyP.bin (fun t -> t.exchange_pub)
|+ field TimeAbsoluteNBO.bin (fun t -> t.anchor_time)
|+ field TimeRelativeNBO.bin (fun t -> t.duration)
|> sealr
end
(* --- BIN IMPL END --- *)
module SingleWithdrawRequestPS = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW *)
type t = {
amount_with_fee: AmountNBO.t;
h_denomination_pub: DenominationHash.t;
h_coin_envelope: BlindedCoinHash.t;
}
end
module DepositRequestPS = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_COIN_DEPOSIT *)
type t = {
h_contract_terms: PrivateContractHash.t;
h_age_commitment: AgeCommitmentHash.t;
h_policy: ExtensionsPolicyHash.t;
h_wire: MerchantWireHash.t;
h_denom_pub: DenominationHash.t;
timestamp: TimeAbsoluteNBO.t;
refund_deadline: TimeAbsoluteNBO.t;
amount_with_fee: AmountNBO.t;
deposit_fee: AmountNBO.t;
merchant: MerchantPublicKeyP.t;
wallet_data_hash: HashCode.t;
}
end
module DepositConfirmationPS = struct
(* purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT *)
type t = {
h_contract_terms: PrivateContractHash.t;
h_wire: MerchantWireHash.t;
h_policy: ExtensionsPolicyHash.t;
timestamp: TimeAbsoluteNBO.t;
refund_deadline: TimeAbsoluteNBO.t;
amount_without_fee: AmountNBO.t;
coin_pub: CoinSpendPublicKeyP.t;
merchant: MerchantPublicKeyP.t;
}
end
module RefreshCommitmentP = MK_64 ()
module RefreshMeltCoinAffirmationPS = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_COIN_MELT *)
type t = {
session_hash: RefreshCommitmentP.t;
h_denom_pub: DenominationHash.t;
h_age_commitment: AgeCommitmentHash.t;
amount_with_fee: AmountNBO.t;
melt_fee: AmountNBO.t;
}
end
module RefreshMeltConfirmationPS = struct
(* purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT *)
type t = {
session_hash: RefreshCommitmentP.t;
noreveal_index: int; (* uint16_t mapped to OCaml int *)
}
end
module ExchangeSigningKeyValidityPS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_SIGNING_KEY_VALIDITY *)
type t = {
start: TimeAbsoluteNBO.t;
expire: TimeAbsoluteNBO.t;
end_: TimeAbsoluteNBO.t; (* "end" renamed to end_ *)
signkey_pub: ExchangePublicKeyP.t;
}
end
module ExchangeKeySetPS = struct
(* purpose.purpose = TALER_SIGNATURE_EXCHANGE_KEY_SET *)
type t = {
list_issue_date: TimeAbsoluteNBO.t;
hc: HashCode.t;
}
end
module DenominationKeyValidityPS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_DENOMINATION_KEY_VALIDITY *)
type t = {
master: MasterPublicKeyP.t;
start: TimeAbsoluteNBO.t;
expire_withdraw: TimeAbsoluteNBO.t;
expire_spend: TimeAbsoluteNBO.t;
expire_legal: TimeAbsoluteNBO.t;
value: AmountNBO.t;
fee_withdraw: AmountNBO.t;
fee_deposit: AmountNBO.t;
fee_refresh: AmountNBO.t;
denom_hash: DenominationHash.t;
}
end
module MasterWireDetailsPS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_WIRE_DETAILS *)
type t = {
h_wire_details: FullPaytoHash.t;
h_conversion_url: HashCode.t;
h_credit_restrictions: HashCode.t;
h_debit_restrictions: HashCode.t;
}
end
module MasterWireFeePS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_WIRE_FEES *)
type t = {
h_wire_method: HashCode.t;
start_date: TimeAbsoluteNBO.t;
end_date: TimeAbsoluteNBO.t;
wire_fee: AmountNBO.t;
closing_fee: AmountNBO.t;
}
end
module GlobalFeesPS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_GLOBAL_FEES *)
type t = {
start_date: TimeAbsoluteNBO.t;
end_date: TimeAbsoluteNBO.t;
purse_timeout: TimeRelativeNBO.t;
kyc_timeout: TimeRelativeNBO.t;
history_expiration: TimeRelativeNBO.t;
history_fee: AmountNBO.t;
kyc_fee: AmountNBO.t;
account_fee: AmountNBO.t;
purse_fee: AmountNBO.t;
purse_account_limit: int; (* uint32_t → int *)
}
end
module MasterDrainProfitPS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_DRAIN_PROFITS *)
type t = {
wtid: WireTransferIdentifierRawP.t;
date: TimeAbsoluteNBO.t;
amount: AmountNBO.t;
h_section: HashCode.t;
h_payto: FullPaytoHash.t;
}
end
module DepositTrackPS = struct
(* purpose.purpose = TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION *)
type t = {
h_contract_terms: PrivateContractHash.t;
h_wire: MerchantWireHash.t;
coin_pub: CoinSpendPublicKeyP.t;
}
end
module WireDepositDetailP = struct
type t = {
h_contract_terms: PrivateContractHash.t;
execution_time: TimeAbsoluteNBO.t;
coin_pub: CoinSpendPublicKeyP.t;
deposit_value: AmountNBO.t;
deposit_fee: AmountNBO.t;
}
end
module WireDepositDataPS = struct
(* purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT *)
type t = {
total: AmountNBO.t;
wire_fee: AmountNBO.t;
merchant_pub: MerchantPublicKeyP.t;
h_wire: MerchantWireHash.t;
h_details: HashCode.t;
}
end
module ExchangeKeyValidityPS = struct
(* purpose.purpose = TALER_SIGNATURE_AUDITOR_EXCHANGE_KEYS *)
type t = {
auditor_url_hash: HashCode.t;
master: MasterPublicKeyP.t;
start: TimeAbsoluteNBO.t;
expire_withdraw: TimeAbsoluteNBO.t;
expire_spend: TimeAbsoluteNBO.t;
expire_legal: TimeAbsoluteNBO.t;
value: AmountNBO.t;
fee_withdraw: AmountNBO.t;
fee_deposit: AmountNBO.t;
fee_refresh: AmountNBO.t;
denom_hash: DenominationHash.t;
}
end
module PaymentResponsePS = struct
(* purpose.purpose = TALER_SIGNATURE_MERCHANT_PAYMENT_OK *)
type t = { h_contract_terms: PrivateContractHash.t }
end
module ContractPS = struct
(* purpose.purpose = TALER_SIGNATURE_MERCHANT_CONTRACT *)
type t = { h_contract_terms: PrivateContractHash.t }
end
module ConfirmWirePS = struct
(* purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE *)
type t = {
h_wire: MerchantWireHash.t;
h_contract_terms: PrivateContractHash.t;
wtid: WireTransferIdentifierRawP.t;
coin_pub: CoinSpendPublicKeyP.t;
execution_time: TimeAbsoluteNBO.t;
coin_contribution: AmountNBO.t;
}
end
module RefundConfirmationPS = struct
(* purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND *)
type t = {
h_contract_terms: PrivateContractHash.t;
coin_pub: CoinSpendPublicKeyP.t;
merchant: MerchantPublicKeyP.t;
rtransaction_id: int64;
refund_amount: AmountNBO.t;
}
end
module DepositTrackPS2 = struct
(* purpose.purpose = TALER_SIGNATURE_MERCHANT_TRACK_TRANSACTION *)
type t = {
h_contract_terms: PrivateContractHash.t;
h_wire: MerchantWireHash.t;
merchant: MerchantPublicKeyP.t;
coin_pub: CoinSpendPublicKeyP.t;
}
end
module RefundRequestPS = struct
(* purpose.purpose = TALER_SIGNATURE_MERCHANT_REFUND *)
type t = {
h_contract_terms: PrivateContractHash.t;
coin_pub: CoinSpendPublicKeyP.t;
rtransaction_id: int64;
refund_amount: AmountNBO.t;
refund_fee: AmountNBO.t;
}
end
module MerchantRefundConfirmationPS = struct
(* purpose.purpose = TALER_SIGNATURE_MERCHANT_REFUND_OK *)
(* Hash of the order ID (a string), hashed without the 0-termination. *)
type t = { h_order_id: HashCode.t }
end
module RecoupRequestPS = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_COIN_RECOUP or TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH *)
type t = {
h_denom_pub: DenominationHash.t;
coin_blind: DenominationBlindingKeyP.t;
}
end
module RecoupRefreshConfirmationPS = struct
(* purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH *)
type t = {
timestamp: TimeAbsoluteNBO.t;
recoup_amount: AmountNBO.t;
coin_pub: CoinSpendPublicKeyP.t;
old_coin_pub: CoinSpendPublicKeyP.t;
}
end
module RecoupConfirmationPS = struct
(* purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP *)
type t = {
timestamp: TimeAbsoluteNBO.t;
recoup_amount: AmountNBO.t;
coin_pub: CoinSpendPublicKeyP.t;
reserve_pub: ReservePublicKeyP.t;
}
end
module DenominationUnknownAffirmationPS = struct
(* purpose.purpose = TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN *)
type t = {
timestamp: TimeAbsoluteNBO.t;
h_denom_pub: DenominationHash.t;
}
end
module DenominationExpiredAffirmationPS = struct
(* purpose.purpose = TALER_SIGNATURE_EXCHANGE_GENERIC_DENOMINATIN_EXPIRED *)
type t = {
timestamp: TimeAbsoluteNBO.t;
operation: string; (* char[8] → string *)
h_denom_pub: DenominationHash.t;
}
end
module ReserveCloseConfirmationPS = struct
(* purpose.purpose = TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED *)
type t = {
timestamp: TimeAbsoluteNBO.t;
closing_amount: AmountNBO.t;
reserve_pub: ReservePublicKeyP.t;
h_wire: FullPaytoHash.t;
}
end
module CoinLinkSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_COIN_LINK *)
type t = {
h_denom_pub: DenominationHash.t;
old_coin_pub: CoinSpendPublicKeyP.t;
transfer_pub: TransferPublicKeyP.t;
coin_envelope_hash: BlindedCoinHash.t;
}
end
module RefreshNonceSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_COIN_LINK *)
type t = { nonce: PublicRefreshCoinNonceP.t }
end
module ReserveStatusRequestSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_RESERVE_STATUS_REQUEST *)
type t = { request_timestamp: TimeAbsoluteNBO.t }
end
module ReserveHistoryRequestSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_RESERVE_HISTORY_REQUEST *)
type t = {
history_fee: AmountNBO.t;
request_timestamp: TimeAbsoluteNBO.t;
}
end
module PurseStatusRequestSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_PURSE_STATUS_REQUEST *)
type t = unit
end
module PurseStatusResponseSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_PURSE_STATUS_RESPONSE *)
type t = {
total_purse_amount: AmountNBO.t;
total_deposit_amount: AmountNBO.t;
max_deposit_fees: AmountNBO.t;
purse_expiration: TimeAbsoluteNBO.t;
status_timestamp: TimeAbsoluteNBO.t;
h_contract_terms: PrivateContractHash.t;
}
end
module ReserveCloseRequestSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_CLOSE *)
type t = unit
end
module PurseRequestSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_PURSE_CREATE *)
type t = {
purse_expiration: TimeAbsoluteNBO.t;
merge_value_after_fees: AmountNBO.t;
h_contract_terms: PrivateContractHash.t;
min_age: int;
}
end
module PurseDepositSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_PURSE_DEPOSIT *)
type t = {
coin_contribution: AmountNBO.t;
h_denom_pub: DenominationHash.t;
h_age_commitment: AgeCommitmentHash.t;
purse_pub: PursePublicKey.t;
h_exchange_base_url: HashCode.t;
}
end
module PurseDepositSignaturePS2 = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT *)
type t = {
reserve_sig: ReserveSignatureP.t;
coin_contribution: AmountNBO.t;
}
end
module PurseDepositConfirmedSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_PURSE_DEPOSIT_CONFIRMED *)
type t = {
total_purse_amount: AmountNBO.t;
total_deposit_fees: AmountNBO.t;
purse_pub: PursePublicKey.t;
purse_expiration: TimeAbsoluteNBO.t;
h_contract_terms: PrivateContractHash.t;
}
end
module PurseMergeSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_PURSE_MERGE *)
type t = {
merge_timestamp: TimeAbsoluteNBO.t;
h_wire: NormalizedPaytoHash.t;
}
end
module AccountMergeSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_ACCOUNT_MERGE *)
type t = {
reserve_pub: ReservePublicKeyP.t;
purse_pub: PursePublicKey.t;
merge_amount_after_fees: AmountNBO.t;
merge_timestamp: TimeAbsoluteNBO.t;
purse_expiration: TimeAbsoluteNBO.t;
h_contract_terms: PrivateContractHash.t;
min_age: int;
}
end
module AccountSetupRequestSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_ACCOUNT_SETUP *)
type t = { threshold: AmountNBO.t }
end
module PurseMergeSuccessSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_PURSE_MERGE_SUCCESS *)
type t = {
reserve_pub: ReservePublicKeyP.t;
purse_pub: PursePublicKey.t;
merge_amount_after_fees: AmountNBO.t;
contract_time: TimeAbsoluteNBO.t;
h_contract_terms: PrivateContractHash.t;
h_wire: NormalizedPaytoHash.t;
min_age: int;
}
end
module WadDataSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_WAD_DATA *)
type t = {
wad_execution_time: TimeAbsoluteNBO.t;
total_amount: AmountNBO.t;
h_items: HashCode.t;
wad_id: WadId.t;
}
end
module WadPartnerSignaturePS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_PARTNER_DETAILS *)
type t = {
h_partner_base_url: HashCode.t;
master_public_key: MasterPublicKeyP.t;
start_date: TimeAbsoluteNBO.t;
end_date: TimeAbsoluteNBO.t;
wad_fee: AmountNBO.t;
wad_frequency: TimeRelativeNBO.t;
}
end
module P2PFeesPS = struct
(* purpose.purpose = TALER_SIGNATURE_P2P_FEES *)
type t = {
start_date: TimeAbsoluteNBO.t;
end_date: TimeAbsoluteNBO.t;
kyc_fee: AmountNBO.t;
purse_fee: AmountNBO.t;
account_history_fee: AmountNBO.t;
account_annual_fee: AmountNBO.t;
account_kyc_timeout: TimeRelativeNBO.t;
purse_timeout: TimeRelativeNBO.t;
purse_account_limit: int;
}
end
module CoinPurseRefundConfirmationPS = struct
(* purpose.purpose = TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND *)
type t = {
purse_pub: PursePublicKey.t;
coin_pub: CoinSpendPublicKeyP.t;
refunded_amount: AmountNBO.t;
refund_fee: AmountNBO.t;
}
end
module MasterDenominationKeyRevocationPS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_DENOMINATION_KEY_REVOKED *)
type t = { h_denom_pub: DenominationHash.t }
end
module MasterSigningKeyRevocationPS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_SIGNING_KEY_REVOKED *)
type t = { exchange_pub: ExchangePublicKeyP.t }
end
module MasterAddAuditorPS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_ADD_AUDITOR *)
type t = {
start_date: TimeAbsoluteNBO.t;
auditor_pub: AuditorPublicKeyP.t;
h_auditor_url: HashCode.t;
}
end
module MasterDelAuditorPS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_DEL_AUDITOR *)
type t = {
end_date: TimeAbsoluteNBO.t;
auditor_pub: AuditorPublicKeyP.t;
}
end
module MasterAddWirePS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_ADD_WIRE *)
type t = {
start_date: TimeAbsoluteNBO.t;
h_wire: FullPaytoHash.t;
h_conversion_url: HashCode.t;
h_credit_restrictions: HashCode.t;
h_debit_restrictions: HashCode.t;
}
end
module MasterDelWirePS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_DEL_WIRE *)
type t = {
end_date: TimeAbsoluteNBO.t;
h_wire: FullPaytoHash.t;
}
end
module MasterAmlOfficerStatusPS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_AML_KEY *)
type t = {
change_date: TimestampNBO.t;
officer_pub: AmlOfficerPublicKeyP.t;
h_officer_name: HashCode.t;
is_active: int;
}
end
module AmlDecisionPS = struct
(* purpose.purpose = TALER_SIGNATURE_AML_DECISION *)
type t = {
h_justification: HashCode.t;
decision_time: TimestampNBO.t;
new_threshold: AmountNBO.t;
h_payto: NormalizedPaytoHash.t;
h_kyc_requirements: HashCode.t;
new_state: int;
}
end
module PartnerConfigurationPS = struct
(* purpose.purpose = TALER_SIGNATURE_MASTER_PARNTER_DETAILS *)
type t = {
partner_pub: MasterPublicKeyP.t;
start_date: TimestampNBO.t;
end_date: TimestampNBO.t;
wad_frequency: TimeRelativeNBO.t;
wad_fee: AmountNBO.t;
h_url: HashCode.t;
}
end
module ReserveOpenPS = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_OPEN *)
type t = {
reserve_payment: AmountNBO.t;
request_timestamp: TimestampNBO.t;
reserve_expiration: TimestampNBO.t;
purse_limit: int;
}
end
module ReserveClosePS = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_RESERVE_CLOSE *)
type t = {
request_timestamp: TimestampNBO.t;
target_account_h_payto: FullPaytoHash.t;
}
end
module ReserveAttestRequestPS = struct
(* purpose.purpose = TALER_SIGNATURE_WALLET_ATTEST_REQUEST *)
type t = {
request_timestamp: TimestampNBO.t;
h_details: HashCode.t;
}
end
module ExchangeAttestPS = struct
(* purpose.purpose = TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS *)
type t = {
attest_timestamp: TimestampNBO.t;
expiration_time: TimestampNBO.t;
reserve_pub: ReservePublicKeyP.t;
h_attributes: HashCode.t;
}
end