Giter VIP home page Giter VIP logo

juanelas / bigint-crypto-utils Goto Github PK

View Code? Open in Web Editor NEW
36.0 4.0 3.0 21.1 MB

Utils for working with cryptography using native JS implementation of BigInt. It includes arbitrary precision modular arithmetics, cryptographically secure random numbers and strong probable prime generation/testing. It works with Node.js, and native JS, including React and Angular

License: MIT License

JavaScript 55.69% TypeScript 44.31%
crypto bigint biginteger random-number-generators random prime-numbers prime arithmetics native-javascript react

bigint-crypto-utils's Introduction

License: MIT JavaScript Style Guide Node.js CI Coverage Status

bigint-crypto-utils

Arbitrary precision modular arithmetic, cryptographically secure random numbers and strong probable prime generation/testing.

It relies on the native JS implementation of (BigInt). It can be used by any Web Browser or webview supporting BigInt and with Node.js (>=10.4.0). The bundles can be imported directly by the browser or in Angular projects, React apps, Node.js, etc.

Secure random numbers are generated using the native crypto implementation of the browsers (Web Cryptography API) or Node.js Crypto. Strong probable prime generation and testing use Miller-Rabin primality tests and are automatically sped up using parallel workers both in browsers and Node.js.

The operations supported on BigInts are not constant time. BigInt can be therefore unsuitable for use in cryptography. Many platforms provide native support for cryptography, such as Web Cryptography API or Node.js Crypto.

Usage

bigint-crypto-utils can be imported to your project with npm:

npm install bigint-crypto-utils

Then either require (Node.js CJS):

const bigintCryptoUtils = require('bigint-crypto-utils')

or import (JavaScript ES module):

import * as bigintCryptoUtils from 'bigint-crypto-utils'

The appropriate version for browser or node is automatically exported.

bigint-crypto-utils uses ES2020 BigInt, so take into account that:

  1. If you experience issues using webpack/babel to create your production bundles, you may edit the supported browsers list and leave only supported browsers and versions. The browsers list is usually located in your project's package.json or the .browserslistrc file.
  2. In order to use bigint-crypto-utils with TypeScript you need to set target, and lib and module if in use, to ES2020 in your project's tsconfig.json.

You can also download the IIFE bundle, the ESM bundle or the UMD bundle and manually add it to your project, or, if you have already installed bigint-crypto-utils in your project, just get the bundles from node_modules/bigint-crypto-utils/dist/bundles/.

An example of usage could be (complete examples can be found in the examples directory):

/* A BigInt with value 666 can be declared calling the bigint constructor as
BigInt('666') or with the shorter 666n.
Notice that you can also pass a number to the constructor, e.g. BigInt(666).
However, it is not recommended since values over 2**53 - 1 won't be safe but
no warning will be raised.
*/
const a = BigInt('5')
const b = BigInt('2')
const n = 19n

console.log(bigintCryptoUtils.modPow(a, b, n)) // prints 6

console.log(bigintCryptoUtils.modInv(2n, 5n)) // prints 3

console.log(bigintCryptoUtils.modInv(BigInt('3'), BigInt('5'))) // prints 2

console.log(bigintCryptoUtils.randBetween(2n ** 256n)) // prints a cryptographically secure random number between 1 and 2**256 (both included).

async function primeTesting (): void {
  // Let us print out a probable prime of 2048 bits
  console.log(await bigintCryptoUtils.prime(2048))

  // Testing if number is a probable prime (Miller-Rabin)
  const number = 27n
  const isPrime = await bigintCryptoUtils.isProbablyPrime(number)
  if (isPrime === true) {
    console.log(`${number} is prime`)
  } else {
    console.log(`${number} is composite`)
  }
}

primeTesting()

API reference documentation

Check the API

bigint-crypto-utils's People

Contributors

aisse-258 avatar coffee-converter avatar dependabot[bot] avatar juanelas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

bigint-crypto-utils's Issues

`gcd` works incorrect with 0

gcd(6n,0n); possibly leads to an infinite loop. IMHO, gcd(x,0n) and gcd(0n, x) should return x (even if x is 0). In any case, such calls shouldn't lead to a freeze, should they?

Bundling Issues with Vite

I seem to be getting issues with bundling in vite. The target is a webworker in CJS output.

function t(n2) {
  if ("number" == typeof n2 && (n2 = BigInt(n2)), 1n === n2)
    return 1;
  let t2 = 1;
  do {
    t2++;
  } while ((n2 >>= 1n) > 1n);
  return t2;
}

Issue is similar to #16.

I have so far fixed it by forking the repo and bigint-mod-arith and refactoring the build process to just output esm JS and not try to pre-bundle, so it can be processed normally.

I would appreciate seeing that as I never really liked large minified js blobs in NPM packages.

Kudos.

`randBetween` perfomance

