Security News
NVD Backlog Tops 20,000 CVEs Awaiting Analysis as NIST Prepares System Updates
NVD’s backlog surpasses 20,000 CVEs as analysis slows and NIST announces new system updates to address ongoing delays.
@noble/ed25519
Advanced tools
Fastest JS implementation of ed25519 & ristretto255. Auditable, high-security, 0-dependency EDDSA, X25519 ECDH & scalarmult
@noble/ed25519 is a JavaScript library for the Ed25519 public-key signature system. It provides functionalities for key generation, signing, and verification using the Ed25519 algorithm, which is known for its high performance and security.
Key Generation
This feature allows you to generate a new pair of public and private keys using the Ed25519 algorithm.
const { generateKeyPair } = require('@noble/ed25519');
(async () => {
const { publicKey, privateKey } = await generateKeyPair();
console.log('Public Key:', publicKey);
console.log('Private Key:', privateKey);
})();
Signing
This feature allows you to sign a message using a private key. The resulting signature can be used to verify the authenticity of the message.
const { sign, generateKeyPair } = require('@noble/ed25519');
(async () => {
const { privateKey } = await generateKeyPair();
const message = new TextEncoder().encode('Hello, world!');
const signature = await sign(message, privateKey);
console.log('Signature:', signature);
})();
Verification
This feature allows you to verify a signature using the corresponding public key. It ensures that the message was signed by the holder of the private key.
const { verify, generateKeyPair, sign } = require('@noble/ed25519');
(async () => {
const { publicKey, privateKey } = await generateKeyPair();
const message = new TextEncoder().encode('Hello, world!');
const signature = await sign(message, privateKey);
const isValid = await verify(signature, message, publicKey);
console.log('Is the signature valid?', isValid);
})();
TweetNaCl is a cryptographic library that provides similar functionalities for the Ed25519 algorithm, including key generation, signing, and verification. It is known for its simplicity and small size, making it suitable for environments with limited resources.
Libsodium is a widely-used cryptographic library that offers a comprehensive set of cryptographic primitives, including support for the Ed25519 algorithm. It is known for its high performance and security, and it provides additional features such as encryption and key exchange.
Elliptic is a JavaScript library for elliptic curve cryptography, including support for various algorithms such as Ed25519. It provides a flexible and modular approach to cryptographic operations, making it suitable for a wide range of applications.
Fastest JS implementation of ed25519, an elliptic curve that could be used for EDDSA signature scheme and X25519 ECDH key agreement.
Conforms to RFC7748 and RFC8032. Includes support for ristretto255: a technique for constructing prime order elliptic curve groups with non-malleable encodings.
Check out the online demo.
noble-crypto — high-security, easily auditable set of contained cryptographic libraries and tools.
Use NPM in node.js / browser, or include single file from GitHub's releases page:
npm install @noble/ed25519
// Common.js and ECMAScript Modules (ESM)
import * as ed from '@noble/ed25519';
// If you're using single file, use global variable: nobleEd25519
const privateKey = ed.utils.randomPrivateKey(); // 32-byte Uint8Array or string.
const message = 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef';
(async () => {
const publicKey = await ed.getPublicKey(privateKey);
const signature = await ed.sign(message, privateKey);
const isSigned = await ed.verify(signature, message, publicKey);
})();
To use the module with Deno, you will need import map:
deno run --import-map=imports.json app.ts
app.ts
import * as secp from "https://deno.land/x/secp256k1/mod.ts";
const publicKey = ed.getPublicKey(ed.utils.randomPrivateKey());
console.log(publicKey);
imports.json
{
"imports": {
"crypto": "https://deno.land/std@0.119.0/node/crypto.ts"
}
}
getPublicKey(privateKey)
sign(message, privateKey)
verify(signature, message, publicKey)
getSharedSecret(privateKey, publicKey)
getPublicKey(privateKey)
function getPublicKey(privateKey: Uint8Array | string | bigint): Promise<Uint8Array>;
privateKey: Uint8Array | string | bigint
will be used to generate public key.Promise<Uint8Array>
. Uses promises, because ed25519 uses SHA internally; and we're using built-in browser window.crypto
, which returns Promise
.To generate ed25519 public key:
Point.fromPrivateKey(privateKey)
if you want Point
instance insteadPoint.fromHex(publicKey)
if you want to convert hex / bytes into Point.
It will use decompression algorithm 5.1.3 of RFC 8032.utils.getExtendedPublicKey
if you need full SHA512 hash of seedsign(message, privateKey)
function sign(message: Uint8Array | string, privateKey: Uint8Array | string): Promise<Uint8Array>;
message: Uint8Array | string
- message which would be signedprivateKey: Uint8Array | string
- private key which will sign the hashSignature.fromHex()
method:
Signature.fromHex(ed25519.sign(hash, privateKey))
verify(signature, message, publicKey)
function verify(
signature: Uint8Array | string | Signature,
message: Uint8Array | string,
publicKey: Uint8Array | string | Point
): Promise<boolean>
signature: Uint8Array | string | Signature
- returned by the sign
functionmessage: Uint8Array | string
- message that needs to be verifiedpublicKey: Uint8Array | string | Point
- e.g. that was generated from privateKey
by getPublicKey
Promise<boolean>
getSharedSecret(privateKey, publicKey)
function getSharedSecret(privateKey: Uint8Array | string | bigint, publicKey: Hex): Promise<Uint8Array>;
Converts ed25519 private / public keys to Curve25519 and calculates Elliptic Curve Diffie Hellman (ECDH) with X25519. Conforms to RFC7748.
const pub = ed25519.curve25519.scalarMultBase(privateKey);
const shared = ed25519.curve25519.scalarMult(privateKeyA, publicKeyB);
The library includes namespace curve25519
that you could use to calculate
Curve25519 keys. It uses Montgomery Ladder specified in RFC7748.
You cannot use ed25519 keys, because they are hashed with sha512. However, you can use
Point#toX25519()
method on ed25519 public keys. See implementation of ed25519.getSharedSecret
for details.
To use Ristretto, simply use fromRistrettoHash()
and toRistrettoBytes()
methods.
// The hash-to-group operation applies Elligator twice and adds the results.
ExtendedPoint.fromRistrettoHash(hash: Uint8Array | string): ExtendedPoint;
// Decode a byte-string s_bytes representing a compressed Ristretto point into extended coordinates.
ExtendedPoint.fromRistrettoBytes(bytes: Uint8Array | string): ExtendedPoint;
// Encode a Ristretto point represented by the point (X:Y:Z:T) in extended coordinates to Uint8Array.
ExtendedPoint#toRistrettoBytes(): Uint8Array
It extends Mike Hamburg's Decaf approach to cofactor elimination to support cofactor-8 curves such as Curve25519.
In particular, this allows an existing Curve25519 library to implement a prime-order group with only a thin abstraction layer, and makes it possible for systems using Ed25519 signatures to be safely extended with zero-knowledge protocols, with no additional cryptographic assumptions and minimal code changes.
utils.randomPrivateKey()
Returns cryptographically secure random Uint8Array
that could be used as Private Key.
utils.precompute(W = 8, point = Point.BASE)
Returns cached point which you can use to #multiply
by it.
This is done by default, no need to run it unless you want to disable precomputation or change window size.
We're doing scalar multiplication (used in getPublicKey etc) with precomputed BASE_POINT values.
This slows down first getPublicKey() by milliseconds (see Speed section), but allows to speed-up subsequent getPublicKey() calls up to 20x.
You may want to precompute values for your own point.
utils.TORSION_SUBGROUP
The 8-torsion subgroup ℰ8. Those are "buggy" points, if you multiply them by 8, you'll receive Point.ZERO.
Useful to check implementations for signature malleability. See the link
Point#toX25519
You can use the method to use ed25519 keys for curve25519 encryption.
https://blog.filippo.io/using-ed25519-keys-for-encryption
ed25519.CURVE.P // 2 ** 255 - 19
ed25519.CURVE.n // 2 ** 252 - 27742317777372353535851937790883648493
ed25519.Point.BASE // new ed25519.Point(Gx, Gy) where
// Gx = 15112221349535400772501151409588531511454012693041857206046113283949847762202n
// Gy = 46316835694926478169428394003475163141307993866256225615783033603165251855960n;
// Elliptic curve point in Affine (x, y) coordinates.
ed25519.Point {
constructor(x: bigint, y: bigint);
static fromHex(hash: string);
static fromPrivateKey(privateKey: string | Uint8Array);
toX25519(): bigint; // Converts to Curve25519 u coordinate
toRawBytes(): Uint8Array;
toHex(): string; // Compact representation of a Point
equals(other: Point): boolean;
negate(): Point;
add(other: Point): Point;
subtract(other: Point): Point;
multiply(scalar: bigint): Point;
}
// Elliptic curve point in Extended (x, y, z, t) coordinates.
ed25519.ExtendedPoint {
constructor(x: bigint, y: bigint, z: bigint, t: bigint);
static fromAffine(point: Point): ExtendedPoint;
static fromRistrettoHash(hash: Uint8Array | string): ExtendedPoint;
static fromRistrettoBytes(bytes: Uint8Array | string): ExtendedPoint;
toRistrettoBytes(): Uint8Array;
toAffine(): Point;
}
ed25519.Signature {
constructor(r: bigint, s: bigint);
toHex(): string;
}
// Precomputation helper
utils.precompute(W, point);
// returns { head, prefix, scalar, point, pubBytes }
utils.getExtendedPublicKey(privateKey);
Noble is production-ready.
We're using built-in JS BigInt
, which is "unsuitable for use in cryptography" as per official spec. This means that the lib is potentially vulnerable to timing attacks. 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 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.
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.
getPublicKey(utils.randomPrivateKey()) x 6,790 ops/sec @ 147μs/op
sign x 3,276 ops/sec @ 305μs/op
verify x 726 ops/sec @ 1ms/op
verifyBatch x 842 ops/sec @ 1ms/op
Point.fromHex decompression x 11,332 ops/sec @ 88μs/op
ristretto255#fromHash x 5,428 ops/sec @ 184μs/op
ristretto255 round x 5,467 ops/sec @ 182μs/op
getSharedSecret x 778 ops/sec @ 1285μs/op
curve25519.scalarMultBase x 1,010 ops/sec @ 989μs/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@0.1.1
getPublicKey x 877 ops/sec @ 1ms/op # aka scalarMultBase
# sodium-native@3.2.1, native bindings to libsodium, node.js-only
sodium-native#sign x 58,661 ops/sec @ 17μs/op
npm install
to install build dependencies like TypeScriptnpm run compile
to compile TypeScript codenpm run test
to run jest on test/index.ts
MIT (c) 2019 Paul Miller (https://paulmillr.com), see LICENSE file.
FAQs
Fastest 4KB JS implementation of ed25519 EDDSA signatures compliant with RFC8032, FIPS 186-5 & ZIP215
The npm package @noble/ed25519 receives a total of 90,787 weekly downloads. As such, @noble/ed25519 popularity was classified as popular.
We found that @noble/ed25519 demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
NVD’s backlog surpasses 20,000 CVEs as analysis slows and NIST announces new system updates to address ongoing delays.
Security News
Research
A malicious npm package disguised as a WhatsApp client is exploiting authentication flows with a remote kill switch to exfiltrate data and destroy files.
Security News
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.