# Mathematical Module

This module defines the mathematical API for Scytl's JavaScript cryptographic library. The starting point for using this module is the instantiation of a mathematical 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-mathematical/lib`.

To build this module, change to the directory `scytl-cryptolib/cryptolib-js-mathematical` 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-mathematical/spec`. To run the tests, change to the directory `scytl-cryptolib/cryptolib-js-mathematical` 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 new ZpGroupElement object that should be able to ..',
...
```
To only run a chosen test, add an `f` in front of the corresponding `it` statement. For example:

```javascript
fit('be multiplied with another ZpGroupElement object', 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-mathematical`, 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-mathematical
```
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-codec": "^2.1.0",
    "scytl-securerandom": "^2.1.0",
    "scytl-mathematical": "^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 mathematical service

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

```javascript
var mathematical = require('scytl-mathematical');

var mathService = mathematical.newService();
```
The following example shows how to supply one's own secure random service to the mathematical service.

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

var mySecureRandomService = secureRandom.newService();

var mathService = mathematical.newService({secureRandomService: mySecureRandomService});
```
## How to instantiate mathematical objects

The following examples show how to create new `ZpSubgroup`, `ZpGroupElement`, `Exponent` and quadratic residue group objects, given the generator, modulus `p` and order `q` of the Zp subgroup. The quadratic residue group object is a `ZpSubgroup` object, defined such that its modulus and order satisfy the relationship `p = 2q + 1`.

```javascript
var mathematical = require('scytl-mathematical');
var forge = require('node-forge');

var BigInteger = forge.jsbn.BigInteger;

var mathService = mathematical.newService();

var p = new BigInteger('23');
var q = new BigInteger('11');
var g = new BigInteger('2');
var elementValue = new BigInteger('3');
var exponentValue = new BigInteger('2');

var group = mathService.newZpSubroup(p, q, g);
var element = mathService.newZpGroupElement(p, q, elementValue);
var exponent = mathService.newExponent(q, exponentValue);
var qrGroup = mathService.newQuadraticResidueGroup(p, q);
```
The following examples show how to create new `ZpSubgroup`, `ZpGroupElement` and `Exponent` objects from their JSON string representations.

```javascript
var group = mathService.newZpSubroup(groupJson);
var element = mathService.newZpGubroupElement(elementJson);
var exponent = mathService.newExponent(exponentJson);
```
The `ZpSubgroup` object defines the following properties and functions.

```java
@property p The modulus of the Zp subgroup.
@property q The order of the Zp subgroup.
@property generator The generator element of the Zp subgroup.
@property identity The identity element of the Zp subgroup.

@function equals Checks that the Zp subgroup element is equal to the Zp subgroup element provided as input.
@function isGroupMember Checks whether a Zp group element provided as input is a member of the Zp subgroup.
@function isQuadraticResidueGroup Checks whether the Zp subgroup is a quadratic residue group.
@function toJson Serializes the Zp subgroup into a JSON string representation.
```
The `ZpGroupElement` object defines the following properties and functions.

```java
@property p The modulus of the Zp subgroup to which the Zp group element belongs.
@property q The order of the Zp subgroup to which the Zp group element belongs.
@property value The value of the Zp group element.

@function multiply Multiplies the Zp group element by the Zp group element provided as input.
@function invert Exponentiates the Zp group element with the exponent provided as input.
@function equals Checks that the Zp group element is equal to the Zp group element provided as input.
@function toJson Serializes the Zp group element into a JSON string representation.
```
The `Exponent` object defines the following properties and functions.

```java
@property q The order of the Zp subgroup associated with the exponent.
@property value The value of the exponent.

@function add Adds the exponent to the exponent provided as input.
@function subtract Subtracts the exponent provided as input from the exponent.
@function multiply Multiplies the exponent with the exponent provided as input.
@function negate Negates the exponent.
@function equals Checks whether the exponent is equal to the exponent provided as input.
@function toJson Serializes the exponent into a JSON string representation.
```
## How to compress mathematical arrays

The following examples show how to compress an array of Zp group elements into a single Zp group element or how to compress a number of trailing Zp group elements in the input array so that the output array has the specified number of elements.

```javascript
var mathArrayCompressor = mathService.newArrayCompressor();

var compressedElement = mathArrayCompressor.compressZpGroupElements(elements);
var compressedElements = mathArrayCompressor.compressTrailingZpGroupElements(elements, numOutputElements);
```
The following examples show how to compress an array of exponents into a single exponent or how to compress a number of trailing exponents in the input array so that the output array has the specified number of exponents.

```javascript
var compressedExponent = mathArrayCompressor.compressExponents(exponents);
var compressedExponents = mathArrayCompressor.compressTrailingExponents(exponents, numOutputExponents);
```
## How to generate random mathematical objects

The following examples show how to generate a random Zp group element or a random exponent.

```javascript
var mathRandomGenerator = mathService.newRandomGenerator();

var element = mathRandomGenerator.nextZpGroupElement(group);
var exponent = mathRandomGenerator.nextExponent(group);
```
**Note:** If the additional input argument `{useShortExponent: true}` is provided to the method `nextZpGroupElement`, then only a so-called `short exponent` (presently defined as less than 256 bits) will be used to generate the Zp group element. Similarly, if this input argument is provided to the method `nextExponent` then the generated exponent will be a `short exponent`.

The following example shows how to generate a random `quadratic residue` Zp subgroup with a specified certainty that its order `q` is prime.

```javascript
var qrGroup = mathRandomGenerator.nextQuadraticResidueGroup(pBitLength, certainty);
```
## How to perform mathematical group operations.

The following examples show how to exponentiate an array of Zp group elements and how to divide one array of Zp group elements by another.

```javascript
var mathGroupHandler = mathService.newGroupHandler();

var exponentiatedElements = mathGroupHandler.exponentiateElements(group, elements, exponent, true);
var dividedElements = mathGroupHandler.divideElements(dividendElements, divisorElements);
```
**Note:** The value of **true** in the call to method `exponentiateElements` is optional and will trigger a check that all of the Zp group elements provided as input are really members of the Zp subgroup provided as input. By default, this operation is not performed because it can be computationally costly.

The following example shows how to check if an array of Zp group elements are members of the Zp subgroup provided as input. An error will be thrown if any element in the array fails the membership check.

```javascript
mathGroupHandler.checkGroupMembership(group, elements);
```

The following example shows how to extract a specified number of members of a specified Zp subgroup from an array of Zp group element values provided as input.

```javascript
var groupMembers = mathGroupHandler.extractGroupMembers(group, values, numMembersRequired);
```
The following example shows how to find the smallest possible generator of a Zp subgroup, given its modulus `p` and its order `q`.

```javascript
var minGenerator = mathGroupHandler.findMinGenerator(p, q);
```
