From 7151140bdef7b39e1b9d54ae43f05ee91d41c185 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sun, 4 Oct 2026 11:39:55 +0200 Subject: [PATCH] crypto.sha3.tuplehash: fix XOF output length encoding We should append TupleHashXOF's right_encode(0) marker directly to the cSHAKE instance, not treat is as another tuple element. The existing tests didn't catch this because they were using TupleHash as a hash function, not as a XOF. --- lib/std/crypto/sha3.zig | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/std/crypto/sha3.zig b/lib/std/crypto/sha3.zig index f194f62f4b02f543b7f14f280d974f4368d5490a..5c0eb697b0c8a1472f76413e7c511b6c20db7a09 100644 --- a/lib/std/crypto/sha3.zig +++ b/lib/std/crypto/sha3.zig @@ -441,7 +441,7 @@ fn TupleHashLike(comptime security_level: u11, comptime default_delim: u8, compt pub fn squeeze(self: *Self, out: []u8) void { if (!self.xof_mode) { const encoded_out_len = comptime NistLengthEncoding.encode(.right, 0); - self.update(encoded_out_len.slice()); + self.cshaker.update(encoded_out_len.slice()); self.xof_mode = true; } self.cshaker.squeeze(out); @@ -772,6 +772,15 @@ test "TupleHash-128" { try htest.assertEqual("3938d49ade8ec0f0c305ac63497b2d2e8b2f650714f9667cc41816b1c11ffd20", &out); } +test "TupleHashXOF-128 as a XOF" { + var st = TupleHash128.init(); + st.update(&.{ 0x00, 0x01, 0x02 }); + st.update(&.{ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15 }); + var out: [32]u8 = undefined; + st.squeeze(&out); + try htest.assertEqual("2f103cd7c32320353495c68de1a8129245c6325f6f2a3d608d92179c96e68488", &out); +} + test "TupleHash-256" { var st = TupleHash256.init(); st.update("hello"); -- 2.54.0