Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

paillier-bigint

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

paillier-bigint - npm Package Compare versions

Comparing version 2.0.0 to 3.0.0

build/build.dts.js

64

package.json
{
"name": "paillier-bigint",
"version": "2.0.0",
"description": "An implementation of the Paillier cryptosystem using native JS (stage 3) implementation of BigInt",
"version": "3.0.0",
"description": "An implementation of the Paillier cryptosystem using native JS (ECMA 2020) implementation of BigInt",
"keywords": [

@@ -9,3 +9,4 @@ "paillier",

"crypto",
"cryptosystem"
"cryptosystem",
"bigint"
],

@@ -19,33 +20,52 @@ "license": "MIT",

"repository": "github:juanelas/paillier-bigint",
"main": "./dist/paillier-bigint-latest.node.js",
"browser": "./dist/paillier-bigint-latest.browser.mod.js",
"main": "./lib/index.node.js",
"browser": "./lib/index.browser.mod.js",
"types": "./types/index.d.ts",
"directories": {
"build": "./build",
"dist": "./dist",
"lib": "./lib",
"src": "./src",
"test": "./test"
"test": "./test",
"types": "./types"
},
"scripts": {
"test": "node --experimental-worker node_modules/mocha/bin/_mocha --timeout 600000",
"build": "node build/build.rollup.js",
"build:browserTests": "node build/build.browser.tests.js",
"build:docs": "jsdoc2md --template=README.hbs --files ./src/main.js > README.md",
"build:all": "npm run build && npm run build:browserTests && npm run build:docs",
"prepublishOnly": "npm run build && npm run build:docs"
"test": "mocha",
"build:js": "rollup -c build/rollup.config.js",
"build:standard": "standard --fix",
"build:browserTests": "rollup -c build/rollup.tests.config.js",
"build:docs": "jsdoc2md --template=./src/doc/readme-template.md --files ./src/js/index.js > README.md",
"build:dts": "node build/build.dts.js",
"build": "run-s build:**",
"prepublishOnly": "npm run build"
},
"standard": {
"env": [
"mocha"
],
"globals": [
"BigInt"
],
"ignore": [
"/test/browser/",
"/lib/index.browser.bundle.js",
"/lib/index.browser.bundle.mod.js"
]
},
"devDependencies": {
"@rollup/plugin-commonjs": "^11.0.2",
"@rollup/plugin-multi-entry": "^3.0.0",
"@rollup/plugin-node-resolve": "^7.1.1",
"@rollup/plugin-replace": "^2.3.1",
"chai": "^4.2.0",
"eslint": "^6.8.0",
"jsdoc-to-markdown": "^5.0.3",
"mocha": "^7",
"rollup": "^1.29.1",
"rollup-plugin-babel-minify": "^9.1.1",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-multi-entry": "^2.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-replace": "^2.2.0"
"mocha": "^7.1.1",
"npm-run-all": "^4.1.5",
"rollup": "^2.2.0",
"rollup-plugin-terser": "^5.3.0",
"standard": "^14.3.3",
"typescript": "^3.8.3"
},
"dependencies": {
"bigint-crypto-utils": "^2.4.2"
"bigint-crypto-utils": "^2.5.2"
}
}

@@ -0,1 +1,3 @@

