added sync version of prime

This commit is contained in:
Juan Hernández Serrano 2019-10-09 14:56:11 +02:00
parent 94e69a09ea
commit ace7d479ee
9 changed files with 116 additions and 44 deletions

View File

@ -116,13 +116,17 @@ iterations of Miller-Rabin Probabilistic Primality Test (FIPS 186-4 C.3.1)</p>
<dt><a href="#modPow">modPow(b, e, n)</a><code>bigint</code></dt>
<dd><p>Modular exponentiation b**e mod n. Currently using the right-to-left binary method</p>
</dd>
<dt><a href="#prime">prime(bitLength, iterations, sync)</a><code>Promise</code> | <code>bigint</code></dt>
<dt><a href="#prime">prime(bitLength, iterations, sync)</a><code>Promise</code></dt>
<dd><p>A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
The browser version uses web workers to parallelise prime look up. Therefore, it does not lock the UI
main process, and it can be much faster (if several cores or cpu are available).
The node version can also use worker_threads if they are available (enabled by default with Node 11 and
and can be enabled at runtime executing node --experimental-worker with node &gt;=10.5.0).</p>
</dd>
<dt><a href="#primeSync">primeSync(bitLength, iterations)</a><code>bigint</code></dt>
<dd><p>A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
The sync version is NOT RECOMMENDED since it won&#39;t use workers and thus it&#39;ll be slower and may freeze thw window in browser&#39;s javascript. Please consider using prime() instead.</p>
</dd>
<dt><a href="#randBetween">randBetween(max, min)</a><code>bigint</code></dt>
<dd><p>Returns a cryptographically secure random integer between [min,max]</p>
</dd>
@ -281,7 +285,7 @@ Modular exponentiation b**e mod n. Currently using the right-to-left binary meth
<a name="prime"></a>
## prime(bitLength, iterations, sync) ⇒ <code>Promise</code> \| <code>bigint</code>
## prime(bitLength, iterations, sync) ⇒ <code>Promise</code>
A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
The browser version uses web workers to parallelise prime look up. Therefore, it does not lock the UI
main process, and it can be much faster (if several cores or cpu are available).
@ -289,7 +293,7 @@ The node version can also use worker_threads if they are available (enabled by d
and can be enabled at runtime executing node --experimental-worker with node >=10.5.0).
**Kind**: global function
**Returns**: <code>Promise</code> \| <code>bigint</code> - A promise that resolves to a bigint probable prime of bitLength bits or a bigint if called in synchronous mode.
**Returns**: <code>Promise</code> - A promise that resolves to a bigint probable prime of bitLength bits.
| Param | Type | Description |
| --- | --- | --- |
@ -297,6 +301,20 @@ and can be enabled at runtime executing node --experimental-worker with node >=1
| iterations | <code>number</code> | The number of iterations for the Miller-Rabin Probabilistic Primality Test |
| sync | <code>boolean</code> | NOT RECOMMENDED. Invoke the function synchronously. It won't use workers so it'll be slower and may freeze thw window in browser's javascript. |
<a name="primeSync"></a>
## primeSync(bitLength, iterations) ⇒ <code>bigint</code>
A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.
**Kind**: global function
**Returns**: <code>bigint</code> - A bigint probable prime of bitLength bits.
| Param | Type | Description |
| --- | --- | --- |
| bitLength | <code>number</code> | The required bit length for the generated prime |
| iterations | <code>number</code> | The number of iterations for the Miller-Rabin Probabilistic Primality Test |
<a name="randBetween"></a>
## randBetween(max, min) ⇒ <code>bigint</code>

View File

