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

ethereum-cryptography

Package Overview
Dependencies
Maintainers
2
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ethereum-cryptography - npm Package Compare versions

Comparing version 2.2.1 to 3.0.0

bls.d.ts

4

aes.d.ts

@@ -1,2 +0,2 @@

export declare function encrypt(msg: Uint8Array, key: Uint8Array, iv: Uint8Array, mode?: string, pkcs7PaddingEnabled?: boolean): Promise<Uint8Array>;
export declare function decrypt(cypherText: Uint8Array, key: Uint8Array, iv: Uint8Array, mode?: string, pkcs7PaddingEnabled?: boolean): Promise<Uint8Array>;
export declare function encrypt(msg: Uint8Array, key: Uint8Array, iv: Uint8Array, mode?: string, pkcs7PaddingEnabled?: boolean): Uint8Array;
export declare function decrypt(ciphertext: Uint8Array, key: Uint8Array, iv: Uint8Array, mode?: string, pkcs7PaddingEnabled?: boolean): Uint8Array;

@@ -5,94 +5,27 @@ "use strict";

exports.decrypt = decrypt;
const crypto_1 = require("@noble/hashes/crypto");
const utils_js_1 = require("./utils.js");
const crypto = { web: crypto_1.crypto };
function validateOpt(key, iv, mode) {
const aes_1 = require("@noble/ciphers/aes");
function getCipher(key, iv, mode, pkcs7PaddingEnabled = true) {
if (!mode.startsWith("aes-")) {
throw new Error(`AES submodule doesn't support mode ${mode}`);
throw new Error("AES: unsupported mode");
}
const len = key.length;
if ((mode.startsWith("aes-128") && len !== 16) || (mode.startsWith("aes-256") && len !== 32)) {
throw new Error("AES: wrong key length");
}
if (iv.length !== 16) {
throw new Error("AES: wrong IV length");
}
if ((mode.startsWith("aes-128") && key.length !== 16) ||
(mode.startsWith("aes-256") && key.length !== 32)) {
throw new Error("AES: wrong key length");
}
}
async function getBrowserKey(mode, key, iv) {
if (!crypto.web) {
throw new Error("Browser crypto not available.");
}
let keyMode;
if (["aes-128-cbc", "aes-256-cbc"].includes(mode)) {
keyMode = "cbc";
return (0, aes_1.cbc)(key, iv, { disablePadding: !pkcs7PaddingEnabled });
}
if (["aes-128-ctr", "aes-256-ctr"].includes(mode)) {
keyMode = "ctr";
return (0, aes_1.ctr)(key, iv);
}
if (!keyMode) {
throw new Error("AES: unsupported mode");
}
const wKey = await crypto.web.subtle.importKey("raw", key, { name: `AES-${keyMode.toUpperCase()}`, length: key.length * 8 }, true, ["encrypt", "decrypt"]);
// node.js uses whole 128 bit as a counter, without nonce, instead of 64 bit
// recommended by NIST SP800-38A
return [wKey, { name: `aes-${keyMode}`, iv, counter: iv, length: 128 }];
throw new Error("AES: unsupported mode");
}
async function encrypt(msg, key, iv, mode = "aes-128-ctr", pkcs7PaddingEnabled = true) {
validateOpt(key, iv, mode);
if (crypto.web) {
const [wKey, wOpt] = await getBrowserKey(mode, key, iv);
const cipher = await crypto.web.subtle.encrypt(wOpt, wKey, msg);
// Remove PKCS7 padding on cbc mode by stripping end of message
let res = new Uint8Array(cipher);
if (!pkcs7PaddingEnabled && wOpt.name === "aes-cbc" && !(msg.length % 16)) {
res = res.slice(0, -16);
}
return res;
}
else if (crypto.node) {
const cipher = crypto.node.createCipheriv(mode, key, iv);
cipher.setAutoPadding(pkcs7PaddingEnabled);
return (0, utils_js_1.concatBytes)(cipher.update(msg), cipher.final());
}
else {
throw new Error("The environment doesn't have AES module");
}
function encrypt(msg, key, iv, mode = "aes-128-ctr", pkcs7PaddingEnabled = true) {
return getCipher(key, iv, mode, pkcs7PaddingEnabled).encrypt(msg);
}
async function getPadding(cypherText, key, iv, mode) {
const lastBlock = cypherText.slice(-16);
for (let i = 0; i < 16; i++) {
// Undo xor of iv and fill with lastBlock ^ padding (16)
lastBlock[i] ^= iv[i] ^ 16;
}
const res = await encrypt(lastBlock, key, iv, mode);
return res.slice(0, 16);
function decrypt(ciphertext, key, iv, mode = "aes-128-ctr", pkcs7PaddingEnabled = true) {
return getCipher(key, iv, mode, pkcs7PaddingEnabled).decrypt(ciphertext);
}
async function decrypt(cypherText, key, iv, mode = "aes-128-ctr", pkcs7PaddingEnabled = true) {
validateOpt(key, iv, mode);
if (crypto.web) {
const [wKey, wOpt] = await getBrowserKey(mode, key, iv);
// Add empty padding so Chrome will correctly decrypt message
if (!pkcs7PaddingEnabled && wOpt.name === "aes-cbc") {
const padding = await getPadding(cypherText, key, iv, mode);
cypherText = (0, utils_js_1.concatBytes)(cypherText, padding);
}
const msg = await crypto.web.subtle.decrypt(wOpt, wKey, cypherText);
const msgBytes = new Uint8Array(msg);
// Safari always ignores padding (if no padding -> broken message)
if (wOpt.name === "aes-cbc") {
const encrypted = await encrypt(msgBytes, key, iv, mode);
if (!(0, utils_js_1.equalsBytes)(encrypted, cypherText)) {
throw new Error("AES: wrong padding");
}
}
return msgBytes;
}
else if (crypto.node) {
const decipher = crypto.node.createDecipheriv(mode, key, iv);
decipher.setAutoPadding(pkcs7PaddingEnabled);
return (0, utils_js_1.concatBytes)(decipher.update(cypherText), decipher.final());
}
else {
throw new Error("The environment doesn't have AES module");
}
}

@@ -1,93 +0,26 @@

import { crypto as cr } from "@noble/hashes/crypto";
import { concatBytes, equalsBytes } from "./utils.js";
const crypto = { web: cr };
function validateOpt(key, iv, mode) {
import { ctr, cbc } from "@noble/ciphers/aes";
function getCipher(key, iv, mode, pkcs7PaddingEnabled = true) {
if (!mode.startsWith("aes-")) {
throw new Error(`AES submodule doesn't support mode ${mode}`);
throw new Error("AES: unsupported mode");
}
const len = key.length;
if ((mode.startsWith("aes-128") && len !== 16) || (mode.startsWith("aes-256") && len !== 32)) {
throw new Error("AES: wrong key length");
}
if (iv.length !== 16) {
throw new Error("AES: wrong IV length");
}
if ((mode.startsWith("aes-128") && key.length !== 16) ||
(mode.startsWith("aes-256") && key.length !== 32)) {
throw new Error("AES: wrong key length");
}
}
async function getBrowserKey(mode, key, iv) {
if (!crypto.web) {
throw new Error("Browser crypto not available.");
}
let keyMode;
if (["aes-128-cbc", "aes-256-cbc"].includes(mode)) {
keyMode = "cbc";
return cbc(key, iv, { disablePadding: !pkcs7PaddingEnabled });
}
if (["aes-128-ctr", "aes-256-ctr"].includes(mode)) {
keyMode = "ctr";
return ctr(key, iv);
}
if (!keyMode) {
throw new Error("AES: unsupported mode");
}
const wKey = await crypto.web.subtle.importKey("raw", key, { name: `AES-${keyMode.toUpperCase()}`, length: key.length * 8 }, true, ["encrypt", "decrypt"]);
// node.js uses whole 128 bit as a counter, without nonce, instead of 64 bit
// recommended by NIST SP800-38A
return [wKey, { name: `aes-${keyMode}`, iv, counter: iv, length: 128 }];
throw new Error("AES: unsupported mode");
}
export async function encrypt(msg, key, iv, mode = "aes-128-ctr", pkcs7PaddingEnabled = true) {
validateOpt(key, iv, mode);
if (crypto.web) {
const [wKey, wOpt] = await getBrowserKey(mode, key, iv);
const cipher = await crypto.web.subtle.encrypt(wOpt, wKey, msg);
// Remove PKCS7 padding on cbc mode by stripping end of message
let res = new Uint8Array(cipher);
if (!pkcs7PaddingEnabled && wOpt.name === "aes-cbc" && !(msg.length % 16)) {
res = res.slice(0, -16);
}
return res;
}
else if (crypto.node) {
const cipher = crypto.node.createCipheriv(mode, key, iv);
cipher.setAutoPadding(pkcs7PaddingEnabled);
return concatBytes(cipher.update(msg), cipher.final());
}
else {
throw new Error("The environment doesn't have AES module");
}
export function encrypt(msg, key, iv, mode = "aes-128-ctr", pkcs7PaddingEnabled = true) {
return getCipher(key, iv, mode, pkcs7PaddingEnabled).encrypt(msg);
}
async function getPadding(cypherText, key, iv, mode) {
const lastBlock = cypherText.slice(-16);
for (let i = 0; i < 16; i++) {
// Undo xor of iv and fill with lastBlock ^ padding (16)
lastBlock[i] ^= iv[i] ^ 16;
}
const res = await encrypt(lastBlock, key, iv, mode);
return res.slice(0, 16);
export function decrypt(ciphertext, key, iv, mode = "aes-128-ctr", pkcs7PaddingEnabled = true) {
return getCipher(key, iv, mode, pkcs7PaddingEnabled).decrypt(ciphertext);
}
export async function decrypt(cypherText, key, iv, mode = "aes-128-ctr", pkcs7PaddingEnabled = true) {
validateOpt(key, iv, mode);
if (crypto.web) {
const [wKey, wOpt] = await getBrowserKey(mode, key, iv);
// Add empty padding so Chrome will correctly decrypt message
if (!pkcs7PaddingEnabled && wOpt.name === "aes-cbc") {
const padding = await getPadding(cypherText, key, iv, mode);
cypherText = concatBytes(cypherText, padding);
}
const msg = await crypto.web.subtle.decrypt(wOpt, wKey, cypherText);
const msgBytes = new Uint8Array(msg);
// Safari always ignores padding (if no padding -> broken message)
if (wOpt.name === "aes-cbc") {
const encrypted = await encrypt(msgBytes, key, iv, mode);
if (!equalsBytes(encrypted, cypherText)) {
throw new Error("AES: wrong padding");
}
}
return msgBytes;
}
else if (crypto.node) {
const decipher = crypto.node.createDecipheriv(mode, key, iv);
decipher.setAutoPadding(pkcs7PaddingEnabled);
return concatBytes(decipher.update(cypherText), decipher.final());
}
else {
throw new Error("The environment doesn't have AES module");
}
}

@@ -37,12 +37,1 @@ import assert from "@noble/hashes/_assert";

}
// TODO(v3): switch away from node crypto, remove this unnecessary variable.
export const crypto = (() => {
const webCrypto = typeof globalThis === "object" && "crypto" in globalThis ? globalThis.crypto : undefined;
const nodeRequire = typeof module !== "undefined" &&
typeof module.require === "function" &&
module.require.bind(module);
return {
node: nodeRequire && !webCrypto ? nodeRequire("crypto") : undefined,
web: webCrypto
};
})();
{
"name": "ethereum-cryptography",
"version": "2.2.1",
"version": "3.0.0",
"description": "All the cryptographic primitives used in Ethereum",

@@ -8,2 +8,6 @@ "repository": "https://github.com/ethereum/js-ethereum-cryptography",

"main": "./index.js",
"engines": {
"node": "^14.21.3 || >=16",
"npm": ">=9"
},
"files": [

@@ -19,267 +23,240 @@ "bip39/*.js",

"dependencies": {
"@noble/curves": "1.4.2",
"@noble/hashes": "1.4.0",
"@scure/bip32": "1.4.0",
"@scure/bip39": "1.3.0"
"@noble/ciphers": "1.0.0",
"@noble/curves": "1.6.0",
"@noble/hashes": "1.5.0",
"@scure/bip32": "1.5.0",
"@scure/bip39": "1.4.0"
},
"exports": {
".": {
"types": "./index.d.ts",
"import": "./esm/index.js",
"default": "./index.js"
"require": "./index.js"
},
"./aes": {
"types": "./aes.d.ts",
"import": "./esm/aes.js",
"default": "./aes.js"
"require": "./aes.js"
},
"./bip39": {
"types": "./bip39/index.d.ts",
"import": "./esm/bip39/index.js",
"default": "./bip39/index.js"
"require": "./bip39/index.js"
},
"./blake2b": {
"types": "./blake2b.d.ts",
"import": "./esm/blake2b.js",
"default": "./blake2b.js"
"require": "./blake2b.js"
},
"./bls": {
"import": "./esm/bls.js",
"require": "./bls.js"
},
"./bn": {
"import": "./esm/bn.js",
"require": "./bn.js"
},
"./hdkey": {
"types": "./hdkey.d.ts",
"import": "./esm/hdkey.js",
"default": "./hdkey.js"
"require": "./hdkey.js"
},
"./index": {
"types": "./index.d.ts",
"import": "./esm/index.js",
"default": "./index.js"
"require": "./index.js"
},
"./math": {
"import": "./esm/math.js",
"require": "./math.js"
},
"./keccak": {
"types": "./keccak.d.ts",
"import": "./esm/keccak.js",
"default": "./keccak.js"
"require": "./keccak.js"
},
"./pbkdf2": {
"types": "./pbkdf2.d.ts",
"import": "./esm/pbkdf2.js",
"default": "./pbkdf2.js"
"require": "./pbkdf2.js"
},
"./random": {
"types": "./random.d.ts",
"import": "./esm/random.js",
"default": "./random.js"
"require": "./random.js"
},
"./ripemd160": {
"types": "./ripemd160.d.ts",
"import": "./esm/ripemd160.js",
"default": "./ripemd160.js"
"require": "./ripemd160.js"
},
"./scrypt": {
"types": "./scrypt.d.ts",
"import": "./esm/scrypt.js",
"default": "./scrypt.js"
"require": "./scrypt.js"
},
"./secp256k1-compat": {
"types": "./secp256k1-compat.d.ts",
"import": "./esm/secp256k1-compat.js",
"default": "./secp256k1-compat.js"
"require": "./secp256k1-compat.js"
},
"./secp256k1": {
"types": "./secp256k1.d.ts",
"import": "./esm/secp256k1.js",
"default": "./secp256k1.js"
"require": "./secp256k1.js"
},
"./sha256": {
"types": "./sha256.d.ts",
"import": "./esm/sha256.js",
"default": "./sha256.js"
"require": "./sha256.js"
},
"./sha512": {
"types": "./sha512.d.ts",
"import": "./esm/sha512.js",
"default": "./sha512.js"
"require": "./sha512.js"
},
"./utils": {
"types": "./utils.d.ts",
"import": "./esm/utils.js",
"default": "./utils.js"
"require": "./utils.js"
},
"./bip39/index": {
"types": "./bip39/index.d.ts",
"import": "./esm/bip39/index.js",
"default": "./bip39/index.js"
"require": "./bip39/index.js"
},
"./bip39/wordlists/czech": {
"types": "./bip39/wordlists/czech.d.ts",
"import": "./esm/bip39/wordlists/czech.js",
"default": "./bip39/wordlists/czech.js"
"require": "./bip39/wordlists/czech.js"
},
"./bip39/wordlists/english": {
"types": "./bip39/wordlists/english.d.ts",
"import": "./esm/bip39/wordlists/english.js",
"default": "./bip39/wordlists/english.js"
"require": "./bip39/wordlists/english.js"
},
"./bip39/wordlists/french": {
"types": "./bip39/wordlists/french.d.ts",
"import": "./esm/bip39/wordlists/french.js",
"default": "./bip39/wordlists/french.js"
"require": "./bip39/wordlists/french.js"
},
"./bip39/wordlists/italian": {
"types": "./bip39/wordlists/italian.d.ts",
"import": "./esm/bip39/wordlists/italian.js",
"default": "./bip39/wordlists/italian.js"
"require": "./bip39/wordlists/italian.js"
},
"./bip39/wordlists/japanese": {
"types": "./bip39/wordlists/japanese.d.ts",
"import": "./esm/bip39/wordlists/japanese.js",
"default": "./bip39/wordlists/japanese.js"
"require": "./bip39/wordlists/japanese.js"
},
"./bip39/wordlists/korean": {
"types": "./bip39/wordlists/korean.d.ts",
"import": "./esm/bip39/wordlists/korean.js",
"default": "./bip39/wordlists/korean.js"
"require": "./bip39/wordlists/korean.js"
},
"./bip39/wordlists/portuguese": {
"types": "./bip39/wordlists/portuguese.d.ts",
"import": "./esm/bip39/wordlists/portuguese.js",
"default": "./bip39/wordlists/portuguese.js"
"require": "./bip39/wordlists/portuguese.js"
},
"./bip39/wordlists/simplified-chinese": {
"types": "./bip39/wordlists/simplified-chinese.d.ts",
"import": "./esm/bip39/wordlists/simplified-chinese.js",
"default": "./bip39/wordlists/simplified-chinese.js"
"require": "./bip39/wordlists/simplified-chinese.js"
},
"./bip39/wordlists/spanish": {
"types": "./bip39/wordlists/spanish.d.ts",
"import": "./esm/bip39/wordlists/spanish.js",
"default": "./bip39/wordlists/spanish.js"
"require": "./bip39/wordlists/spanish.js"
},
"./bip39/wordlists/traditional-chinese": {
"types": "./bip39/wordlists/traditional-chinese.d.ts",
"import": "./esm/bip39/wordlists/traditional-chinese.js",
"default": "./bip39/wordlists/traditional-chinese.js"
"require": "./bip39/wordlists/traditional-chinese.js"
},
"./aes.js": {
"types": "./aes.d.ts",
"import": "./esm/aes.js",
"default": "./aes.js"
"require": "./aes.js"
},
"./bip39.js": {
"types": "./bip39/index.d.ts",
"import": "./esm/bip39/index.js",
"default": "./bip39/index.js"
"require": "./bip39/index.js"
},
"./blake2b.js": {
"types": "./blake2b.d.ts",
"import": "./esm/blake2b.js",
"default": "./blake2b.js"
"require": "./blake2b.js"
},
"./bls.js": {
"import": "./esm/bls.js",
"require": "./bls.js"
},
"./bn.js": {
"import": "./esm/bn.js",
"require": "./bn.js"
},
"./hdkey.js": {
"types": "./hdkey.d.ts",
"import": "./esm/hdkey.js",
"default": "./hdkey.js"
"require": "./hdkey.js"
},
"./index.js": {
"types": "./index.d.ts",
"import": "./esm/index.js",
"default": "./index.js"
"require": "./index.js"
},
"./math.js": {
"import": "./esm/math.js",
"require": "./math.js"
},
"./keccak.js": {
"types": "./keccak.d.ts",
"import": "./esm/keccak.js",
"default": "./keccak.js"
"require": "./keccak.js"
},
"./pbkdf2.js": {
"types": "./pbkdf2.d.ts",
"import": "./esm/pbkdf2.js",
"default": "./pbkdf2.js"
"require": "./pbkdf2.js"
},
"./random.js": {
"types": "./random.d.ts",
"import": "./esm/random.js",
"default": "./random.js"
"require": "./random.js"
},
"./ripemd160.js": {
"types": "./ripemd160.d.ts",
"import": "./esm/ripemd160.js",
"default": "./ripemd160.js"
"require": "./ripemd160.js"
},
"./scrypt.js": {
"types": "./scrypt.d.ts",
"import": "./esm/scrypt.js",
"default": "./scrypt.js"
"require": "./scrypt.js"
},
"./secp256k1-compat.js": {
"types": "./secp256k1-compat.d.ts",
"import": "./esm/secp256k1-compat.js",
"default": "./secp256k1-compat.js"
"require": "./secp256k1-compat.js"
},
"./secp256k1.js": {
"types": "./secp256k1.d.ts",
"import": "./esm/secp256k1.js",
"default": "./secp256k1.js"
"require": "./secp256k1.js"
},
"./sha256.js": {
"types": "./sha256.d.ts",
"import": "./esm/sha256.js",
"default": "./sha256.js"
"require": "./sha256.js"
},
"./sha512.js": {
"types": "./sha512.d.ts",
"import": "./esm/sha512.js",
"default": "./sha512.js"
"require": "./sha512.js"
},
"./utils.js": {
"types": "./utils.d.ts",
"import": "./esm/utils.js",
"default": "./utils.js"
"require": "./utils.js"
},
"./bip39/index.js": {
"types": "./bip39/index.d.ts",
"import": "./esm/bip39/index.js",
"default": "./bip39/index.js"
"require": "./bip39/index.js"
},
"./bip39/wordlists/czech.js": {
"types": "./bip39/wordlists/czech.d.ts",
"import": "./esm/bip39/wordlists/czech.js",
"default": "./bip39/wordlists/czech.js"
"require": "./bip39/wordlists/czech.js"
},
"./bip39/wordlists/english.js": {
"types": "./bip39/wordlists/english.d.ts",
"import": "./esm/bip39/wordlists/english.js",
"default": "./bip39/wordlists/english.js"
"require": "./bip39/wordlists/english.js"
},
"./bip39/wordlists/french.js": {
"types": "./bip39/wordlists/french.d.ts",
"import": "./esm/bip39/wordlists/french.js",
"default": "./bip39/wordlists/french.js"
"require": "./bip39/wordlists/french.js"
},
"./bip39/wordlists/italian.js": {
"types": "./bip39/wordlists/italian.d.ts",
"import": "./esm/bip39/wordlists/italian.js",
"default": "./bip39/wordlists/italian.js"
"require": "./bip39/wordlists/italian.js"
},
"./bip39/wordlists/japanese.js": {
"types": "./bip39/wordlists/japanese.d.ts",
"import": "./esm/bip39/wordlists/japanese.js",
"default": "./bip39/wordlists/japanese.js"
"require": "./bip39/wordlists/japanese.js"
},
"./bip39/wordlists/korean.js": {
"types": "./bip39/wordlists/korean.d.ts",
"import": "./esm/bip39/wordlists/korean.js",
"default": "./bip39/wordlists/korean.js"
"require": "./bip39/wordlists/korean.js"
},
"./bip39/wordlists/simplified-chinese.js": {
"types": "./bip39/wordlists/simplified-chinese.d.ts",
"import": "./esm/bip39/wordlists/simplified-chinese.js",
"default": "./bip39/wordlists/simplified-chinese.js"
"require": "./bip39/wordlists/simplified-chinese.js"
},
"./bip39/wordlists/spanish.js": {
"types": "./bip39/wordlists/spanish.d.ts",
"import": "./esm/bip39/wordlists/spanish.js",
"default": "./bip39/wordlists/spanish.js"
"require": "./bip39/wordlists/spanish.js"
},
"./bip39/wordlists/traditional-chinese.js": {
"types": "./bip39/wordlists/traditional-chinese.d.ts",
"import": "./esm/bip39/wordlists/traditional-chinese.js",
"default": "./bip39/wordlists/traditional-chinese.js"
"require": "./bip39/wordlists/traditional-chinese.js"
}

@@ -297,3 +274,3 @@ },

"test:node": "cd test && npm install && cd .. && mocha",
"clean": "rimraf test/test-builds bip39 '*.js' '*.js.map' '*.d.ts' '*.d.ts.map' 'src/**/*.js'",
"clean": "rm -rf test/test-builds bip39 *.js *.js.map *.d.ts *.d.ts.map src/**/*.js",
"lint": "eslint",

@@ -310,27 +287,20 @@ "lint:fix": "eslint --fix",

"devDependencies": {
"@rollup/plugin-commonjs": "22.0.1",
"@rollup/plugin-node-resolve": "13.3.0",
"@types/estree": "1.0.0",
"@types/mocha": "9.1.1",
"@types/mocha": "10.0.7",
"@types/node": "18.15.11",
"@typescript-eslint/eslint-plugin": "5.30.6",
"@typescript-eslint/parser": "5.30.6",
"browserify": "17.0.0",
"eslint": "8.38.0",
"eslint-plugin-prettier": "4.2.1",
"karma": "6.4.0",
"karma": "6.4.4",
"karma-chrome-launcher": "3.1.1",
"karma-mocha": "2.0.1",
"karma-mocha-reporter": "2.2.5",
"mocha": "10.0.0",
"mocha": "10.7.3",
"npm-run-all": "4.1.5",
"parcel": "2.6.2",
"prettier": "2.7.1",
"rimraf": "~3.0.2",
"rollup": "2.76.0",
"ts-node": "10.9.1",
"typescript": "5.5.2",
"webpack": "5.76.0",
"webpack-cli": "4.10.0"
"typescript": "5.5.4"
},
"packageManager": "npm@9.9.3",
"keywords": [

@@ -337,0 +307,0 @@ "ethereum",

# ethereum-cryptography
[![npm version][1]][2] [![license][3]][4]
[Audited](#security) pure JS library containing all Ethereum-related cryptographic primitives. Implemented with 6 [noble & scure](https://paulmillr.com/noble/) dependencies.
[Audited](#security) pure JS library containing all Ethereum-related cryptographic primitives.
Included algorithms, implemented with just 5 [noble & scure](https://paulmillr.com/noble/) dependencies:
* [Hashes: SHA256, keccak-256, RIPEMD160, BLAKE2b](#hashes-sha256-keccak-256-ripemd160-blake2b)
* [KDFs: PBKDF2, Scrypt](#kdfs-pbkdf2-scrypt)
* [CSPRNG (Cryptographically Secure Pseudorandom Number Generator)](#csprng-cryptographically-strong-pseudorandom-number-generator)
* [secp256k1 elliptic curve](#secp256k1-curve)
* [BIP32 HD Keygen](#bip32-hd-keygen)
* [BIP39 Mnemonic phrases](#bip39-mnemonic-seed-phrase)
* [AES Encryption](#aes-encryption)
**April 2023 update:** v2.0 is out, switching
[noble-secp256k1](https://github.com/paulmillr/noble-secp256k1) to
[noble-curves](https://github.com/paulmillr/noble-curves),
which changes re-exported api of `secp256k1` submodule.
There have been no other changes.
**January 2022 update:** v1.0 has been released. We've rewritten the library from
scratch and [audited](#security) it. It became **6x smaller:** ~5,000 lines of
code 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.
Check out [Upgrading](#upgrading) section and an article about the library:
Check out [Changelog / Upgrading](#upgrading) and an article about the library:
[A safer, smaller, and faster Ethereum cryptography stack](https://medium.com/nomic-labs-blog/a-safer-smaller-and-faster-ethereum-cryptography-stack-5eeb47f62d79).

@@ -33,70 +10,58 @@

Use NPM / Yarn in node.js / browser:
> npm install ethereum-cryptography
```bash
# NPM
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 to `engines` field of `package.json` for runtime support information for each version.
Tests are being ran with Webpack, Rollup, Parcel and Browserify.
# Yarn
yarn add ethereum-cryptography
```
See [browser usage](#browser-usage) for information on using the package with major Javascript bundlers. It is
tested with **Webpack, Rollup, Parcel and Browserify**.
This package has no single entry-point, but submodule for each cryptographic
primitive. Read each primitive's section of this document to learn how to use
them.
primitive. 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 be
avoided through tree-shaking, but the possibility of it not working properly
on one of [the supported bundlers](#browser-usage) is too high.
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 be avoided through
tree-shaking, but the possibility of it not working properly on one of
[the supported bundlers](#browser-usage) is too high.
* [Usage](#usage)
* [Dependencies](#dependencies)
* [hashes: sha256, sha512, keccak, ripemd160, blake2b](#hashes-sha256-sha512-keccak-ripemd160-blake2b)
* [kdfs: pbkdf2, scrypt](#kdfs-pbkdf2-scrypt)
* [random: secure randomness](#random-secure-randomness)
* [secp256k1: curve operations](#secp256k1-curve-operations)
* [bn: pairing-friendly curve](#bn-pairing-friendly-curve)
* [bls: pairing-friendly curve](#bls-pairing-friendly-curve)
* [aes: encryption](#aes-encryption)
* [hdkey: bip32 HD wallets](#hdkey-bip32-hd-wallets)
* [bip39: mnemonic phrases](#bip39-mnemonic-phrases)
* [math: utilities](#math-utilities)
* [utils: generic utilities](#utils-generic-utilities)
* [secp256k1-compat: compatibility layer with other libraries](#secp256k1-compat-compatibility-layer-with-other-libraries)
* [All imports](#all-imports)
* [Caveats](#caveats)
* [Browser usage: Rollup setup](#browser-usage-rollup-setup)
* [AES](#aes)
* [Encrypting with passwords](#encrypting-with-passwords)
* [Operation modes](#operation-modes)
* [Padding plaintext messages](#padding-plaintext-messages)
* [How to use the IV parameter](#how-to-use-the-iv-parameter)
* [How to handle errors with this module](#how-to-handle-errors-with-this-module)
* [Upgrading](#upgrading)
* [Changelog](#changelog)
* [From v2 to v3](#from-v2-to-v3)
* [From v1 to v2](#from-v1-to-v2)
* [From v0.1 to v1](#from-v01-to-v1)
* [Security](#security)
* [License](#license)
```js
// Hashes
import { sha256 } from "ethereum-cryptography/sha256.js";
import { keccak256 } from "ethereum-cryptography/keccak.js";
import { ripemd160 } from "ethereum-cryptography/ripemd160.js";
import { blake2b } from "ethereum-cryptography/blake2b.js";
### Dependencies
// KDFs
import { pbkdf2Sync } from "ethereum-cryptography/pbkdf2.js";
import { scryptSync } from "ethereum-cryptography/scrypt.js";
All functionality of the module is simple
re-export of 6 audited [noble & scure libraries](https://paulmillr.com/noble/):
// Random
import { getRandomBytesSync } from "ethereum-cryptography/random.js";
- noble-curves, noble-ciphers, noble-hashes
- scure-base, scure-bip32, scure-bip39
// AES encryption
import { encrypt } from "ethereum-cryptography/aes.js";
ethereum-cryptography pins versions of the libraries to ensure good
protection against supply chain attacks. Ideally, your app would also
pin version of ethereum-cryptography. That means, no `^3.0.0` - use `3.0.0` instead.
// secp256k1 elliptic curve operations
import { secp256k1 } from "ethereum-cryptography/secp256k1.js";
### hashes: sha256, sha512, keccak, ripemd160, blake2b
// BIP32 HD Keygen, BIP39 Mnemonic Phrases
import { HDKey } from "ethereum-cryptography/hdkey.js";
import { generateMnemonic } from "ethereum-cryptography/bip39/index.js";
import { wordlist } from "ethereum-cryptography/bip39/wordlists/english.js";
// utilities
import { hexToBytes, toHex, utf8ToBytes } from "ethereum-cryptography/utils.js";
```
## Hashes: SHA256, keccak-256, RIPEMD160, BLAKE2b
```typescript
function sha256(msg: Uint8Array): Uint8Array;
function sha512(msg: Uint8Array): Uint8Array;
function keccak256(msg: Uint8Array): Uint8Array;
function ripemd160(msg: Uint8Array): Uint8Array;
function blake2b(msg: Uint8Array, outputLength = 64): Uint8Array;
```
Exposes following cryptographic hash functions:
- SHA2 (SHA256, SHA512)
- keccak-256 variant of SHA3 (also `keccak224`, `keccak384`,
and `keccak512`)
- RIPEMD160
- BLAKE2b
```js

@@ -108,21 +73,30 @@ import { sha256 } from "ethereum-cryptography/sha256.js";

import { blake2b } from "ethereum-cryptography/blake2b.js";
sha256(Uint8Array.from([1, 2, 3])) // A: buffers
sha256(Uint8Array.from([1, 2, 3]))
// Can be used with strings
import { utf8ToBytes } from "ethereum-cryptography/utils.js";
sha256(utf8ToBytes("abc"))
sha256(utf8ToBytes("abc")) // B: strings
// If you need hex
import { bytesToHex as toHex } from "ethereum-cryptography/utils.js";
toHex(sha256(utf8ToBytes("abc")))
toHex(sha256(utf8ToBytes("abc"))) // C: hex
```
## KDFs: PBKDF2, Scrypt
### kdfs: pbkdf2, scrypt
```ts
function pbkdf2(password: Uint8Array, salt: Uint8Array, iterations: number, keylen: number, digest: string): Promise<Uint8Array>;
function pbkdf2Sync(password: Uint8Array, salt: Uint8Array, iterations: number, keylen: number, digest: string): Uint8Array;
function scrypt(password: Uint8Array, salt: Uint8Array, N: number, p: number, r: number, dkLen: number, onProgress?: (progress: number) => void): Promise<Uint8Array>;
function scryptSync(password: Uint8Array, salt: Uint8Array, N: number, p: number, r: number, dkLen: number, onProgress?: (progress: number) => void)): Uint8Array;
```js
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 Uint8Array
const pass = utf8ToBytes("password")
const salt = utf8ToBytes("salt")
const iters = 131072;
const outLength = 32;
console.log(await pbkdf2(pass, salt, iters, outLength, "sha256"));
const N = 262144;
const r = 8;
const p = 1;
const outLengths = 32;
console.log(await scrypt(pass, salt, N, r, p, outLengths));
```

@@ -141,76 +115,108 @@

Encoding passwords is a frequent source of errors. Please read
[these notes](https://github.com/ricmoo/scrypt-js/tree/0eb70873ddf3d24e34b53e0d9a99a0cef06a79c0#encoding-notes)
[notes](https://github.com/ricmoo/scrypt-js/tree/0eb70873ddf3d24e34b53e0d9a99a0cef06a79c0#encoding-notes)
before using these submodules.
### random: secure randomness
```js
import { pbkdf2 } from "ethereum-cryptography/pbkdf2.js";
import { utf8ToBytes } from "ethereum-cryptography/utils.js";
// Pass Uint8Array, or convert strings to Uint8Array
console.log(await pbkdf2(utf8ToBytes("password"), utf8ToBytes("salt"), 131072, 32, "sha256"));
import { getRandomBytesSync } from "ethereum-cryptography/random.js";
console.log(getRandomBytesSync(32));
```
The `random` submodule has functions to generate cryptographically strong
pseudo-random data in synchronous and asynchronous ways. Backed by [`crypto.getRandomValues`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) in browser and by [`crypto.randomBytes`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback) 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
```js
import { scrypt } from "ethereum-cryptography/scrypt.js";
import { utf8ToBytes } from "ethereum-cryptography/utils.js";
console.log(await scrypt(utf8ToBytes("password"), utf8ToBytes("salt"), 262144, 8, 1, 32));
import { secp256k1 } from "ethereum-cryptography/secp256k1.js";
// You pass either a hex string, or Uint8Array
const privateKey = "6b911fd37cdf5c81d4c0adb1ab7fa822ed253ab0ad9aa18d77257c88b29b718e";
const messageHash = "a33321f98e4ff1c283c76998f14f57447545d339b3db534c6d886decb4209f28";
const publicKey = secp256k1.getPublicKey(privateKey);
const signature = secp256k1.sign(messageHash, privateKey);
const isSigned = secp256k1.verify(signature, messageHash, publicKey);
```
## CSPRNG (Cryptographically strong pseudorandom number generator)
Elliptic curve operations on the curve secp256k1. Check out [noble-curves docs](https://github.com/paulmillr/noble-curves) for more info.
```ts
function getRandomBytes(bytes: number): Promise<Uint8Array>;
function getRandomBytesSync(bytes: number): Uint8Array;
secp256k1 private keys need to be cryptographically secure random numbers with
certain characteristics. If this is not the case, the security of secp256k1 is
compromised.
### bn: pairing-friendly curve
```js
import { bn } from "ethereum-cryptography/bls.js";
console.log(
bn254.G1,
bn254.G2,
bn254.pairing
)
```
The `random` submodule has functions to generate cryptographically strong
pseudo-random data in synchronous and asynchronous ways.
For example usage, check out [the implementation of bn254 EVM precompiles](https://github.com/paulmillr/noble-curves/blob/3ed792f8ad9932765b84d1064afea8663a255457/test/bn254.test.js#L697).
Backed by [`crypto.getRandomValues`](https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues) in browser and by [`crypto.randomBytes`](https://nodejs.org/api/crypto.html#crypto_crypto_randombytes_size_callback) 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.
### bls: pairing-friendly curve
```js
import { getRandomBytesSync } from "ethereum-cryptography/random.js";
console.log(getRandomBytesSync(32));
```
import { bls12_381 as bls } from "ethereum-cryptography/bls.js";
## secp256k1 curve
// G1 keys, G2 signatures
const privateKey = '67d53f170b908cabb9eb326c3c337762d59289a8fec79f7bc9254b584b73265c';
const message = '64726e3da8';
const publicKey = bls.getPublicKey(privateKey);
const signature = bls.sign(message, privateKey);
const isValid = bls.verify(signature, message, publicKey);
console.log({ publicKey, signature, isValid });
```ts
function getPublicKey(privateKey: Uint8Array, isCompressed = true): Uint8Array;
function sign(msgHash: Uint8Array, privateKey: Uint8Array): { r: bigint; s: bigint; recovery: number };
function verify(signature: Uint8Array, msgHash: Uint8Array, publicKey: Uint8Array): boolean
function getSharedSecret(privateKeyA: Uint8Array, publicKeyB: Uint8Array): Uint8Array;
function utils.randomPrivateKey(): Uint8Array;
```
// G2 signatures, G1 keys
// getPublicKeyForShortSignatures(privateKey)
// signShortSignature(message, privateKey)
// verifyShortSignature(signature, message, publicKey)
// aggregateShortSignatures(signatures)
The `secp256k1` submodule provides a library for elliptic curve operations on
the curve secp256k1. For detailed documentation, follow [README of `noble-curves`](https://github.com/paulmillr/noble-curves), which the module uses as a backend.
// Custom DST
const htfEthereum = { DST: 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_' };
const signatureEth = bls.sign(message, privateKey, htfEthereum);
const isValidEth = bls.verify(signature, message, publicKey, htfEthereum);
secp256k1 private keys need to be cryptographically secure random numbers with
certain characteristics. If this is not the case, the security of secp256k1 is
compromised. We strongly recommend using `utils.randomPrivateKey()` to generate them.
// Aggregation
const aggregatedKey = bls.aggregatePublicKeys([bls.utils.randomPrivateKey(), bls.utils.randomPrivateKey()])
// const aggregatedSig = bls.aggregateSignatures(sigs)
```js
import { secp256k1 } from "ethereum-cryptography/secp256k1.js";
(async () => {
// You pass either a hex string, or Uint8Array
const privateKey = "6b911fd37cdf5c81d4c0adb1ab7fa822ed253ab0ad9aa18d77257c88b29b718e";
const messageHash = "a33321f98e4ff1c283c76998f14f57447545d339b3db534c6d886decb4209f28";
const publicKey = secp256k1.getPublicKey(privateKey);
const signature = secp256k1.sign(messageHash, privateKey);
const isSigned = secp256k1.verify(signature, messageHash, publicKey);
})();
// 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;
```
We're also providing a compatibility layer for users who want to upgrade
from `tiny-secp256k1` or `secp256k1` modules without hassle.
Check out [secp256k1 compatibility layer](#legacy-secp256k1-compatibility-layer).
For example usage, check out [the implementation of BLS EVM precompiles](https://github.com/ethereumjs/ethereumjs-monorepo/blob/361f4edbc239e795a411ac2da7e5567298b9e7e5/packages/evm/src/precompiles/bls12_381/noble.ts).
## BIP32 HD Keygen
### aes: encryption
Hierarchical deterministic (HD) wallets that conform to BIP32 standard.
Also available as standalone package [scure-bip32](https://github.com/paulmillr/scure-bip32).
```js
import * as aes from "ethereum-cryptography/aes.js";
import { hexToBytes, utf8ToBytes } from "ethereum-cryptography/utils.js";
This module exports a single class `HDKey`, which should be used like this:
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;
```
```ts
### hdkey: bip32 HD wallets
```js
import { HDKey } from "ethereum-cryptography/hdkey.js";

@@ -229,102 +235,130 @@ const hdkey1 = HDKey.fromMasterSeed(seed);

Note: `chainCode` property is essentially a private part
of a secret "master" key, it should be guarded from unauthorized access.
Hierarchical deterministic (HD) wallets that conform to
[BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki).
The full API is:
### bip39: mnemonic phrases
```ts
class HDKey {
public static HARDENED_OFFSET: number;
public static fromMasterSeed(seed: Uint8Array, versions: Versions): HDKey;
public static fromExtendedKey(base58key: string, versions: Versions): HDKey;
public static fromJSON(json: { xpriv: string }): HDKey;
```js
import * as bip39 from "ethereum-cryptography/bip39/index.js";
import { wordlist } from "ethereum-cryptography/bip39/wordlists/english.js";
readonly versions: Versions;
readonly depth: number = 0;
readonly index: number = 0;
readonly chainCode: Uint8Array | null = null;
readonly parentFingerprint: number = 0;
// 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";
get fingerprint(): number;
get identifier(): Uint8Array | undefined;
get pubKeyHash(): Uint8Array | undefined;
get privateKey(): Uint8Array | null;
get publicKey(): Uint8Array | null;
get privateExtendedKey(): string;
get publicExtendedKey(): string;
// Generate x random words. Uses Cryptographically-Secure Random Number Generator.
const mn = bip39.generateMnemonic(wordlist);
console.log(mn);
derive(path: string): HDKey;
deriveChild(index: number): HDKey;
sign(hash: Uint8Array): Uint8Array;
verify(hash: Uint8Array, signature: Uint8Array): boolean;
wipePrivateData(): this;
}
// Reversible: Converts mnemonic string to raw entropy in form of byte array.
const ent = bip39.mnemonicToEntropy(mn, wordlist)
interface Versions {
private: number;
public: number;
}
// 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.
await bip39.mnemonicToSeed(mn, 'password');
bip39.mnemonicToSeedSync(mn, 'password');
```
The `hdkey` submodule provides a library for keys derivation according to
[BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki).
The `bip39` submodule provides functions to generate, validate and use seed
recovery phrases according to [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki).
It has almost the exact same API than the version `1.x` of
[`hdkey` from cryptocoinjs](https://github.com/cryptocoinjs/hdkey),
but it's backed by this package's primitives, and has built-in TypeScript types.
Its only difference is that it has to be used with a named import.
The implementation is [loosely based on hdkey, which has MIT License](#LICENSE).
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.
## BIP39 Mnemonic Seed Phrase
### math: utilities
```ts
function generateMnemonic(wordlist: string[], strength: number = 128): string;
function mnemonicToEntropy(mnemonic: string, wordlist: string[]): Uint8Array;
function entropyToMnemonic(entropy: Uint8Array, wordlist: string[]): string;
function validateMnemonic(mnemonic: string, wordlist: string[]): boolean;
async function mnemonicToSeed(mnemonic: string, passphrase: string = ""): Promise<Uint8Array>;
function mnemonicToSeedSync(mnemonic: string, passphrase: string = ""): Uint8Array;
```js
import { modPow, modInvert } from "ethereum-cryptography/math.js";
modPow(123n, 456n, 789n);
modInvert(22n, 5n);
```
The `bip39` submodule provides functions to generate, validate and use seed
recovery phrases according to [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki).
### utils: generic utilities
Also available as standalone package [scure-bip39](https://github.com/paulmillr/scure-bip39).
```js
import { hexToBytes, toHex, utf8ToBytes } from "ethereum-cryptography/utils.js";
```
### secp256k1-compat: compatibility layer with other libraries
```js
import { createPrivateKeySync, ecdsaSign } from "ethereum-cryptography/secp256k1-compat";
const msgHash = Uint8Array.from(
"82ff40c0a986c6a5cfad4ddf4c3aa6996f1a7837f9c398e17e5de5cbd5a12b28",
"hex"
);
const privateKey = createPrivateKeySync();
console.log(Uint8Array.from(ecdsaSign(msgHash, privateKey).signature));
```
**Warning:** use `secp256k1` instead. This module is only for users who upgraded
from ethereum-cryptography v0.1. It could be removed in the future.
The API of `secp256k1-compat` is the same as [secp256k1-node](https://github.com/cryptocoinjs/secp256k1-node):
### All imports
```js
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";
console.log(generateMnemonic(wordlist));
import { modPow, modInvert } from "ethereum-cryptography/math.js";
import { hexToBytes, toHex, utf8ToBytes } from "ethereum-cryptography/utils.js";
```
This submodule also contains the word lists defined by BIP39 for Czech, English,
French, Italian, Japanese, Korean, Simplified and Traditional Chinese, and
Spanish. These are not imported by default, as that would increase bundle sizes
too much. Instead, you should import and use them explicitly.
## Caveats
The word lists are exported as a `wordlist` variable in each of these submodules:
### Browser usage: Rollup setup
* `ethereum-cryptography/bip39/wordlists/czech.js`
* `ethereum-cryptography/bip39/wordlists/english.js`
* `ethereum-cryptography/bip39/wordlists/french.js`
* `ethereum-cryptography/bip39/wordlists/italian.js`
* `ethereum-cryptography/bip39/wordlists/japanese.js`
* `ethereum-cryptography/bip39/wordlists/korean.js`
* `ethereum-cryptography/bip39/wordlists/portuguese.js`
* `ethereum-cryptography/bip39/wordlists/simplified-chinese.js`
* `ethereum-cryptography/bip39/wordlists/spanish.js`
* `ethereum-cryptography/bip39/wordlists/traditional-chinese.js`
Using this library with Rollup requires the following plugins:
## AES Encryption
* [`@rollup/plugin-commonjs`](https://www.npmjs.com/package/@rollup/plugin-commonjs)
* [`@rollup/plugin-node-resolve`](https://www.npmjs.com/package/@rollup/plugin-node-resolve)
```ts
function encrypt(msg: Uint8Array, key: Uint8Array, iv: Uint8Array, mode = "aes-128-ctr", pkcs7PaddingEnabled = true): Promise<Uint8Array>;
function decrypt(cypherText: Uint8Array, key: Uint8Array, iv: Uint8Array, mode = "aes-128-ctr", pkcs7PaddingEnabled = true): Promise<Uint8Array>;
These can be used by setting your `plugins` array like this:
```js
plugins: [
commonjs(),
resolve({
browser: true,
preferBuiltins: false,
}),
]
```
The `aes` submodule contains encryption and decryption functions implementing
the [Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)
algorithm.
### AES
### Encrypting with passwords
#### Encrypting with passwords

@@ -339,3 +373,3 @@ AES is not supposed to be used directly with a password. Doing that will

### Operation modes
#### Operation modes

@@ -352,3 +386,3 @@ This submodule works with different [block cipher modes of operation](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation). If you are using this module in a new

### Padding plaintext messages
#### Padding plaintext messages

@@ -372,3 +406,3 @@ Some operation modes require the plaintext message to be a multiple of `16`. If

### How to use the IV parameter
#### How to use the IV parameter

@@ -383,3 +417,3 @@ The `iv` parameter of the `encrypt` function must be unique, or the security

### How to handle errors with this module
#### How to handle errors with this module

@@ -395,72 +429,25 @@ Sensitive information can be leaked via error messages when using this module.

### Example usage
## Upgrading
```js
import { encrypt } from "ethereum-cryptography/aes.js";
import { hexToBytes, utf8ToBytes } from "ethereum-cryptography/utils.js";
### Changelog
console.log(
encrypt(
utf8ToBytes("message"),
hexToBytes("2b7e151628aed2a6abf7158809cf4f3c"),
hexToBytes("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
)
);
```
* v3.0 (Sep 2024): new modules `bls`, `bn`, `math`
change async AES to non-native sync,
improve typescript compatibility, new dependency [noble-ciphers](https://github.com/paulmillr/noble-ciphers)
* v2.0 (Apr 2023): switched
[noble-secp256k1](https://github.com/paulmillr/noble-secp256k1) to
[noble-curves](https://github.com/paulmillr/noble-curves),
which changes re-exported api of `secp256k1` submodule.
* v1.0 (Jan 2022): rewritten the library from
scratch and [audited](#security) it. It became **6x smaller:** ~5,000 lines of
code 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.
## Browser usage
### From v2 to v3
### Rollup setup
1. utils: `crypto` var had been removed
2. aes: async methods became sync
Using this library with Rollup requires the following plugins:
### From v1 to v2
* [`@rollup/plugin-commonjs`](https://www.npmjs.com/package/@rollup/plugin-commonjs)
* [`@rollup/plugin-node-resolve`](https://www.npmjs.com/package/@rollup/plugin-node-resolve)
These can be used by setting your `plugins` array like this:
```js
plugins: [
commonjs(),
resolve({
browser: true,
preferBuiltins: false,
}),
]
```
## Legacy secp256k1 compatibility layer
**Warning:** use `secp256k1` instead. This module is only for users who upgraded
from ethereum-cryptography v0.1. It could be removed in the future.
The API of `secp256k1-compat` is the same as [secp256k1-node](https://github.com/cryptocoinjs/secp256k1-node):
```js
import { createPrivateKeySync, ecdsaSign } from "ethereum-cryptography/secp256k1-compat";
const msgHash = Uint8Array.from(
"82ff40c0a986c6a5cfad4ddf4c3aa6996f1a7837f9c398e17e5de5cbd5a12b28",
"hex"
);
const privateKey = createPrivateKeySync();
console.log(Uint8Array.from(ecdsaSign(msgHash, privateKey).signature));
```
## Missing cryptographic primitives
This package intentionally excludes the cryptographic primitives necessary
to implement the following EIPs:
* [EIP 196: Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128](https://eips.ethereum.org/EIPS/eip-196)
* [EIP 197: Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128](https://eips.ethereum.org/EIPS/eip-197)
* [EIP 198: Big integer modular exponentiation](https://eips.ethereum.org/EIPS/eip-198)
* [EIP 152: Add Blake2 compression function `F` precompile](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md)
Feel free to open an issue if you want this decision to be reconsidered, or if
you found another primitive that is missing.
## Upgrading
Upgrading from 1.0 to 2.0:
1. `secp256k1` module was changed massively:

@@ -474,4 +461,6 @@ before, it was using [noble-secp256k1 1.7](https://github.com/paulmillr/noble-secp256k1);

Upgrading from 0.1 to 1.0: **Same functionality**, all old APIs remain the same except for the breaking changes:
### From v0.1 to v1
All old APIs remain the same except for the breaking changes:
1. We return `Uint8Array` from all methods that worked with `Buffer` before.

@@ -503,2 +492,4 @@ `Buffer` has never been supported in browsers, while `Uint8Array`s are supported natively in both

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

@@ -517,5 +508,3 @@

[1]: https://img.shields.io/npm/v/ethereum-cryptography.svg
[2]: https://www.npmjs.com/package/ethereum-cryptography
[3]: https://img.shields.io/npm/l/ethereum-cryptography
[4]: https://github.com/ethereum/js-ethereum-cryptography/blob/master/packages/ethereum-cryptography/LICENSE
[1]: https://www.npmjs.com/package/ethereum-cryptography
[2]: https://github.com/ethereum/js-ethereum-cryptography/blob/master/packages/ethereum-cryptography/LICENSE

@@ -9,5 +9,1 @@ declare const assertBool: typeof import("@noble/hashes/_assert").bool;

export declare function wrapHash(hash: (msg: Uint8Array) => Uint8Array): (msg: Uint8Array) => Uint8Array;
export declare const crypto: {
node?: any;
web?: any;
};

@@ -6,3 +6,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.crypto = exports.utf8ToBytes = exports.createView = exports.concatBytes = exports.toHex = exports.bytesToHex = exports.assertBytes = exports.assertBool = void 0;
exports.utf8ToBytes = exports.createView = exports.concatBytes = exports.toHex = exports.bytesToHex = exports.assertBytes = exports.assertBool = void 0;
exports.bytesToUtf8 = bytesToUtf8;

@@ -54,12 +54,1 @@ exports.hexToBytes = hexToBytes;

}
// TODO(v3): switch away from node crypto, remove this unnecessary variable.
exports.crypto = (() => {
const webCrypto = typeof globalThis === "object" && "crypto" in globalThis ? globalThis.crypto : undefined;
const nodeRequire = typeof module !== "undefined" &&
typeof module.require === "function" &&
module.require.bind(module);
return {
node: nodeRequire && !webCrypto ? nodeRequire("crypto") : undefined,
web: webCrypto
};
})();
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