ethereum-cryptographyy 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ethereum-cryptographyy might be problematic. Click here for more details.
- package/LICENSE +21 -0
- package/README.md +508 -0
- package/aes.d.ts +2 -0
- package/aes.js +98 -0
- package/bip39/index.d.ts +1 -0
- package/bip39/index.js +10 -0
- package/bip39/wordlists/czech.d.ts +1 -0
- package/bip39/wordlists/czech.js +5 -0
- package/bip39/wordlists/english.d.ts +1 -0
- package/bip39/wordlists/english.js +5 -0
- package/bip39/wordlists/french.d.ts +1 -0
- package/bip39/wordlists/french.js +5 -0
- package/bip39/wordlists/italian.d.ts +1 -0
- package/bip39/wordlists/italian.js +5 -0
- package/bip39/wordlists/japanese.d.ts +1 -0
- package/bip39/wordlists/japanese.js +5 -0
- package/bip39/wordlists/korean.d.ts +1 -0
- package/bip39/wordlists/korean.js +5 -0
- package/bip39/wordlists/simplified-chinese.d.ts +1 -0
- package/bip39/wordlists/simplified-chinese.js +5 -0
- package/bip39/wordlists/spanish.d.ts +1 -0
- package/bip39/wordlists/spanish.js +5 -0
- package/bip39/wordlists/traditional-chinese.d.ts +1 -0
- package/bip39/wordlists/traditional-chinese.js +5 -0
- package/blake2b.d.ts +1 -0
- package/blake2b.js +13 -0
- package/esm/aes.js +93 -0
- package/esm/bip39/index.js +1 -0
- package/esm/bip39/wordlists/czech.js +1 -0
- package/esm/bip39/wordlists/english.js +1 -0
- package/esm/bip39/wordlists/french.js +1 -0
- package/esm/bip39/wordlists/italian.js +1 -0
- package/esm/bip39/wordlists/japanese.js +1 -0
- package/esm/bip39/wordlists/korean.js +1 -0
- package/esm/bip39/wordlists/simplified-chinese.js +1 -0
- package/esm/bip39/wordlists/spanish.js +1 -0
- package/esm/bip39/wordlists/traditional-chinese.js +1 -0
- package/esm/blake2b.js +9 -0
- package/esm/hdkey.js +1 -0
- package/esm/index.js +2 -0
- package/esm/keccak.js +10 -0
- package/esm/package.json +3 -0
- package/esm/pbkdf2.js +26 -0
- package/esm/random.js +7 -0
- package/esm/ripemd160.js +3 -0
- package/esm/scrypt.js +12 -0
- package/esm/secp256k1-compat.js +254 -0
- package/esm/secp256k1.js +1 -0
- package/esm/sha256.js +3 -0
- package/esm/sha512.js +3 -0
- package/esm/utils.js +47 -0
- package/hdkey.d.ts +1 -0
- package/hdkey.js +6 -0
- package/index.d.ts +0 -0
- package/index.js +2 -0
- package/keccak.d.ts +11 -0
- package/keccak.js +13 -0
- package/package.json +365 -0
- package/pbkdf2.d.ts +2 -0
- package/pbkdf2.js +31 -0
- package/random.d.ts +2 -0
- package/random.js +12 -0
- package/ripemd160.d.ts +1 -0
- package/ripemd160.js +6 -0
- package/scrypt.d.ts +4 -0
- package/scrypt.js +17 -0
- package/secp256k1-compat.d.ts +35 -0
- package/secp256k1-compat.js +278 -0
- package/secp256k1.d.ts +1 -0
- package/secp256k1.js +5 -0
- package/sha256.d.ts +1 -0
- package/sha256.js +6 -0
- package/sha512.d.ts +1 -0
- package/sha512.js +6 -0
- package/utils.d.ts +12 -0
- package/utils.js +63 -0
package/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2021 Patricio Palladino, Paul Miller, ethereum-cryptography contributors
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the “Software”), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
package/README.md
ADDED
@@ -0,0 +1,508 @@
|
|
1
|
+
# ethereum-cryptography
|
2
|
+
|
3
|
+
[![npm version][1]][2] [![license][3]][4]
|
4
|
+
|
5
|
+
[Audited](#security) pure JS library containing all Ethereum-related cryptographic primitives.
|
6
|
+
|
7
|
+
Included algorithms, implemented with just 5 [noble & scure](https://paulmillr.com/noble/) dependencies:
|
8
|
+
|
9
|
+
* [Hashes: SHA256, keccak-256, RIPEMD160, BLAKE2b](#hashes-sha256-keccak-256-ripemd160-blake2b)
|
10
|
+
* [KDFs: PBKDF2, Scrypt](#kdfs-pbkdf2-scrypt)
|
11
|
+
* [CSPRNG (Cryptographically Secure Pseudorandom Number Generator)](#csprng-cryptographically-strong-pseudorandom-number-generator)
|
12
|
+
* [secp256k1 elliptic curve](#secp256k1-curve)
|
13
|
+
* [BIP32 HD Keygen](#bip32-hd-keygen)
|
14
|
+
* [BIP39 Mnemonic phrases](#bip39-mnemonic-seed-phrase)
|
15
|
+
* [AES Encryption](#aes-encryption)
|
16
|
+
|
17
|
+
**April 2023 update:** v2.0 is out, switching
|
18
|
+
[noble-secp256k1](https://github.com/paulmillr/noble-secp256k1) to
|
19
|
+
[noble-curves](https://github.com/paulmillr/noble-curves),
|
20
|
+
which changes re-exported api of `secp256k1` submodule.
|
21
|
+
There have been no other changes.
|
22
|
+
|
23
|
+
**January 2022 update:** v1.0 has been released. We've rewritten the library from
|
24
|
+
scratch and [audited](#security) it. It became **6x smaller:** ~5,000 lines of
|
25
|
+
code instead of ~24,000 (with all deps); 650KB instead of 10.2MB.
|
26
|
+
5 dependencies by 1 author are now used, instead of 38 by 5 authors.
|
27
|
+
|
28
|
+
Check out [Upgrading](#upgrading) section and an article about the library:
|
29
|
+
[A safer, smaller, and faster Ethereum cryptography stack](https://medium.com/nomic-labs-blog/a-safer-smaller-and-faster-ethereum-cryptography-stack-5eeb47f62d79).
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
Use NPM / Yarn in node.js / browser:
|
34
|
+
|
35
|
+
```bash
|
36
|
+
# NPM
|
37
|
+
npm install ethereum-cryptography
|
38
|
+
|
39
|
+
# Yarn
|
40
|
+
yarn add ethereum-cryptography
|
41
|
+
```
|
42
|
+
|
43
|
+
See [browser usage](#browser-usage) for information on using the package with major Javascript bundlers. It is
|
44
|
+
tested with **Webpack, Rollup, Parcel and Browserify**.
|
45
|
+
|
46
|
+
This package has no single entry-point, but submodule for each cryptographic
|
47
|
+
primitive. Read each primitive's section of this document to learn how to use
|
48
|
+
them.
|
49
|
+
|
50
|
+
The reason for this is that importing everything from a single file will lead to
|
51
|
+
huge bundles when using this package for the web. This could be avoided through
|
52
|
+
tree-shaking, but the possibility of it not working properly on one of
|
53
|
+
[the supported bundlers](#browser-usage) is too high.
|
54
|
+
|
55
|
+
```js
|
56
|
+
// Hashes
|
57
|
+
import { sha256 } from "ethereum-cryptography/sha256.js";
|
58
|
+
import { keccak256 } from "ethereum-cryptography/keccak.js";
|
59
|
+
import { ripemd160 } from "ethereum-cryptography/ripemd160.js";
|
60
|
+
import { blake2b } from "ethereum-cryptography/blake2b.js";
|
61
|
+
|
62
|
+
// KDFs
|
63
|
+
import { pbkdf2Sync } from "ethereum-cryptography/pbkdf2.js";
|
64
|
+
import { scryptSync } from "ethereum-cryptography/scrypt.js";
|
65
|
+
|
66
|
+
// Random
|
67
|
+
import { getRandomBytesSync } from "ethereum-cryptography/random.js";
|
68
|
+
|
69
|
+
// AES encryption
|
70
|
+
import { encrypt } from "ethereum-cryptography/aes.js";
|
71
|
+
|
72
|
+
// secp256k1 elliptic curve operations
|
73
|
+
import { secp256k1 } from "ethereum-cryptography/secp256k1.js";
|
74
|
+
|
75
|
+
// BIP32 HD Keygen, BIP39 Mnemonic Phrases
|
76
|
+
import { HDKey } from "ethereum-cryptography/hdkey.js";
|
77
|
+
import { generateMnemonic } from "ethereum-cryptography/bip39/index.js";
|
78
|
+
import { wordlist } from "ethereum-cryptography/bip39/wordlists/english.js";
|
79
|
+
|
80
|
+
// utilities
|
81
|
+
import { hexToBytes, toHex, utf8ToBytes } from "ethereum-cryptography/utils.js";
|
82
|
+
```
|
83
|
+
|
84
|
+
## Hashes: SHA256, keccak-256, RIPEMD160, BLAKE2b
|
85
|
+
```typescript
|
86
|
+
function sha256(msg: Uint8Array): Uint8Array;
|
87
|
+
function sha512(msg: Uint8Array): Uint8Array;
|
88
|
+
function keccak256(msg: Uint8Array): Uint8Array;
|
89
|
+
function ripemd160(msg: Uint8Array): Uint8Array;
|
90
|
+
function blake2b(msg: Uint8Array, outputLength = 64): Uint8Array;
|
91
|
+
```
|
92
|
+
|
93
|
+
Exposes following cryptographic hash functions:
|
94
|
+
|
95
|
+
- SHA2 (SHA256, SHA512)
|
96
|
+
- keccak-256 variant of SHA3 (also `keccak224`, `keccak384`,
|
97
|
+
and `keccak512`)
|
98
|
+
- RIPEMD160
|
99
|
+
- BLAKE2b
|
100
|
+
|
101
|
+
```js
|
102
|
+
import { sha256 } from "ethereum-cryptography/sha256.js";
|
103
|
+
import { sha512 } from "ethereum-cryptography/sha512.js";
|
104
|
+
import { keccak256, keccak224, keccak384, keccak512 } from "ethereum-cryptography/keccak.js";
|
105
|
+
import { ripemd160 } from "ethereum-cryptography/ripemd160.js";
|
106
|
+
import { blake2b } from "ethereum-cryptography/blake2b.js";
|
107
|
+
|
108
|
+
sha256(Uint8Array.from([1, 2, 3]))
|
109
|
+
|
110
|
+
// Can be used with strings
|
111
|
+
import { utf8ToBytes } from "ethereum-cryptography/utils.js";
|
112
|
+
sha256(utf8ToBytes("abc"))
|
113
|
+
|
114
|
+
// If you need hex
|
115
|
+
import { bytesToHex as toHex } from "ethereum-cryptography/utils.js";
|
116
|
+
toHex(sha256(utf8ToBytes("abc")))
|
117
|
+
```
|
118
|
+
|
119
|
+
## KDFs: PBKDF2, Scrypt
|
120
|
+
|
121
|
+
```ts
|
122
|
+
function pbkdf2(password: Uint8Array, salt: Uint8Array, iterations: number, keylen: number, digest: string): Promise<Uint8Array>;
|
123
|
+
function pbkdf2Sync(password: Uint8Array, salt: Uint8Array, iterations: number, keylen: number, digest: string): Uint8Array;
|
124
|
+
function scrypt(password: Uint8Array, salt: Uint8Array, N: number, p: number, r: number, dkLen: number, onProgress?: (progress: number) => void): Promise<Uint8Array>;
|
125
|
+
function scryptSync(password: Uint8Array, salt: Uint8Array, N: number, p: number, r: number, dkLen: number, onProgress?: (progress: number) => void)): Uint8Array;
|
126
|
+
```
|
127
|
+
|
128
|
+
The `pbkdf2` submodule has two functions implementing the PBKDF2 key
|
129
|
+
derivation algorithm in synchronous and asynchronous ways. This algorithm is
|
130
|
+
very slow, and using the synchronous version in the browser is not recommended,
|
131
|
+
as it will block its main thread and hang your UI. The KDF supports `sha256` and `sha512` digests.
|
132
|
+
|
133
|
+
The `scrypt` submodule has two functions implementing the Scrypt key
|
134
|
+
derivation algorithm in synchronous and asynchronous ways. This algorithm is
|
135
|
+
very slow, and using the synchronous version in the browser is not recommended,
|
136
|
+
as it will block its main thread and hang your UI.
|
137
|
+
|
138
|
+
Encoding passwords is a frequent source of errors. Please read
|
139
|
+
[these notes](https://github.com/ricmoo/scrypt-js/tree/0eb70873ddf3d24e34b53e0d9a99a0cef06a79c0#encoding-notes)
|
140
|
+
before using these submodules.
|
141
|
+
|
142
|
+
```js
|
143
|
+
import { pbkdf2 } from "ethereum-cryptography/pbkdf2.js";
|
144
|
+
import { utf8ToBytes } from "ethereum-cryptography/utils.js";
|
145
|
+
// Pass Uint8Array, or convert strings to Uint8Array
|
146
|
+
console.log(await pbkdf2(utf8ToBytes("password"), utf8ToBytes("salt"), 131072, 32, "sha256"));
|
147
|
+
```
|
148
|
+
|
149
|
+
```js
|
150
|
+
import { scrypt } from "ethereum-cryptography/scrypt.js";
|
151
|
+
import { utf8ToBytes } from "ethereum-cryptography/utils.js";
|
152
|
+
console.log(await scrypt(utf8ToBytes("password"), utf8ToBytes("salt"), 262144, 8, 1, 32));
|
153
|
+
```
|
154
|
+
|
155
|
+
## CSPRNG (Cryptographically strong pseudorandom number generator)
|
156
|
+
|
157
|
+
```ts
|
158
|
+
function getRandomBytes(bytes: number): Promise<Uint8Array>;
|
159
|
+
function getRandomBytesSync(bytes: number): Uint8Array;
|
160
|
+
```
|
161
|
+
|
162
|
+
The `random` submodule has functions to generate cryptographically strong
|
163
|
+
pseudo-random data in synchronous and asynchronous ways.
|
164
|
+
|
165
|
+
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.
|
166
|
+
|
167
|
+
```js
|
168
|
+
import { getRandomBytesSync } from "ethereum-cryptography/random.js";
|
169
|
+
console.log(getRandomBytesSync(32));
|
170
|
+
```
|
171
|
+
|
172
|
+
## secp256k1 curve
|
173
|
+
|
174
|
+
```ts
|
175
|
+
function getPublicKey(privateKey: Uint8Array, isCompressed = true): Uint8Array;
|
176
|
+
function sign(msgHash: Uint8Array, privateKey: Uint8Array): { r: bigint; s: bigint; recovery: number };
|
177
|
+
function verify(signature: Uint8Array, msgHash: Uint8Array, publicKey: Uint8Array): boolean
|
178
|
+
function getSharedSecret(privateKeyA: Uint8Array, publicKeyB: Uint8Array): Uint8Array;
|
179
|
+
function utils.randomPrivateKey(): Uint8Array;
|
180
|
+
```
|
181
|
+
|
182
|
+
The `secp256k1` submodule provides a library for elliptic curve operations on
|
183
|
+
the curve secp256k1. For detailed documentation, follow [README of `noble-curves`](https://github.com/paulmillr/noble-curves), which the module uses as a backend.
|
184
|
+
|
185
|
+
secp256k1 private keys need to be cryptographically secure random numbers with
|
186
|
+
certain characteristics. If this is not the case, the security of secp256k1 is
|
187
|
+
compromised. We strongly recommend using `utils.randomPrivateKey()` to generate them.
|
188
|
+
|
189
|
+
```js
|
190
|
+
import { secp256k1 } from "ethereum-cryptography/secp256k1.js";
|
191
|
+
(async () => {
|
192
|
+
// You pass either a hex string, or Uint8Array
|
193
|
+
const privateKey = "6b911fd37cdf5c81d4c0adb1ab7fa822ed253ab0ad9aa18d77257c88b29b718e";
|
194
|
+
const messageHash = "a33321f98e4ff1c283c76998f14f57447545d339b3db534c6d886decb4209f28";
|
195
|
+
const publicKey = secp256k1.getPublicKey(privateKey);
|
196
|
+
const signature = secp256k1.sign(messageHash, privateKey);
|
197
|
+
const isSigned = secp256k1.verify(signature, messageHash, publicKey);
|
198
|
+
})();
|
199
|
+
```
|
200
|
+
|
201
|
+
We're also providing a compatibility layer for users who want to upgrade
|
202
|
+
from `tiny-secp256k1` or `secp256k1` modules without hassle.
|
203
|
+
Check out [secp256k1 compatibility layer](#legacy-secp256k1-compatibility-layer).
|
204
|
+
|
205
|
+
## BIP32 HD Keygen
|
206
|
+
|
207
|
+
Hierarchical deterministic (HD) wallets that conform to BIP32 standard.
|
208
|
+
Also available as standalone package [scure-bip32](https://github.com/paulmillr/scure-bip32).
|
209
|
+
|
210
|
+
This module exports a single class `HDKey`, which should be used like this:
|
211
|
+
|
212
|
+
```ts
|
213
|
+
import { HDKey } from "ethereum-cryptography/hdkey.js";
|
214
|
+
const hdkey1 = HDKey.fromMasterSeed(seed);
|
215
|
+
const hdkey2 = HDKey.fromExtendedKey(base58key);
|
216
|
+
const hdkey3 = HDKey.fromJSON({ xpriv: string });
|
217
|
+
|
218
|
+
// props
|
219
|
+
[hdkey1.depth, hdkey1.index, hdkey1.chainCode];
|
220
|
+
console.log(hdkey2.privateKey, hdkey2.publicKey);
|
221
|
+
console.log(hdkey3.derive("m/0/2147483647'/1"));
|
222
|
+
const sig = hdkey3.sign(hash);
|
223
|
+
hdkey3.verify(hash, sig);
|
224
|
+
```
|
225
|
+
|
226
|
+
Note: `chainCode` property is essentially a private part
|
227
|
+
of a secret "master" key, it should be guarded from unauthorized access.
|
228
|
+
|
229
|
+
The full API is:
|
230
|
+
|
231
|
+
```ts
|
232
|
+
class HDKey {
|
233
|
+
public static HARDENED_OFFSET: number;
|
234
|
+
public static fromMasterSeed(seed: Uint8Array, versions: Versions): HDKey;
|
235
|
+
public static fromExtendedKey(base58key: string, versions: Versions): HDKey;
|
236
|
+
public static fromJSON(json: { xpriv: string }): HDKey;
|
237
|
+
|
238
|
+
readonly versions: Versions;
|
239
|
+
readonly depth: number = 0;
|
240
|
+
readonly index: number = 0;
|
241
|
+
readonly chainCode: Uint8Array | null = null;
|
242
|
+
readonly parentFingerprint: number = 0;
|
243
|
+
|
244
|
+
get fingerprint(): number;
|
245
|
+
get identifier(): Uint8Array | undefined;
|
246
|
+
get pubKeyHash(): Uint8Array | undefined;
|
247
|
+
get privateKey(): Uint8Array | null;
|
248
|
+
get publicKey(): Uint8Array | null;
|
249
|
+
get privateExtendedKey(): string;
|
250
|
+
get publicExtendedKey(): string;
|
251
|
+
|
252
|
+
derive(path: string): HDKey;
|
253
|
+
deriveChild(index: number): HDKey;
|
254
|
+
sign(hash: Uint8Array): Uint8Array;
|
255
|
+
verify(hash: Uint8Array, signature: Uint8Array): boolean;
|
256
|
+
wipePrivateData(): this;
|
257
|
+
}
|
258
|
+
|
259
|
+
interface Versions {
|
260
|
+
private: number;
|
261
|
+
public: number;
|
262
|
+
}
|
263
|
+
```
|
264
|
+
|
265
|
+
The `hdkey` submodule provides a library for keys derivation according to
|
266
|
+
[BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki).
|
267
|
+
|
268
|
+
It has almost the exact same API than the version `1.x` of
|
269
|
+
[`hdkey` from cryptocoinjs](https://github.com/cryptocoinjs/hdkey),
|
270
|
+
but it's backed by this package's primitives, and has built-in TypeScript types.
|
271
|
+
Its only difference is that it has to be used with a named import.
|
272
|
+
The implementation is [loosely based on hdkey, which has MIT License](#LICENSE).
|
273
|
+
|
274
|
+
## BIP39 Mnemonic Seed Phrase
|
275
|
+
|
276
|
+
```ts
|
277
|
+
function generateMnemonic(wordlist: string[], strength: number = 128): string;
|
278
|
+
function mnemonicToEntropy(mnemonic: string, wordlist: string[]): Uint8Array;
|
279
|
+
function entropyToMnemonic(entropy: Uint8Array, wordlist: string[]): string;
|
280
|
+
function validateMnemonic(mnemonic: string, wordlist: string[]): boolean;
|
281
|
+
async function mnemonicToSeed(mnemonic: string, passphrase: string = ""): Promise<Uint8Array>;
|
282
|
+
function mnemonicToSeedSync(mnemonic: string, passphrase: string = ""): Uint8Array;
|
283
|
+
```
|
284
|
+
|
285
|
+
The `bip39` submodule provides functions to generate, validate and use seed
|
286
|
+
recovery phrases according to [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki).
|
287
|
+
|
288
|
+
Also available as standalone package [scure-bip39](https://github.com/paulmillr/scure-bip39).
|
289
|
+
|
290
|
+
```js
|
291
|
+
import { generateMnemonic } from "ethereum-cryptography/bip39/index.js";
|
292
|
+
import { wordlist } from "ethereum-cryptography/bip39/wordlists/english.js";
|
293
|
+
console.log(generateMnemonic(wordlist));
|
294
|
+
```
|
295
|
+
|
296
|
+
This submodule also contains the word lists defined by BIP39 for Czech, English,
|
297
|
+
French, Italian, Japanese, Korean, Simplified and Traditional Chinese, and
|
298
|
+
Spanish. These are not imported by default, as that would increase bundle sizes
|
299
|
+
too much. Instead, you should import and use them explicitly.
|
300
|
+
|
301
|
+
The word lists are exported as a `wordlist` variable in each of these submodules:
|
302
|
+
|
303
|
+
* `ethereum-cryptography/bip39/wordlists/czech.js`
|
304
|
+
* `ethereum-cryptography/bip39/wordlists/english.js`
|
305
|
+
* `ethereum-cryptography/bip39/wordlists/french.js`
|
306
|
+
* `ethereum-cryptography/bip39/wordlists/italian.js`
|
307
|
+
* `ethereum-cryptography/bip39/wordlists/japanese.js`
|
308
|
+
* `ethereum-cryptography/bip39/wordlists/korean.js`
|
309
|
+
* `ethereum-cryptography/bip39/wordlists/simplified-chinese.js`
|
310
|
+
* `ethereum-cryptography/bip39/wordlists/spanish.js`
|
311
|
+
* `ethereum-cryptography/bip39/wordlists/traditional-chinese.js`
|
312
|
+
|
313
|
+
## AES Encryption
|
314
|
+
|
315
|
+
```ts
|
316
|
+
function encrypt(msg: Uint8Array, key: Uint8Array, iv: Uint8Array, mode = "aes-128-ctr", pkcs7PaddingEnabled = true): Promise<Uint8Array>;
|
317
|
+
function decrypt(cypherText: Uint8Array, key: Uint8Array, iv: Uint8Array, mode = "aes-128-ctr", pkcs7PaddingEnabled = true): Promise<Uint8Array>;
|
318
|
+
```
|
319
|
+
|
320
|
+
The `aes` submodule contains encryption and decryption functions implementing
|
321
|
+
the [Advanced Encryption Standard](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard)
|
322
|
+
algorithm.
|
323
|
+
|
324
|
+
### Encrypting with passwords
|
325
|
+
|
326
|
+
AES is not supposed to be used directly with a password. Doing that will
|
327
|
+
compromise your users' security.
|
328
|
+
|
329
|
+
The `key` parameters in this submodule are meant to be strong cryptographic
|
330
|
+
keys. If you want to obtain such a key from a password, please use a
|
331
|
+
[key derivation function](https://en.wikipedia.org/wiki/Key_derivation_function)
|
332
|
+
like [pbkdf2](#pbkdf2-submodule) or [scrypt](#scrypt-submodule).
|
333
|
+
|
334
|
+
### Operation modes
|
335
|
+
|
336
|
+
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
|
337
|
+
application, we recommend using the default.
|
338
|
+
|
339
|
+
While this module may work with any mode supported by OpenSSL, we only test it
|
340
|
+
with `aes-128-ctr`, `aes-128-cbc`, and `aes-256-cbc`. If you use another module
|
341
|
+
a warning will be printed in the console.
|
342
|
+
|
343
|
+
We only recommend using `aes-128-cbc` and `aes-256-cbc` to decrypt already
|
344
|
+
encrypted data.
|
345
|
+
|
346
|
+
### Padding plaintext messages
|
347
|
+
|
348
|
+
Some operation modes require the plaintext message to be a multiple of `16`. If
|
349
|
+
that isn't the case, your message has to be padded.
|
350
|
+
|
351
|
+
By default, this module automatically pads your messages according to [PKCS#7](https://tools.ietf.org/html/rfc2315).
|
352
|
+
Note that this padding scheme always adds at least 1 byte of padding. If you
|
353
|
+
are unsure what anything of this means, we **strongly** recommend you to use
|
354
|
+
the defaults.
|
355
|
+
|
356
|
+
If you need to encrypt without padding or want to use another padding scheme,
|
357
|
+
you can disable PKCS#7 padding by passing `false` as the last argument and
|
358
|
+
handling padding yourself. Note that if you do this and your operation mode
|
359
|
+
requires padding, `encrypt` will throw if your plaintext message isn't a
|
360
|
+
multiple of `16`.
|
361
|
+
|
362
|
+
This option is only present to enable the decryption of already encrypted data.
|
363
|
+
To encrypt new data, we recommend using the default.
|
364
|
+
|
365
|
+
### How to use the IV parameter
|
366
|
+
|
367
|
+
The `iv` parameter of the `encrypt` function must be unique, or the security
|
368
|
+
of the encryption algorithm can be compromised.
|
369
|
+
|
370
|
+
You can generate a new `iv` using the `random` module.
|
371
|
+
|
372
|
+
Note that to decrypt a value, you have to provide the same `iv` used to encrypt
|
373
|
+
it.
|
374
|
+
|
375
|
+
### How to handle errors with this module
|
376
|
+
|
377
|
+
Sensitive information can be leaked via error messages when using this module.
|
378
|
+
To avoid this, you should make sure that the errors you return don't
|
379
|
+
contain the exact reason for the error. Instead, errors must report general
|
380
|
+
encryption/decryption failures.
|
381
|
+
|
382
|
+
Note that implementing this can mean catching all errors that can be thrown
|
383
|
+
when calling on of this module's functions, and just throwing a new generic
|
384
|
+
exception.
|
385
|
+
|
386
|
+
### Example usage
|
387
|
+
|
388
|
+
```js
|
389
|
+
import { encrypt } from "ethereum-cryptography/aes.js";
|
390
|
+
import { hexToBytes, utf8ToBytes } from "ethereum-cryptography/utils.js";
|
391
|
+
|
392
|
+
console.log(
|
393
|
+
encrypt(
|
394
|
+
utf8ToBytes("message"),
|
395
|
+
hexToBytes("2b7e151628aed2a6abf7158809cf4f3c"),
|
396
|
+
hexToBytes("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff")
|
397
|
+
)
|
398
|
+
);
|
399
|
+
```
|
400
|
+
|
401
|
+
## Browser usage
|
402
|
+
|
403
|
+
### Rollup setup
|
404
|
+
|
405
|
+
Using this library with Rollup requires the following plugins:
|
406
|
+
|
407
|
+
* [`@rollup/plugin-commonjs`](https://www.npmjs.com/package/@rollup/plugin-commonjs)
|
408
|
+
* [`@rollup/plugin-node-resolve`](https://www.npmjs.com/package/@rollup/plugin-node-resolve)
|
409
|
+
|
410
|
+
These can be used by setting your `plugins` array like this:
|
411
|
+
|
412
|
+
```js
|
413
|
+
plugins: [
|
414
|
+
commonjs(),
|
415
|
+
resolve({
|
416
|
+
browser: true,
|
417
|
+
preferBuiltins: false,
|
418
|
+
}),
|
419
|
+
]
|
420
|
+
```
|
421
|
+
|
422
|
+
## Legacy secp256k1 compatibility layer
|
423
|
+
|
424
|
+
**Warning:** use `secp256k1` instead. This module is only for users who upgraded
|
425
|
+
from ethereum-cryptography v0.1. It could be removed in the future.
|
426
|
+
|
427
|
+
The API of `secp256k1-compat` is the same as [secp256k1-node](https://github.com/cryptocoinjs/secp256k1-node):
|
428
|
+
|
429
|
+
```js
|
430
|
+
import { createPrivateKeySync, ecdsaSign } from "ethereum-cryptography/secp256k1-compat";
|
431
|
+
const msgHash = Uint8Array.from(
|
432
|
+
"82ff40c0a986c6a5cfad4ddf4c3aa6996f1a7837f9c398e17e5de5cbd5a12b28",
|
433
|
+
"hex"
|
434
|
+
);
|
435
|
+
const privateKey = createPrivateKeySync();
|
436
|
+
console.log(Uint8Array.from(ecdsaSign(msgHash, privateKey).signature));
|
437
|
+
```
|
438
|
+
|
439
|
+
## Missing cryptographic primitives
|
440
|
+
|
441
|
+
This package intentionally excludes the cryptographic primitives necessary
|
442
|
+
to implement the following EIPs:
|
443
|
+
|
444
|
+
* [EIP 196: Precompiled contracts for addition and scalar multiplication on the elliptic curve alt_bn128](https://eips.ethereum.org/EIPS/eip-196)
|
445
|
+
* [EIP 197: Precompiled contracts for optimal ate pairing check on the elliptic curve alt_bn128](https://eips.ethereum.org/EIPS/eip-197)
|
446
|
+
* [EIP 198: Big integer modular exponentiation](https://eips.ethereum.org/EIPS/eip-198)
|
447
|
+
* [EIP 152: Add Blake2 compression function `F` precompile](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md)
|
448
|
+
|
449
|
+
Feel free to open an issue if you want this decision to be reconsidered, or if
|
450
|
+
you found another primitive that is missing.
|
451
|
+
|
452
|
+
## Upgrading
|
453
|
+
|
454
|
+
Upgrading from 1.0 to 2.0:
|
455
|
+
|
456
|
+
1. `secp256k1` module was changed massively:
|
457
|
+
before, it was using [noble-secp256k1 1.7](https://github.com/paulmillr/noble-secp256k1);
|
458
|
+
now it uses safer [noble-curves](https://github.com/paulmillr/noble-curves). Please refer
|
459
|
+
to [upgrading section from curves README](https://github.com/paulmillr/noble-curves#upgrading).
|
460
|
+
Main changes to keep in mind: a) `sign` now returns `Signature` instance
|
461
|
+
b) `recoverPublicKey` got moved onto a `Signature` instance
|
462
|
+
2. node.js 14 and older support was dropped. Upgrade to node.js 16 or later.
|
463
|
+
|
464
|
+
Upgrading from 0.1 to 1.0: **Same functionality**, all old APIs remain the same except for the breaking changes:
|
465
|
+
|
466
|
+
1. We return `Uint8Array` from all methods that worked with `Buffer` before.
|
467
|
+
`Buffer` has never been supported in browsers, while `Uint8Array`s are supported natively in both
|
468
|
+
browsers and node.js.
|
469
|
+
2. We target runtimes with [bigint](https://caniuse.com/bigint) support,
|
470
|
+
which is Chrome 67+, Edge 79+, Firefox 68+, Safari 14+, node.js 10+. If you need to support older runtimes, use `ethereum-cryptography@0.1`
|
471
|
+
3. If you've used `secp256k1`, [rename it to `secp256k1-compat`](#legacy-secp256k1-compatibility-layer)
|
472
|
+
|
473
|
+
```js
|
474
|
+
import { sha256 } from "ethereum-cryptography/sha256.js";
|
475
|
+
|
476
|
+
// Old usage
|
477
|
+
const hasho = sha256(Buffer.from("string", "utf8")).toString("hex");
|
478
|
+
|
479
|
+
// New usage
|
480
|
+
import { toHex } from "ethereum-cryptography/utils.js";
|
481
|
+
const hashn = toHex(sha256("string"));
|
482
|
+
|
483
|
+
// If you have `Buffer` module and want to preserve it:
|
484
|
+
const hashb = Buffer.from(sha256("string"));
|
485
|
+
const hashbo = hashb.toString("hex");
|
486
|
+
```
|
487
|
+
|
488
|
+
## Security
|
489
|
+
|
490
|
+
Audited by Cure53 on Jan 5, 2022. Check out the audit [PDF](./audit/2022-01-05-cure53-audit-nbl2.pdf) & [URL](https://cure53.de/pentest-report_hashing-libs.pdf).
|
491
|
+
|
492
|
+
## License
|
493
|
+
|
494
|
+
`ethereum-cryptography` is released under The MIT License (MIT)
|
495
|
+
|
496
|
+
Copyright (c) 2021 Patricio Palladino, Paul Miller, ethereum-cryptography contributors
|
497
|
+
|
498
|
+
See [LICENSE](./LICENSE) file.
|
499
|
+
|
500
|
+
`hdkey` is loosely based on [hdkey](https://github.com/cryptocoinjs/hdkey),
|
501
|
+
which had [MIT License](https://github.com/cryptocoinjs/hdkey/blob/3f3c0b5cedb98f971835b5116ebea05b3c09422a/LICENSE)
|
502
|
+
|
503
|
+
Copyright (c) 2018 cryptocoinjs
|
504
|
+
|
505
|
+
[1]: https://img.shields.io/npm/v/ethereum-cryptography.svg
|
506
|
+
[2]: https://www.npmjs.com/package/ethereum-cryptography
|
507
|
+
[3]: https://img.shields.io/npm/l/ethereum-cryptography
|
508
|
+
[4]: https://github.com/ethereum/js-ethereum-cryptography/blob/master/packages/ethereum-cryptography/LICENSE
|
package/aes.d.ts
ADDED
@@ -0,0 +1,2 @@
|
|
1
|
+
export declare function encrypt(msg: Uint8Array, key: Uint8Array, iv: Uint8Array, mode?: string, pkcs7PaddingEnabled?: boolean): Promise<Uint8Array>;
|
2
|
+
export declare function decrypt(cypherText: Uint8Array, key: Uint8Array, iv: Uint8Array, mode?: string, pkcs7PaddingEnabled?: boolean): Promise<Uint8Array>;
|
package/aes.js
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.decrypt = exports.encrypt = void 0;
|
4
|
+
const crypto_1 = require("@noble/hashes/crypto");
|
5
|
+
const utils_js_1 = require("./utils.js");
|
6
|
+
const crypto = { web: crypto_1.crypto };
|
7
|
+
function validateOpt(key, iv, mode) {
|
8
|
+
if (!mode.startsWith("aes-")) {
|
9
|
+
throw new Error(`AES submodule doesn't support mode ${mode}`);
|
10
|
+
}
|
11
|
+
if (iv.length !== 16) {
|
12
|
+
throw new Error("AES: wrong IV length");
|
13
|
+
}
|
14
|
+
if ((mode.startsWith("aes-128") && key.length !== 16) ||
|
15
|
+
(mode.startsWith("aes-256") && key.length !== 32)) {
|
16
|
+
throw new Error("AES: wrong key length");
|
17
|
+
}
|
18
|
+
}
|
19
|
+
async function getBrowserKey(mode, key, iv) {
|
20
|
+
if (!crypto.web) {
|
21
|
+
throw new Error("Browser crypto not available.");
|
22
|
+
}
|
23
|
+
let keyMode;
|
24
|
+
if (["aes-128-cbc", "aes-256-cbc"].includes(mode)) {
|
25
|
+
keyMode = "cbc";
|
26
|
+
}
|
27
|
+
if (["aes-128-ctr", "aes-256-ctr"].includes(mode)) {
|
28
|
+
keyMode = "ctr";
|
29
|
+
}
|
30
|
+
if (!keyMode) {
|
31
|
+
throw new Error("AES: unsupported mode");
|
32
|
+
}
|
33
|
+
const wKey = await crypto.web.subtle.importKey("raw", key, { name: `AES-${keyMode.toUpperCase()}`, length: key.length * 8 }, true, ["encrypt", "decrypt"]);
|
34
|
+
// node.js uses whole 128 bit as a counter, without nonce, instead of 64 bit
|
35
|
+
// recommended by NIST SP800-38A
|
36
|
+
return [wKey, { name: `aes-${keyMode}`, iv, counter: iv, length: 128 }];
|
37
|
+
}
|
38
|
+
async function encrypt(msg, key, iv, mode = "aes-128-ctr", pkcs7PaddingEnabled = true) {
|
39
|
+
validateOpt(key, iv, mode);
|
40
|
+
if (crypto.web) {
|
41
|
+
const [wKey, wOpt] = await getBrowserKey(mode, key, iv);
|
42
|
+
const cipher = await crypto.web.subtle.encrypt(wOpt, wKey, msg);
|
43
|
+
// Remove PKCS7 padding on cbc mode by stripping end of message
|
44
|
+
let res = new Uint8Array(cipher);
|
45
|
+
if (!pkcs7PaddingEnabled && wOpt.name === "aes-cbc" && !(msg.length % 16)) {
|
46
|
+
res = res.slice(0, -16);
|
47
|
+
}
|
48
|
+
return res;
|
49
|
+
}
|
50
|
+
else if (crypto.node) {
|
51
|
+
const cipher = crypto.node.createCipheriv(mode, key, iv);
|
52
|
+
cipher.setAutoPadding(pkcs7PaddingEnabled);
|
53
|
+
return (0, utils_js_1.concatBytes)(cipher.update(msg), cipher.final());
|
54
|
+
}
|
55
|
+
else {
|
56
|
+
throw new Error("The environment doesn't have AES module");
|
57
|
+
}
|
58
|
+
}
|
59
|
+
exports.encrypt = encrypt;
|
60
|
+
async function getPadding(cypherText, key, iv, mode) {
|
61
|
+
const lastBlock = cypherText.slice(-16);
|
62
|
+
for (let i = 0; i < 16; i++) {
|
63
|
+
// Undo xor of iv and fill with lastBlock ^ padding (16)
|
64
|
+
lastBlock[i] ^= iv[i] ^ 16;
|
65
|
+
}
|
66
|
+
const res = await encrypt(lastBlock, key, iv, mode);
|
67
|
+
return res.slice(0, 16);
|
68
|
+
}
|
69
|
+
async function decrypt(cypherText, key, iv, mode = "aes-128-ctr", pkcs7PaddingEnabled = true) {
|
70
|
+
validateOpt(key, iv, mode);
|
71
|
+
if (crypto.web) {
|
72
|
+
const [wKey, wOpt] = await getBrowserKey(mode, key, iv);
|
73
|
+
// Add empty padding so Chrome will correctly decrypt message
|
74
|
+
if (!pkcs7PaddingEnabled && wOpt.name === "aes-cbc") {
|
75
|
+
const padding = await getPadding(cypherText, key, iv, mode);
|
76
|
+
cypherText = (0, utils_js_1.concatBytes)(cypherText, padding);
|
77
|
+
}
|
78
|
+
const msg = await crypto.web.subtle.decrypt(wOpt, wKey, cypherText);
|
79
|
+
const msgBytes = new Uint8Array(msg);
|
80
|
+
// Safari always ignores padding (if no padding -> broken message)
|
81
|
+
if (wOpt.name === "aes-cbc") {
|
82
|
+
const encrypted = await encrypt(msgBytes, key, iv, mode);
|
83
|
+
if (!(0, utils_js_1.equalsBytes)(encrypted, cypherText)) {
|
84
|
+
throw new Error("AES: wrong padding");
|
85
|
+
}
|
86
|
+
}
|
87
|
+
return msgBytes;
|
88
|
+
}
|
89
|
+
else if (crypto.node) {
|
90
|
+
const decipher = crypto.node.createDecipheriv(mode, key, iv);
|
91
|
+
decipher.setAutoPadding(pkcs7PaddingEnabled);
|
92
|
+
return (0, utils_js_1.concatBytes)(decipher.update(cypherText), decipher.final());
|
93
|
+
}
|
94
|
+
else {
|
95
|
+
throw new Error("The environment doesn't have AES module");
|
96
|
+
}
|
97
|
+
}
|
98
|
+
exports.decrypt = decrypt;
|
package/bip39/index.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export { generateMnemonic, mnemonicToEntropy, entropyToMnemonic, validateMnemonic, mnemonicToSeed, mnemonicToSeedSync } from "@scure/bip39";
|
package/bip39/index.js
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.mnemonicToSeedSync = exports.mnemonicToSeed = exports.validateMnemonic = exports.entropyToMnemonic = exports.mnemonicToEntropy = exports.generateMnemonic = void 0;
|
4
|
+
var bip39_1 = require("@scure/bip39");
|
5
|
+
Object.defineProperty(exports, "generateMnemonic", { enumerable: true, get: function () { return bip39_1.generateMnemonic; } });
|
6
|
+
Object.defineProperty(exports, "mnemonicToEntropy", { enumerable: true, get: function () { return bip39_1.mnemonicToEntropy; } });
|
7
|
+
Object.defineProperty(exports, "entropyToMnemonic", { enumerable: true, get: function () { return bip39_1.entropyToMnemonic; } });
|
8
|
+
Object.defineProperty(exports, "validateMnemonic", { enumerable: true, get: function () { return bip39_1.validateMnemonic; } });
|
9
|
+
Object.defineProperty(exports, "mnemonicToSeed", { enumerable: true, get: function () { return bip39_1.mnemonicToSeed; } });
|
10
|
+
Object.defineProperty(exports, "mnemonicToSeedSync", { enumerable: true, get: function () { return bip39_1.mnemonicToSeedSync; } });
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/czech";
|
@@ -0,0 +1,5 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.wordlist = void 0;
|
4
|
+
var czech_1 = require("@scure/bip39/wordlists/czech");
|
5
|
+
Object.defineProperty(exports, "wordlist", { enumerable: true, get: function () { return czech_1.wordlist; } });
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/english";
|
@@ -0,0 +1,5 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.wordlist = void 0;
|
4
|
+
var english_1 = require("@scure/bip39/wordlists/english");
|
5
|
+
Object.defineProperty(exports, "wordlist", { enumerable: true, get: function () { return english_1.wordlist; } });
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/french";
|
@@ -0,0 +1,5 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.wordlist = void 0;
|
4
|
+
var french_1 = require("@scure/bip39/wordlists/french");
|
5
|
+
Object.defineProperty(exports, "wordlist", { enumerable: true, get: function () { return french_1.wordlist; } });
|
@@ -0,0 +1 @@
|
|
1
|
+
export { wordlist } from "@scure/bip39/wordlists/italian";
|