[![JavaScript Style Guide](https://cdn.rawgit.com/standard/standard/master/badge.svg)](https://github.com/standard/standard)
# paillier-bigint

@@ -7,4 +9,3 @@

The Paillier cryptosystem, named after and invented by Pascal Paillier in 1999, is a probabilistic asymmetric algorithm
for public key cryptography. A notable feature of the Paillier cryptosystem is its homomorphic properties.
The Paillier cryptosystem, named after and invented by Pascal Paillier in 1999, is a probabilistic asymmetric algorithm for public key cryptography. A notable feature of the Paillier cryptosystem is its homomorphic properties.

@@ -78,72 +79,39 @@ ## Homomorphic properties

For web browsers, you can also directly download the minimised version of the [IIFE file](https://aw.githubusercontent.com/juanelas/paillier-bigint/master/dist/paillier-bigint-latest.browser.min.js) or the [ES6 module](https://raw.githubusercontent.com/juanelas/paillier-bigint/master/dist/paillier-bigint-latest.browser.mod.min.js) from GitHub.
For web browsers, you can also directly download the minimized version of the [IIFE file](https://aw.githubusercontent.com/juanelas/paillier-bigint/master/dist/index.browser.bundle.js) or the [ES6 module](https://raw.githubusercontent.com/juanelas/paillier-bigint/master/dist/index.browser.bundle.mod.js) from GitHub.
## Usage
Every input number should be a string in base 10, an integer, or a bigint. All the output numbers are of type `bigint`.
An example with Node.js:
```javascript
// import paillier
const paillier = require('paillier-bigint.js');
// import paillier in node.js
const paillier = require('paillier-bigint.js')
// import paillier in native JS
import * as paillier from 'paillier-bigint'
// (asynchronous) creation of a random private, public key pair for the Paillier cryptosystem
const {publicKey, privateKey} = await paillier.generateRandomKeys(3072);
const {publicKey, privateKey} = await paillier.generateRandomKeys(3072)
// optionally, you can create your public/private keys from known parameters
const publicKey = new paillier.PublicKey(n, g);
const privateKey = new paillier.PrivateKey(lambda, mu, publicKey);
const publicKey = new paillier.PublicKey(n, g)
const privateKey = new paillier.PrivateKey(lambda, mu, publicKey)
// encrypt m
let c = publicKey.encrypt(m);
let c = publicKey.encrypt(m)
// decrypt c
let d = privateKey.decrypt(c);
let d = privateKey.decrypt(c)
// homomorphic addition of two ciphertexts (encrypted numbers)
let c1 = publicKey.encrypt(m1);
let c2 = publicKey.encrypt(m2);
let encryptedSum = publicKey.addition(c1, c2);
let sum = privateKey.decrypt(encryptedSum); // m1 + m2
let c1 = publicKey.encrypt(m1)
let c2 = publicKey.encrypt(m2)
let encryptedSum = publicKey.addition(c1, c2)
let sum = privateKey.decrypt(encryptedSum) // m1 + m2
// multiplication by k
let c1 = publicKey.encrypt(m1);
let encryptedMul = publicKey.multiply(c1, k);
let mul = privateKey.decrypt(encryptedMul); // k · m1
let c1 = publicKey.encrypt(m1)
let encryptedMul = publicKey.multiply(c1, k)
let mul = privateKey.decrypt(encryptedMul) // k · m1
```
From a browser, you can just load the module in a html page as:
```html
<script type="module">
import * as paillier from 'paillier-bigint-latest.browser.mod.min.js';
# JS Doc
// (asynchronous) creation of a random private, public key pair for the Paillier cryptosystem
paillier.generateRandomKeys(3072).then((keyPair) => {
const publicKey = keyPair.publicKey;
const privateKey = keyPair.privateKey;
// ...
});
// You can also create your public/private keys from known parameters
const publicKey = new paillier.PublicKey(n, g);
const privateKey = new paillier.PrivateKey(lambda, mu, publicKey);
// encrypt m is just
let c = publicKey.encrypt(m);
// decrypt c
let d = privateKey.decrypt(c);
// homomorphic addition of two ciphertexts (encrypted numbers)
let c1 = publicKey.encrypt(m1);
let c2 = publicKey.encrypt(m2);
let encryptedSum = publicKey.addition(c1, c2);
let sum = privateKey.decrypt(encryptedSum); // m1 + m2
// multiplication by k
let c1 = publicKey.encrypt(m1);
let encryptedMul = publicKey.multiply(c1, k);
let mul = privateKey.decrypt(encryptedMul); // k · m1
</script>
```
## Classes

@@ -161,7 +129,7 @@

<dl>
<dt><a href="#generateRandomKeys">generateRandomKeys</a> ⇒ <code>Promise</code></dt>
<dt><a href="#generateRandomKeys">generateRandomKeys</a> ⇒ <code><a href="#KeyPair">Promise.&lt;KeyPair&gt;</a></code></dt>
<dd><p>Generates a pair private, public key for the Paillier cryptosystem.</p>
</dd>
<dt><a href="#generateRandomKeysSync">generateRandomKeysSync</a> ⇒</dt>
<dd><p>Generates a pair private, public key for the Paillier cryptosystem in synchronous mode.
<dt><a href="#generateRandomKeysSync">generateRandomKeysSync</a> ⇒ <code><a href="#KeyPair">KeyPair</a></code></dt>
<dd><p>Generates a pair private, public key for the Paillier cryptosystem in synchronous mode.
Synchronous mode 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.</p>

@@ -204,4 +172,4 @@ </dd>

| --- | --- | --- |
| n | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | the public modulo |
| g | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | the public generator |
| n | <code>bigint</code> | the public modulo |
| g | <code>bigint</code> \| <code>number</code> | the public generator |

@@ -225,3 +193,3 @@ <a name="PublicKey+bitLength"></a>

| --- | --- | --- |
| m | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | a cleartext number |
| m | <code>bigint</code> | a bigint representation of a cleartext message |

@@ -238,3 +206,3 @@ <a name="PublicKey+addition"></a>

| --- | --- | --- |
| ...ciphertexts | <code>bigint</code> \| <code>number</code> | n >= 2 ciphertexts (c_1,..., c_n) that are the encryption of (m_1, ..., m_n) with this public key |
| ...ciphertexts | <code>bigint</code> | n >= 2 ciphertexts (c_1,..., c_n) that are the encryption of (m_1, ..., m_n) with this public key |

@@ -252,3 +220,3 @@ <a name="PublicKey+multiply"></a>

| c | <code>bigint</code> | a number m encrypted with this public key |
| k | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | either a cleartext message (number) or a scalar |
| k | <code>bigint</code> \| <code>number</code> | either a bigint or a number |

@@ -274,7 +242,7 @@ <a name="PrivateKey"></a>

| --- | --- | --- | --- |
| lambda | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | | |
| mu | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | | |
| lambda | <code>bigint</code> | | |
| mu | <code>bigint</code> | | |
| publicKey | <code>PaillierPublicKey</code> | | |
| [p] | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | <code></code> | a big prime |
| [q] | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | <code></code> | a big prime |
| [p] | <code>bigint</code> | <code></code> | a big prime |
| [q] | <code>bigint</code> | <code></code> | a big prime |

@@ -305,11 +273,11 @@ <a name="PrivateKey+bitLength"></a>

| --- | --- | --- |
| c | <code>bigint</code> \| <code>stringBase10</code> | a (big) number encrypted with the public key |
| c | <code>bigint</code> | a bigint encrypted with the public key |
<a name="generateRandomKeys"></a>
## generateRandomKeys ⇒ <code>Promise</code>
## generateRandomKeys ⇒ [<code>Promise.&lt;KeyPair&gt;</code>](#KeyPair)
Generates a pair private, public key for the Paillier cryptosystem.
**Kind**: global constant
**Returns**: <code>Promise</code> - - a promise that resolves to a [KeyPair](#KeyPair) of public, private keys
**Returns**: [<code>Promise.&lt;KeyPair&gt;</code>](#KeyPair) - - a promise that resolves to a [KeyPair](#KeyPair) of public, private keys

@@ -323,8 +291,8 @@ | Param | Type | Default | Description |

## generateRandomKeysSync ⇒
Generates a pair private, public key for the Paillier cryptosystem in synchronous mode.
## generateRandomKeysSync ⇒ [<code>KeyPair</code>](#KeyPair)
Generates a pair private, public key for the Paillier cryptosystem in synchronous mode.
Synchronous mode is NOT RECOMMENDED since it won't use workers and thus it'll be slower and may freeze thw window in browser's javascript.
**Kind**: global constant
**Returns**: [KeyPair](#KeyPair) - a [KeyPair](#KeyPair) of public, private keys
**Returns**: [<code>KeyPair</code>](#KeyPair) - - a [KeyPair](#KeyPair) of public, private keys

@@ -358,4 +326,4 @@ | Param | Type | Default | Description |

| --- | --- | --- |
| n | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | the public modulo |
| g | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | the public generator |
| n | <code>bigint</code> | the public modulo |
| g | <code>bigint</code> \| <code>number</code> | the public generator |

@@ -379,3 +347,3 @@ <a name="PublicKey+bitLength"></a>

| --- | --- | --- |
| m | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | a cleartext number |
| m | <code>bigint</code> | a bigint representation of a cleartext message |

@@ -392,3 +360,3 @@ <a name="PublicKey+addition"></a>

| --- | --- | --- |
| ...ciphertexts | <code>bigint</code> \| <code>number</code> | n >= 2 ciphertexts (c_1,..., c_n) that are the encryption of (m_1, ..., m_n) with this public key |
| ...ciphertexts | <code>bigint</code> | n >= 2 ciphertexts (c_1,..., c_n) that are the encryption of (m_1, ..., m_n) with this public key |

@@ -406,3 +374,3 @@ <a name="PublicKey+multiply"></a>

| c | <code>bigint</code> | a number m encrypted with this public key |
| k | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | either a cleartext message (number) or a scalar |
| k | <code>bigint</code> \| <code>number</code> | either a bigint or a number |

@@ -430,7 +398,7 @@ <a name="PrivateKey"></a>

| --- | --- | --- | --- |
| lambda | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | | |
| mu | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | | |
| lambda | <code>bigint</code> | | |
| mu | <code>bigint</code> | | |
| publicKey | <code>PaillierPublicKey</code> | | |
| [p] | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | <code></code> | a big prime |
| [q] | <code>bigint</code> \| <code>stringBase10</code> \| <code>number</code> | <code></code> | a big prime |
| [p] | <code>bigint</code> | <code></code> | a big prime |
| [q] | <code>bigint</code> | <code></code> | a big prime |

@@ -461,3 +429,3 @@ <a name="PrivateKey+bitLength"></a>

| --- | --- | --- |
| c | <code>bigint</code> \| <code>stringBase10</code> | a (big) number encrypted with the public key |
| c | <code>bigint</code> | a bigint encrypted with the public key |

@@ -475,3 +443,1 @@ <a name="KeyPair"></a>

* * *

@@ -8,3 +8,3 @@ const _ZERO = BigInt(0);

*
* @param {number|bigint} a
* @param {number | bigint} a
*

@@ -124,3 +124,3 @@ * @returns {bigint} the absolute value of a

*
* @return {Promise} A promise that resolves to a boolean that is either true (a probably prime number) or false (definitely composite)
* @returns {Promise<boolean>} A promise that resolves to a boolean that is either true (a probably prime number) or false (definitely composite)
*/

@@ -260,3 +260,3 @@ async function isProbablyPrime(w, iterations = 16) {

*
* @returns {Promise} A promise that resolves to a bigint probable prime of bitLength bits.
* @returns {Promise<bigint>} A promise that resolves to a bigint probable prime of bitLength bits.
*/

@@ -363,7 +363,10 @@ function prime(bitLength, iterations = 16) {

const byteLength = Math.ceil(bitLength / 8);
let rndBytes = randBytesSync(byteLength, false);
// Fill with 0's the extra bits
rndBytes[0] = rndBytes[0] & (2 ** (bitLength % 8) - 1);
const rndBytes = randBytesSync(byteLength, false);
const bitLengthMod8 = bitLength % 8;
if (bitLengthMod8) {
// Fill with 0's the extra bits
rndBytes[0] = rndBytes[0] & (2 ** bitLengthMod8 - 1);
}
if (forceLength) {
let mask = (bitLength % 8) ? 2 ** ((bitLength % 8) - 1) : 128;
const mask = bitLengthMod8 ? 2 ** (bitLengthMod8 - 1) : 128;
rndBytes[0] = rndBytes[0] | mask;

@@ -380,3 +383,3 @@ }

*
* @returns {Promise} A promise that resolves to a Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bytes
* @returns {Promise<Buffer|Uint8Array>} A promise that resolves to a Buffer/UInt8Array (Node.js/Browser) filled with cryptographically secure random bytes
*/

@@ -817,76 +820,78 @@ function randBytes(byteLength, forceLength = false) {

// For the browser test builder to work you MUST import them module in a variable that
// is the camelised version of the package name.
// Every test file (you can create as many as you want) should start like this
// Please, do NOT touch. They will be automatically removed for browser tests -->
// <--
const bitLengths = [1024, 2048, 3072];
for (const bitLength of bitLengths) {
describe(`Testing Paillier with keys of ${bitLength} bits`, function () {
let keyPair;
const tests = 32;
let numbers = [];
let ciphertexts = [];
describe(`Testing Paillier with keys of ${bitLength} bits`, function () {
this.timeout(90000);
let keyPair;
const tests = 32;
const numbers = [];
const ciphertexts = [];
describe(`generateRandomKeys(${bitLength})`, function () {
it(`it should return a publicKey and a privateKey with public modulus of ${bitLength} bits`, async function () {
keyPair = await paillierBigint.generateRandomKeys(bitLength);
chai.expect(keyPair.publicKey).to.be.an.instanceOf(paillierBigint.PublicKey);
chai.expect(keyPair.privateKey).to.be.an.instanceOf(paillierBigint.PrivateKey);
chai.expect(keyPair.publicKey.bitLength).to.equal(bitLength);
});
});
describe(`generateRandomKeys(${bitLength})`, function () {
it(`it should return a publicKey and a privateKey with public modulus of ${bitLength} bits`, async function () {
keyPair = await _pkg.generateRandomKeys(bitLength);
chai.expect(keyPair.publicKey).to.be.an.instanceOf(_pkg.PublicKey);
chai.expect(keyPair.privateKey).to.be.an.instanceOf(_pkg.PrivateKey);
chai.expect(keyPair.publicKey.bitLength).to.equal(bitLength);
});
});
describe(`Correctness. For ${tests} random r in (1,n), encrypt r with publicKey and then decrypt with privateKey: D(E(r))`, function () {
it('all should return r', function () {
let testPassed = true;
for (let i = 0; i < tests; i++) {
numbers[i] = bigintCryptoUtilsLatest_browser_mod.randBetween(keyPair.publicKey.n);
ciphertexts[i] = keyPair.publicKey.encrypt(numbers[i]);
const decrypted = keyPair.privateKey.decrypt(ciphertexts[i]);
if (numbers[i] !== decrypted) {
testPassed = false;
break;
}
}
chai.expect(testPassed).equals(true);
});
});
describe(`Correctness. For ${tests} random r in (1,n), encrypt r with publicKey and then decrypt with privateKey: D(E(r))`, function () {
it('all should return r', function () {
let testPassed = true;
for (let i = 0; i < tests; i++) {
numbers[i] = bigintCryptoUtilsLatest_browser_mod.randBetween(keyPair.publicKey.n);
ciphertexts[i] = keyPair.publicKey.encrypt(numbers[i]);
const decrypted = keyPair.privateKey.decrypt(ciphertexts[i]);
if (numbers[i] !== decrypted) {
testPassed = false;
break
}
}
chai.expect(testPassed).equals(true);
});
});
describe('Homomorphic properties', function () {
describe(`Homomorphic addtion: D( E(m1)·...·E(m${tests})) mod n^2 )`, function () {
it(`should return m1+...+m${tests} mod n`, function () {
const encSum = keyPair.publicKey.addition(...ciphertexts);
let d = keyPair.privateKey.decrypt(encSum);
const sumNumbers = numbers.reduce((sum, next) => (sum + next) % keyPair.publicKey.n);
chai.expect(d === sumNumbers);
});
});
describe(`For all the ${tests} random r, the (pseudo-)homomorphic multiplication: D( E(r)^r mod n^2 )`, function () {
it('should return r^2 mod n', function () {
let testPassed = true;
for (let i = 0; i < numbers.length; i++) {
const encMul = keyPair.publicKey.multiply(ciphertexts[i], numbers[i]);
const d = keyPair.privateKey.decrypt(encMul);
if (d !== bigintCryptoUtilsLatest_browser_mod.modPow(numbers[i], 2, keyPair.publicKey.n)) {
testPassed = false;
break;
}
}
chai.expect(testPassed).equals(true);
});
});
describe('Homomorphic properties', function () {
describe(`Homomorphic addtion: D( E(m1)·...·E(m${tests})) mod n^2 )`, function () {
it(`should return m1+...+m${tests} mod n`, function () {
const encSum = keyPair.publicKey.addition(...ciphertexts);
const d = keyPair.privateKey.decrypt(encSum);
const sumNumbers = numbers.reduce((sum, next) => (sum + next) % keyPair.publicKey.n);
chai.expect(d === sumNumbers);
});
});
describe(`For all the ${tests} random r, the (pseudo-)homomorphic multiplication: D( E(r)^r mod n^2 )`, function () {
it('should return r^2 mod n', function () {
let testPassed = true;
for (let i = 0; i < numbers.length; i++) {
const encMul = keyPair.publicKey.multiply(ciphertexts[i], numbers[i]);
const d = keyPair.privateKey.decrypt(encMul);
if (d !== bigintCryptoUtilsLatest_browser_mod.modPow(numbers[i], 2, keyPair.publicKey.n)) {
testPassed = false;
break
}
}
chai.expect(testPassed).equals(true);
});
});
});
});
}
describe('Testing generateRandomKeysSync(2048) NOT RECOMMENDED', function () {
it('it should return a publicKey and a privateKey with public modulus of 2048 bits', function () {
const keyPair = paillierBigint.generateRandomKeysSync(2048);
chai.expect(keyPair.publicKey).to.be.an.instanceOf(paillierBigint.PublicKey);
chai.expect(keyPair.privateKey).to.be.an.instanceOf(paillierBigint.PrivateKey);
chai.expect(keyPair.publicKey.bitLength).to.equal(2048);
});
this.timeout(90000);
it('it should return a publicKey and a privateKey with public modulus of 2048 bits', function () {
const keyPair = _pkg.generateRandomKeysSync(2048);
chai.expect(keyPair.publicKey).to.be.an.instanceOf(_pkg.PublicKey);
chai.expect(keyPair.privateKey).to.be.an.instanceOf(_pkg.PrivateKey);
chai.expect(keyPair.publicKey.bitLength).to.equal(2048);
});
});

@@ -1,77 +0,79 @@

'use strict';
'use strict'
// For the browser test builder to work you MUST import them module in a variable that
// is the camelised version of the package name.
const paillierBigint = require('../dist/paillier-bigint-latest.node');
const chai = require('chai');
// Every test file (you can create as many as you want) should start like this
// Please, do NOT touch. They will be automatically removed for browser tests -->
const _pkg = require('../lib/index.node')
const chai = require('chai')
// <--
const bcu = require('bigint-crypto-utils');
const bcu = require('bigint-crypto-utils')
const bitLengths = [1024, 2048, 3072];
const bitLengths = [1024, 2048, 3072]
for (const bitLength of bitLengths) {
describe(`Testing Paillier with keys of ${bitLength} bits`, function () {
let keyPair;
const tests = 32;
let numbers = [];
let ciphertexts = [];
describe(`Testing Paillier with keys of ${bitLength} bits`, function () {
this.timeout(90000)
let keyPair
const tests = 32
const numbers = []
const ciphertexts = []
describe(`generateRandomKeys(${bitLength})`, function () {
it(`it should return a publicKey and a privateKey with public modulus of ${bitLength} bits`, async function () {
keyPair = await paillierBigint.generateRandomKeys(bitLength);
chai.expect(keyPair.publicKey).to.be.an.instanceOf(paillierBigint.PublicKey);
chai.expect(keyPair.privateKey).to.be.an.instanceOf(paillierBigint.PrivateKey);
chai.expect(keyPair.publicKey.bitLength).to.equal(bitLength);
});
});
describe(`generateRandomKeys(${bitLength})`, function () {
it(`it should return a publicKey and a privateKey with public modulus of ${bitLength} bits`, async function () {
keyPair = await _pkg.generateRandomKeys(bitLength)
chai.expect(keyPair.publicKey).to.be.an.instanceOf(_pkg.PublicKey)
chai.expect(keyPair.privateKey).to.be.an.instanceOf(_pkg.PrivateKey)
chai.expect(keyPair.publicKey.bitLength).to.equal(bitLength)
})
})
describe(`Correctness. For ${tests} random r in (1,n), encrypt r with publicKey and then decrypt with privateKey: D(E(r))`, function () {
it('all should return r', function () {
let testPassed = true;
for (let i = 0; i < tests; i++) {
numbers[i] = bcu.randBetween(keyPair.publicKey.n);
ciphertexts[i] = keyPair.publicKey.encrypt(numbers[i]);
const decrypted = keyPair.privateKey.decrypt(ciphertexts[i]);
if (numbers[i] !== decrypted) {
testPassed = false;
break;
}
}
chai.expect(testPassed).equals(true);
});
});
describe(`Correctness. For ${tests} random r in (1,n), encrypt r with publicKey and then decrypt with privateKey: D(E(r))`, function () {
it('all should return r', function () {
let testPassed = true
for (let i = 0; i < tests; i++) {
numbers[i] = bcu.randBetween(keyPair.publicKey.n)
ciphertexts[i] = keyPair.publicKey.encrypt(numbers[i])
const decrypted = keyPair.privateKey.decrypt(ciphertexts[i])
if (numbers[i] !== decrypted) {
testPassed = false
break
}
}
chai.expect(testPassed).equals(true)
})
})
describe('Homomorphic properties', function () {
describe(`Homomorphic addtion: D( E(m1)·...·E(m${tests})) mod n^2 )`, function () {
it(`should return m1+...+m${tests} mod n`, function () {
const encSum = keyPair.publicKey.addition(...ciphertexts);
let d = keyPair.privateKey.decrypt(encSum);
const sumNumbers = numbers.reduce((sum, next) => (sum + next) % keyPair.publicKey.n);
chai.expect(d === sumNumbers);
});
});
describe(`For all the ${tests} random r, the (pseudo-)homomorphic multiplication: D( E(r)^r mod n^2 )`, function () {
it('should return r^2 mod n', function () {
let testPassed = true;
for (let i = 0; i < numbers.length; i++) {
const encMul = keyPair.publicKey.multiply(ciphertexts[i], numbers[i]);
const d = keyPair.privateKey.decrypt(encMul);
if (d !== bcu.modPow(numbers[i], 2, keyPair.publicKey.n)) {
testPassed = false;
break;
}
}
chai.expect(testPassed).equals(true);
});
});
});
});
describe('Homomorphic properties', function () {
describe(`Homomorphic addtion: D( E(m1)·...·E(m${tests})) mod n^2 )`, function () {
it(`should return m1+...+m${tests} mod n`, function () {
const encSum = keyPair.publicKey.addition(...ciphertexts)
const d = keyPair.privateKey.decrypt(encSum)
const sumNumbers = numbers.reduce((sum, next) => (sum + next) % keyPair.publicKey.n)
chai.expect(d === sumNumbers)
})
})
describe(`For all the ${tests} random r, the (pseudo-)homomorphic multiplication: D( E(r)^r mod n^2 )`, function () {
it('should return r^2 mod n', function () {
let testPassed = true
for (let i = 0; i < numbers.length; i++) {
const encMul = keyPair.publicKey.multiply(ciphertexts[i], numbers[i])
const d = keyPair.privateKey.decrypt(encMul)
if (d !== bcu.modPow(numbers[i], 2, keyPair.publicKey.n)) {
testPassed = false
break
}
}
chai.expect(testPassed).equals(true)
})
})
})
})
}
describe('Testing generateRandomKeysSync(2048) NOT RECOMMENDED', function () {
it('it should return a publicKey and a privateKey with public modulus of 2048 bits', function () {
const keyPair = paillierBigint.generateRandomKeysSync(2048);
chai.expect(keyPair.publicKey).to.be.an.instanceOf(paillierBigint.PublicKey);
chai.expect(keyPair.privateKey).to.be.an.instanceOf(paillierBigint.PrivateKey);
chai.expect(keyPair.publicKey.bitLength).to.equal(2048);
});
});
this.timeout(90000)
it('it should return a publicKey and a privateKey with public modulus of 2048 bits', function () {
const keyPair = _pkg.generateRandomKeysSync(2048)
chai.expect(keyPair.publicKey).to.be.an.instanceOf(_pkg.PublicKey)
chai.expect(keyPair.privateKey).to.be.an.instanceOf(_pkg.PrivateKey)
chai.expect(keyPair.publicKey.bitLength).to.equal(2048)
})
})

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc