11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ciconst common = require('../common');
31cb0ef41Sopenharmony_ciif (!common.hasCrypto)
41cb0ef41Sopenharmony_ci  common.skip('missing crypto');
51cb0ef41Sopenharmony_ci
61cb0ef41Sopenharmony_ciconst assert = require('assert');
71cb0ef41Sopenharmony_ciconst crypto = require('crypto');
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci// 'should consider equal strings to be equal'
101cb0ef41Sopenharmony_ciassert.strictEqual(
111cb0ef41Sopenharmony_ci  crypto.timingSafeEqual(Buffer.from('foo'), Buffer.from('foo')),
121cb0ef41Sopenharmony_ci  true
131cb0ef41Sopenharmony_ci);
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ci// 'should consider unequal strings to be unequal'
161cb0ef41Sopenharmony_ciassert.strictEqual(
171cb0ef41Sopenharmony_ci  crypto.timingSafeEqual(Buffer.from('foo'), Buffer.from('bar')),
181cb0ef41Sopenharmony_ci  false
191cb0ef41Sopenharmony_ci);
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci{
221cb0ef41Sopenharmony_ci  // Test TypedArrays with different lengths but equal byteLengths.
231cb0ef41Sopenharmony_ci  const buf = crypto.randomBytes(16).buffer;
241cb0ef41Sopenharmony_ci  const a1 = new Uint8Array(buf);
251cb0ef41Sopenharmony_ci  const a2 = new Uint16Array(buf);
261cb0ef41Sopenharmony_ci  const a3 = new Uint32Array(buf);
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci  for (const left of [a1, a2, a3]) {
291cb0ef41Sopenharmony_ci    for (const right of [a1, a2, a3]) {
301cb0ef41Sopenharmony_ci      assert.strictEqual(crypto.timingSafeEqual(left, right), true);
311cb0ef41Sopenharmony_ci    }
321cb0ef41Sopenharmony_ci  }
331cb0ef41Sopenharmony_ci}
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci{
361cb0ef41Sopenharmony_ci  // When the inputs are floating-point numbers, timingSafeEqual neither has
371cb0ef41Sopenharmony_ci  // equality nor SameValue semantics. It just compares the underlying bytes,
381cb0ef41Sopenharmony_ci  // ignoring the TypedArray type completely.
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  const cmp = (fn) => (a, b) => a.every((x, i) => fn(x, b[i]));
411cb0ef41Sopenharmony_ci  const eq = cmp((a, b) => a === b);
421cb0ef41Sopenharmony_ci  const is = cmp(Object.is);
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci  function test(a, b, { equal, sameValue, timingSafeEqual }) {
451cb0ef41Sopenharmony_ci    assert.strictEqual(eq(a, b), equal);
461cb0ef41Sopenharmony_ci    assert.strictEqual(is(a, b), sameValue);
471cb0ef41Sopenharmony_ci    assert.strictEqual(crypto.timingSafeEqual(a, b), timingSafeEqual);
481cb0ef41Sopenharmony_ci  }
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci  test(new Float32Array([NaN]), new Float32Array([NaN]), {
511cb0ef41Sopenharmony_ci    equal: false,
521cb0ef41Sopenharmony_ci    sameValue: true,
531cb0ef41Sopenharmony_ci    timingSafeEqual: true
541cb0ef41Sopenharmony_ci  });
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci  test(new Float64Array([0]), new Float64Array([-0]), {
571cb0ef41Sopenharmony_ci    equal: true,
581cb0ef41Sopenharmony_ci    sameValue: false,
591cb0ef41Sopenharmony_ci    timingSafeEqual: false
601cb0ef41Sopenharmony_ci  });
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci  const x = new BigInt64Array([0x7ff0000000000001n, 0xfff0000000000001n]);
631cb0ef41Sopenharmony_ci  test(new Float64Array(x.buffer), new Float64Array([NaN, NaN]), {
641cb0ef41Sopenharmony_ci    equal: false,
651cb0ef41Sopenharmony_ci    sameValue: true,
661cb0ef41Sopenharmony_ci    timingSafeEqual: false
671cb0ef41Sopenharmony_ci  });
681cb0ef41Sopenharmony_ci}
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ciassert.throws(
711cb0ef41Sopenharmony_ci  () => crypto.timingSafeEqual(Buffer.from([1, 2, 3]), Buffer.from([1, 2])),
721cb0ef41Sopenharmony_ci  {
731cb0ef41Sopenharmony_ci    code: 'ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH',
741cb0ef41Sopenharmony_ci    name: 'RangeError',
751cb0ef41Sopenharmony_ci    message: 'Input buffers must have the same byte length'
761cb0ef41Sopenharmony_ci  }
771cb0ef41Sopenharmony_ci);
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ciassert.throws(
801cb0ef41Sopenharmony_ci  () => crypto.timingSafeEqual('not a buffer', Buffer.from([1, 2])),
811cb0ef41Sopenharmony_ci  {
821cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
831cb0ef41Sopenharmony_ci    name: 'TypeError',
841cb0ef41Sopenharmony_ci  }
851cb0ef41Sopenharmony_ci);
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ciassert.throws(
881cb0ef41Sopenharmony_ci  () => crypto.timingSafeEqual(Buffer.from([1, 2]), 'not a buffer'),
891cb0ef41Sopenharmony_ci  {
901cb0ef41Sopenharmony_ci    code: 'ERR_INVALID_ARG_TYPE',
911cb0ef41Sopenharmony_ci    name: 'TypeError',
921cb0ef41Sopenharmony_ci  }
931cb0ef41Sopenharmony_ci);
94