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

@noble/ed25519

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@noble/ed25519 - npm Package Compare versions

Comparing version 1.6.1 to 1.7.0

94

lib/esm/index.js
/*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
import nodeCrypto from 'crypto';
import * as nodeCrypto from 'crypto';
const _0n = BigInt(0);

@@ -8,3 +8,3 @@ const _1n = BigInt(1);

const CURVE_ORDER = _2n ** BigInt(252) + BigInt('27742317777372353535851937790883648493');
const CURVE = {
const CURVE = Object.freeze({
a: BigInt(-1),

@@ -18,3 +18,3 @@ d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),

Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
};
});
export { CURVE };

@@ -593,6 +593,4 @@ const MAX_256B = _2n ** BigInt(256);

}
async function sha512ModqLE(...args) {
const hash = await utils.sha512(concatBytes(...args));
const value = bytesToNumberLE(hash);
return mod(value, CURVE.l);
function modlLE(hash) {
return mod(bytesToNumberLE(hash), CURVE.l);
}

@@ -642,3 +640,3 @@ function equalBytes(b1, b2) {

}
async function getExtendedPublicKey(key) {
function checkPrivateKey(key) {
key =

@@ -650,6 +648,8 @@ typeof key === 'bigint' || typeof key === 'number'

throw new Error(`Expected 32 bytes`);
const hashed = await utils.sha512(key);
return key;
}
function getKeyFromHash(hashed) {
const head = adjustBytes25519(hashed.slice(0, 32));
const prefix = hashed.slice(32, 64);
const scalar = mod(bytesToNumberLE(head), CURVE.l);
const scalar = modlLE(head);
const point = Point.BASE.multiply(scalar);

@@ -659,16 +659,40 @@ const pointBytes = point.toRawBytes();

}
let _sha512Sync;
function sha512s(...m) {
if (typeof _sha512Sync !== 'function')
throw new Error('utils.sha512Sync must be set to use sync methods');
return _sha512Sync(...m);
}
async function getExtendedPublicKey(key) {
return getKeyFromHash(await utils.sha512(checkPrivateKey(key)));
}
function getExtendedPublicKeySync(key) {
return getKeyFromHash(sha512s(checkPrivateKey(key)));
}
export async function getPublicKey(privateKey) {
return (await getExtendedPublicKey(privateKey)).pointBytes;
}
function getPublicKeySync(privateKey) {
return getExtendedPublicKeySync(privateKey).pointBytes;
}
export async function sign(message, privateKey) {
message = ensureBytes(message);
const { prefix, scalar, pointBytes } = await getExtendedPublicKey(privateKey);
const r = await sha512ModqLE(prefix, message);
const r = modlLE(await utils.sha512(prefix, message));
const R = Point.BASE.multiply(r);
const k = await sha512ModqLE(R.toRawBytes(), pointBytes, message);
const k = modlLE(await utils.sha512(R.toRawBytes(), pointBytes, message));
const s = mod(r + k * scalar, CURVE.l);
return new Signature(R, s).toRawBytes();
}
export async function verify(sig, message, publicKey) {
function signSync(message, privateKey) {
message = ensureBytes(message);
const { prefix, scalar, pointBytes } = getExtendedPublicKeySync(privateKey);
const r = modlLE(sha512s(prefix, message));
const R = Point.BASE.multiply(r);
const k = modlLE(sha512s(R.toRawBytes(), pointBytes, message));
const s = mod(r + k * scalar, CURVE.l);
return new Signature(R, s).toRawBytes();
}
function prepareVerification(sig, message, publicKey) {
message = ensureBytes(message);
if (!(publicKey instanceof Point))

@@ -678,3 +702,6 @@ publicKey = Point.fromHex(publicKey, false);

const SB = ExtendedPoint.BASE.multiplyUnsafe(s);
const k = await sha512ModqLE(r.toRawBytes(), publicKey.toRawBytes(), message);
return { r, s, SB, pub: publicKey, msg: message };
}
function finishVerification(publicKey, r, SB, hashed) {
const k = modlLE(hashed);
const kA = ExtendedPoint.fromAffine(publicKey).multiplyUnsafe(k);

@@ -684,2 +711,18 @@ const RkA = ExtendedPoint.fromAffine(r).add(kA);

}
export async function verify(sig, message, publicKey) {
const { r, SB, msg, pub } = prepareVerification(sig, message, publicKey);
const hashed = await utils.sha512(r.toRawBytes(), pub.toRawBytes(), msg);
return finishVerification(pub, r, SB, hashed);
}
function verifySync(sig, message, publicKey) {
const { r, SB, msg, pub } = prepareVerification(sig, message, publicKey);
const hashed = sha512s(r.toRawBytes(), pub.toRawBytes(), msg);
return finishVerification(pub, r, SB, hashed);
}
export const sync = {
getExtendedPublicKey: getExtendedPublicKeySync,
getPublicKey: getPublicKeySync,
sign: signSync,
verify: verifySync,
};
export async function getSharedSecret(privateKey, publicKey) {

@@ -781,2 +824,4 @@ const { head } = await getExtendedPublicKey(privateKey);

bytesToHex,
hexToBytes,
concatBytes,
getExtendedPublicKey,

@@ -789,6 +834,3 @@ mod,

throw new Error('Expected 40-1024 bytes of private key as per FIPS 186');
const num = mod(bytesToNumberLE(hash), CURVE.l);
if (num === _0n || num === _1n)
throw new Error('Invalid private key');
return num;
return mod(bytesToNumberLE(hash), CURVE.l - _1n) + _1n;
},

@@ -810,3 +852,4 @@ randomBytes: (bytesLength = 32) => {

},
sha512: async (message) => {
sha512: async (...messages) => {
const message = concatBytes(...messages);
if (crypto.web) {

@@ -829,2 +872,15 @@ const buffer = await crypto.web.subtle.digest('SHA-512', message.buffer);

},
sha512Sync: undefined,
};
Object.defineProperties(utils, {
sha512Sync: {
configurable: false,
get() {
return _sha512Sync;
},
set(val) {
if (!_sha512Sync)
_sha512Sync = val;
},
},
});
/*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
declare const CURVE: {
declare const CURVE: Readonly<{
a: bigint;

@@ -11,3 +11,3 @@ d: bigint;

Gy: bigint;
};
}>;
export { CURVE };

@@ -92,5 +92,8 @@ declare type Hex = Uint8Array | string;

export { ExtendedPoint, RistrettoPoint, Point, Signature };
declare function concatBytes(...arrays: Uint8Array[]): Uint8Array;
declare function bytesToHex(uint8a: Uint8Array): string;
declare function hexToBytes(hex: string): Uint8Array;
declare function mod(a: bigint, b?: bigint): bigint;
declare function invert(number: bigint, modulo?: bigint): bigint;
declare type Sha512FnSync = undefined | ((...messages: Uint8Array[]) => Uint8Array);
declare function getExtendedPublicKey(key: PrivKey): Promise<{

@@ -103,5 +106,21 @@ head: Uint8Array;

}>;
declare function getExtendedPublicKeySync(key: PrivKey): {
head: Uint8Array;
prefix: Uint8Array;
scalar: bigint;
point: Point;
pointBytes: Uint8Array;
};
export declare function getPublicKey(privateKey: PrivKey): Promise<Uint8Array>;
declare function getPublicKeySync(privateKey: PrivKey): Uint8Array;
export declare function sign(message: Hex, privateKey: Hex): Promise<Uint8Array>;
declare function signSync(message: Hex, privateKey: Hex): Uint8Array;
export declare function verify(sig: SigType, message: Hex, publicKey: PubKey): Promise<boolean>;
declare function verifySync(sig: SigType, message: Hex, publicKey: PubKey): boolean;
export declare const sync: {
getExtendedPublicKey: typeof getExtendedPublicKeySync;
getPublicKey: typeof getPublicKeySync;
sign: typeof signSync;
verify: typeof verifySync;
};
export declare function getSharedSecret(privateKey: PrivKey, publicKey: Hex): Promise<Uint8Array>;

@@ -116,2 +135,4 @@ export declare const curve25519: {

bytesToHex: typeof bytesToHex;
hexToBytes: typeof hexToBytes;
concatBytes: typeof concatBytes;
getExtendedPublicKey: typeof getExtendedPublicKey;

@@ -123,4 +144,5 @@ mod: typeof mod;

randomPrivateKey: () => Uint8Array;
sha512: (message: Uint8Array) => Promise<Uint8Array>;
sha512: (...messages: Uint8Array[]) => Promise<Uint8Array>;
precompute(windowSize?: number, point?: Point): Point;
sha512Sync: Sha512FnSync;
};
"use strict";
/*! noble-ed25519 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.utils = exports.curve25519 = exports.getSharedSecret = exports.verify = exports.sign = exports.getPublicKey = exports.Signature = exports.Point = exports.RistrettoPoint = exports.ExtendedPoint = exports.CURVE = void 0;
const crypto_1 = __importDefault(require("crypto"));
exports.utils = exports.curve25519 = exports.getSharedSecret = exports.sync = exports.verify = exports.sign = exports.getPublicKey = exports.Signature = exports.Point = exports.RistrettoPoint = exports.ExtendedPoint = exports.CURVE = void 0;
const nodeCrypto = require("crypto");
const _0n = BigInt(0);

@@ -14,3 +11,3 @@ const _1n = BigInt(1);

const CURVE_ORDER = _2n ** BigInt(252) + BigInt('27742317777372353535851937790883648493');
const CURVE = {
const CURVE = Object.freeze({
a: BigInt(-1),

@@ -24,3 +21,3 @@ d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),

Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
};
});
exports.CURVE = CURVE;

@@ -602,6 +599,4 @@ const MAX_256B = _2n ** BigInt(256);

}
async function sha512ModqLE(...args) {
const hash = await exports.utils.sha512(concatBytes(...args));
const value = bytesToNumberLE(hash);
return mod(value, CURVE.l);
function modlLE(hash) {
return mod(bytesToNumberLE(hash), CURVE.l);
}

@@ -651,3 +646,3 @@ function equalBytes(b1, b2) {

}
async function getExtendedPublicKey(key) {
function checkPrivateKey(key) {
key =

@@ -659,6 +654,8 @@ typeof key === 'bigint' || typeof key === 'number'

throw new Error(`Expected 32 bytes`);
const hashed = await exports.utils.sha512(key);
return key;
}
function getKeyFromHash(hashed) {
const head = adjustBytes25519(hashed.slice(0, 32));
const prefix = hashed.slice(32, 64);
const scalar = mod(bytesToNumberLE(head), CURVE.l);
const scalar = modlLE(head);
const point = Point.BASE.multiply(scalar);

@@ -668,2 +665,14 @@ const pointBytes = point.toRawBytes();

}
let _sha512Sync;
function sha512s(...m) {
if (typeof _sha512Sync !== 'function')
throw new Error('utils.sha512Sync must be set to use sync methods');
return _sha512Sync(...m);
}
async function getExtendedPublicKey(key) {
return getKeyFromHash(await exports.utils.sha512(checkPrivateKey(key)));
}
function getExtendedPublicKeySync(key) {
return getKeyFromHash(sha512s(checkPrivateKey(key)));
}
async function getPublicKey(privateKey) {

@@ -673,8 +682,11 @@ return (await getExtendedPublicKey(privateKey)).pointBytes;

exports.getPublicKey = getPublicKey;
function getPublicKeySync(privateKey) {
return getExtendedPublicKeySync(privateKey).pointBytes;
}
async function sign(message, privateKey) {
message = ensureBytes(message);
const { prefix, scalar, pointBytes } = await getExtendedPublicKey(privateKey);
const r = await sha512ModqLE(prefix, message);
const r = modlLE(await exports.utils.sha512(prefix, message));
const R = Point.BASE.multiply(r);
const k = await sha512ModqLE(R.toRawBytes(), pointBytes, message);
const k = modlLE(await exports.utils.sha512(R.toRawBytes(), pointBytes, message));
const s = mod(r + k * scalar, CURVE.l);

@@ -684,4 +696,13 @@ return new Signature(R, s).toRawBytes();

exports.sign = sign;
async function verify(sig, message, publicKey) {
function signSync(message, privateKey) {
message = ensureBytes(message);
const { prefix, scalar, pointBytes } = getExtendedPublicKeySync(privateKey);
const r = modlLE(sha512s(prefix, message));
const R = Point.BASE.multiply(r);
const k = modlLE(sha512s(R.toRawBytes(), pointBytes, message));
const s = mod(r + k * scalar, CURVE.l);
return new Signature(R, s).toRawBytes();
}
function prepareVerification(sig, message, publicKey) {
message = ensureBytes(message);
if (!(publicKey instanceof Point))

@@ -691,3 +712,6 @@ publicKey = Point.fromHex(publicKey, false);

const SB = ExtendedPoint.BASE.multiplyUnsafe(s);
const k = await sha512ModqLE(r.toRawBytes(), publicKey.toRawBytes(), message);
return { r, s, SB, pub: publicKey, msg: message };
}
function finishVerification(publicKey, r, SB, hashed) {
const k = modlLE(hashed);
const kA = ExtendedPoint.fromAffine(publicKey).multiplyUnsafe(k);

@@ -697,3 +721,19 @@ const RkA = ExtendedPoint.fromAffine(r).add(kA);

}
async function verify(sig, message, publicKey) {
const { r, SB, msg, pub } = prepareVerification(sig, message, publicKey);
const hashed = await exports.utils.sha512(r.toRawBytes(), pub.toRawBytes(), msg);
return finishVerification(pub, r, SB, hashed);
}
exports.verify = verify;
function verifySync(sig, message, publicKey) {
const { r, SB, msg, pub } = prepareVerification(sig, message, publicKey);
const hashed = sha512s(r.toRawBytes(), pub.toRawBytes(), msg);
return finishVerification(pub, r, SB, hashed);
}
exports.sync = {
getExtendedPublicKey: getExtendedPublicKeySync,
getPublicKey: getPublicKeySync,
sign: signSync,
verify: verifySync,
};
async function getSharedSecret(privateKey, publicKey) {

@@ -781,3 +821,3 @@ const { head } = await getExtendedPublicKey(privateKey);

const crypto = {
node: crypto_1.default,
node: nodeCrypto,
web: typeof self === 'object' && 'crypto' in self ? self.crypto : undefined,

@@ -797,2 +837,4 @@ };

bytesToHex,
hexToBytes,
concatBytes,
getExtendedPublicKey,

@@ -805,6 +847,3 @@ mod,

throw new Error('Expected 40-1024 bytes of private key as per FIPS 186');
const num = mod(bytesToNumberLE(hash), CURVE.l);
if (num === _0n || num === _1n)
throw new Error('Invalid private key');
return num;
return mod(bytesToNumberLE(hash), CURVE.l - _1n) + _1n;
},

@@ -826,3 +865,4 @@ randomBytes: (bytesLength = 32) => {

},
sha512: async (message) => {
sha512: async (...messages) => {
const message = concatBytes(...messages);
if (crypto.web) {

@@ -845,2 +885,15 @@ const buffer = await crypto.web.subtle.digest('SHA-512', message.buffer);

},
sha512Sync: undefined,
};
Object.defineProperties(exports.utils, {
sha512Sync: {
configurable: false,
get() {
return _sha512Sync;
},
set(val) {
if (!_sha512Sync)
_sha512Sync = val;
},
},
});
{
"name": "@noble/ed25519",
"version": "1.6.1",
"description": "Fastest JS implementation of ed25519. Independently audited, high-security, 0-dependency EDDSA, X25519 ECDH, ristretto255 & scalarmult",
"version": "1.7.0",
"description": "Fastest JS implementation of ed25519. Independently audited, high-security, 0-dependency EDDSA, X25519 ECDH & ristretto255",
"files": [

@@ -16,3 +16,3 @@ "lib"

"test": "jest",
"bench": "node test/benchmark.js"
"bench": "node test/benchmark/benchmark.js"
},

@@ -30,2 +30,3 @@ "author": "Paul Miller (https://paulmillr.com)",

"devDependencies": {
"@noble/hashes": "1.1.2",
"@rollup/plugin-node-resolve": "13.3.0",

@@ -36,3 +37,3 @@ "@types/jest": "28.1.1",

"jest": "28.1.0",
"micro-bmark": "^0.1.3",
"micro-bmark": "0.2.0",
"prettier": "2.6.2",

@@ -39,0 +40,0 @@ "rollup": "2.75.5",

@@ -10,3 +10,3 @@ # noble-ed25519 ![Node CI](https://github.com/paulmillr/noble-ed25519/workflows/Node%20CI/badge.svg) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)

### This library belongs to *noble* crypto
### This library belongs to _noble_ crypto

@@ -37,2 +37,3 @@ > **noble-crypto** — high-security, easily auditable set of contained cryptographic libraries and tools.

// Supports both async and sync methods, see docs
(async () => {

@@ -54,3 +55,3 @@ // keys, messages & other inputs can be Uint8Arrays or hex strings

- app.ts: `import * as ed from "https://deno.land/x/ed25519/mod.ts";`
- imports.json: `{"imports": {"crypto": "https://deno.land/std@0.125.0/node/crypto.ts"}}`
- imports.json: `{"imports": {"crypto": "https://deno.land/std@0.153.0/node/crypto.ts"}}`

@@ -65,11 +66,14 @@ ## API

- [ristretto255](#ristretto255)
- [Synchronous methods](#synchronous-methods)
- [Utilities](#utilities)
##### `getPublicKey(privateKey)`
```typescript
function getPublicKey(privateKey: Uint8Array | string | bigint): Promise<Uint8Array>;
```
- `privateKey: Uint8Array | string | bigint` will be used to generate public key. If you want to pass bigints,
ensure they are Big-Endian.
- Returns `Promise<Uint8Array>`. Uses **promises**, because ed25519 uses SHA internally; and we're using built-in browser `window.crypto`, which returns `Promise`.
- Returns `Promise<Uint8Array>`. Uses **promises**, because ed25519 uses SHA internally; and we're using built-in browser `window.crypto`, which returns `Promise`. Synchronous non-promise method is available for this and others: [see below](#synchronous-methods).

@@ -87,11 +91,14 @@ To generate ed25519 public key:

##### `sign(message, privateKey)`
```typescript
function sign(message: Uint8Array | string, privateKey: Uint8Array | string): Promise<Uint8Array>;
```
- `message: Uint8Array | string` - message (not message hash) which would be signed
- `privateKey: Uint8Array | string` - private key which will sign the hash
- Returns EdDSA signature. You can consume it with `Signature.fromHex()` method:
- `Signature.fromHex(ed25519.sign(hash, privateKey))`
- `Signature.fromHex(ed25519.sign(hash, privateKey))`
##### `verify(signature, message, publicKey)`
```typescript

@@ -102,4 +109,5 @@ function verify(

publicKey: Uint8Array | string | Point
): Promise<boolean>
): Promise<boolean>;
```
- `signature: Uint8Array | string | Signature` - returned by the `sign` function

@@ -115,3 +123,3 @@ - `message: Uint8Array | string` - message that needs to be verified

*Not compatible with RFC8032* because rfc encorces canonical encoding of R/publicKey. There is no security risk in ZIP behavior, and there is no effect on honestly generated signatures. For additional info about verification strictness, check out [It’s 255:19AM](https://hdevalence.ca/blog/2020-10-04-its-25519am).
_Not compatible with RFC8032_ because rfc encorces canonical encoding of R/publicKey. There is no security risk in ZIP behavior, and there is no effect on honestly generated signatures. For additional info about verification strictness, check out [It’s 255:19AM](https://hdevalence.ca/blog/2020-10-04-its-25519am).

@@ -121,3 +129,6 @@ ##### `getSharedSecret(privateKey, publicKey)`

```typescript
function getSharedSecret(privateKey: Uint8Array | string | bigint, publicKey: Uint8Array | string): Promise<Uint8Array>;
function getSharedSecret(
privateKey: Uint8Array | string | bigint,
publicKey: Uint8Array | string
): Promise<Uint8Array>;
```

@@ -156,3 +167,3 @@

2. Never mix `ExtendedPoint` & `RistrettoPoint`: ristretto is not a subgroup of ed25519.
`ExtendedPoint` you are mixing with, may not be the representative for the set of possible points.
`ExtendedPoint` you are mixing with, may not be the representative for the set of possible points.

@@ -186,2 +197,18 @@ ```typescript

### Synchronous methods
The library is using built-in async hash functions by default in order to follow its 0-dependency approach.
This means, built-in `getPublicKey`, `sync` and others are asynchronous. Some use-cases require
sync versions of those. You can use them: all you need to do is make sure ed25519 knows
how to hash synchronously. Redefining `ed.utils.sha512Sync` is enough:
```ts
import { sha512 } from '@noble/hashes/sha512';
ed.utils.sha512Sync = (...m) => sha512(ed.utils.concatBytes(...m));
const { getPublicKey, sign, verify, getExtendedPublicKey } = ed.sync;
// Use it freely
getPublicKey(privKey);
```
### Utilities

@@ -275,3 +302,3 @@

We're using built-in JS `BigInt`, which is "unsuitable for use in cryptography" as [per official spec](https://github.com/tc39/proposal-bigint#cryptography). This means that the lib is potentially vulnerable to [timing attacks](https://en.wikipedia.org/wiki/Timing_attack). But, *JIT-compiler* and *Garbage Collector* make "constant time" extremely hard to achieve in a scripting language. Which means *any other JS library doesn't use constant-time bigints*. Including bn.js or anything else. Even statically typed Rust, a language without GC, [makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security) for some cases. If your goal is absolute security, don't use any JS lib — including bindings to native ones. Use low-level libraries & languages. Nonetheless we've hardened implementation of ec curve multiplication to be algorithmically constant time.
We're using built-in JS `BigInt`, which is "unsuitable for use in cryptography" as [per official spec](https://github.com/tc39/proposal-bigint#cryptography). This means that the lib is potentially vulnerable to [timing attacks](https://en.wikipedia.org/wiki/Timing_attack). But, _JIT-compiler_ and _Garbage Collector_ make "constant time" extremely hard to achieve in a scripting language. Which means _any other JS library doesn't use constant-time bigints_. Including bn.js or anything else. Even statically typed Rust, a language without GC, [makes it harder to achieve constant-time](https://www.chosenplaintext.ca/open-source/rust-timing-shield/security) for some cases. If your goal is absolute security, don't use any JS lib — including bindings to native ones. Use low-level libraries & languages. Nonetheless we've hardened implementation of ec curve multiplication to be algorithmically constant time.

@@ -282,25 +309,30 @@ We however consider infrastructure attacks like rogue NPM modules very important; that's why it's crucial to minimize the amount of 3rd-party dependencies & native bindings. If your app uses 500 dependencies, any dep could get hacked and you'll be downloading malware with every `npm install`. Our goal is to minimize this attack vector.

Benchmarks done with Apple M1 on macOS 12.
Benchmarks done with Apple M2 on macOS 12 with Node.js 18.
getPublicKey(utils.randomPrivateKey()) x 7,600 ops/sec @ 131μs/op
sign x 3,819 ops/sec @ 261μs/op
verify x 762 ops/sec @ 1ms/op
Point.fromHex decompression x 12,055 ops/sec @ 82μs/op
ristretto255#hashToCurve x 5,617 ops/sec @ 178μs/op
ristretto255 round x 5,734 ops/sec @ 174μs/op
curve25519.scalarMultBase x 1,173 ops/sec @ 852μs/op
ed25519.getSharedSecret x 883 ops/sec @ 1ms/op
getPublicKey(utils.randomPrivateKey()) x 8,627 ops/sec @ 115μs/op
sign x 4,355 ops/sec @ 229μs/op
verify x 852 ops/sec @ 1ms/op
verify (no decompression) x 975 ops/sec @ 1ms/op
Point.fromHex decompression x 13,512 ops/sec @ 74μs/op
ristretto255#hashToCurve x 6,419 ops/sec @ 155μs/op
ristretto255 round x 6,451 ops/sec @ 155μs/op
curve25519.scalarMultBase x 1,273 ops/sec @ 785μs/op
ed25519.getSharedSecret x 968 ops/sec @ 1ms/op
Compare to alternative implementations:
# tweetnacl-fast@1.0.3
getPublicKey x 920 ops/sec @ 1ms/op # aka scalarMultBase
sign x 519 ops/sec @ 2ms/op
ristretto255 x 669 ops/sec @ 1ms/op ± 1.41% (min: 1ms, max: 8ms)
sodium-native x 82,925 ops/sec @ 12μs/op
# ristretto255@0.1.1
getPublicKey x 877 ops/sec @ 1ms/op # aka scalarMultBase
# tweetnacl@1.0.3 (fast)
getPublicKey x 2,087 ops/sec @ 479μs/op # aka scalarMultBase
sign x 667 ops/sec @ 1ms/op
# sodium-native@3.2.1, native bindings to libsodium, node.js-only
sodium-native#sign x 58,661 ops/sec @ 17μs/op
# ristretto255@0.1.2
getPublicKey x 669 ops/sec @ 1ms/op ± 1.41% (min: 1ms, max: 8ms)
# sodium-native@3.4.1
# native bindings to libsodium, **node.js-only**
sign x 82,925 ops/sec @ 12μs/op
## Contributing

@@ -307,0 +339,0 @@

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