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