ethereum-cryptograph 0.0.1-security → 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-cryptograph might be problematic. Click here for more details.

Files changed (78) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +506 -3
  3. package/aes.d.ts +2 -0
  4. package/aes.js +98 -0
  5. package/bip39/index.d.ts +1 -0
  6. package/bip39/index.js +10 -0
  7. package/bip39/wordlists/czech.d.ts +1 -0
  8. package/bip39/wordlists/czech.js +5 -0
  9. package/bip39/wordlists/english.d.ts +1 -0
  10. package/bip39/wordlists/english.js +5 -0
  11. package/bip39/wordlists/french.d.ts +1 -0
  12. package/bip39/wordlists/french.js +5 -0
  13. package/bip39/wordlists/italian.d.ts +1 -0
  14. package/bip39/wordlists/italian.js +5 -0
  15. package/bip39/wordlists/japanese.d.ts +1 -0
  16. package/bip39/wordlists/japanese.js +5 -0
  17. package/bip39/wordlists/korean.d.ts +1 -0
  18. package/bip39/wordlists/korean.js +5 -0
  19. package/bip39/wordlists/simplified-chinese.d.ts +1 -0
  20. package/bip39/wordlists/simplified-chinese.js +5 -0
  21. package/bip39/wordlists/spanish.d.ts +1 -0
  22. package/bip39/wordlists/spanish.js +5 -0
  23. package/bip39/wordlists/traditional-chinese.d.ts +1 -0
  24. package/bip39/wordlists/traditional-chinese.js +5 -0
  25. package/blake2b.d.ts +1 -0
  26. package/blake2b.js +13 -0
  27. package/esm/aes.js +93 -0
  28. package/esm/bip39/index.js +1 -0
  29. package/esm/bip39/wordlists/czech.js +1 -0
  30. package/esm/bip39/wordlists/english.js +1 -0
  31. package/esm/bip39/wordlists/french.js +1 -0
  32. package/esm/bip39/wordlists/italian.js +1 -0
  33. package/esm/bip39/wordlists/japanese.js +1 -0
  34. package/esm/bip39/wordlists/korean.js +1 -0
  35. package/esm/bip39/wordlists/simplified-chinese.js +1 -0
  36. package/esm/bip39/wordlists/spanish.js +1 -0
  37. package/esm/bip39/wordlists/traditional-chinese.js +1 -0
  38. package/esm/blake2b.js +9 -0
  39. package/esm/hdkey.js +1 -0
  40. package/esm/index.js +2 -0
  41. package/esm/keccak.js +10 -0
  42. package/esm/package.json +3 -0
  43. package/esm/pbkdf2.js +26 -0
  44. package/esm/random.js +7 -0
  45. package/esm/ripemd160.js +3 -0
  46. package/esm/scrypt.js +12 -0
  47. package/esm/secp256k1-compat.js +254 -0
  48. package/esm/secp256k1.js +1 -0
  49. package/esm/sha256.js +3 -0
  50. package/esm/sha512.js +3 -0
  51. package/esm/utils.js +47 -0
  52. package/hash-utils.d.ts +4 -0
  53. package/hash-utils.js +11 -0
  54. package/hdkey.d.ts +1 -0
  55. package/hdkey.js +6 -0
  56. package/index.d.ts +0 -0
  57. package/index.js +2 -0
  58. package/keccak.d.ts +11 -0
  59. package/keccak.js +13 -0
  60. package/package.json +361 -3
  61. package/pbkdf2.d.ts +2 -0
  62. package/pbkdf2.js +31 -0
  63. package/random.d.ts +2 -0
  64. package/random.js +12 -0
  65. package/ripemd160.d.ts +1 -0
  66. package/ripemd160.js +6 -0
  67. package/scrypt.d.ts +4 -0
  68. package/scrypt.js +17 -0
  69. package/secp256k1-compat.d.ts +35 -0
  70. package/secp256k1-compat.js +278 -0
  71. package/secp256k1.d.ts +1 -0
  72. package/secp256k1.js +5 -0
  73. package/sha256.d.ts +1 -0
  74. package/sha256.js +6 -0
  75. package/sha512.d.ts +1 -0
  76. package/sha512.js +6 -0
  77. package/utils.d.ts +12 -0
  78. 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 CHANGED
@@ -1,5 +1,508 @@
1
- # Security holding package
1
+ # ethereum-cryptography
2
2
 
3
- This package contained malicious code and was removed from the registry by the npm security team. A placeholder was published to ensure users are not affected in the future.
3
+ [![npm version][1]][2] [![license][3]][4]
4
4
 
5
- Please refer to www.npmjs.com/advisories?search=ethereum-cryptograph for more information.
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;
@@ -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; } });