constant-time.test.ts

1.9 KB · raw

1import { describe, expect, it } from "vitest";2import { constantTimeEqualBytes, constantTimeEqualHex } from "./constant-time";34describe("constantTimeEqualBytes", () => {5  it("matches identical contents and rejects a single differing byte", () => {6    const a = Uint8Array.from([1, 2, 3, 4]);7    expect(constantTimeEqualBytes(a, Uint8Array.from([1, 2, 3, 4]))).toBe(true);8    expect(constantTimeEqualBytes(a, Uint8Array.from([1, 2, 3, 5]))).toBe(false);9    expect(constantTimeEqualBytes(a, Uint8Array.from([9, 2, 3, 4]))).toBe(false);10  });1112  it("rejects a length mismatch even when the shared prefix matches", () => {13    // The out-of-range reads fold in as 0, so a trailing zero byte must not14    // make a longer value compare equal to its own prefix.15    const prefix = Uint8Array.from([1, 2, 3]);16    expect(constantTimeEqualBytes(prefix, Uint8Array.from([1, 2, 3, 0]))).toBe(false);17    expect(constantTimeEqualBytes(Uint8Array.from([1, 2, 3, 0]), prefix)).toBe(false);18    expect(constantTimeEqualBytes(new Uint8Array(0), new Uint8Array(0))).toBe(true);19  });2021  it("scans the whole buffer rather than stopping at the first difference", () => {22    // Same number of iterations regardless of where the mismatch sits — the23    // property the callers depend on. Verified by behaviour, not by timing.24    const left = new Uint8Array(64);25    const early = new Uint8Array(64);26    early[0] = 1;27    const late = new Uint8Array(64);28    late[63] = 1;29    expect(constantTimeEqualBytes(left, early)).toBe(false);30    expect(constantTimeEqualBytes(left, late)).toBe(false);31  });32});3334describe("constantTimeEqualHex", () => {35  it("compares hex case-insensitively", () => {36    expect(constantTimeEqualHex("ABcd12", "abCD12")).toBe(true);37    expect(constantTimeEqualHex("abcd12", "abcd13")).toBe(false);38  });3940  it("rejects differing lengths", () => {41    expect(constantTimeEqualHex("abcd", "abcd00")).toBe(false);42    expect(constantTimeEqualHex("", "")).toBe(true);43  });44});