Functional Weave
Code in Rust

crypto.constant-time-equal@1.0.0

impl/typescript.ts

1,015 bytes · the TypeScript implementation · view raw

function checkBytes(value: readonly number[], name: string): void {
  if (!Array.isArray(value) && !(value instanceof Uint8Array)) {
    throw new TypeError(`${name} must be a list of integers from 0 to 255`);
  }
  for (let i = 0; i < value.length; i++) {
    const b = value[i];
    if (typeof b !== "number" || !Number.isInteger(b) || b < 0 || b > 255) {
      throw new RangeError(`${name} must be a list of integers from 0 to 255`);
    }
  }
}

/**
 * Are two byte strings equal, without stopping at the first difference?
 * Every byte is visited and the differences OR-ed together, so the time
 * taken says nothing about where a forged tag goes wrong. Different lengths
 * answer false at once: a digest's length is not a secret.
 */
export function constantTimeEqual(a: readonly number[], b: readonly number[]): boolean {
  checkBytes(a, "a");
  checkBytes(b, "b");
  if (a.length !== b.length) return false;
  let diff = 0;
  for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];
  return diff === 0;
}