Summary

  • RFC 9861 defines TurboSHAKE128, TurboSHAKE256, KT128 and KT256, but a reproducible output also depends on exact message bytes, a domain byte or customization string, and the requested output length.
  • KangarooTwelve changes from one node to a tree when its encoded input exceeds 8192 bytes; parallel execution may vary, but the final bytes must not.
  • RFC publication and IANA registration stabilize names. They do not prove implementation conformance, protocol suitability, key custody, authorization or a deployed result.

Two services both recorded KT128. Their stored identifiers did not match.

Nothing in that sentence proves a broken primitive. One service may have used a non-empty customization string. One may have requested 32 bytes and the other 64. Their serializers may have emitted different byte order, or their streaming adapters may have joined chunks differently. The names agreed at the symbolic layer while the actual function inputs diverged.

RFC 9861 makes this problem unusually visible because it defines extendable-output functions rather than a fixed-length digest alone. TurboSHAKE128, TurboSHAKE256, KT128 and KT256 can return arbitrary-length output. The RFC is an October 2025 IRTF Informational publication and a stable implementation reference from the Crypto Forum Research Group. Its publication record is explicit: this is not an IETF Internet Standard, and IRTF results might not be suitable for deployment. Stable description and local adoption authority are different records.

The output length belongs to the input contract

A fixed hash name often carries an expected output size in its identity. An XOF does not. TurboSHAKE takes message bytes M, a domain-separation byte D and a positive output length L. The default D is 1F; valid domain bytes run from 01 through 7F. For identical M and D, a shorter result is the prefix of a longer one.

That prefix property is useful, but it is easy to misread. It does not give an application permission to truncate a stored identifier, compare values of different length or upgrade from 32 to 64 bytes without a version boundary. It says what the primitive returns when the caller asks two related questions. The consuming protocol still decides which question is valid.

The minimum TurboSHAKE receipt therefore records the exact variant, D, L, byte serialization and message order. “Default settings” is not durable evidence. A future library may expose a new domain parameter, a wrapper may silently select a profile, and a storage field may preserve only the output while losing the call contract that made it meaningful.

Incremental APIs add another boundary. RFC 9861 permits message input in pieces, but the result must equal hashing their concatenation in the order supplied. It permits output in pieces, but their ordered concatenation must equal one request for the total length. Buffer boundaries are implementation details; byte order is not. A streaming job receipt needs the ordered input manifest, not merely a claim that every chunk was eventually seen.

Customization is cryptographic material, not a comment

KT128 and KT256 replace TurboSHAKE's one-byte domain selector with an optional customization string C. An empty string is the default. The construction reversibly forms S = M || C || length_encode(|C|). That final length encoding is what prevents a reader from treating customization as a decorative suffix.

This matters institutionally. Teams often use names, URIs, tenant identifiers or protocol labels as customization. If one service normalizes a URI, another changes character encoding, or a migration drops the field because it looks like metadata, the digest changes by design. A dashboard that displays only “KT256” conceals the authority exercised by the component that selected and serialized C.

The receipt should preserve the customization bytes themselves when they are public and safe, or a protected digest and a resolvable provenance reference when they are not. It must also say whether empty means deliberately empty, unavailable, or omitted by an API that forces the RFC default. Those states can produce the same call today while carrying very different migration risk.

The tree boundary is part of conformance

KangarooTwelve processes the encoded S in 8192-byte chunks. At 8192 bytes or fewer, the final node is the input itself. Above that limit, later chunks produce chaining values that are combined with the first chunk and encoded tree structure before the final TurboSHAKE call. KT128 uses 32-byte chaining values; KT256 uses 64-byte values.

The threshold applies to S, not just the application message. Because S includes customization and its length encoding, an apparently unchanged message can cross from the single-node path into tree mode when C changes. That makes the boundary a valuable canary. Test immediately below it, at it and above it, with both empty and non-empty customization. Exercise serial and parallel backends and require identical final bytes.

Parallelism is an execution choice, not a licence for alternate answers. The RFC allows implementations to exploit SIMD or other parallel capacity for the independent chunks. A production benchmark may show different speed on different processors, but no benchmark was performed for this report. The only portable result asserted here is byte equivalence under the declared inputs.

Registry names can close some parameters, not all evidence

RFC 9861 uses the Named Information registry to define two fixed profiles. k12-256 means KT128 with empty customization and a 32-byte output. k12-512 means KT256 with empty customization and a 64-byte output. Those names carry more of the contract than the generic label KT128 or KT256.

The COSE Algorithms registry also records TurboSHAKE128, TurboSHAKE256, KT128 and KT256 with assigned negative values. Registration is coordination evidence: two systems can refer to the same definition. It is not an implementation receipt. A code point cannot show which message bytes entered, which parameters a surrounding protocol fixed, whether an accelerated backend matched test vectors or whether a relying application accepted the result for the right reason.

The same distinction applies to the RFC's security statements. The document claims 128-bit strength for the 128 variants and 256-bit strength for the 256 variants, relying on analysis of 12-round Keccak and on Sakura coding for the tree mode. NIST FIPS 202 supplies the underlying SHA-3/Keccak permutation definitions; NIST SP 800-185 provides nearby derived-function and parallel-hash context. These sources explain the design lineage. They do not certify a local binary, approve an application profile or prove that secret-dependent code is resistant to side channels on a particular machine.

Test vectors need labels as much as bytes

RFC 9861 includes extensive vectors across function variants, output lengths, message sizes, customization sizes and the tree boundary. A useful conformance record stores the vector identifier, every argument, expected bytes, actual bytes, implementation build, hardware path and time of execution. “Tests passed” is too weak when a backend can change under the same package version.

The current RFC Editor errata record sharpens the point. Errata 8997 is a Reported technical item from June 2026. It observes that several KT vector invocations omit the explicit M= label even though the first argument is positional; the proposed correction makes parameter labelling consistent and does not change the displayed output bytes. Reported is not Verified. An evidence system should preserve both the test data and the process status instead of silently treating a proposed editorial clarification as incorporated normative text.

A digest is still not an outcome

Even a perfect match proves only that one declared byte contract produced one expected byte string. It does not prove who authored the message, whether the content is current, whether a release was authorized, whether a key was protected, or whether a downstream action succeeded. RFC 9861 also defines HopMAC constructions and permits other reversible placements of a key. “KT128 MAC” is therefore incomplete without the exact construction, key identifier, custody boundary, customization and tag length.

This is the reality-layer discipline behind the commission. A public specification defines shared meaning. A configuration selects parameters. Running code consumes bytes. A comparison records equality. A protocol applies an acceptance rule. A human or system then acts. Collapsing those records into one green algorithm label gives symbolic power to the earliest layer and hides every later principal.

Sources