Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Audited pure JS library containing all Ethereum-related cryptographic primitives

License

NotificationsYou must be signed in to change notification settings

ethereum/js-ethereum-cryptography

Repository files navigation

Audited pure JS library containing all Ethereum-related cryptographic primitives. Implemented with 6noble & scure dependencies.

Check outChangelog / Upgrading and an article about the library:A safer, smaller, and faster Ethereum cryptography stack.

Usage

npm install ethereum-cryptography

We explicitly support major browsers and Node.js on x86 and arm64. Other major runtimes and platforms are supported on a best-effort basis.Refer toengines field ofpackage.json for runtime support information for each version.Tests are being ran with Webpack, Rollup, Parcel and Browserify.

This package has no single entry-point, but submodule for each cryptographicprimitive. The reason for this is that importing everything from a single file will lead to huge bundles when using this package for the web. This could beavoided through tree-shaking, but the possibility of it not working properlyon one ofthe supported bundlers is too high.

Dependencies

All functionality of the module is simplere-export of 6 auditednoble & scure libraries:

  • noble-curves, noble-ciphers, noble-hashes
  • scure-base, scure-bip32, scure-bip39

ethereum-cryptography pins versions of the libraries to ensure goodprotection against supply chain attacks. Ideally, your app would alsopin version of ethereum-cryptography. That means, no^3.1.0 - use3.1.0 instead.

hashes: sha256, sha512, keccak, ripemd160, blake2b

import{sha256}from"ethereum-cryptography/sha256.js";import{sha512}from"ethereum-cryptography/sha512.js";import{keccak256,keccak224,keccak384,keccak512,}from"ethereum-cryptography/keccak.js";import{ripemd160}from"ethereum-cryptography/ripemd160.js";import{blake2b}from"ethereum-cryptography/blake2b.js";sha256(Uint8Array.from([1,2,3]));// A: buffersimport{utf8ToBytes}from"ethereum-cryptography/utils.js";sha256(utf8ToBytes("abc"));// B: stringsimport{bytesToHexastoHex}from"ethereum-cryptography/utils.js";toHex(sha256(utf8ToBytes("abc")));// C: hex

kdfs: pbkdf2, scrypt

import{pbkdf2,pbkdf2Sync}from"ethereum-cryptography/pbkdf2.js";import{scrypt,scryptSync}from"ethereum-cryptography/scrypt.js";import{utf8ToBytes}from"ethereum-cryptography/utils.js";// Pass Uint8Array, or convert strings to Uint8Arrayconstpass=utf8ToBytes("password");constsalt=utf8ToBytes("salt");constiters=131072;constoutLength=32;console.log(awaitpbkdf2(pass,salt,iters,outLength,"sha256"));constN=262144;constr=8;constp=1;constoutLengths=32;console.log(awaitscrypt(pass,salt,N,r,p,outLengths));

Thepbkdf2 submodule has two functions implementing the PBKDF2 keyderivation algorithm in synchronous and asynchronous ways. This algorithm isvery slow, and using the synchronous version in the browser is not recommended,as it will block its main thread and hang your UI. The KDF supportssha256 andsha512 digests.

Thescrypt submodule has two functions implementing the Scrypt keyderivation algorithm in synchronous and asynchronous ways. This algorithm isvery slow, and using the synchronous version in the browser is not recommended,as it will block its main thread and hang your UI.

Encoding passwords is a frequent source of errors. Please readnotesbefore using these submodules.

random: secure randomness

import{getRandomBytesSync}from"ethereum-cryptography/random.js";console.log(getRandomBytesSync(32));

Therandom submodule has functions to generate cryptographically strongpseudo-random data in synchronous and asynchronous ways. Backed bycrypto.getRandomValues in browser and bycrypto.randomBytes in node.js. If backends are somehow not available, the module would throw an error and won't work, as keeping them working would be insecure.

secp256k1: curve operations

import{secp256k1}from"ethereum-cryptography/secp256k1.js";// You pass either a hex string, or Uint8ArrayconstprivateKey="6b911fd37cdf5c81d4c0adb1ab7fa822ed253ab0ad9aa18d77257c88b29b718e";constmessageHash="a33321f98e4ff1c283c76998f14f57447545d339b3db534c6d886decb4209f28";constpublicKey=secp256k1.getPublicKey(privateKey);constsignature=secp256k1.sign(messageHash,privateKey);constisSigned=secp256k1.verify(signature,messageHash,publicKey);

