# Secure Random Module

This module defines the secure random API for Scytl's JavaScript cryptographic library. The starting point for using this module is the instantiation of a secure random service.

## How to view, build and test the source code of this module

Start by git cloning the project `comm/scytl-cryptolib` from `Stash`.

The source code of this module will be found in the directory `scytl-cryptolib/cryptolib-js-securerandom/lib`.

To build this module, change to the directory `scytl-cryptolib/cryptolib-js-securerandom` and do the following:

```java
npm install
--or--
mvn clean install -DskipTests
```
The unit tests of this module will be found in the directory `scytl-cryptolib/cryptolib-js-securerandom/spec`. To run the tests, change to the directory `scytl-cryptolib/cryptolib-js-securerandom` and do the following:

```javascript
karma test
--or--
mvn test
```
To only run a chosen test suite, add an `f` in front of the corresponding `describe` statement. For example:

```javascript
fdescribe('create a secure random generator that should be able to', function()
...
```
To only run a chosen test, add an `f` in front of the corresponding `it` statement. For example:

```javascript
fit('generate a specified number of random bytes', function()
...
```
**Note:** To build and test the entire `scytl-cryptolib` project, change to the directory `scytl-cryptolib` and do the following:

```javascript
mvn clean install
```
## How to generate the JSDoc for this module

To generate the JSDoc for this module, change to the directory `scytl-cryptolib/cryptolib-js-securerandom`, build the module (if not already done) and do the following:

```javascript
node_modules/.bin/jsdoc lib
```
This will generate a file called `out`. Double click on the file `out/index.html` to view the JSDoc.

## How to `npm` install this module

To `npm` install this module in standalone mode, do the following:

```javascript
npm install --registry https://nexus.scytl.net/content/groups/public-npm/ scytl-securerandom
```
To `npm` install this module as a dependency of your own module, do the following:

1. Add the following lines to the `dependencies` section of your module's `package.json` file.
    ```javascript
    "scytl-bitwise": "^2.1.0",
    "scytl-codec": "^2.1.0",
    "scytl-securerandom": "^2.1.0",
    ```
2. Make sure that the `.npmrc` file of your module contains the following line.
    ```javascript
    registry=https://nexus.scytl.net/content/groups/public-npm/
    ```
3. Install all dependencies.
    ```javascript
    npm install
    ```
## How to instantiate a secure random service

The following example shows the default way to create a new instance of a secure random service.

```javascript
var secureRandom = require('scytl-securerandom');

var secureRandomService = secureRandom.newService();
```
The secure random service accepts an optional input argument that can be used to override the default values used by the service.

For example, to provide one's own seed to initialize the PRNG used internally by the service, one could do the following, where the seed is provided as an array of bytes, wrapped in a Uint8Array object:

```javascript
var myPrngSeed = ...;
var secureRandomService = secureRandom.newService({prngSeed: myPrngSeed});
```
In addition, the optional input argument can be used to override the default entropy collection behavior of the secure random service. A detailed description of the available fields is provided in the section **How to configure the entropy collection behavior**.

## How to instantiate a secure random generator.

The following example shows the default way to create a new secure random generator.

```javascript
var randomGenerator = secureRandomService.newRandomGenerator();
```
The following example shows how to create a new secure random generator, using a specified maximum allowed number of bytes that can be generated per method call (Default is 512):

```javascript
var randomGenerator = secureRandomService.newRandomGenerator({maxNumBytes: 1024});
```
The following example shows how to create a new secure random generator, using a specified maximum allowed number of BigInteger digits that can be generated per method call (Default is 512):

```javascript
var randomGenerator = secureRandomService.newRandomGenerator({maxNumDigits: 1024});
```

## How to generate random values

The following example shows how to generate an array of random bytes of length 8, wrapped in a `Uint8Array` object:

```javascript
var randomBytes = randomGenerator.nextBytes(8);
```
The following example shows how to generate a random `BigInteger` object with a value that is 256 bits in length:

```javascript
var randomBigInteger = randomGenerator.nextBigInteger(256);
```
The following example shows how to generate a random `BigInteger` object with a value that contains 10 digits:

```javascript
var randomBigInteger = randomGenerator.nextBigIntegerByDigits(10);
```
## How to work with seeds.

The following example shows how to generate a 16 byte random seed, wrapped in a `Uint8Array` object, that can be used to initialize the PRNG of a new SecureRandomService object. If no input argument is provided, the resulting seed will be 32 bytes in length:

```javascript
var randomSeed = secureRandomService.nextSeed(16);
...
var secureRandomService2 = new SecureRandomService({prngSeed: randomSeed});
```
## How to configure the entropy collection behavior

Entropy collection will start as soon as the secure random service is instantiated and will stop once the required amount of entropy has been collected or when the PRNG is needed for the first time. If the WebKit entropy collector is available, it will be used exclusively. Otherwise, the entropy will be collected from a combination of several available sources (e.g. mouse movement, key board activity).

As mentioned above, the optional argument used for secure random service instantiation can be used to override the default entropy collection behavior. The available entropy related fields for the optional argument are the following:

* `maxEntropyCounter`: The amount of entropy to accumulate before stopping the collectors (Default is 256). It must be a positive number.
* `hashUpdaterInterval`: The interval (in milliseconds) at which entropy data is to be hashed (Default is 1000). It must be a positive number.
* `windowObject`: The *window* object provided to the collectors (Default is built-in *window* object).
* `cryptoApi`: The cryptographic library supplied to the *WebKit* entropy collector, if being used (Default is user's built-in cryptographic library)
* `privateKeyData`: The private key entropy collector data (By default, this collector is not used). If provided, it must consist of an object with the following two fields:
  1. `privateKeyData.privateKey`: The private key, in PEM format.
  2. `privateKeyData.pinEntropy`: The PIN entropy of the private key. It must be a positive number.
* `noDefaultCollectors`: If *true*, indicates that no default entropy collectors are to be used (Default is *false*).

In addition, the SecureRandomService object defines some methods that can be used for work with entropy collection.

The following example shows how to start the entropy collection manually. It will have no effect if the SecureRandomService object is already collecting entropy. The optional input argument is a callback function that will be executed when the entropy collection process has completed.

```javascript
secureRandomService.startEntropyCollection(callback);
```
The following example shows how to stop the entropy collection manually. It will have no effect if the SecureRandomService object is not collecting entropy. After entropy collection is stopped, the service will be reseeded using the resulting entropy as the seed. The return value of this method can be used to determine if the maximum amount of entropy required was collected:

```javascript
secureRandomService.stopEntropyCollection();
     --or--
var maxEntropyCollected = secureRandomService.stopEntropyCollection();
```
The following example shows how to retrieve the percentage of entropy collected so far, as a percentage of the maximum amount of entropy required:

```javascript
secureRandomService.getEntropyPercentage();
```
