From 169a73d180ad3e32d7a70902762a1b9d1451dd51 Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Sun, 14 Jun 2026 17:05:30 +0000 Subject: [PATCH] Fix flaky TestTamperedTokenFails in qryptinvite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit flipLastChar toggled only the last base64 char of the signature segment. For a 64-byte Ed25519 signature that char carries unused trailing bits, so the toggle could decode back to the same bytes and still verify — making the "corrupted signature must fail" assertion flaky (it reddened main CI). Corrupt a decoded signature byte (sig[0] ^= 0xFF) and re-encode instead, so the signature always differs. Verified deterministic over 50 runs. Co-Authored-By: Claude Opus 4.8 --- internal/qryptinvite/qryptinvite_test.go | 26 +++++++++--------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/internal/qryptinvite/qryptinvite_test.go b/internal/qryptinvite/qryptinvite_test.go index 9348549..c7c9618 100644 --- a/internal/qryptinvite/qryptinvite_test.go +++ b/internal/qryptinvite/qryptinvite_test.go @@ -148,8 +148,16 @@ func TestTamperedTokenFails(t *testing.T) { t.Fatal("original token failed to verify") } - // Tampering with the signature segment must also fail. - badSig := parts[0] + "." + parts[1] + "." + flipLastChar(parts[2]) + // Tampering with the signature segment must also fail. Corrupt a DECODED + // signature byte (not a base64 char): flipping the last base64 char can land + // on the unused trailing bits of a 64-byte signature, which decode back to + // the same bytes and still verify — that made this test flaky. + sigBytes, err := base64.RawURLEncoding.DecodeString(parts[2]) + if err != nil || len(sigBytes) == 0 { + t.Fatalf("decode signature segment: %v", err) + } + sigBytes[0] ^= 0xFF + badSig := parts[0] + "." + parts[1] + "." + base64.RawURLEncoding.EncodeToString(sigBytes) if verifySig(badSig, pub) { t.Fatal("token with corrupted signature verified but should have failed") } @@ -168,20 +176,6 @@ func verifySig(token string, pub ed25519.PublicKey) bool { return ed25519.Verify(pub, []byte(parts[0]+"."+parts[1]), sig) } -func flipLastChar(s string) string { - if s == "" { - return s - } - b := []byte(s) - last := b[len(b)-1] - if last == 'A' { - b[len(b)-1] = 'B' - } else { - b[len(b)-1] = 'A' - } - return string(b) -} - func TestParsePrivateKeyAcceptsSeedAndFull(t *testing.T) { _, priv, err := ed25519.GenerateKey(nil) if err != nil {