• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const common = require('../common');
3if (!common.hasCrypto)
4  common.skip('missing crypto');
5
6const assert = require('assert');
7const crypto = require('crypto');
8
9// 'should consider equal strings to be equal'
10assert.strictEqual(
11  crypto.timingSafeEqual(Buffer.from('foo'), Buffer.from('foo')),
12  true
13);
14
15// 'should consider unequal strings to be unequal'
16assert.strictEqual(
17  crypto.timingSafeEqual(Buffer.from('foo'), Buffer.from('bar')),
18  false
19);
20
21{
22  // Test TypedArrays with different lengths but equal byteLengths.
23  const buf = crypto.randomBytes(16).buffer;
24  const a1 = new Uint8Array(buf);
25  const a2 = new Uint16Array(buf);
26  const a3 = new Uint32Array(buf);
27
28  for (const left of [a1, a2, a3]) {
29    for (const right of [a1, a2, a3]) {
30      assert.strictEqual(crypto.timingSafeEqual(left, right), true);
31    }
32  }
33}
34
35{
36  // When the inputs are floating-point numbers, timingSafeEqual neither has
37  // equality nor SameValue semantics. It just compares the underlying bytes,
38  // ignoring the TypedArray type completely.
39
40  const cmp = (fn) => (a, b) => a.every((x, i) => fn(x, b[i]));
41  const eq = cmp((a, b) => a === b);
42  const is = cmp(Object.is);
43
44  function test(a, b, { equal, sameValue, timingSafeEqual }) {
45    assert.strictEqual(eq(a, b), equal);
46    assert.strictEqual(is(a, b), sameValue);
47    assert.strictEqual(crypto.timingSafeEqual(a, b), timingSafeEqual);
48  }
49
50  test(new Float32Array([NaN]), new Float32Array([NaN]), {
51    equal: false,
52    sameValue: true,
53    timingSafeEqual: true
54  });
55
56  test(new Float64Array([0]), new Float64Array([-0]), {
57    equal: true,
58    sameValue: false,
59    timingSafeEqual: false
60  });
61
62  const x = new BigInt64Array([0x7ff0000000000001n, 0xfff0000000000001n]);
63  test(new Float64Array(x.buffer), new Float64Array([NaN, NaN]), {
64    equal: false,
65    sameValue: true,
66    timingSafeEqual: false
67  });
68}
69
70assert.throws(
71  () => crypto.timingSafeEqual(Buffer.from([1, 2, 3]), Buffer.from([1, 2])),
72  {
73    code: 'ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH',
74    name: 'RangeError',
75    message: 'Input buffers must have the same byte length'
76  }
77);
78
79assert.throws(
80  () => crypto.timingSafeEqual('not a buffer', Buffer.from([1, 2])),
81  {
82    code: 'ERR_INVALID_ARG_TYPE',
83    name: 'TypeError',
84  }
85);
86
87assert.throws(
88  () => crypto.timingSafeEqual(Buffer.from([1, 2]), 'not a buffer'),
89  {
90    code: 'ERR_INVALID_ARG_TYPE',
91    name: 'TypeError',
92  }
93);
94