Class VoucherCanonicalBytes
This is the single definition of the voucher signing preimage. It is deliberately its own
class rather than a detail of VoucherSignatureService: the bytes are a wire contract
shared with every verifier, including the offline TypeScript wallet, so anything that needs
to reproduce them must be able to call the one implementation instead of copying it.
The form is [kind, "data_hex", "nonce", [[tag, value...], ...]], matching
WellKnownSecretSerializer, with issuer_sig and issuer_pubkey omitted
because they are only added after signing.
The kind is read from the secret
It used to be the literal "VOUCHER". Two kinds now carry voucher metadata —
VOUCHER and P2PK_VOUCHER, the latter being a voucher that is also
P2PK-locked — and the signature has to commit to which one it is. A fixed string would let a
signature made for an unlocked voucher verify against a locked one carrying the same
metadata, and vice versa, so the kind would not be covered by what the issuer signed.
This does not change the bytes for a VOUCHER secret: the value read is the same
string that was previously hardcoded, so every signature made under the old code still
verifies.
Why the tag key decides what is numeric
NUT-10 carries every tag value as a string, so the runtime type of a value says nothing
about how it was written when a signature was made. An earlier version keyed off
value instanceof Number; when cashu-lib began modelling tag values as String,
every numeric tag silently changed from 1000 to "1000" and every voucher
signature ever issued would have stopped verifying. The voucher tag schema is fixed and
known, so the key is the durable record of which values are numbers.
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumHow numeric tag values are rendered. -
Method Summary
Modifier and TypeMethodDescriptionstatic byte[]of(@NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret) Renders the canonical signing bytes for a voucher secret.static byte[]of(@NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret, @NonNull VoucherCanonicalBytes.NumericTagForm numericForm) Renders the canonical signing bytes, choosing how numeric values are written.
-
Method Details
-
of
public static byte[] of(@NonNull @NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret) Renders the canonical signing bytes for a voucher secret.- Parameters:
secret- the voucher secret to render; either aVoucherSecretor aP2PKVoucherSecret- Returns:
- the bytes that are hashed and signed
-
of
public static byte[] of(@NonNull @NonNull xyz.tcheeric.cashu.common.nut10.WellKnownSecret secret, @NonNull @NonNull VoucherCanonicalBytes.NumericTagForm numericForm) Renders the canonical signing bytes, choosing how numeric values are written.- Parameters:
secret- the voucher secret to rendernumericForm- the rendering of numeric tag values- Returns:
- the bytes that are hashed and signed
- Throws:
IllegalArgumentException- if the secret's kind carries no voucher metadata
-