Elliptic curve operations on the curve secp256k1. Check outnoble-curves docs for more info.

secp256k1 private keys need to be cryptographically secure random numbers withcertain characteristics. If this is not the case, the security of secp256k1 iscompromised.

bn: pairing-friendly curve

import{bn}from"ethereum-cryptography/bls.js";console.log(bn254.G1,bn254.G2,bn254.pairing);

For example usage, check outthe implementation of bn254 EVM precompiles.

bls: pairing-friendly curve

import{bls12_381asbls}from"ethereum-cryptography/bls.js";// G1 keys, G2 signaturesconstprivateKey="67d53f170b908cabb9eb326c3c337762d59289a8fec79f7bc9254b584b73265c";constmessage="64726e3da8";constpublicKey=bls.getPublicKey(privateKey);constsignature=bls.sign(message,privateKey);constisValid=bls.verify(signature,message,publicKey);console.log({ publicKey, signature, isValid});// G2 signatures, G1 keys// getPublicKeyForShortSignatures(privateKey)// signShortSignature(message, privateKey)// verifyShortSignature(signature, message, publicKey)// aggregateShortSignatures(signatures)// Custom DSTconsthtfEthereum={DST:"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_"};constsignatureEth=bls.sign(message,privateKey,htfEthereum);constisValidEth=bls.verify(signature,message,publicKey,htfEthereum);// AggregationconstaggregatedKey=bls.aggregatePublicKeys([bls.getPublicKey(bls.utils.randomPrivateKey()),bls.getPublicKey(bls.utils.randomPrivateKey()),]);// const aggregatedSig = bls.aggregateSignatures(sigs)// Pairings, with and without final exponentiation// bls.pairing(PointG1, PointG2);// bls.pairing(PointG1, PointG2, false);// bls.fields.Fp12.finalExponentiate(bls.fields.Fp12.mul(PointG1, PointG2));// Others// bls.G1.ProjectivePoint.BASE, bls.G2.ProjectivePoint.BASE;// bls.fields.Fp, bls.fields.Fp2, bls.fields.Fp12, bls.fields.Fr;

For example usage, check outthe implementation of BLS EVM precompiles.

aes: encryption

import*asaesfrom"ethereum-cryptography/aes.js";import{hexToBytes,utf8ToBytes}from"ethereum-cryptography/utils.js";console.log(aes.encrypt(utf8ToBytes("message"),hexToBytes("2b7e151628aed2a6abf7158809cf4f3c"),hexToBytes("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")));// const mode = "aes-128-ctr"; // "aes-128-cbc", "aes-256-ctr", "aes-256-cbc"// function encrypt(msg: Uint8Array, key: Uint8Array, iv: Uint8Array, mode = "aes-128-ctr", pkcs7PaddingEnabled = true): Uint8Array;// function decrypt(cipherText: Uint8Array, key: Uint8Array, iv: Uint8Array, mode = "aes-128-ctr", pkcs7PaddingEnabled = true): Uint8Array;

hdkey: bip32 HD wallets

import{HDKey}from"ethereum-cryptography/hdkey.js";consthdkey1=HDKey.fromMasterSeed(seed);consthdkey2=HDKey.fromExtendedKey(base58key);consthdkey3=HDKey.fromJSON({xpriv:string});// props[hdkey1.depth,hdkey1.index,hdkey1.chainCode];console.log(hdkey2.privateKey,hdkey2.publicKey);console.log(hdkey3.derive("m/0/2147483647'/1"));constsig=hdkey3.sign(hash);hdkey3.verify(hash,sig);

Hierarchical deterministic (HD) wallets that conform toBIP32.

bip39: mnemonic phrases

