Socket
Socket
Sign inDemoInstall

@noble/curves

Package Overview
Dependencies
Maintainers
1
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@noble/curves - npm Package Compare versions

Comparing version 0.2.1 to 0.3.0

lib/crypto.d.ts

4

lib/edwards.d.ts

@@ -14,3 +14,3 @@ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */

hash: CHash;
randomBytes: (bytesLength?: number) => Uint8Array;
randomBytes?: (bytesLength?: number) => Uint8Array;
adjustScalarBytes?: (bytes: Uint8Array) => Uint8Array;

@@ -35,3 +35,3 @@ domain?: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array;

readonly hash: CHash;
readonly randomBytes: (bytesLength?: number | undefined) => Uint8Array;
randomBytes: (bytesLength?: number | undefined) => Uint8Array;
readonly adjustScalarBytes?: ((bytes: Uint8Array) => Uint8Array) | undefined;

@@ -38,0 +38,0 @@ readonly domain?: ((data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array) | undefined;

@@ -30,7 +30,3 @@ "use strict";

}
for (const fn of ['randomBytes']) {
if (typeof opts[fn] !== 'function')
throw new Error(`Invalid ${fn} function`);
}
for (const fn of ['adjustScalarBytes', 'domain', 'uvRatio']) {
for (const fn of ['adjustScalarBytes', 'domain', 'randomBytes', 'uvRatio']) {
if (opts[fn] === undefined)

@@ -42,3 +38,3 @@ continue; // Optional

// Set defaults
return Object.freeze({ ...opts });
return Object.freeze({ randomBytes: utils_js_1.randomBytes, ...opts });
}

@@ -45,0 +41,0 @@ // NOTE: it is not generic twisted curve for now, but ed25519/ed448 generic implementation

@@ -11,3 +11,3 @@ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */

import * as mod from './modular.js';
import { bytesToHex, concatBytes, ensureBytes, numberToBytesLE, bytesToNumberLE, hashToPrivateScalar, validateOpts as utilOpts, } from './utils.js'; // TODO: import * as u from './utils.js'?
import { bytesToHex, concatBytes, ensureBytes, numberToBytesLE, bytesToNumberLE, hashToPrivateScalar, validateOpts as utilOpts, randomBytes as utilRandomBytes } from './utils.js'; // TODO: import * as u from './utils.js'?
import { wNAF } from './group.js';

@@ -28,7 +28,3 @@ // Be friendly to bad ECMAScript parsers by not using bigint literals like 123n

}
for (const fn of ['randomBytes']) {
if (typeof opts[fn] !== 'function')
throw new Error(`Invalid ${fn} function`);
}
for (const fn of ['adjustScalarBytes', 'domain', 'uvRatio']) {
for (const fn of ['adjustScalarBytes', 'domain', 'randomBytes', 'uvRatio']) {
if (opts[fn] === undefined)

@@ -40,3 +36,3 @@ continue; // Optional

// Set defaults
return Object.freeze({ ...opts });
return Object.freeze({ randomBytes: utilRandomBytes, ...opts });
}

@@ -43,0 +39,0 @@ // NOTE: it is not generic twisted curve for now, but ed25519/ed448 generic implementation

@@ -6,6 +6,2 @@ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */

const _2n = BigInt(2);
const _3n = BigInt(3);
const _4n = BigInt(4);
const _5n = BigInt(5);
const _8n = BigInt(8);
// Calculates a modulo b

@@ -18,2 +14,3 @@ export function mod(a, b) {

* Efficiently exponentiate num to power and do modular division.
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
* @example

@@ -106,5 +103,10 @@ * powMod(2n, 6n, 11n) // 64n % 11n == 9n

}
// Calculates Legendre symbol: num^((P-1)/2)
export function legendre(num, fieldPrime) {
return pow(num, (fieldPrime - _1n) / _2n, fieldPrime);
/**
* Calculates Legendre symbol (a | p), which denotes the value of a^((p-1)/2) (mod p).
* * (a | p) ≡ 1 if a is a square (mod p)
* * (a | p) ≡ -1 if a is not a square (mod p)
* * (a | p) ≡ 0 if a ≡ 0 (mod p)
*/
export function legendre(num, P) {
return pow(num, (P - _1n) / _2n, P);
}

@@ -115,10 +117,12 @@ /**

export function sqrt(number, modulo) {
// prettier-ignore
const _3n = BigInt(3), _4n = BigInt(4), _5n = BigInt(5), _8n = BigInt(8);
const n = number;
const P = modulo;
const p1div4 = (P + _1n) / _4n;
// P = 3 (mod 4)
// P ≡ 3 (mod 4)
// sqrt n = n^((P+1)/4)
if (P % _4n === _3n)
return pow(n, p1div4, P);
// P = 5 (mod 8)
// P ≡ 5 (mod 8)
if (P % _8n === _5n) {

@@ -133,2 +137,3 @@ const n2 = mod(n * _2n, P);

// Other cases: Tonelli-Shanks algorithm
// Check whether n is square
if (legendre(n, P) !== _1n)

@@ -135,0 +140,0 @@ throw new Error('Cannot find square root');

/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
// The import here is via the package name. This is to ensure
// that exports mapping/resolution does fall into place.
import { crypto } from '@noble/curves/crypto';
export function validateOpts(curve) {

@@ -125,1 +128,15 @@ for (const i of ['P', 'n', 'h', 'Gx', 'Gy']) {

}
/**
* Cryptographically secure PRNG
*/
export function randomBytes(bytesLength = 32) {
if (crypto.web) {
return crypto.web.getRandomValues(new Uint8Array(bytesLength));
}
else if (crypto.node) {
return new Uint8Array(crypto.node.randomBytes(bytesLength).buffer);
}
else {
throw new Error("The environment doesn't have randomBytes function");
}
}

@@ -11,3 +11,3 @@ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */

import * as mod from './modular.js';
import { bytesToHex, bytesToNumberBE, concatBytes, ensureBytes, hexToBytes, hexToNumber, numberToHexUnpadded, hashToPrivateScalar, validateOpts as utilOpts, } from './utils.js';
import { bytesToHex, bytesToNumberBE, concatBytes, ensureBytes, hexToBytes, hexToNumber, numberToHexUnpadded, hashToPrivateScalar, validateOpts as utilOpts, randomBytes as utilRandomBytes, } from './utils.js';
import { wNAF } from './group.js';

@@ -17,8 +17,2 @@ // Should be separate from overrides, since overrides can use information about curve (for example nBits)

const opts = utilOpts(curve);
if (typeof opts.hash !== 'function' || !Number.isSafeInteger(opts.hash.outputLen))
throw new Error('Invalid hash function');
if (typeof opts.hmac !== 'function')
throw new Error('Invalid hmac function');
if (typeof opts.randomBytes !== 'function')
throw new Error('Invalid randomBytes function');
for (const i of ['a', 'b']) {

@@ -28,2 +22,14 @@ if (typeof opts[i] !== 'bigint')

}
for (const fn of ['hash', 'hmac']) {
if (typeof opts[fn] !== 'function')
throw new Error(`Invalid ${fn} function`);
}
for (const fn of ['randomBytes']) {
if (opts[fn] === undefined)
continue; // Optional
if (typeof opts[fn] !== 'function')
throw new Error(`Invalid ${fn} function`);
}
if (!Number.isSafeInteger(opts.hash.outputLen))
throw new Error('Invalid hash function');
const endo = opts.endo;

@@ -41,3 +47,3 @@ if (endo) {

// Set defaults
return Object.freeze({ lowS: true, ...opts });
return Object.freeze({ lowS: true, randomBytes: utilRandomBytes, ...opts });
}

@@ -190,2 +196,5 @@ // TODO: convert bits to bytes aligned to 32 bits? (224 for example)

let num;
if (typeof CURVE.normalizePrivateKey === 'function') {
key = CURVE.normalizePrivateKey(key);
}
if (typeof key === 'bigint') {

@@ -198,3 +207,3 @@ num = key;

else if (typeof key === 'string') {
key = key.padStart(2 * groupLen, '0'); // Eth-like hexes
// key = key.padStart(2 * groupLen, '0'); // Eth-like hexes
if (key.length !== 2 * groupLen)

@@ -201,0 +210,0 @@ throw new Error(`Expected ${groupLen} bytes of private key`);

@@ -5,2 +5,3 @@ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */

* Efficiently exponentiate num to power and do modular division.
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
* @example

@@ -27,4 +28,10 @@ * powMod(2n, 6n, 11n) // 64n % 11n == 9n

export declare function invertBatch(nums: bigint[], modulo: bigint): bigint[];
export declare function legendre(num: bigint, fieldPrime: bigint): bigint;
/**
* Calculates Legendre symbol (a | p), which denotes the value of a^((p-1)/2) (mod p).
* * (a | p) ≡ 1 if a is a square (mod p)
* * (a | p) ≡ -1 if a is not a square (mod p)
* * (a | p) ≡ 0 if a ≡ 0 (mod p)
*/
export declare function legendre(num: bigint, P: bigint): bigint;
/**
* Calculates square root of a number in a finite field.

@@ -31,0 +38,0 @@ */

@@ -9,6 +9,2 @@ "use strict";

const _2n = BigInt(2);
const _3n = BigInt(3);
const _4n = BigInt(4);
const _5n = BigInt(5);
const _8n = BigInt(8);
// Calculates a modulo b

@@ -22,2 +18,3 @@ function mod(a, b) {

* Efficiently exponentiate num to power and do modular division.
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
* @example

@@ -115,5 +112,10 @@ * powMod(2n, 6n, 11n) // 64n % 11n == 9n

exports.invertBatch = invertBatch;
// Calculates Legendre symbol: num^((P-1)/2)
function legendre(num, fieldPrime) {
return pow(num, (fieldPrime - _1n) / _2n, fieldPrime);
/**
* Calculates Legendre symbol (a | p), which denotes the value of a^((p-1)/2) (mod p).
* * (a | p) ≡ 1 if a is a square (mod p)
* * (a | p) ≡ -1 if a is not a square (mod p)
* * (a | p) ≡ 0 if a ≡ 0 (mod p)
*/
function legendre(num, P) {
return pow(num, (P - _1n) / _2n, P);
}

@@ -125,10 +127,12 @@ exports.legendre = legendre;

function sqrt(number, modulo) {
// prettier-ignore
const _3n = BigInt(3), _4n = BigInt(4), _5n = BigInt(5), _8n = BigInt(8);
const n = number;
const P = modulo;
const p1div4 = (P + _1n) / _4n;
// P = 3 (mod 4)
// P ≡ 3 (mod 4)
// sqrt n = n^((P+1)/4)
if (P % _4n === _3n)
return pow(n, p1div4, P);
// P = 5 (mod 8)
// P ≡ 5 (mod 8)
if (P % _8n === _5n) {

@@ -143,2 +147,3 @@ const n2 = mod(n * _2n, P);

// Other cases: Tonelli-Shanks algorithm
// Check whether n is square
if (legendre(n, P) !== _1n)

@@ -145,0 +150,0 @@ throw new Error('Cannot find square root');

@@ -33,1 +33,5 @@ /*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */

export declare function equalBytes(b1: Uint8Array, b2: Uint8Array): boolean;
/**
* Cryptographically secure PRNG
*/
export declare function randomBytes(bytesLength?: number): Uint8Array;
"use strict";
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
Object.defineProperty(exports, "__esModule", { value: true });
exports.equalBytes = exports.hashToPrivateScalar = exports.nLength = exports.concatBytes = exports.ensureBytes = exports.numberToBytesLE = exports.numberToBytesBE = exports.bytesToNumberLE = exports.bytesToNumberBE = exports.hexToBytes = exports.hexToNumber = exports.numberToHexUnpadded = exports.bytesToHex = exports.validateOpts = void 0;
exports.randomBytes = exports.equalBytes = exports.hashToPrivateScalar = exports.nLength = exports.concatBytes = exports.ensureBytes = exports.numberToBytesLE = exports.numberToBytesBE = exports.bytesToNumberLE = exports.bytesToNumberBE = exports.hexToBytes = exports.hexToNumber = exports.numberToHexUnpadded = exports.bytesToHex = exports.validateOpts = void 0;
// The import here is via the package name. This is to ensure
// that exports mapping/resolution does fall into place.
const crypto_1 = require("@noble/curves/crypto");
function validateOpts(curve) {

@@ -142,1 +145,16 @@ for (const i of ['P', 'n', 'h', 'Gx', 'Gy']) {

exports.equalBytes = equalBytes;
/**
* Cryptographically secure PRNG
*/
function randomBytes(bytesLength = 32) {
if (crypto_1.crypto.web) {
return crypto_1.crypto.web.getRandomValues(new Uint8Array(bytesLength));
}
else if (crypto_1.crypto.node) {
return new Uint8Array(crypto_1.crypto.node.randomBytes(bytesLength).buffer);
}
else {
throw new Error("The environment doesn't have randomBytes function");
}
}
exports.randomBytes = randomBytes;
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
import { BasicCurve, Hex, PrivKey } from './utils.js';
import { BasicCurve, Hex, PrivKey, randomBytes as utilRandomBytes } from './utils.js';
import { Group, GroupConstructor } from './group.js';

@@ -26,5 +26,6 @@ export declare type CHash = {

hmac: HmacFnSync;
randomBytes: (bytesLength?: number) => Uint8Array;
randomBytes?: (bytesLength?: number) => Uint8Array;
truncateHash?: (hash: Uint8Array, truncateOnly?: boolean) => bigint;
sqrtMod?: (n: bigint) => bigint;
normalizePrivateKey?: (key: PrivKey) => PrivKey;
endo?: EndomorphismOpts;

@@ -45,5 +46,6 @@ };

readonly hmac: HmacFnSync;
readonly randomBytes: (bytesLength?: number | undefined) => Uint8Array;
randomBytes: typeof utilRandomBytes;
readonly truncateHash?: ((hash: Uint8Array, truncateOnly?: boolean | undefined) => bigint) | undefined;
readonly sqrtMod?: ((n: bigint) => bigint) | undefined;
readonly normalizePrivateKey?: ((key: PrivKey) => PrivKey) | undefined;
readonly endo?: EndomorphismOpts | undefined;

@@ -50,0 +52,0 @@ }>;

@@ -19,8 +19,2 @@ "use strict";

const opts = (0, utils_js_1.validateOpts)(curve);
if (typeof opts.hash !== 'function' || !Number.isSafeInteger(opts.hash.outputLen))
throw new Error('Invalid hash function');
if (typeof opts.hmac !== 'function')
throw new Error('Invalid hmac function');
if (typeof opts.randomBytes !== 'function')
throw new Error('Invalid randomBytes function');
for (const i of ['a', 'b']) {

@@ -30,2 +24,14 @@ if (typeof opts[i] !== 'bigint')

}
for (const fn of ['hash', 'hmac']) {
if (typeof opts[fn] !== 'function')
throw new Error(`Invalid ${fn} function`);
}
for (const fn of ['randomBytes']) {
if (opts[fn] === undefined)
continue; // Optional
if (typeof opts[fn] !== 'function')
throw new Error(`Invalid ${fn} function`);
}
if (!Number.isSafeInteger(opts.hash.outputLen))
throw new Error('Invalid hash function');
const endo = opts.endo;

@@ -43,3 +49,3 @@ if (endo) {

// Set defaults
return Object.freeze({ lowS: true, ...opts });
return Object.freeze({ lowS: true, randomBytes: utils_js_1.randomBytes, ...opts });
}

@@ -192,2 +198,5 @@ // TODO: convert bits to bytes aligned to 32 bits? (224 for example)

let num;
if (typeof CURVE.normalizePrivateKey === 'function') {
key = CURVE.normalizePrivateKey(key);
}
if (typeof key === 'bigint') {

@@ -200,3 +209,3 @@ num = key;

else if (typeof key === 'string') {
key = key.padStart(2 * groupLen, '0'); // Eth-like hexes
// key = key.padStart(2 * groupLen, '0'); // Eth-like hexes
if (key.length !== 2 * groupLen)

@@ -203,0 +212,0 @@ throw new Error(`Expected ${groupLen} bytes of private key`);

{
"name": "@noble/curves",
"version": "0.2.1",
"version": "0.3.0",
"description": "Minimal, zero-dependency JS implementation of elliptic curve cryptography",

@@ -11,8 +11,8 @@ "files": [

"scripts": {
"bench": "node curve-definitions/benchmark/index.js",
"bench": "node benchmark/index.js",
"build": "tsc && tsc -p tsconfig.esm.json",
"build:release": "rollup -c rollup.config.js",
"lint": "prettier --check 'src/**/*.{js,ts}' 'curve-definitions/src/**/*.{js,ts}'",
"format": "prettier --write 'src/**/*.{js,ts}' 'curve-definitions/src/**/*.{js,ts}'",
"test": "cd curve-definitions; node test/index.test.js"
"lint": "prettier --check 'src/**/*.{js,ts}'",
"format": "prettier --write 'src/**/*.{js,ts}'",
"test": "node test/index.test.js"
},

@@ -26,7 +26,14 @@ "author": "Paul Miller (https://paulmillr.com)",

"license": "MIT",
"dependencies": {
"@noble/hashes": "1.1.5"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "13.3.0",
"@scure/base": "^1.1.1",
"@scure/bip32": "^1.1.1",
"@scure/bip39": "^1.1.0",
"fast-check": "^3.4.0",
"micro-bmark": "0.2.0",
"micro-should": "0.2.0",
"prettier": "2.6.2",
"micro-should": "^0.2.0",
"prettier": "^2.6.2",
"rollup": "2.75.5",

@@ -37,2 +44,11 @@ "typescript": "4.7.3"

"exports": {
"./crypto": {
"types": "./lib/crypto.d.ts",
"browser": {
"import": "./lib/esm/cryptoBrowser.js",
"default": "./lib/cryptoBrowser.js"
},
"import": "./lib/esm/crypto.js",
"default": "./lib/crypto.js"
},
"./edwards": {

@@ -64,2 +80,6 @@ "types": "./lib/edwards.d.ts",

},
"browser": {
"crypto": false,
"./crypto": "./cryptoBrowser.js"
},
"keywords": [

@@ -91,2 +111,2 @@ "elliptic",

]
}
}

@@ -48,5 +48,5 @@ # noble-curves

import { weierstrass } from '@noble/curves/weierstrass'; // Short Weierstrass curve
import { concatBytes, randomBytes } from '@noble/curves/utils';
import { sha256 } from '@noble/hashes/sha256';
import { hmac } from '@noble/hashes/hmac';
import { concatBytes, randomBytes } from '@noble/hashes/utils';

@@ -85,5 +85,9 @@ const secp256k1 = weierstrass({

* All arithmetics is done with JS bigints in finite fields
* Curve variables, order (number of points on curve), field prime (over which the modular division would be done)
are required
* To initialize new curve, you must specify its variables, order (number of points on curve), field prime (over which the modular division would be done)
* All curves expose same generic interface:
* `getPublicKey()`, `sign()`, `verify()` functions
* `Point` conforming to `Group` interface with add/multiply/double/negate/add/equals methods
* `CURVE` object with curve variables like `Gx`, `Gy`, `P` (field), `n` (order)
* `utils` object with `randomPrivateKey()`, `mod()`, `invert()` methods (`mod CURVE.P`)
* All arithmetics is done with JS bigints over finite fields
* Many features require hashing, which is not provided. `@noble/hashes` can be used for this purpose.

@@ -102,13 +106,5 @@ Any other library must conform to the CHash interface:

Use `curve.utils.precompute()`
* Special params that tune performance can be optionally provided.
For example, square root calculation, which is commonly used in point decompression routines
* Curves export `Point`, which conforms to `Group` interface, which has following methods:
- `double()`, `negate()`
- `add()`, `subtract()`, `equals()`
- `multiply()`
Every group also has `BASE` (generator) and `ZERO` (infinity) static properties.
* Curves export `CURVE` object
* Curves export `utils`:
* `randomPrivateKey()` specific for the curve, avoiding modulo bias
* `mod()` & `invert()` methods: function from `modular` with default `P` set to CURVE
* Special params that tune performance can be optionally provided. For example:
* `sqrtMod` square root calculation, used for point decompression
* `endo` endomorphism options for Koblitz curves

@@ -125,7 +121,7 @@ ### edwards: Twisted Edwards curve

import { sha512 } from '@noble/hashes/sha512';
import { div } from '@noble/curves/modular';
import * as mod from '@noble/curves/modular';
const ed25519 = twistedEdwards({
a: -1n,
d: div(-121665n, 121666n, 2n ** 255n - 19n), // -121665n/121666n
d: mod.div(-121665n, 121666n, 2n ** 255n - 19n), // -121665n/121666n
P: 2n ** 255n - 19n,

@@ -137,4 +133,3 @@ n: 2n ** 252n + 27742317777372353535851937790883648493n,

hash: sha512,
randomBytes,
adjustScalarBytes(bytes) { // could be no-op
adjustScalarBytes(bytes) { // optional
bytes[0] &= 248;

@@ -141,0 +136,0 @@ bytes[31] &= 127;

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