Expand description
Hex and Base64 codecs.
These exist so the CLI, MCP server, PEM and ontology exports can move key material and test vectors around without pulling in a dependency. Both directions are constant time in the values they carry, which matters because private keys pass through them: a PKCS#8 key in PEM is Base64, and agents paste hex keys into the CLI.
§How, and what went wrong before
No character is classified by a branch and no value indexes a table.
- Encoding computes each character arithmetically: the offset from the value to its character changes at the alphabet’s range boundaries, and each change is a mask made from the sign of a subtraction. A table of 64 or 16 characters indexed by secret bits is a cache-timing channel when it spans two lines, and the encoders used one.
- Decoding computes a value and a validity mask for every character the
same way, and accumulates the validity behind
core::hint::black_box. The input is rejected once, at the end, if any character was invalid.
The decoders were written branch-free before, but each character’s
validity was tested at once with ensure!, an early return, and every
compiler this workspace targets – x86-64, both Cortex-M cores, 32-bit
RISC-V – turned the OR of the class masks feeding that test into a chain
of short-circuit branches: plus? slash? upper case? lower case? digit? Which
branch left the chain was the class of a secret character. That is the
channel Sieck et al. used against PEM key decoding (“Util::Lookup”, USENIX
Security 2021), and it was found here by reading the compiled code.
Functions§
- b64
- Encode
inputas a padded standard Base64String. - base64_
decode - Decode padded standard Base64, returning the number of bytes written.
- base64_
encode - Encode
inputas padded standard Base64 intoout. - base64_
encoded_ len - Length of the standard-alphabet, padded Base64 encoding of
nbytes. - hex
- Encode
inputas a lowercase hexString. - hex_
decode - Decode a hex string into
out, accepting either case. - hex_
encode - Encode
inputas lowercase hex intoout. - unb64
- Decode a padded standard Base64 string into a freshly allocated
Vec. - unhex
- Decode a hex string into a freshly allocated
Vec.