import*asbip39from"ethereum-cryptography/bip39/index.js";import{wordlist}from"ethereum-cryptography/bip39/wordlists/english.js";// import { wordlist } from "ethereum-cryptography/bip39/wordlists/czech.js";// import { wordlist } from "ethereum-cryptography/bip39/wordlists/english.js";// import { wordlist } from "ethereum-cryptography/bip39/wordlists/french.js";// import { wordlist } from "ethereum-cryptography/bip39/wordlists/italian.js";// import { wordlist } from "ethereum-cryptography/bip39/wordlists/japanese.js";// import { wordlist } from "ethereum-cryptography/bip39/wordlists/korean.js";// import { wordlist } from "ethereum-cryptography/bip39/wordlists/portuguese.js";// import { wordlist } from "ethereum-cryptography/bip39/wordlists/simplified-chinese.js";// import { wordlist } from "ethereum-cryptography/bip39/wordlists/spanish.js";// import { wordlist } from "ethereum-cryptography/bip39/wordlists/traditional-chinese.js";// Generate x random words. Uses Cryptographically-Secure Random Number Generator.constmn=bip39.generateMnemonic(wordlist);console.log(mn);// Reversible: Converts mnemonic string to raw entropy in form of byte array.constent=bip39.mnemonicToEntropy(mn,wordlist);// Reversible: Converts raw entropy in form of byte array to mnemonic string.bip39.entropyToMnemonic(ent,wordlist);// Validates mnemonic for being 12-24 words contained in `wordlist`.bip39.validateMnemonic(mn,wordlist);// Irreversible: Uses KDF to derive 64 bytes of key data from mnemonic + optional password.awaitbip39.mnemonicToSeed(mn,"password");bip39.mnemonicToSeedSync(mn,"password");

Thebip39 submodule provides functions to generate, validate and use seedrecovery phrases according toBIP39.

Wordlists for different languages are not imported by default,as that would increase bundle sizes too much. Instead, you should import and use them explicitly.

math: utilities

import{modPow,modInvert}from"ethereum-cryptography/math.js";modPow(123n,456n,789n);modInvert(22n,5n);

utils: generic utilities

import{hexToBytes,toHex,utf8ToBytes}from"ethereum-cryptography/utils.js";

secp256k1-compat: compatibility layer with other libraries

import{createPrivateKeySync,ecdsaSign,}from"ethereum-cryptography/secp256k1-compat";constmsgHash=Uint8Array.from("82ff40c0a986c6a5cfad4ddf4c3aa6996f1a7837f9c398e17e5de5cbd5a12b28","hex");constprivateKey=createPrivateKeySync();console.log(Uint8Array.from(ecdsaSign(msgHash,privateKey).signature));

Warning: usesecp256k1 instead. This module is only for users who upgradedfrom ethereum-cryptography v0.1. It could be removed in the future.

The API ofsecp256k1-compat is the same assecp256k1-node:

All imports

import{sha256}from"ethereum-cryptography/sha256.js";import{sha512}from"ethereum-cryptography/sha512.js";import{keccak256,keccak224,keccak384,keccak512,}from"ethereum-cryptography/keccak.js";import{ripemd160}from"ethereum-cryptography/ripemd160.js";import{blake2b}from"ethereum-cryptography/blake2b.js";import{pbkdf2Sync}from"ethereum-cryptography/pbkdf2.js";import{scryptSync}from"ethereum-cryptography/scrypt.js";import{getRandomBytesSync}from"ethereum-cryptography/random.js";import{encrypt}from"ethereum-cryptography/aes.js";import{modPow,modInvert}from"ethereum-cryptography/math.js";import{secp256k1}from"ethereum-cryptography/secp256k1.js";import{bls12_381}from"ethereum-cryptography/bls.js";import{bn254}from"ethereum-cryptography/bn.js";import{HDKey}from"ethereum-cryptography/hdkey.js";import{generateMnemonic}from"ethereum-cryptography/bip39/index.js";import{wordlist}from"ethereum-cryptography/bip39/wordlists/english.js";import{modPow,modInvert}from"ethereum-cryptography/math.js";import{hexToBytes,toHex,utf8ToBytes}from"ethereum-cryptography/utils.js";

Caveats

Browser usage: Rollup setup

Using this library with Rollup requires the following plugins:

These can be used by setting yourplugins array like this:

plugins:[commonjs(),resolve({browser:true,preferBuiltins:false,}),];

AES

Encrypting with passwords

AES is not supposed to be used directly with a password. Doing that willcompromise your users' security.

Thekey parameters in this submodule are meant to be strong cryptographickeys. If you want to obtain such a key from a password, please use akey derivation functionlikepbkdf2 orscrypt.

