authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2026-10-04 11:39:55+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-07 00:29:24+02:00
log57e52b7edb1312d84abf079259e7ed153074ea9f
treeadc396efc0908dee59b755f40e197e6c2b5a3bb4
parent289dc3656c34d3d81d77a45d99502873e62fd845
signature Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

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.

1 files changed, 10 insertions(+), 1 deletions(-)

lib/std/crypto/sha3.zig+10-1
......@@ -441,7 +441,7 @@ fn TupleHashLike(comptime security_level: u11, comptime default_delim: u8, compt
441441 pub fn squeeze(self: *Self, out: []u8) void {
442442 if (!self.xof_mode) {
443443 const encoded_out_len = comptime NistLengthEncoding.encode(.right, 0);
444 self.update(encoded_out_len.slice());
444 self.cshaker.update(encoded_out_len.slice());
445445 self.xof_mode = true;
446446 }
447447 self.cshaker.squeeze(out);
......@@ -772,6 +772,15 @@ test "TupleHash-128" {
772772 try htest.assertEqual("3938d49ade8ec0f0c305ac63497b2d2e8b2f650714f9667cc41816b1c11ffd20", &out);
773773}
774774
775test "TupleHashXOF-128 as a XOF" {
776 var st = TupleHash128.init();
777 st.update(&.{ 0x00, 0x01, 0x02 });
778 st.update(&.{ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15 });
779 var out: [32]u8 = undefined;
780 st.squeeze(&out);
781 try htest.assertEqual("2f103cd7c32320353495c68de1a8129245c6325f6f2a3d608d92179c96e68488", &out);
782}
783
775784test "TupleHash-256" {
776785 var st = TupleHash256.init();
777786 st.update("hello");