commit 67ff83ddd7b4cb077c9b783c1c64eb608cd49c0b
parent 8134ab719366f124819141f8dab2e0adcbd4d5ff
Author: Bohdan Potuzhnyi <bohdan.potuzhnyi@gmail.com>
Date: Wed, 8 Oct 2025 12:15:58 +0200
Adding an idea for the test vector + few english updates
Diffstat:
| M | draft-donau.xml | | | 106 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------- |
1 file changed, 88 insertions(+), 18 deletions(-)
diff --git a/draft-donau.xml b/draft-donau.xml
@@ -99,7 +99,7 @@
<t>
This specification only covers the syntax of the 'donau' URI
scheme and excludes details on the protocol(s) that would
- allow tax payers to donate to recognized charities to obtain
+ allow taxpayers to donate to recognized charities to obtain
these suitable signed donation statements. While a
privacy-preserving protocol to obtain such statements exists
within the context of the GNU Taler protocol suite, other
@@ -123,16 +123,16 @@
<t>
A 'donau' URI always instructs a Donau validator to perform the
validation of a Donau donation statement.
- A 'donau' URI consists of the reference to a the authority
+ A 'donau' URI consists of the reference to the authority
that signed the statement, an identifier for the specific taxpayer,
the year of the donation, a salt and optional parameters.
Optional parameters include the amount donated by the
- tax payer and the signature of the Donau donation statement.
+ taxpayer and the signature of the Donau donation statement.
</t>
</section>
<section title="Requirements Language">
<t>
- The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in BCP 14
<xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when,
@@ -172,7 +172,7 @@
target="RFC1123"/>, its IP v4 address <xref target="RFC791"/>, or
its IP v6 address <xref target="RFC8200"/>.
- The year of a Donau URI referes to the year where the donations
+ The year of a Donau URI referes to the year when the donations
have been done.
The taxid of a Donau URI referes to the taxid of the person that
@@ -181,7 +181,7 @@
The salt of a Donau URI referes to the information used by the
Donau-wallet application to generate the Donau donation statement. This salt is
- specific for each wallet, allowing a tax payer to have many Donau
+ specific for each wallet, allowing a taxpayer to have many Donau
donation statements for the same year that should be treated as
cummulative by the validator application. The salt can also be
used to obfuscate the taxpayer ID in the donation protocol.
@@ -229,10 +229,10 @@
</t>
</section>
-<section anchor="examples" title="Examples">
-<figure>
- <artwork><![CDATA[
- donau://example.com/2025/7560001010000/1234?total=EUR:15&sig=ED25519:SAAM5BA1F9H4VT6T78CFC3X63HAMY2TXB597XBVZ0EMXEZ90QPJ3000BXDBJ3ECHGB8AEX9FFQ5BAXVSF6X6NXM98PY353F2R99PP1R
+ <section anchor="examples" title="Examples">
+ <figure>
+ <artwork><![CDATA[
+ donau://example.com/2025/7560001010000/1234?total=EUR:15&sig=ED25519:H9PM3BW3P8MEKB34GZ0G1F7JSNVX7B8AHXRFFMS37QZM7TXZ5MWPXTEDZZGN1QRB1AFPKNCFXJB39NJHP3BAFGCZSCXHEYPHA1YJY28
]]>
</artwork>
</figure>
@@ -247,7 +247,7 @@
verify that the Donau-URI corresponds to a valid Donau donation
statement. The Donau verification application MUST verify the
validity of the donation statement. There are two possibilities:
- signature and total are available or at least one is not available.
+ signature and total are available, or at least one is not available.
</t>
<t>
If signature and total are available, then the verification
@@ -371,7 +371,7 @@ Example, a response to a GET request to the /key/ endpoint.
The verification app will hash together the taxid and the salt
using SHA256 <xref target="RFC6234"/>. The app concatenates both
taxid and salt and then runs the function SHA256 on the
- concatenated binary data this produce the hash-donor-id. The verification app will contact the
+ concatenated binary data this produces the hash-donor-id. The verification app will contact the
host in the endpoint /donation-statement with the year and the hash-donor-id.
The hash-donor-id must be encoded using Base 32 U Crockford
@@ -393,7 +393,7 @@ RESPONSE-EB : I do not know, this is just https://docs.taler.net/core/api-donau.
Servers implementing the donation-statement endpoint MUST respect the
-following syntax, all three fields (total-field, sig-field, pub-field) MUST be included.
+following syntax; all three fields (total-field, sig-field, pub-field) MUST be included.
The amount is a string formed first of the currency (in capital
letters) then ":" and then the value (can be an integer or a decimal
@@ -463,10 +463,10 @@ Example of an element of USD 100.00 :
<ul>
<li>The size of the confirmation to verify written
- in the network order on an 32 bit unsigned integer.</li>
+ in the network order on an 32-bit unsigned integer.</li>
<li>The value 1500 written
- in the network order on an 32 bit unsigned integer.</li>
- <li>The total number is written in three fields. First the integer part of the value represented on 64 bit unsigned integer in big endian. Then comes the fractional part of the total value represented by a unsigned integer on 32 bit (also big endian) representing the number of 1/100000000th of the base unit. The third part is a 12 byte string (terminating with the 0x00 character) representing the currency of the total value.</li>
+ in the network order on an 32-bit unsigned integer.</li>
+ <li>The total number is written in three fields. First, the integer part of the value represented on 64-bit unsigned integer in big endian. Then comes the fractional part of the total value represented by a unsigned integer on 32 bit (also big endian) representing the number of 1/100000000th of the base unit. The third part is a 12-byte string (terminating with the 0x00 character) representing the currency of the total value.</li>
<li>The year on a 64 bit long unsigned integer in network order.</li>
<li>FIXME-EB: this should include hashing over the salt, not just the taxpayer
ID and thus needs to be elaborated on how exactly this is hashed.</li>
@@ -617,8 +617,78 @@ Value Encoding Value Encoding Value Encoding Value Encoding
</figure>
-
-</section>
+
+ </section>
+
+ <section anchor="appendix-test-vectors" title="Appendix. Test Vector: Verify from URI">
+ <t>
+ This appendix shows how to verify a donation statement starting from a
+ received URI. Public key is fetched from the Donau host.
+ </t>
+
+ <figure>
+ <artwork><![CDATA[
+Example URI:
+donau://example.com/megacharity/1234/2025/7560001010000/1234?total=EUR:15&sig=ED25519:H9PM3BW3P8MEKB34GZ0G1F7JSNVX7B8AHXRFFMS37QZM7TXZ5MWPXTEDZZGN1QRB1AFPKNCFXJB39NJHP3BAFGCZSCXHEYPHA1YJY28
+
+Extracted fields:
+- host: example.com/megacharity/1234
+- year: 2025
+- taxid: 7560001010000
+- salt: 1234
+- total: EUR:15
+- signature: ED25519:H9PM3BW3P8MEKB34GZ0G1F7JSNVX7B8AHXRFFMS37QZM7TXZ5MWPXTEDZZGN1QRB1AFPKNCFXJB39NJHP3BAFGCZSCXHEYPHA1YJY28
+
+Fetched public key for year 2025 from https://example.com/megacharity/1234/keys:
+- pub (Base32 Crockford): K641W1CZM7DRSV184M8CPM3Z8MZRBYYJMNYMJK70FTYJHBPX21J0
+ ]]></artwork>
+ </figure>
+
+ <t>Verification steps:</t>
+ <list style="numbers">
+ <t>
+ Decode the public key from Base32 (Crockford) to 32 bytes. Accept
+ OCR-normalized characters as defined in <xref target="base32-U-crockford"/>.
+ Decoded public key (hex):
+ <tt>99881e059fa1db8cec282510cb507f453f85fbd2a57d494ce07ebd28aedd1064</tt>.
+ </t>
+ <t>
+ Normalize and decode the signature: remove the <tt>ED25519:</tt> prefix, then
+ decode the remainder using Base32 (Crockford) to 64 bytes.
+ Decoded signature (hex):
+ <tt>8a6d41af83b228e9ac6487c100bcf2cd77d3ad0a8f70f7d3233dff43ebbf2d396ee9cdffe150df0b0a9f69d58fec9634d651b0d6a7c19fcb3b177ad1507d2f09</tt>.
+ </t>
+ <t>
+ Compute the donor hash H from the exact UTF-8 bytes of <tt>taxid</tt>
+ followed by <tt>salt</tt> (no separator):
+ <tt>SHA-256("7560001010000" || "1234")</tt> =
+ <tt>1172853d7ff368186af26cfced4a70e34c5e93ea9cf92b6980a432be65241417</tt> (hex).
+ When requesting the donation statement, encode H with Base32 (Crockford)
+ for the URL path.
+ </t>
+ <t>
+ Construct the signed payload bytes in network byte order (big endian)
+ using the following field sequence:
+ <figure><artwork><![CDATA[
+SIZE (4 bytes): 0x00000044 (total payload length = 68)
+PURPOSE (4 bytes): 0x000005DC (decimal 1500)
+AMOUNT (8+4+12): value=15 (0x000000000000000F), fraction=0 (0x00000000), currency="EUR" + 9x 0x00
+DONOR HASH (32 B): H = SHA-256(taxid || salt)
+YEAR (4 bytes): 0x000007E9 (2025)
+ ]]></artwork></figure>
+ Complete payload (hex):
+ <figure><artwork><![CDATA[
+00000044000005dc000000000000000f000000004555520000000000000000001172853d7ff368186af26cfced4a70e34c5e93ea9cf92b6980a432be65241417000007e9
+ ]]></artwork></figure>
+ </t>
+ <t>
+ Verify the Ed25519 detached signature over the payload using the decoded
+ public key. For example, with libsodium:
+ <tt>crypto_sign_verify_detached(signature, payload, payload_len, public_key)</tt>.
+ The verification returns success for this example.
+ </t>
+ </list>
+ </section>