Operation modes

This submodule works with differentblock cipher modes of operation. If you are using this module in a newapplication, we recommend using the default.

While this module may work with any mode supported by OpenSSL, we only test itwithaes-128-ctr,aes-128-cbc, andaes-256-cbc. If you use another modulea warning will be printed in the console.

We only recommend usingaes-128-cbc andaes-256-cbc to decrypt alreadyencrypted data.

Padding plaintext messages

Some operation modes require the plaintext message to be a multiple of16. Ifthat isn't the case, your message has to be padded.

By default, this module automatically pads your messages according toPKCS#7.Note that this padding scheme always adds at least 1 byte of padding. If youare unsure what anything of this means, westrongly recommend you to usethe defaults.

If you need to encrypt without padding or want to use another padding scheme,you can disable PKCS#7 padding by passingfalse as the last argument andhandling padding yourself. Note that if you do this and your operation moderequires padding,encrypt will throw if your plaintext message isn't amultiple of16.

This option is only present to enable the decryption of already encrypted data.To encrypt new data, we recommend using the default.

How to use the IV parameter

Theiv parameter of theencrypt function must be unique, or the securityof the encryption algorithm can be compromised.

You can generate a newiv using therandom module.

Note that to decrypt a value, you have to provide the sameiv used to encryptit.

How to handle errors with this module

Sensitive information can be leaked via error messages when using this module.To avoid this, you should make sure that the errors you return don'tcontain the exact reason for the error. Instead, errors must report generalencryption/decryption failures.

Note that implementing this can mean catching all errors that can be thrownwhen calling on of this module's functions, and just throwing a new genericexception.

Upgrading

Changelog

  • v3.0 (Sep 2024): new modulesbls,bn,mathchange async AES to non-native sync,improve typescript compatibility, new dependencynoble-ciphers
  • v2.0 (Apr 2023): switchednoble-secp256k1 tonoble-curves,which changes re-exported api ofsecp256k1 submodule.
  • v1.0 (Jan 2022): rewritten the library fromscratch andaudited it. It became6x smaller: ~5,000 lines ofcode instead of ~24,000 (with all deps); 650KB instead of 10.2MB.5 dependencies by 1 author are now used, instead of 38 by 5 authors.

From v2 to v3

  1. utils:crypto var had been removed
  2. aes: async methods became sync

From v1 to v2

  1. secp256k1 module was changed massively:before, it was usingnoble-secp256k1 1.7;now it uses safernoble-curves. Please refertoupgrading section from curves README.Main changes to keep in mind: a)sign now returnsSignature instanceb)recoverPublicKey got moved onto aSignature instance
  2. node.js 14 and older support was dropped. Upgrade to node.js 16 or later.

From v0.1 to v1

All old APIs remain the same except for the breaking changes:

  1. We returnUint8Array from all methods that worked withBuffer before.Buffer has never been supported in browsers, whileUint8Arrays are supported natively in bothbrowsers and node.js.
  2. We target runtimes withbigint support,which is Chrome 67+, Edge 79+, Firefox 68+, Safari 14+, node.js 10+. If you need to support older runtimes, useethereum-cryptography@0.1
  3. If you've usedsecp256k1,rename it tosecp256k1-compat
import{sha256}from"ethereum-cryptography/sha256.js";// Old usageconsthasho=sha256(Buffer.from("string","utf8")).toString("hex");// New usageimport{toHex}from"ethereum-cryptography/utils.js";consthashn=toHex(sha256("string"));// If you have `Buffer` module and want to preserve it:consthashb=Buffer.from(sha256("string"));consthashbo=hashb.toString("hex");

Security

Audited by Cure53 on Jan 5, 2022. Check out the auditPDF &URL.

Dependencies are having separate regular audits: check out their documentation for more info.

License

ethereum-cryptography is released under The MIT License (MIT)

Copyright (c) 2021 Patricio Palladino, Paul Miller, ethereum-cryptography contributors

SeeLICENSE file.

hdkey is loosely based onhdkey,which hadMIT License

Copyright (c) 2018 cryptocoinjs

Packages

No packages published

Contributors12


[8]ページ先頭

©2009-2025 Movatter.jp