paillier-bigint
Advanced tools
Comparing version 3.2.1 to 3.2.2
@@ -1,3 +0,62 @@ | ||
paillier-bigint - v3.2.1 | ||
paillier-bigint - v3.2.2 | ||
# paillier-bigint - v3.2.1 | ||
# paillier-bigint - v3.2.2 | ||
## Table of contents | ||
### Classes | ||
- [PrivateKey](classes/privatekey.md) | ||
- [PublicKey](classes/publickey.md) | ||
### Interfaces | ||
- [KeyPair](interfaces/keypair.md) | ||
### Functions | ||
- [generateRandomKeys](API.md#generaterandomkeys) | ||
- [generateRandomKeysSync](API.md#generaterandomkeyssync) | ||
## Functions | ||
### generateRandomKeys | ||
▸ **generateRandomKeys**(`bitlength?`: *number*, `simpleVariant?`: *boolean*): *Promise*<[*KeyPair*](interfaces/keypair.md)\> | ||
Generates a pair private, public key for the Paillier cryptosystem. | ||
#### Parameters: | ||
Name | Type | Default value | Description | | ||
:------ | :------ | :------ | :------ | | ||
`bitlength` | *number* | 3072 | The bit length of the public modulo | | ||
`simpleVariant` | *boolean* | false | - | | ||
**Returns:** *Promise*<[*KeyPair*](interfaces/keypair.md)\> | ||
A promise that resolves to a [KeyPair](interfaces/keypair.md) of public, private keys | ||
Defined in: [generateRandomKeys.ts:18](https://github.com/juanelas/paillier-bigint/blob/f5e0621/src/ts/generateRandomKeys.ts#L18) | ||
___ | ||
### generateRandomKeysSync | ||
▸ **generateRandomKeysSync**(`bitlength?`: *number*, `simpleVariant?`: *boolean*): [*KeyPair*](interfaces/keypair.md) | ||
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. | ||
#### Parameters: | ||
Name | Type | Default value | Description | | ||
:------ | :------ | :------ | :------ | | ||
`bitlength` | *number* | 3072 | The bit length of the public modulo | | ||
`simpleVariant` | *boolean* | false | - | | ||
**Returns:** [*KeyPair*](interfaces/keypair.md) | ||
A pair of public, private keys | ||
Defined in: [generateRandomKeys.ts:55](https://github.com/juanelas/paillier-bigint/blob/f5e0621/src/ts/generateRandomKeys.ts#L55) |
{ | ||
"name": "paillier-bigint", | ||
"version": "3.2.1", | ||
"version": "3.2.2", | ||
"description": "An implementation of the Paillier cryptosystem using native JS (ECMA 2020) implementation of BigInt", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
139
README.md
@@ -6,83 +6,73 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) | ||
# Skeleton for developing modules for browser and Node.js in Typescript | ||
# paillier-bigint | ||
> This entire section with all its subsections (Installation, Tooling, Scripts) should be removed from your `src/docs/index.md` after installing. The rest of sections may be useful for your package readme, and you may just modified them in `src/docs/index.md` to meet your needs. | ||
An implementation of the Paillier cryptosystem relying on the native JS implementation of BigInt. | ||
This is a skeleton for developing JS modules in Typescript that work both in Node.js and native Javascript. The idea is that you should just focus on developing your typescript code in the `src/ts` folder, and the necessary JS files and bundles will be created so that it can be used with no effort in every environment. | ||
It can be used by any [Web Browser or webview supporting BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#Browser_compatibility) and with Node.js (>=10.4.0). In the latter case, for multi-threaded primality tests, you should use Node.js v11 or newer or enable at runtime with `node --experimental-worker` with Node.js version >= 10.5.0 and < 11. | ||
You can use string variable `IS_BROWSER` to create specific code for native JS or Node. For example: | ||
_The operations supported on BigInts are not constant time. BigInt can be therefore **[unsuitable for use in cryptography](https://www.chosenplaintext.ca/articles/beginners-guide-constant-time-cryptography.html).** Many platforms provide native support for cryptography, such as [Web Cryptography API](https://w3c.github.io/webcrypto/) or [Node.js Crypto](https://nodejs.org/dist/latest/docs/api/crypto.html)._ | ||
```typescript | ||
if (IS_BROWSER === 'true') { | ||
// browser specific code here | ||
} else { | ||
// node.js specific code here | ||
} | ||
``` | ||
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. | ||
Besides the actual code, you should create unit testing (mocha+chai) files either in the `test` or the `src/ts` directory, although in the latter case only files ending with `.spec.ts` will be considered as test files. | ||
## Homomorphic properties | ||
When creating the tests, you MUST NOT import either `mocha`, `chai` or your package. They have been automatically added to the global scope: | ||
### Homomorphic addition of plaintexts | ||
- `mocha` global variable points to mocha, | ||
- `chai` points to chai, | ||
- `_pkg` points to your package (all your exports), | ||
- `_pkgTypes` points to your package typings. | ||
The product of two ciphertexts will decrypt to the sum of their corresponding plaintexts, | ||
## Installation | ||
**D( E(m<sub>1</sub>) · E(m<sub>2</sub>) ) mod n<sup>2</sup> = m<sub>1</sub> + m<sub>2</sub> mod n** | ||
Clone this repo to your desired project directory (`my-project` in the following example) and reset the git. | ||
The product of a ciphertext with a plaintext raising g will decrypt to the sum of the corresponding plaintexts, | ||
```console | ||
git clone https://github.com/juanelas/node-browser-skel.git my-project | ||
cd my-project | ||
rm -rf .git | ||
git init | ||
git add -A | ||
``` | ||
**D( E(m<sub>1</sub>) · g<sup>m<sub>2</sub></sup> ) mod n<sup>2</sup> = m<sub>1</sub> + m<sub>2</sub> mod n** | ||
Edit `package.json` to suit your needs and initialize the project with: | ||
### (pseudo-)homomorphic multiplication of plaintexts | ||
```console | ||
npm i | ||
npm update | ||
npm run build | ||
``` | ||
An encrypted plaintext raised to the power of another plaintext will decrypt to the product of the two plaintexts, | ||
The `README.md` file is automatically generated from the `src/docs/index.md` file. EDIT `src/docs/index.md` and rewrite it to your heart's content. Recall removing the section "Skeleton for developing modules for browser and Node.js in Typescript" with all its subsections (Installation, Tooling, Scripts). | ||
**D( E(m<sub>1</sub>)<sup>m<sub>2</sub></sup> mod n<sup>2</sup> ) = m<sub>1</sub> · m<sub>2</sub> mod n**, | ||
## Tooling | ||
**D( E(m<sub>2</sub>)<sup>m<sub>1</sub></sup> mod n<sup>2</sup> ) = m<sub>1</sub> · m<sub>2</sub> mod n**. | ||
- Build: [Rollup](https://rollupjs.org) is used for generating UMD, IIFE, ESM and CJS modules with the corresponding Typescript declaration files and sourcemaps in the `dist` directory. | ||
- Coverage: [Nyc-Istanbul](https://github.com/istanbuljs/nyc) is used to track how well your unit-tests exercise your codebase. | ||
- Doc: [TsCode](https://tsdoc.org/) is used for automatically generating the [API docs](./docs/API.md). Consider documenting your code with TsCode for it to be useful. | ||
- Lint: [ts-stamdard](https://github.com/standard/ts-standard) is the chosen linter, although you can easily change it by any other linter (update `scripts.lint` in the `package.json`). If developing with [Visual Studio Code](https://code.visualstudio.com/), consider installing the [Standard-JS extension](https://marketplace.visualstudio.com/items?itemName=chenxsan.vscode-standardjs) and select `ts-standard` as the `Standard:engine` in the extension settings. | ||
- Test: [Mocha](https://mochajs.org/) with [Chai](https://www.chaijs.com/) running both in Node.js and browser (using [puppeteer](https://pptr.dev/)). Test files should be created assuming that Mocha methods and Chai are declared global, so there is no need to import them (see the provided test examples). There is also no need to create separate test files for browser and Node.js, since every file will be tested against both. Test files are transpiled using [tsc CLI](https://www.typescriptlang.org/docs/handbook/compiler-options.html). | ||
More generally, an encrypted plaintext raised to a constant k will decrypt to the product of the plaintext and the | ||
constant, | ||
## Scripts | ||
**D( E(m<sub>1</sub>)<sup>k</sup> mod n<sup>2</sup> ) = k · m<sub>1</sub> mod n**. | ||
- `npm run build`. Runs the linter (`lint`), builds the JS files (`build:js`), builds the `README.md` and the API doc `./docs/API.md` (`docs`), runs the unit tests in browser (`test:browser`), and creates a coverage report of the tests run in Node.js (`coverage`). See the specific scripts for more details. | ||
- `npm run build:js`. Creates your distributable module files (UMD, IIFE, ESM and CJS), along with the sourcemap and typescript declaration files in the `dist` directory. | ||
- `npm run clean`. Cleans all the artifacts created by the rest of the script (most likely not needed). | ||
- `npm run coverage`. Runs all the unit tests (`src/**/*.spec.ts` and `test/**/*.ts`) in Node.js and track how well they exercise your codebase. Besides the on-screen summary, a complete report in HTML will be generated in the `coverage` directory. | ||
- `npm run docs`. Generates the `README.md` and the API doc `./docs/API.md`. Some labels in the `src/README.md` file will be automatically replaced in the generated `README.md`: | ||
However, given the Paillier encryptions of two messages there is no known way to compute an encryption of the product of | ||
these messages without knowing the private key. | ||
- {{PKG_NAME}} is automatically replaced with property `name` in `package.json` file. | ||
- {{PKG_CAMELCASE}} will be replaced by a came case transformation of the package_name. | ||
- {{IIFE_BUNDLE}} will point to the IIFE bundle file if using github or gitlab as repository. | ||
- {{ESM_BUNDLE}} will point to the ESM bundle file if using github or gitlab as repository. | ||
- {{UMD_BUNDLE}} will point to the UMD bundle file if using github or gitlab as repository. | ||
- It has also some automatically added badges (see the top of this file), that you can remove if desired. | ||
## Key generation | ||
- `npm run lint`. Uses the `ts-standard` linter to fix all the project files. If unconfortable, change the linter for the one of your liking. | ||
- `npm run mocha -- <glob>`. Runs Node.js mocha for the selected tests (use glob pattern). Add `--watch` before the glob to start mocha in watch mode. | ||
- `npm test`. Runs all the unit tests (`src/**/*.spec.ts` and `test/**/*.ts`) in both Node.js and browser (using puppeteer). | ||
- `npm run test:browser`. Runs all the unit tests (`src/**/*.spec.ts` and `test/**/*.ts`) in a browser (using pupppeteer). | ||
- `npm run test:node`. Runs all the unit tests (`src/**/*.spec.ts` and `test/**/*.ts`) in Node.js. | ||
- `npm run watch`. Likely to be the default script during development. Tests are automatically reexecuted whenever a test or source file changes. | ||
1. Define the bit length of the modulus `n`, or `keyLength` in bits. | ||
2. Choose two large prime numbers `p` and `q` randomly and independently of each other such that `gcd( p·q, (p-1)(q-1) )=1` and `n=p·q` has a key length of keyLength. For instance: | ||
1. Generate a random prime `p` with a bit length of `keyLength/2 + 1`. | ||
2. Generate a random prime `q` with a bit length of `keyLength/2`. | ||
3. Repeat until the bitlength of `n=p·q` is `keyLength`. | ||
3. Compute parameters `λ`, `g` and `μ`. Among other ways, it can be done as follows: | ||
1. Standard approach: | ||
1. Compute `λ = lcm(p-1, q-1)` with `lcm(a, b) = a·b / gcd(a, b)`. | ||
2. Generate randoms `α` and `β` in `Z*` of `n`, and select generator `g` in `Z*` of `n**2` as `g = ( α·n + 1 ) β**n mod n**2`. | ||
3. Compute `μ = ( L( g^λ mod n**2 ) )**(-1) mod n` where `L(x)=(x-1)/n`. | ||
2. If using p,q of equivalent length, a simpler variant would be: | ||
1. `λ = (p-1, q-1)` | ||
2. `g = n+1` | ||
3. `μ = λ**(-1) mod n` | ||
The **public** (encryption) **key** is **(n, g)**. | ||
# paillier-bigint | ||
The **private** (decryption) **key** is **(λ, μ)**. | ||
## Encryption | ||
Let `m` in `[0, n)` be the clear-text message, | ||
Your package description | ||
1. Select random integer `r` in `Z*` of `n`. | ||
2. Compute ciphertext as: **`c = g**m · r**n mod n**2`** | ||
## Decryption | ||
Let `c` be the ciphertext to decrypt, where `c` in `(0, n**2)`. | ||
1. Compute the plaintext message as: **`m = L( c**λ mod n**2 ) · μ mod n`** | ||
## Usage | ||
@@ -114,8 +104,35 @@ | ||
```typescript | ||
YOUR TYPESCRIPT EXAMPLE CODE HERE | ||
```javascript | ||
async function paillierTest () { | ||
// (asynchronous) creation of a random private, public key pair for the Paillier cryptosystem | ||
const { publicKey, privateKey } = await paillierBigint.generateRandomKeys(3072) | ||
// Optionally, you can create your public/private keys from known parameters | ||
// const publicKey = new paillierBigint.PublicKey(n, g) | ||
// const privateKey = new paillierBigint.PrivateKey(lambda, mu, publicKey) | ||
const m1 = 12345678901234567890n | ||
const m2 = 5n | ||
// encryption/decryption | ||
const c1 = publicKey.encrypt(m1) | ||
console.log(privateKey.decrypt(c1)) // 12345678901234567890n | ||
// homomorphic addition of two ciphertexts (encrypted numbers) | ||
const c2 = publicKey.encrypt(m2) | ||
const encryptedSum = publicKey.addition(c1, c2) | ||
console.log(privateKey.decrypt(encryptedSum)) // m1 + m2 = 12345678901234567895n | ||
// multiplication by k | ||
const k = 10n | ||
const encryptedMul = publicKey.multiply(c1, k) | ||
console.log(privateKey.decrypt(encryptedMul)) // k · m1 = 123456789012345678900n | ||
} | ||
paillierTest() | ||
``` | ||
> Consider using [bigint-conversion](https://github.com/juanelas/bigint-conversion) if you need to convert from/to bigint to/from unicode text, hex, buffer. | ||
## API reference documentation | ||
[Check the API](./docs/API.md) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
105003
26
137
0