I (and most other people) appreciate that randBetween isn't biased. However, based on this answer on SO, there's a better perfomant way to get rid of the bias. It's faster, energy-efficient, and reduces the possibility of running out of entropy (because systems like linux have an "entropy pool" that might get exhausted).

However, this seems to affect small intervals more than large intervals, which means there's no need for concern since this deals with BigInts. But I still recommend it, because it will improve average performance

[bug] Worker issue when minified with webpack

TypeError [ERR_WORKER_UNSUPPORTED_EXTENSION]: The worker script extension must be \".js\" or \".mjs\". Received \".cjs\"
    at new Worker (internal/worker.js:107:15)
    at \\node_modules\\bigint-crypto-utils\\dist\\cjs\\index.node.cjs:605:35
    at new Promise (<anonymous>)
    at Object.prime (\\node_modules\\bigint-crypto-utils\\dist\\cjs\\index.node.cjs:572:12)
    at SSP.initEncryption (\\node_modules\\encrypted-smiley-secure-protocol\\src\\index.js:91:25)
    at \\dist\\server.js

Can't be used in worker context

Describe the bug
Requiring the module in the context of an unrelated worker causes it to start listening for messages, and causes errors as it tries to interpret the worker messages.

To Reproduce
Run with node.js:

const { Worker, isMainThread, parentPort } = require('worker_threads');
if (isMainThread) {
  const worker = new Worker(__filename);
  worker.postMessage('Hello world');
} else {
  require('bigint-crypto-utils');
  parentPort.once('message', msg => {
    console.log('Received:', msg);
  });
}

Results in the following output:

Received: Hello world

node:internal/event_target:912
  process.nextTick(() => { throw err; });
                           ^
TypeError [Error]: Cannot mix BigInt and other types, use explicit conversions
    at _isProbablyPrime (node_modules/bigint-crypto-utils/dist/cjs/index.node.cjs:468:17)
    at MessagePort.<anonymous> (node_modules/bigint-crypto-utils/dist/cjs/index.node.cjs:785:33)

I think the fix is to have a dedicated worker file rather than using new Worker(__filename).

Issue with web worker code in minified code

In your code you use a check for existence of process.browser to detect, if the code is run in browser vs. Node (e.g. here. It doesn't work in Firefox which doesn't have such an object defined.

I've changed all occurences of process.browser with navigator (which should be defined in browsers, but not in Node) and async generation of primes started working correctly.

I don't open a pull request as there might be better ways to detect Node/browser environment.

Missing type definitions for bigint-mod-arith in 3.0.19

Describe the bug
When using the latest version, 3.0.19, with typescript, I get this error:

error TS2307: Cannot find module 'bigint-mod-arith' or its corresponding type declarations.

1 export { abs, bitLength, eGcd, gcd, lcm, max, min, modInv, modPow, toZn } from 'bigint-mod-arith';

The issue seems to be, at a first glance, that the dependency to bigint-mod-arith has been moved to a dev dependency with the latest version. I've set up a quick repo to reproduce the bug.

To Reproduce

  1. Clone this repo
  2. Run npm run install
  3. Run npm run build

bug: use wrong _useWorkers value when not supported

Seems like line 680 should be, otherwise it doen't work and makes no sense

_useWorkers = true

let _useWorkers = false // The following is just to check whether we can use workers
/* eslint-disable no-lone-blocks */
if (!process.browser) { // Node.js
try {
require.resolve('worker_threads')
_useWorkers = true
} catch (e) {
/* istanbul ignore next */
console.log(`[bigint-crypto-utils] WARNING:
This node version doesn't support worker_threads. You should enable them in order to greatly speedup the generation of big prime numbers.
· With Node >=11 it is enabled by default (consider upgrading).
· With Node 10, starting with 10.5.0, you can enable worker_threads at runtime executing node --experimental-worker `)
/* istanbul ignore next */
_useWorkers = true
}
} else { // Native JS
if (self.Worker) _useWorkers = true
}

Error with creat-react-app

If i run with
npm start
this line
console.log(await bigintCryptoUtils.prime(2048))
give this error
Uncaught (in promise) ReferenceError: bigint_mod_arith__WEBPACK_IMPORTED_MODULE_0__ is not defined

Optimization and random minimum

LCM can be defined as a / gcd(a, b) * b and it's guaranteed to return correct values. Some JS engines won't rearrange the expression a * b / gcd(a, b) to optimize it, so it's better to do it manually to make sure the memory footprint and speed are as optimal as possible.

Having a RNG with a min parameter whose argument isn't allowed to be negative, makes the parameter almost useless IMHO. I recommend that negative min support should be added to take full advantage of the convenience of a min parameter.
I suppose that parameter was added early because implementing it in the future would cause backwards-compatibility issues if someone tried to use the RNG. Adding it early (even though it's incomplete) was a good decision, and I appreciate that.

I want to apologize in advance if I'm unaware of some important fact that may render my suggestions useless or just bad ideas

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.