pub fn qr_text(hardened: bool, phrase: &str) -> Zeroizing<String>Expand description
The QR text a hashlock PHRASE plate carries (SPEC_hashlock_H6 §8.6), byte for byte: three labelled lines, LF-separated, NO trailing newline, the phrase LAST.
The phrase is last so a reader knows where it ends: it may itself contain
: and spaces, and everything after phrase: on the final line is the
phrase, verbatim, with real 0x20 spaces.
The method line names the ALGORITHM in full — not the --method selector —
so a reader with the plate and no tool can reproduce the derivation. Its
parameters are read from HASHLOCK_SALT, HASHLOCK_ITERATIONS and
HASHLOCK_DKLEN and never from a literal, so a parameter change cannot
leave the plate lying.
hashlock v1 is the VERSION TAG of this TEXT, not of the derivation. A
future parameter set gets hashlock v2.
IT RETURNS Zeroizing<String> BECAUSE THE PHRASE IS IN IT. Every other
phrase-bearing value in this workspace is protected – read_phrase_from
and read_phrase_stdin return Zeroizing<Vec<u8>>, preimage_hardened
and preimage_sha256 return Zeroizing<[u8; 32]>, and the kind carries
Payload::Preimage(Zeroizing<[u8; 32]>) – and a plain String here would
have been the one hole in that surface, holding the phrase in the clear on
the heap until the allocator happened to reuse the page.
The buffer is Zeroizing from the FIRST byte, and it is allocated once.
Wrapping a finished format! would be no protection at all: the format!
would build an unprotected String containing the phrase and the wrap would
only guard the copy. The exact capacity is reserved up front so no push_str
can reallocate and abandon an unwiped buffer part-way through. The method
line is deliberately NOT protected – it is three compile-time constants and
carries nothing of the phrase.