1'use strict'; 2 3const common = require('../common'); 4if (!common.hasCrypto) 5 common.skip('missing crypto'); 6 7const assert = require('assert'); 8 9const { 10 generatePrime, 11 generatePrimeSync, 12 checkPrime, 13 checkPrimeSync, 14} = require('crypto'); 15 16const { promisify } = require('util'); 17const pgeneratePrime = promisify(generatePrime); 18const pCheckPrime = promisify(checkPrime); 19 20['hello', false, {}, []].forEach((i) => { 21 assert.throws(() => generatePrime(i), { 22 code: 'ERR_INVALID_ARG_TYPE' 23 }); 24 assert.throws(() => generatePrimeSync(i), { 25 code: 'ERR_INVALID_ARG_TYPE' 26 }); 27}); 28 29['hello', false, 123].forEach((i) => { 30 assert.throws(() => generatePrime(80, i, common.mustNotCall()), { 31 code: 'ERR_INVALID_ARG_TYPE' 32 }); 33 assert.throws(() => generatePrimeSync(80, i), { 34 code: 'ERR_INVALID_ARG_TYPE' 35 }); 36}); 37 38['hello', false, 123].forEach((i) => { 39 assert.throws(() => generatePrime(80, {}), { 40 code: 'ERR_INVALID_ARG_TYPE' 41 }); 42}); 43 44[-1, 0, 2 ** 31, 2 ** 31 + 1, 2 ** 32 - 1, 2 ** 32].forEach((size) => { 45 assert.throws(() => generatePrime(size, common.mustNotCall()), { 46 code: 'ERR_OUT_OF_RANGE', 47 message: />= 1 && <= 2147483647/ 48 }); 49 assert.throws(() => generatePrimeSync(size), { 50 code: 'ERR_OUT_OF_RANGE', 51 message: />= 1 && <= 2147483647/ 52 }); 53}); 54 55['test', -1, {}, []].forEach((i) => { 56 assert.throws(() => generatePrime(8, { safe: i }, common.mustNotCall()), { 57 code: 'ERR_INVALID_ARG_TYPE' 58 }); 59 assert.throws(() => generatePrime(8, { rem: i }, common.mustNotCall()), { 60 code: 'ERR_INVALID_ARG_TYPE' 61 }); 62 assert.throws(() => generatePrime(8, { add: i }, common.mustNotCall()), { 63 code: 'ERR_INVALID_ARG_TYPE' 64 }); 65 assert.throws(() => generatePrimeSync(8, { safe: i }), { 66 code: 'ERR_INVALID_ARG_TYPE' 67 }); 68 assert.throws(() => generatePrimeSync(8, { rem: i }), { 69 code: 'ERR_INVALID_ARG_TYPE' 70 }); 71 assert.throws(() => generatePrimeSync(8, { add: i }), { 72 code: 'ERR_INVALID_ARG_TYPE' 73 }); 74}); 75 76{ 77 // Negative BigInts should not be converted to 0 silently. 78 79 assert.throws(() => generatePrime(20, { add: -1n }, common.mustNotCall()), { 80 code: 'ERR_OUT_OF_RANGE', 81 message: 'The value of "options.add" is out of range. It must be >= 0. ' + 82 'Received -1n' 83 }); 84 85 assert.throws(() => generatePrime(20, { rem: -1n }, common.mustNotCall()), { 86 code: 'ERR_OUT_OF_RANGE', 87 message: 'The value of "options.rem" is out of range. It must be >= 0. ' + 88 'Received -1n' 89 }); 90 91 assert.throws(() => checkPrime(-1n, common.mustNotCall()), { 92 code: 'ERR_OUT_OF_RANGE', 93 message: 'The value of "candidate" is out of range. It must be >= 0. ' + 94 'Received -1n' 95 }); 96} 97 98generatePrime(80, common.mustSucceed((prime) => { 99 assert(checkPrimeSync(prime)); 100 checkPrime(prime, common.mustSucceed((result) => { 101 assert(result); 102 })); 103})); 104 105assert(checkPrimeSync(generatePrimeSync(80))); 106 107generatePrime(80, {}, common.mustSucceed((prime) => { 108 assert(checkPrimeSync(prime)); 109})); 110 111assert(checkPrimeSync(generatePrimeSync(80, {}))); 112 113generatePrime(32, { safe: true }, common.mustSucceed((prime) => { 114 assert(checkPrimeSync(prime)); 115 const buf = Buffer.from(prime); 116 const val = buf.readUInt32BE(); 117 const check = (val - 1) / 2; 118 buf.writeUInt32BE(check); 119 assert(checkPrimeSync(buf)); 120})); 121 122{ 123 const prime = generatePrimeSync(32, { safe: true }); 124 assert(checkPrimeSync(prime)); 125 const buf = Buffer.from(prime); 126 const val = buf.readUInt32BE(); 127 const check = (val - 1) / 2; 128 buf.writeUInt32BE(check); 129 assert(checkPrimeSync(buf)); 130} 131 132const add = 12; 133const rem = 11; 134const add_buf = Buffer.from([add]); 135const rem_buf = Buffer.from([rem]); 136generatePrime( 137 32, 138 { add: add_buf, rem: rem_buf }, 139 common.mustSucceed((prime) => { 140 assert(checkPrimeSync(prime)); 141 const buf = Buffer.from(prime); 142 const val = buf.readUInt32BE(); 143 assert.strictEqual(val % add, rem); 144 })); 145 146{ 147 const prime = generatePrimeSync(32, { add: add_buf, rem: rem_buf }); 148 assert(checkPrimeSync(prime)); 149 const buf = Buffer.from(prime); 150 const val = buf.readUInt32BE(); 151 assert.strictEqual(val % add, rem); 152} 153 154{ 155 const prime = generatePrimeSync(32, { add: BigInt(add), rem: BigInt(rem) }); 156 assert(checkPrimeSync(prime)); 157 const buf = Buffer.from(prime); 158 const val = buf.readUInt32BE(); 159 assert.strictEqual(val % add, rem); 160} 161 162{ 163 // The behavior when specifying only add without rem should depend on the 164 // safe option. 165 166 if (process.versions.openssl >= '1.1.1f') { 167 generatePrime(128, { 168 bigint: true, 169 add: 5n 170 }, common.mustSucceed((prime) => { 171 assert(checkPrimeSync(prime)); 172 assert.strictEqual(prime % 5n, 1n); 173 })); 174 175 generatePrime(128, { 176 bigint: true, 177 safe: true, 178 add: 5n 179 }, common.mustSucceed((prime) => { 180 assert(checkPrimeSync(prime)); 181 assert.strictEqual(prime % 5n, 3n); 182 })); 183 } 184} 185 186{ 187 // This is impossible because it implies (prime % 2**64) == 1 and 188 // prime < 2**64, meaning prime = 1, but 1 is not prime. 189 for (const add of [2n ** 64n, 2n ** 65n]) { 190 assert.throws(() => { 191 generatePrimeSync(64, { add }); 192 }, { 193 code: 'ERR_OUT_OF_RANGE', 194 message: 'invalid options.add' 195 }); 196 } 197 198 // Any parameters with rem >= add lead to an impossible condition. 199 for (const rem of [7n, 8n, 3000n]) { 200 assert.throws(() => { 201 generatePrimeSync(64, { add: 7n, rem }); 202 }, { 203 code: 'ERR_OUT_OF_RANGE', 204 message: 'invalid options.rem' 205 }); 206 } 207 208 // This is possible, but not allowed. It implies prime == 7, which means that 209 // we did not actually generate a random prime. 210 assert.throws(() => { 211 generatePrimeSync(3, { add: 8n, rem: 7n }); 212 }, { 213 code: 'ERR_OUT_OF_RANGE' 214 }); 215 216 if (process.versions.openssl >= '1.1.1f') { 217 // This is possible and allowed (but makes little sense). 218 assert.strictEqual(generatePrimeSync(4, { 219 add: 15n, 220 rem: 13n, 221 bigint: true 222 }), 13n); 223 } 224} 225 226[1, 'hello', {}, []].forEach((i) => { 227 assert.throws(() => checkPrime(i), { 228 code: 'ERR_INVALID_ARG_TYPE' 229 }); 230}); 231 232for (const checks of ['hello', {}, []]) { 233 assert.throws(() => checkPrime(2n, { checks }, common.mustNotCall()), { 234 code: 'ERR_INVALID_ARG_TYPE', 235 message: /checks/ 236 }); 237 assert.throws(() => checkPrimeSync(2n, { checks }), { 238 code: 'ERR_INVALID_ARG_TYPE', 239 message: /checks/ 240 }); 241} 242 243for (const checks of [-(2 ** 31), -1, 2 ** 31, 2 ** 32 - 1, 2 ** 32, 2 ** 50]) { 244 assert.throws(() => checkPrime(2n, { checks }, common.mustNotCall()), { 245 code: 'ERR_OUT_OF_RANGE', 246 message: /<= 2147483647/ 247 }); 248 assert.throws(() => checkPrimeSync(2n, { checks }), { 249 code: 'ERR_OUT_OF_RANGE', 250 message: /<= 2147483647/ 251 }); 252} 253 254assert(!checkPrimeSync(Buffer.from([0x1]))); 255assert(checkPrimeSync(Buffer.from([0x2]))); 256assert(checkPrimeSync(Buffer.from([0x3]))); 257assert(!checkPrimeSync(Buffer.from([0x4]))); 258 259assert( 260 !checkPrimeSync( 261 Buffer.from([0x1]), 262 { 263 fast: true, 264 trialDivision: true, 265 checks: 10 266 })); 267 268(async function() { 269 const prime = await pgeneratePrime(36); 270 assert(await pCheckPrime(prime)); 271})().then(common.mustCall()); 272 273assert.throws(() => { 274 generatePrimeSync(32, { bigint: '' }); 275}, { code: 'ERR_INVALID_ARG_TYPE' }); 276 277assert.throws(() => { 278 generatePrime(32, { bigint: '' }, common.mustNotCall()); 279}, { code: 'ERR_INVALID_ARG_TYPE' }); 280 281{ 282 const prime = generatePrimeSync(3, { bigint: true }); 283 assert.strictEqual(typeof prime, 'bigint'); 284 assert.strictEqual(prime, 7n); 285 assert(checkPrimeSync(prime)); 286 checkPrime(prime, common.mustSucceed(assert)); 287} 288 289{ 290 generatePrime(3, { bigint: true }, common.mustSucceed((prime) => { 291 assert.strictEqual(typeof prime, 'bigint'); 292 assert.strictEqual(prime, 7n); 293 assert(checkPrimeSync(prime)); 294 checkPrime(prime, common.mustSucceed(assert)); 295 })); 296} 297