commit 018ea9e7e0bcadbbd849f3f90cbbd08cee1c48c2
parent 3ad0ff1ca646cdb9e1d5d9a0432a99bccf868f4e
Author: Mikolai Gütschow <mikolai.guetschow@tu-dresden.de>
Date: Mon, 11 Aug 2025 19:27:42 +0200
notation: bigEndian -> uintx
Diffstat:
2 files changed, 233 insertions(+), 188 deletions(-)
diff --git a/draft-guetschow-taler-protocol.md b/draft-guetschow-taler-protocol.md
@@ -57,16 +57,12 @@ Use at your own risk!
- `"abc"` denotes the literal string `abc` encoded as ASCII [RFC20]
- `a | b` denotes the concatenation of a with b
-- `padZero(12, a)` denotes the byte string a, zero-padded to the length of 12 bytes
-- `bits(x)` (`bytes(x)`) denotes the minimal number of bits (bytes) necessary to represent the multiple precision integer x
-- `bigEndian(16, x)` denotes the 16 least significant bits of the integer x encoded in network byte order (big-endian)
-- `bigEndianAmount(amount)` is formed from a fixed-point representation of `amount`
- as `bigEndian(64, amount.value) | bigEndian(32, amount.fraction) | padZero(12, amount.currency)`,
- where `amount.value` is the non-negative integer part of the base currency,
- `amount.fraction` is given in unites of one hundred millionth (1e-8) of the base currency,
- and `amount.currency` are the 3-11 ASCII characters used as currency code by the exchange.
-- `random(256)` denotes a randomly generated sequence of 256 bits
-- `a * b (mod N)` denotes the multiplication, `a ** b (mod N)` the exponentiation of a and b, modulo N
+- `padZero(y, a)` denotes the byte string a, zero-padded to the length of y bytes
+- `bits(x)`/`bytes(x)` denotes the minimal number of bits/bytes necessary to represent the multiple precision integer x
+- `uint(y, x)` denotes the `y` least significant bits of the integer `x` encoded in network byte order (big endian)
+- `uint16(x)`/`uint32(x)`/`uint64(x)`/`uint256(x)`/`uint512(x)` is equivalent to `uint(16, x)`/`uint(32, x)`/`uint(64, x)`/`uint(256, x)`/`uint(512, x)`, respectively
+- `random(y)` denotes a randomly generated sequence of y bits
+- `a * b (mod N)` / `a ** b (mod N)` denotes the multiplication / exponentiation of multiple precision integers a and b, modulo N
# Cryptographic Primitives
@@ -198,8 +194,8 @@ The final output `OKM` is determined deterministically based on a counter initia
~~~
counter = 0
do until OKM < N:
- x = HKDF(salt, IKM, info | bigEndian(16, counter), bytes(N))
- OKM = bigEndian(bits(N), x)
+ x = HKDF(salt, IKM, info | uint16(counter), bytes(N))
+ OKM = uint(bits(N), x)
counter += 1
~~~
@@ -228,7 +224,7 @@ Output:
~~~
info = "RSA-FDA FTpsW!"
-salt = bigEndian(16, bytes(pubkey.N)) | bigEndian(16, bytes(pubkey.e))
+salt = uint16(bytes(pubkey.N)) | uint16(bytes(pubkey.e))
| pubkey.N | pubkey.e
fdh = HKDF-Mod(pubkey.N, salt, msg, info)
~~~
@@ -345,6 +341,29 @@ out = (data == exp)
# The Taler Crypto Protocol
+## Datatypes
+
+### Amount
+
+Amounts are represented in Taler as positive fixed-point values
+consisting of `value` as the non-negative integer part of the base currency,
+the `fraction` given in units of one hundred millionth (1e-8) of the base currency,
+and `currency` as the 3-11 ASCII characters identifying the currency.
+
+Whenever used in the protocol, the binary representation of an `amount` is
+`uint64(amount.value) | uint32(amount.fraction) | padZero(12, amount.currency)`.
+
+### Timestamps
+
+Absolute timestamps are represented as `uint64(x)` where `x` corresponds to
+the microseconds since `1970-01-01 00:00 CEST` (the UNIX epoch).
+The special value `0xFFFFFFFFFFFFFFFF` represents "never".
+<!--
+// todo: check if needed and correct
+Relative timestamps are represented as `uint64(x)` where `x` is given in microseconds.
+The special value `0xFFFFFFFFFFFFFFFF` represents "forever".
+-->
+
// todo: explain persist, check
## Withdrawal
@@ -371,7 +390,7 @@ persist (reserve, value) |
master_secret = random(256) |
persist master_secret |
*(coin, blind_secret) = GenerateCoin(master_secret, ?*) |
-*coin.h_denom = SHA-512(bigEndian(32, 0) | bigEndian(32, 1) | denom.pub)
+*coin.h_denom = SHA-512(uint32(0) | uint32(1) | denom.pub)
*blind_coin = RSA-FDH-Blind(SHA-512(coin.pub), blind_secret, denom.pub)
sig0 = EdDSA-Sign(reserve.priv, msg0) |
| |
@@ -398,11 +417,11 @@ persist *(coin, blind_secret)
where `msg0` is formed as follows:
~~~
-msg0 = bigEndian(32, 160) | bigEndian(32, 1200) /* TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW */
- | bigEndianAmount(sum(*denom.value)) | bigEndianAmount(sum(*denom.fee_withdraw))
- | SHA-512( *(SHA-512(denom.pub) | bigEndian(32, 0x1) | blind_coin) )
- | bigEndian(256, 0x0)
- | bigEndian(32, 0x0) | bigEndian(32, 0x0)
+msg0 = uint32(160) | uint32(1200) /* TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW */
+ | sum(*denom.value) | sum(*denom.fee_withdraw)
+ | SHA-512( *(SHA-512(denom.pub) | uint32(0x1) | blind_coin) )
+ | uint256(0x0)
+ | uint32(0x0) | uint32(0x0)
~~~
The wallet derives coins and blinding secrets using `GenerateCoin` from a master secret and an integer index.
@@ -426,7 +445,7 @@ Output:
`coin` and `blind_secret` are calculated as follows:
~~~
-tmp = HKDF(bigEndian(32, idx), master_secret, "taler-withdrawal-coin-derivation", 64)
+tmp = HKDF(uint32(idx), master_secret, "taler-withdrawal-coin-derivation", 64)
(coin.priv, bks) = (tmp[:32], tmp[32:])
coin.pub = EdDSA-GetPub(coin.priv)
~~~
@@ -489,15 +508,15 @@ where `msg0`, `*msg1`, and `msg2` are formed as follows:
~~~
h_contract = SHA-512(canonicalJSON(contract))
-msg0 = bigEndian(32, 72) | bigEndian(32, 1101) /* TALER_SIGNATURE_MERCHANT_CONTRACT */
+msg0 = uint32(72) | uint32(1101) /* TALER_SIGNATURE_MERCHANT_CONTRACT */
| h_contract
-*msg1 = bigEndian(32, 456) | bigEndian(32, 1201) /* TALER_SIGNATURE_WALLET_COIN_DEPOSIT */
- | h_contract | bigEndian(256, 0x0)
- | bigEndian(512, 0x0) | contract.h_wire | *coin.h_denom
- | bigEndianTime(contract.timestamp) | bigEndianTime(contract.refund_deadline)
- | bigEndianAmount(*fraction + *denom.fee_deposit)
- | bigEndianAmount(*denom.fee_deposit) | merchant.pub | bigEndian(512, 0x0)
-msg2 = bigEndian(32, 72) | bigEndian(32, 1104) /* TALER_SIGNATURE_MERCHANT_PAYMENT_OK */
+*msg1 = uint32(456) | uint32(1201) /* TALER_SIGNATURE_WALLET_COIN_DEPOSIT */
+ | h_contract | uint256(0x0)
+ | uint512(0x0) | contract.h_wire | *coin.h_denom
+ | contract.timestamp | contract.refund_deadline
+ | *fraction + *denom.fee_deposit
+ | *denom.fee_deposit | merchant.pub | uint512(0x0)
+msg2 = uint32(72) | uint32(1104) /* TALER_SIGNATURE_MERCHANT_PAYMENT_OK */
| h_contract
~~~
@@ -543,11 +562,11 @@ check EdDSA-Verify(exchange.pub, msg3, sig3) |
where `msg3` is formed as follows:
~~~
-msg3 = bigEndian(32, 344) | bigEndian(32, 1033) /* TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT */
- | h_contract | contract.h_wire | bigEndian(512, 0x0)
- | bigEndianTime(exchange_timestamp) | bigEndianTime(contract.wire_deadline)
- | bigEndianTime(contract.refund_deadline)
- | bigEndianAmount(sum(*deposit.fraction - *denom.fee_deposit))
+msg3 = uint32(344) | uint32(1033) /* TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT */
+ | h_contract | contract.h_wire | uint512(0x0)
+ | exchange_timestamp | contract.wire_deadline
+ | contract.refund_deadline
+ | sum(*deposit.fraction - *denom.fee_deposit)
| SHA-512(*deposit.sig1) | merchant.pub
~~~
diff --git a/draft-guetschow-taler-protocol.xml b/draft-guetschow-taler-protocol.xml
@@ -29,7 +29,7 @@
</address>
</author>
- <date year="2025" month="June" day="30"/>
+ <date year="2025" month="August" day="11"/>
<workgroup>independent</workgroup>
@@ -68,16 +68,12 @@ Use at your own risk!</t>
<t><list style="symbols">
<t><spanx style="verb">"abc"</spanx> denotes the literal string <spanx style="verb">abc</spanx> encoded as ASCII <xref target="RFC20"></xref></t>
<t><spanx style="verb">a | b</spanx> denotes the concatenation of a with b</t>
- <t><spanx style="verb">padZero(12, a)</spanx> denotes the byte string a, zero-padded to the length of 12 bytes</t>
- <t><spanx style="verb">bits(x)</spanx> (<spanx style="verb">bytes(x)</spanx>) denotes the minimal number of bits (bytes) necessary to represent the multiple precision integer x</t>
- <t><spanx style="verb">bigEndian(16, x)</spanx> denotes the 16 least significant bits of the integer x encoded in network byte order (big-endian)</t>
- <t><spanx style="verb">bigEndianAmount(amount)</spanx> is formed from a fixed-point representation of <spanx style="verb">amount</spanx>
-as <spanx style="verb">bigEndian(64, amount.value) | bigEndian(32, amount.fraction) | padZero(12, amount.currency)</spanx>,
-where <spanx style="verb">amount.value</spanx> is the non-negative integer part of the base currency,
-<spanx style="verb">amount.fraction</spanx> is given in unites of one hundred millionth (1e-8) of the base currency,
-and <spanx style="verb">amount.currency</spanx> are the 3-11 ASCII characters used as currency code by the exchange.</t>
- <t><spanx style="verb">random(256)</spanx> denotes a randomly generated sequence of 256 bits</t>
- <t><spanx style="verb">a * b (mod N)</spanx> denotes the multiplication, <spanx style="verb">a ** b (mod N)</spanx> the exponentiation of a and b, modulo N</t>
+ <t><spanx style="verb">padZero(y, a)</spanx> denotes the byte string a, zero-padded to the length of y bytes</t>
+ <t><spanx style="verb">bits(x)</spanx>/<spanx style="verb">bytes(x)</spanx> denotes the minimal number of bits/bytes necessary to represent the multiple precision integer x</t>
+ <t><spanx style="verb">uint(y, x)</spanx> denotes the <spanx style="verb">y</spanx> least significant bits of the integer <spanx style="verb">x</spanx> encoded in network byte order (big endian)</t>
+ <t><spanx style="verb">uint16(x)</spanx>/<spanx style="verb">uint32(x)</spanx>/<spanx style="verb">uint64(x)</spanx>/<spanx style="verb">uint256(x)</spanx>/<spanx style="verb">uint512(x)</spanx> is equivalent to <spanx style="verb">uint(16, x)</spanx>/<spanx style="verb">uint(32, x)</spanx>/<spanx style="verb">uint(64, x)</spanx>/<spanx style="verb">uint(256, x)</spanx>/<spanx style="verb">uint(512, x)</spanx>, respectively</t>
+ <t><spanx style="verb">random(y)</spanx> denotes a randomly generated sequence of y bits</t>
+ <t><spanx style="verb">a * b (mod N)</spanx> / <spanx style="verb">a ** b (mod N)</spanx> denotes the multiplication / exponentiation of multiple precision integers a and b, modulo N</t>
</list></t>
</section>
@@ -118,7 +114,7 @@ Output:
<section anchor="sha512-trunc"><name>SHA-512-256 (truncated SHA-512)</name>
<figure><artwork><![CDATA[
-SHA-512(msg) -> hash
+SHA-512-256(msg) -> hash
Input:
msg input message of length L < 2^125 octets
@@ -216,8 +212,8 @@ Output:
<figure><artwork><![CDATA[
counter = 0
do until OKM < N:
- x = HKDF(salt, IKM, info | bigEndian(16, counter), bytes(N))
- OKM = bigEndian(bits(N), x)
+ x = HKDF(salt, IKM, info | uint16(counter), bytes(N))
+ OKM = uint(bits(N), x)
counter += 1
]]></artwork></figure>
@@ -250,7 +246,7 @@ Output:
<figure><artwork><![CDATA[
info = "RSA-FDA FTpsW!"
-salt = bigEndian(16, bytes(pubkey.N)) | bigEndian(16, bytes(pubkey.e))
+salt = uint16(bytes(pubkey.N)) | uint16(bytes(pubkey.e))
| pubkey.N | pubkey.e
fdh = HKDF-Mod(pubkey.N, salt, msg, info)
]]></artwork></figure>
@@ -376,8 +372,34 @@ out = (data == exp)
</section>
<section anchor="the-taler-crypto-protocol"><name>The Taler Crypto Protocol</name>
+<section anchor="datatypes"><name>Datatypes</name>
+
+<section anchor="amount"><name>Amount</name>
+
+<t>Amounts are represented in Taler as positive fixed-point values
+consisting of <spanx style="verb">value</spanx> as the non-negative integer part of the base currency,
+the <spanx style="verb">fraction</spanx> given in units of one hundred millionth (1e-8) of the base currency,
+and <spanx style="verb">currency</spanx> as the 3-11 ASCII characters identifying the currency.</t>
+
+<t>Whenever used in the protocol, the binary representation of an <spanx style="verb">amount</spanx> is
+<spanx style="verb">uint64(amount.value) | uint32(amount.fraction) | padZero(12, amount.currency)</spanx>.</t>
+
+</section>
+<section anchor="timestamps"><name>Timestamps</name>
+
+<t>Absolute timestamps are represented as <spanx style="verb">uint64(x)</spanx> where <spanx style="verb">x</spanx> corresponds to
+the microseconds since <spanx style="verb">1970-01-01 00:00 CEST</spanx> (the UNIX epoch).
+The special value <spanx style="verb">0xFFFFFFFFFFFFFFFF</spanx> represents "never".
+<!--
+// todo: check if needed and correct
+Relative timestamps are represented as `uint64(x)` where `x` is given in microseconds.
+The special value `0xFFFFFFFFFFFFFFFF` represents "forever".
+--></t>
+
<t>// todo: explain persist, check</t>
+</section>
+</section>
<section anchor="withdrawal"><name>Withdrawal</name>
<t>The wallet creates <spanx style="verb">n > 0</spanx> coins and requests <spanx style="verb">n</spanx> signatures from the exchange,
@@ -402,7 +424,7 @@ persist (reserve, value) |
master_secret = random(256) |
persist master_secret |
*(coin, blind_secret) = GenerateCoin(master_secret, ?*) |
-*coin.h_denom = SHA-512(bigEndian(32, 0) | bigEndian(32, 1) | denom.pub)
+*coin.h_denom = SHA-512(uint32(0) | uint32(1) | denom.pub)
*blind_coin = RSA-FDH-Blind(SHA-512(coin.pub), blind_secret, denom.pub)
sig0 = EdDSA-Sign(reserve.priv, msg0) |
| |
@@ -429,11 +451,11 @@ persist *(coin, blind_secret)
<t>where <spanx style="verb">msg0</spanx> is formed as follows:</t>
<figure><artwork><![CDATA[
-msg0 = bigEndian(32, 160) | bigEndian(32, 1200) /* TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW */
- | bigEndianAmount(sum(*denom.value)) | bigEndianAmount(sum(*denom.fee_withdraw))
- | SHA-512( *(SHA-512(denom.pub) | bigEndian(32, 0x1) | blind_coin) )
- | bigEndian(256, 0x0)
- | bigEndian(32, 0x0) | bigEndian(32, 0x0)
+msg0 = uint32(160) | uint32(1200) /* TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW */
+ | sum(*denom.value) | sum(*denom.fee_withdraw)
+ | SHA-512( *(SHA-512(denom.pub) | uint32(0x1) | blind_coin) )
+ | uint256(0x0)
+ | uint32(0x0) | uint32(0x0)
]]></artwork></figure>
<t>The wallet derives coins and blinding secrets using <spanx style="verb">GenerateCoin</spanx> from a master secret and an integer index.
@@ -457,7 +479,7 @@ Output:
<t><spanx style="verb">coin</spanx> and <spanx style="verb">blind_secret</spanx> are calculated as follows:</t>
<figure><artwork><![CDATA[
-tmp = HKDF(bigEndian(32, idx), master_secret, "taler-withdrawal-coin-derivation", 64)
+tmp = HKDF(uint32(idx), master_secret, "taler-withdrawal-coin-derivation", 64)
(coin.priv, bks) = (tmp[:32], tmp[32:])
coin.pub = EdDSA-GetPub(coin.priv)
]]></artwork></figure>
@@ -521,15 +543,15 @@ check EdDSA-Verify(merchant.pub, msg2, sig2) |
<figure><artwork><![CDATA[
h_contract = SHA-512(canonicalJSON(contract))
-msg0 = bigEndian(32, 72) | bigEndian(32, 1101) /* TALER_SIGNATURE_MERCHANT_CONTRACT */
+msg0 = uint32(72) | uint32(1101) /* TALER_SIGNATURE_MERCHANT_CONTRACT */
| h_contract
-*msg1 = bigEndian(32, 456) | bigEndian(32, 1201) /* TALER_SIGNATURE_WALLET_COIN_DEPOSIT */
- | h_contract | bigEndian(256, 0x0)
- | bigEndian(512, 0x0) | contract.h_wire | *coin.h_denom
- | bigEndianTime(contract.timestamp) | bigEndianTime(contract.refund_deadline)
- | bigEndianAmount(*fraction + *denom.fee_deposit)
- | bigEndianAmount(*denom.fee_deposit) | merchant.pub | bigEndian(512, 0x0)
-msg2 = bigEndian(32, 72) | bigEndian(32, 1104) /* TALER_SIGNATURE_MERCHANT_PAYMENT_OK */
+*msg1 = uint32(456) | uint32(1201) /* TALER_SIGNATURE_WALLET_COIN_DEPOSIT */
+ | h_contract | uint256(0x0)
+ | uint512(0x0) | contract.h_wire | *coin.h_denom
+ | contract.timestamp | contract.refund_deadline
+ | *fraction + *denom.fee_deposit
+ | *denom.fee_deposit | merchant.pub | uint512(0x0)
+msg2 = uint32(72) | uint32(1104) /* TALER_SIGNATURE_MERCHANT_PAYMENT_OK */
| h_contract
]]></artwork></figure>
@@ -576,11 +598,11 @@ check EdDSA-Verify(exchange.pub, msg3, sig3) |
<t>where <spanx style="verb">msg3</spanx> is formed as follows:</t>
<figure><artwork><![CDATA[
-msg3 = bigEndian(32, 344) | bigEndian(32, 1033) /* TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT */
- | h_contract | contract.h_wire | bigEndian(512, 0x0)
- | bigEndianTime(exchange_timestamp) | bigEndianTime(contract.wire_deadline)
- | bigEndianTime(contract.refund_deadline)
- | bigEndianAmount(sum(*deposit.fraction - *denom.fee_deposit))
+msg3 = uint32(344) | uint32(1033) /* TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT */
+ | h_contract | contract.h_wire | uint512(0x0)
+ | exchange_timestamp | contract.wire_deadline
+ | contract.refund_deadline
+ | sum(*deposit.fraction - *denom.fee_deposit)
| SHA-512(*deposit.sig1) | merchant.pub
]]></artwork></figure>
@@ -692,7 +714,7 @@ msg3 = bigEndian(32, 344) | bigEndian(32, 1033) /* TALER_SIGNATURE_EXCHANGE_CONF
-<?line 562?>
+<?line 581?>
<section anchor="change-log"><name>Change log</name>
@@ -710,125 +732,129 @@ Education and Research (BMBF) within the project Concrete Contracts.</t>
</back>
<!-- ##markdown-source:
-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
-fiHJQNb3f2muy5AjSQAA
+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
-->