Formats and hashing
All hashes are SHA-256. ‖ is byte concatenation. Integers are noted with their byte order.
LM-OTS parameters
Section titled “LM-OTS parameters”LMOTS_SHA256_N24_W8 from SP 800-208.
| n | 24 bytes |
| w | 8 bits |
| p | 26 chains |
| Signature | 4 + 24 + 26 × 24 = 652 bytes |
| Key generation | about 6,600 hashes |
Chain start for chain i: x_i = H(I ‖ u32be(q) ‖ u16be(i) ‖ 0xff ‖ SEED)[..24], then 255 steps of H(I ‖ u32be(q) ‖ u16be(i) ‖ u8(j) ‖ tmp)[..24]. Public key: H(I ‖ u32be(q) ‖ 0x8080 ‖ y_0 ‖ … ‖ y_25)[..24].
Treasury withdrawal message
Section titled “Treasury withdrawal message”"QARK-VAULT-v1" 13 bytesprogram id 32vault address 32q u32 big-endiannext_key 24mint 32destination 32amount u64 little-endianThe program recomputes the candidate public key from sig and this message at leaf q, and accepts if the first 24 bytes equal the stored key.
Lifeboat commitment
Section titled “Lifeboat commitment”commitment = sha256("QARK-LIFEBOAT-v1" ‖ I ‖ K)I is the 16-byte key id and K the 24-byte LM-OTS public key, both at q = 0.
Snapshot tree
Section titled “Snapshot tree”leaf = sha256(holder_pubkey ‖ commitment ‖ u64le(balance))node = sha256(min(a, b) ‖ max(a, b)) // sorted pair, byte order- Leaves are sorted before building, so the root does not depend on input order.
- An odd node at the end of a level is carried up unchanged.
- Holders without a Lifeboat use 32 zero bytes as
commitment. - An empty coin has a root of 32 zero bytes.
- Balances are summed per owner across all their token accounts of the coin.
A proof is the list of sibling hashes from leaf to root. Verify by folding node over the proof starting from the leaf.