@ -259,21 +259,11 @@ var bigintCryptoUtils = (function (exports) {
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test
* @param {boolean} sync NOT RECOMMENDED. Invoke the function synchronously. It won't use workers so it'll be slower and may freeze thw window in browser's javascript.
*
* @returns {Promise|bigint} A promise that resolves to a bigint probable prime of bitLength bits or a bigint if called in synchronous mode.
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits.
*/
function prime(bitLength, iterations = 16, sync = false) {
function prime(bitLength, iterations = 16) {
if (bitLength < 1)
throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);
if ( sync) {
let rnd = _ZERO;
do {
rnd = fromBuffer(randBytesSync(bitLength / 8, true));
} while (!_isProbablyPrime(rnd, iterations));
if(sync)
return rnd;
return new Promise((resolve) => { resolve(rnd); });
}
return new Promise((resolve) => {
let workerList = [];
const _onmessage = (msg, newWorker) => {
@ -320,6 +310,25 @@ var bigintCryptoUtils = (function (exports) {
});
}
/**
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
* The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.
*
* @param {number} bitLength The required bit length for the generated prime
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test
*
* @returns {bigint} A bigint probable prime of bitLength bits.
*/
function primeSync(bitLength, iterations = 16) {
if (bitLength < 1)
throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);
let rnd = _ZERO;
do {
rnd = fromBuffer(randBytesSync(bitLength / 8, true));
} while (!_isProbablyPrime(rnd, iterations));
return rnd;
}
/**
* Returns a cryptographically secure random integer between [min,max]
* @param {bigint} max Returned value will be <= max
@ -794,6 +803,7 @@ var bigintCryptoUtils = (function (exports) {
exports.modInv = modInv;
exports.modPow = modPow;
exports.prime = prime;
exports.primeSync = primeSync;
exports.randBetween = randBetween;
exports.randBits = randBits;
exports.randBytes = randBytes;

File diff suppressed because one or more lines are too long

View File

@ -256,21 +256,11 @@ function modPow(b, e, n) {
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test
* @param {boolean} sync NOT RECOMMENDED. Invoke the function synchronously. It won't use workers so it'll be slower and may freeze thw window in browser's javascript.
*
* @returns {Promise|bigint} A promise that resolves to a bigint probable prime of bitLength bits or a bigint if called in synchronous mode.
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits.
*/
function prime(bitLength, iterations = 16, sync = false) {
function prime(bitLength, iterations = 16) {
if (bitLength < 1)
throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);
if ( sync) {
let rnd = _ZERO;
do {
rnd = fromBuffer(randBytesSync(bitLength / 8, true));
} while (!_isProbablyPrime(rnd, iterations));
if(sync)
return rnd;
return new Promise((resolve) => { resolve(rnd); });
}
return new Promise((resolve) => {
let workerList = [];
const _onmessage = (msg, newWorker) => {
@ -317,6 +307,25 @@ function prime(bitLength, iterations = 16, sync = false) {
});
}
/**
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
* The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.
*
* @param {number} bitLength The required bit length for the generated prime
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test
*
* @returns {bigint} A bigint probable prime of bitLength bits.
*/
function primeSync(bitLength, iterations = 16) {
if (bitLength < 1)
throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);
let rnd = _ZERO;
do {
rnd = fromBuffer(randBytesSync(bitLength / 8, true));
} while (!_isProbablyPrime(rnd, iterations));
return rnd;
}
/**
* Returns a cryptographically secure random integer between [min,max]
* @param {bigint} max Returned value will be <= max
@ -780,4 +789,4 @@ function _isProbablyPrime(w, iterations = 16) {
return true;
}
export { abs, bitLength, eGcd, gcd, isProbablyPrime, lcm, max, min, modInv, modPow, prime, randBetween, randBits, randBytes, randBytesSync, toZn };
export { abs, bitLength, eGcd, gcd, isProbablyPrime, lcm, max, min, modInv, modPow, prime, primeSync, randBetween, randBits, randBytes, randBytesSync, toZn };

File diff suppressed because one or more lines are too long

View File

@ -266,19 +266,17 @@ function modPow(b, e, n) {
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test
* @param {boolean} sync NOT RECOMMENDED. Invoke the function synchronously. It won't use workers so it'll be slower and may freeze thw window in browser's javascript.
*
* @returns {Promise|bigint} A promise that resolves to a bigint probable prime of bitLength bits or a bigint if called in synchronous mode.
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits.
*/
function prime(bitLength, iterations = 16, sync = false) {
function prime(bitLength, iterations = 16) {
if (bitLength < 1)
throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);
if (( !_useWorkers) || sync) {
if ( !_useWorkers) {
let rnd = _ZERO;
do {
rnd = fromBuffer(randBytesSync(bitLength / 8, true));
} while (!_isProbablyPrime(rnd, iterations));
if(sync)
return rnd;
return new Promise((resolve) => { resolve(rnd); });
}
return new Promise((resolve) => {
@ -328,6 +326,25 @@ function prime(bitLength, iterations = 16, sync = false) {
});
}
/**
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
* The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.
*
* @param {number} bitLength The required bit length for the generated prime
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test
*
* @returns {bigint} A bigint probable prime of bitLength bits.
*/
function primeSync(bitLength, iterations = 16) {
if (bitLength < 1)
throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);
let rnd = _ZERO;
do {
rnd = fromBuffer(randBytesSync(bitLength / 8, true));
} while (!_isProbablyPrime(rnd, iterations));
return rnd;
}
/**
* Returns a cryptographically secure random integer between [min,max]
* @param {bigint} max Returned value will be <= max
@ -812,6 +829,7 @@ exports.min = min;
exports.modInv = modInv;
exports.modPow = modPow;
exports.prime = prime;
exports.primeSync = primeSync;
exports.randBetween = randBetween;
exports.randBits = randBits;
exports.randBytes = randBytes;

View File

@ -283,19 +283,17 @@ export function modPow(b, e, n) {
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test
* @param {boolean} sync NOT RECOMMENDED. Invoke the function synchronously. It won't use workers so it'll be slower and may freeze thw window in browser's javascript.
*
* @returns {Promise|bigint} A promise that resolves to a bigint probable prime of bitLength bits or a bigint if called in synchronous mode.
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits.
*/
export function prime(bitLength, iterations = 16, sync = false) {
export function prime(bitLength, iterations = 16) {
if (bitLength < 1)
throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);
if ((!process.browser && !_useWorkers) || sync) {
if (!process.browser && !_useWorkers) {
let rnd = _ZERO;
do {
rnd = fromBuffer(randBytesSync(bitLength / 8, true));
} while (!_isProbablyPrime(rnd, iterations));
if(sync)
return rnd;
return new Promise((resolve) => { resolve(rnd); });
}
return new Promise((resolve) => {
@ -352,6 +350,25 @@ export function prime(bitLength, iterations = 16, sync = false) {
});
}
/**
* A probably-prime (Miller-Rabin), cryptographically-secure, random-number generator.
* The sync version is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript. Please consider using prime() instead.
*
* @param {number} bitLength The required bit length for the generated prime
* @param {number} iterations The number of iterations for the Miller-Rabin Probabilistic Primality Test
*
* @returns {bigint} A bigint probable prime of bitLength bits.
*/
export function primeSync(bitLength, iterations = 16) {
if (bitLength < 1)
throw new RangeError(`bitLength MUST be > 0 and it is ${bitLength}`);
let rnd = _ZERO;
do {
rnd = fromBuffer(randBytesSync(bitLength / 8, true));
} while (!_isProbablyPrime(rnd, iterations));
return rnd;
}
/**
* Returns a cryptographically secure random integer between [min,max]
* @param {bigint} max Returned value will be <= max

View File

@ -537,9 +537,9 @@ describe('prime', function () {
});
});
}
describe('Testing sync (NOT-RECOMMENDED) version of prime', function() {
describe('Testing sync (NOT-RECOMMENDED) version: primeSync()', function() {
it('should return a random 1024-bits probable prime', function () {
const prime = bigintCryptoUtils.prime(1024, 16, true);
const prime = bigintCryptoUtils.primeSync(1024, 16);
const primeBitLength = bigintCryptoUtils.bitLength(prime);
chai.expect(primeBitLength).to.equal(1024);
});

View File

@ -24,9 +24,9 @@ describe('prime', function () {
});
});
}
describe('Testing sync (NOT-RECOMMENDED) version of prime', function() {
describe('Testing sync (NOT-RECOMMENDED) version: primeSync()', function() {
it('should return a random 1024-bits probable prime', function () {
const prime = bigintCryptoUtils.prime(1024, 16, true);
const prime = bigintCryptoUtils.primeSync(1024, 16);
const primeBitLength = bigintCryptoUtils.bitLength(prime);
chai.expect(primeBitLength).to.equal(1024);
});