@twin.org/crypto 0.0.1-next.9 → 0.0.2-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +156 -52
- package/dist/esm/index.mjs +128 -25
- package/dist/types/address/bip44.d.ts +15 -0
- package/dist/types/curves/ed25519.d.ts +12 -0
- package/dist/types/helpers/pemHelper.d.ts +19 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/keys/bip39.d.ts +8 -0
- package/docs/changelog.md +526 -1
- package/docs/reference/classes/Bech32.md +15 -7
- package/docs/reference/classes/Bip32Path.md +17 -9
- package/docs/reference/classes/Bip39.md +62 -12
- package/docs/reference/classes/Bip44.md +121 -21
- package/docs/reference/classes/Blake2b.md +35 -17
- package/docs/reference/classes/Blake3.md +28 -14
- package/docs/reference/classes/ChaCha20Poly1305.md +18 -8
- package/docs/reference/classes/Ed25519.md +65 -9
- package/docs/reference/classes/HmacSha1.md +17 -9
- package/docs/reference/classes/HmacSha256.md +26 -12
- package/docs/reference/classes/HmacSha512.md +38 -16
- package/docs/reference/classes/Hotp.md +9 -5
- package/docs/reference/classes/PasswordGenerator.md +6 -4
- package/docs/reference/classes/PasswordValidator.md +23 -11
- package/docs/reference/classes/Pbkdf2.md +27 -11
- package/docs/reference/classes/PemHelper.md +69 -0
- package/docs/reference/classes/Secp256k1.md +21 -9
- package/docs/reference/classes/Sha1.md +11 -7
- package/docs/reference/classes/Sha256.md +17 -9
- package/docs/reference/classes/Sha3.md +23 -11
- package/docs/reference/classes/Sha512.md +23 -11
- package/docs/reference/classes/Slip0010.md +27 -11
- package/docs/reference/classes/Totp.md +42 -16
- package/docs/reference/classes/X25519.md +9 -5
- package/docs/reference/classes/Zip215.md +12 -6
- package/docs/reference/index.md +1 -0
- package/docs/reference/type-aliases/KeyType.md +1 -1
- package/docs/reference/variables/KeyType.md +1 -1
- package/locales/en.json +4 -0
- package/package.json +14 -13
package/dist/cjs/index.cjs
CHANGED
|
@@ -2,21 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
var base = require('@scure/base');
|
|
4
4
|
var core = require('@twin.org/core');
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var
|
|
5
|
+
var ed25519_js = require('@noble/curves/ed25519.js');
|
|
6
|
+
var secp256k1_js = require('@noble/curves/secp256k1.js');
|
|
7
|
+
var blake2_js = require('@noble/hashes/blake2.js');
|
|
8
8
|
var bip32 = require('@scure/bip32');
|
|
9
9
|
var slip10_js = require('micro-key-producer/slip10.js');
|
|
10
|
-
var
|
|
11
|
-
var
|
|
12
|
-
var
|
|
13
|
-
var
|
|
14
|
-
var
|
|
15
|
-
var
|
|
16
|
-
var
|
|
17
|
-
var sha3 = require('@noble/hashes/sha3');
|
|
10
|
+
var chacha_js = require('@noble/ciphers/chacha.js');
|
|
11
|
+
var blake3_js = require('@noble/hashes/blake3.js');
|
|
12
|
+
var hmac_js = require('@noble/hashes/hmac.js');
|
|
13
|
+
var legacy_js = require('@noble/hashes/legacy.js');
|
|
14
|
+
var sha2_js = require('@noble/hashes/sha2.js');
|
|
15
|
+
var pbkdf2_js = require('@noble/hashes/pbkdf2.js');
|
|
16
|
+
var sha3_js = require('@noble/hashes/sha3.js');
|
|
18
17
|
var bip39 = require('@scure/bip39');
|
|
19
|
-
var
|
|
18
|
+
var english_js = require('@scure/bip39/wordlists/english.js');
|
|
20
19
|
var otp = require('micro-key-producer/otp.js');
|
|
21
20
|
|
|
22
21
|
function _interopNamespaceDefault(e) {
|
|
@@ -143,7 +142,7 @@ class Ed25519 {
|
|
|
143
142
|
actualSize: privateKey.length
|
|
144
143
|
});
|
|
145
144
|
}
|
|
146
|
-
return
|
|
145
|
+
return ed25519_js.ed25519.getPublicKey(privateKey);
|
|
147
146
|
}
|
|
148
147
|
/**
|
|
149
148
|
* Sign the block with privateKey and returns a signature.
|
|
@@ -161,7 +160,7 @@ class Ed25519 {
|
|
|
161
160
|
actualSize: privateKey ? privateKey.length : 0
|
|
162
161
|
});
|
|
163
162
|
}
|
|
164
|
-
return
|
|
163
|
+
return ed25519_js.ed25519.sign(block, privateKey);
|
|
165
164
|
}
|
|
166
165
|
/**
|
|
167
166
|
* Verify reports whether sig is a valid signature of block by publicKey.
|
|
@@ -182,12 +181,45 @@ class Ed25519 {
|
|
|
182
181
|
});
|
|
183
182
|
}
|
|
184
183
|
try {
|
|
185
|
-
return
|
|
184
|
+
return ed25519_js.ed25519.verify(signature, block, publicKey);
|
|
186
185
|
}
|
|
187
186
|
catch {
|
|
188
187
|
return false;
|
|
189
188
|
}
|
|
190
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Convert a private key in PKCS8 format.
|
|
192
|
+
* @param privateKey The private key to convert.
|
|
193
|
+
* @returns The private key in PKCS8 format.
|
|
194
|
+
*/
|
|
195
|
+
static async privateKeyToPkcs8(privateKey) {
|
|
196
|
+
core.Guards.uint8Array(Ed25519._CLASS_NAME, "privateKey", privateKey);
|
|
197
|
+
if (privateKey.length !== Ed25519.PRIVATE_KEY_SIZE) {
|
|
198
|
+
throw new core.GeneralError(Ed25519._CLASS_NAME, "privateKeyLength", {
|
|
199
|
+
requiredSize: Ed25519.PRIVATE_KEY_SIZE,
|
|
200
|
+
actualSize: privateKey.length
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
// crypto.subtle.importKey does not support Ed25519 keys in raw format.
|
|
204
|
+
// We need to convert the key to PKCS8 format before importing.
|
|
205
|
+
// The PKCS8 format is the raw key prefixed with the ASN.1 sequence for an Ed25519 private key.
|
|
206
|
+
// The ASN.1 sequence is 48 46 02 01 00 30 05 06 03 2b 65 70 04 20 04 20 (0x302e020100300506032b657004220420)
|
|
207
|
+
const pkcs8Prefix = new Uint8Array([48, 46, 2, 1, 0, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32]);
|
|
208
|
+
const fullKey = core.Uint8ArrayHelper.concat([pkcs8Prefix, privateKey]);
|
|
209
|
+
return crypto.subtle.importKey("pkcs8", new Uint8Array(fullKey), "Ed25519", true, ["sign"]);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Convert a crypto key to raw private key.
|
|
213
|
+
* @param cryptoKey The crypto key to convert.
|
|
214
|
+
* @returns The raw private key.
|
|
215
|
+
*/
|
|
216
|
+
static async pkcs8ToPrivateKey(cryptoKey) {
|
|
217
|
+
core.Guards.defined(Ed25519._CLASS_NAME, "cryptoKey", cryptoKey);
|
|
218
|
+
// crypto.subtle.exportKey does not support Ed25519 keys in raw format.
|
|
219
|
+
// so we export as PKCS8 and remove the ASN.1 sequence prefix.
|
|
220
|
+
const pkcs8Bytes = await crypto.subtle.exportKey("pkcs8", cryptoKey);
|
|
221
|
+
return new Uint8Array(pkcs8Bytes.slice(16));
|
|
222
|
+
}
|
|
191
223
|
}
|
|
192
224
|
|
|
193
225
|
// Copyright 2024 IOTA Stiftung.
|
|
@@ -223,7 +255,7 @@ class Secp256k1 {
|
|
|
223
255
|
actualSize: privateKey.length
|
|
224
256
|
});
|
|
225
257
|
}
|
|
226
|
-
return
|
|
258
|
+
return secp256k1_js.secp256k1.getPublicKey(privateKey);
|
|
227
259
|
}
|
|
228
260
|
/**
|
|
229
261
|
* Sign the block with privateKey and returns a signature.
|
|
@@ -238,11 +270,11 @@ class Secp256k1 {
|
|
|
238
270
|
if (privateKey.length !== Secp256k1.PRIVATE_KEY_SIZE) {
|
|
239
271
|
throw new core.GeneralError(Secp256k1._CLASS_NAME, "privateKeyLength", {
|
|
240
272
|
requiredSize: Secp256k1.PRIVATE_KEY_SIZE,
|
|
241
|
-
actualSize: privateKey
|
|
273
|
+
actualSize: privateKey.length
|
|
242
274
|
});
|
|
243
275
|
}
|
|
244
|
-
const res =
|
|
245
|
-
return res
|
|
276
|
+
const res = secp256k1_js.secp256k1.sign(block, privateKey, { prehash: false });
|
|
277
|
+
return res;
|
|
246
278
|
}
|
|
247
279
|
/**
|
|
248
280
|
* Verify reports whether sig is a valid signature of block by publicKey.
|
|
@@ -263,7 +295,7 @@ class Secp256k1 {
|
|
|
263
295
|
});
|
|
264
296
|
}
|
|
265
297
|
try {
|
|
266
|
-
return
|
|
298
|
+
return secp256k1_js.secp256k1.verify(signature, block, publicKey, { prehash: false });
|
|
267
299
|
}
|
|
268
300
|
catch {
|
|
269
301
|
return false;
|
|
@@ -306,7 +338,7 @@ class Blake2b {
|
|
|
306
338
|
* @param key Optional key for the hash.
|
|
307
339
|
*/
|
|
308
340
|
constructor(outputLength, key) {
|
|
309
|
-
this._instance =
|
|
341
|
+
this._instance = blake2_js.blake2b.create({
|
|
310
342
|
dkLen: outputLength,
|
|
311
343
|
key
|
|
312
344
|
});
|
|
@@ -451,7 +483,6 @@ const KeyType = {
|
|
|
451
483
|
|
|
452
484
|
// Copyright 2024 IOTA Stiftung.
|
|
453
485
|
// SPDX-License-Identifier: Apache-2.0.
|
|
454
|
-
/* eslint-disable no-bitwise */
|
|
455
486
|
/**
|
|
456
487
|
* Class to help with slip0010 key derivation
|
|
457
488
|
* https://github.com/satoshilabs/slips/blob/master/slip-0010.md.
|
|
@@ -592,6 +623,24 @@ class Bip44 {
|
|
|
592
623
|
static basePath(coinType) {
|
|
593
624
|
return `m/44'/${coinType}'`;
|
|
594
625
|
}
|
|
626
|
+
/**
|
|
627
|
+
* Generate an address from the seed and parts.
|
|
628
|
+
* @param seed The account seed.
|
|
629
|
+
* @param keyType The key type.
|
|
630
|
+
* @param coinType The coin type.
|
|
631
|
+
* @param accountIndex The account index.
|
|
632
|
+
* @param isInternal Is this an internal address.
|
|
633
|
+
* @param addressIndex The address index.
|
|
634
|
+
* @returns The generated path and the associated keypair.
|
|
635
|
+
*/
|
|
636
|
+
static address(seed, keyType, coinType, accountIndex, isInternal, addressIndex) {
|
|
637
|
+
const keyPair = Bip44.keyPair(seed, keyType, coinType, accountIndex, isInternal, addressIndex);
|
|
638
|
+
const addressData = Blake2b.sum256(keyPair.publicKey);
|
|
639
|
+
return {
|
|
640
|
+
address: core.Converter.bytesToHex(addressData, true),
|
|
641
|
+
...keyPair
|
|
642
|
+
};
|
|
643
|
+
}
|
|
595
644
|
/**
|
|
596
645
|
* Generate a bech32 address from the seed and parts.
|
|
597
646
|
* @param seed The account seed.
|
|
@@ -641,7 +690,7 @@ class ChaCha20Poly1305 {
|
|
|
641
690
|
constructor(key, nonce, aad) {
|
|
642
691
|
core.Guards.uint8Array(ChaCha20Poly1305._CLASS_NAME, "key", key);
|
|
643
692
|
core.Guards.uint8Array(ChaCha20Poly1305._CLASS_NAME, "nonce", nonce);
|
|
644
|
-
this._instance =
|
|
693
|
+
this._instance = chacha_js.chacha20poly1305(key, nonce, aad);
|
|
645
694
|
}
|
|
646
695
|
/**
|
|
647
696
|
* Encrypt the block.
|
|
@@ -665,9 +714,6 @@ class ChaCha20Poly1305 {
|
|
|
665
714
|
|
|
666
715
|
// Copyright 2024 IOTA Stiftung.
|
|
667
716
|
// SPDX-License-Identifier: Apache-2.0.
|
|
668
|
-
/**
|
|
669
|
-
* This is a TypeScript port of https://github.com/katzenpost/core/blob/master/crypto/extra25519/extra25519.go.
|
|
670
|
-
*/
|
|
671
717
|
/**
|
|
672
718
|
* Implementation of X25519.
|
|
673
719
|
*/
|
|
@@ -684,7 +730,7 @@ class X25519 {
|
|
|
684
730
|
*/
|
|
685
731
|
static convertPrivateKeyToX25519(ed25519PrivateKey) {
|
|
686
732
|
core.Guards.uint8Array(X25519._CLASS_NAME, "ed25519PrivateKey", ed25519PrivateKey);
|
|
687
|
-
return ed25519.
|
|
733
|
+
return ed25519_js.ed25519.utils.toMontgomerySecret(ed25519PrivateKey.slice(0, Ed25519.PRIVATE_KEY_SIZE));
|
|
688
734
|
}
|
|
689
735
|
/**
|
|
690
736
|
* Convert Ed25519 public key to X25519 public key.
|
|
@@ -694,7 +740,7 @@ class X25519 {
|
|
|
694
740
|
*/
|
|
695
741
|
static convertPublicKeyToX25519(ed25519PublicKey) {
|
|
696
742
|
core.Guards.uint8Array(X25519._CLASS_NAME, "ed25519PublicKey", ed25519PublicKey);
|
|
697
|
-
return ed25519.
|
|
743
|
+
return ed25519_js.ed25519.utils.toMontgomery(ed25519PublicKey);
|
|
698
744
|
}
|
|
699
745
|
}
|
|
700
746
|
|
|
@@ -725,7 +771,7 @@ class Zip215 {
|
|
|
725
771
|
if (publicKey.length !== Ed25519.PUBLIC_KEY_SIZE) {
|
|
726
772
|
return false;
|
|
727
773
|
}
|
|
728
|
-
return
|
|
774
|
+
return ed25519_js.ed25519.verify(sig, block, publicKey, { zip215: true });
|
|
729
775
|
}
|
|
730
776
|
}
|
|
731
777
|
|
|
@@ -760,7 +806,7 @@ class Blake3 {
|
|
|
760
806
|
* @param key Optional key for the hash.
|
|
761
807
|
*/
|
|
762
808
|
constructor(outputLength, key) {
|
|
763
|
-
this._instance =
|
|
809
|
+
this._instance = blake3_js.blake3.create({
|
|
764
810
|
dkLen: outputLength,
|
|
765
811
|
key
|
|
766
812
|
});
|
|
@@ -826,7 +872,7 @@ class HmacSha1 {
|
|
|
826
872
|
* @param key The key for the hmac.
|
|
827
873
|
*/
|
|
828
874
|
constructor(key) {
|
|
829
|
-
this._instance =
|
|
875
|
+
this._instance = hmac_js.hmac.create(legacy_js.sha1, key);
|
|
830
876
|
}
|
|
831
877
|
/**
|
|
832
878
|
* Perform Sum on the block.
|
|
@@ -892,7 +938,7 @@ class HmacSha256 {
|
|
|
892
938
|
if (bits !== HmacSha256.SIZE_224 && bits !== HmacSha256.SIZE_256) {
|
|
893
939
|
throw new core.GeneralError(HmacSha256._CLASS_NAME, "bitSize", { bitSize: bits });
|
|
894
940
|
}
|
|
895
|
-
this._instance =
|
|
941
|
+
this._instance = hmac_js.hmac.create(bits === HmacSha256.SIZE_256 ? sha2_js.sha256 : sha2_js.sha224, key);
|
|
896
942
|
}
|
|
897
943
|
/**
|
|
898
944
|
* Perform Sum 224 on the block.
|
|
@@ -986,16 +1032,16 @@ class HmacSha512 {
|
|
|
986
1032
|
throw new core.GeneralError(HmacSha512._CLASS_NAME, "bitSize", { bitSize: bits });
|
|
987
1033
|
}
|
|
988
1034
|
if (bits === HmacSha512.SIZE_224) {
|
|
989
|
-
this._instance =
|
|
1035
|
+
this._instance = hmac_js.hmac.create(sha2_js.sha512_224, key);
|
|
990
1036
|
}
|
|
991
1037
|
else if (bits === HmacSha512.SIZE_256) {
|
|
992
|
-
this._instance =
|
|
1038
|
+
this._instance = hmac_js.hmac.create(sha2_js.sha512_256, key);
|
|
993
1039
|
}
|
|
994
1040
|
else if (bits === HmacSha512.SIZE_384) {
|
|
995
|
-
this._instance =
|
|
1041
|
+
this._instance = hmac_js.hmac.create(sha2_js.sha384, key);
|
|
996
1042
|
}
|
|
997
1043
|
else {
|
|
998
|
-
this._instance =
|
|
1044
|
+
this._instance = hmac_js.hmac.create(sha2_js.sha512, key);
|
|
999
1045
|
}
|
|
1000
1046
|
}
|
|
1001
1047
|
/**
|
|
@@ -1093,7 +1139,7 @@ class Pbkdf2 {
|
|
|
1093
1139
|
core.Guards.uint8Array(Pbkdf2._CLASS_NAME, "salt", salt);
|
|
1094
1140
|
core.Guards.number(Pbkdf2._CLASS_NAME, "iterations", iterations);
|
|
1095
1141
|
core.Guards.number(Pbkdf2._CLASS_NAME, "keyLength", keyLength);
|
|
1096
|
-
return
|
|
1142
|
+
return pbkdf2_js.pbkdf2(sha2_js.sha256, password, salt, { c: iterations, dkLen: keyLength });
|
|
1097
1143
|
}
|
|
1098
1144
|
/**
|
|
1099
1145
|
* Derive a key from the parameters using Sha512.
|
|
@@ -1108,7 +1154,7 @@ class Pbkdf2 {
|
|
|
1108
1154
|
core.Guards.uint8Array(Pbkdf2._CLASS_NAME, "salt", salt);
|
|
1109
1155
|
core.Guards.number(Pbkdf2._CLASS_NAME, "iterations", iterations);
|
|
1110
1156
|
core.Guards.number(Pbkdf2._CLASS_NAME, "keyLength", keyLength);
|
|
1111
|
-
return
|
|
1157
|
+
return pbkdf2_js.pbkdf2(sha2_js.sha512, password, salt, { c: iterations, dkLen: keyLength });
|
|
1112
1158
|
}
|
|
1113
1159
|
}
|
|
1114
1160
|
|
|
@@ -1133,7 +1179,7 @@ class Sha1 {
|
|
|
1133
1179
|
* Create a new instance of Sha1.
|
|
1134
1180
|
*/
|
|
1135
1181
|
constructor() {
|
|
1136
|
-
this._instance =
|
|
1182
|
+
this._instance = legacy_js.sha1.create();
|
|
1137
1183
|
}
|
|
1138
1184
|
/**
|
|
1139
1185
|
* Perform Sum on the block.
|
|
@@ -1196,7 +1242,7 @@ class Sha256 {
|
|
|
1196
1242
|
if (bits !== Sha256.SIZE_224 && bits !== Sha256.SIZE_256) {
|
|
1197
1243
|
throw new core.GeneralError(Sha256._CLASS_NAME, "bitSize", { bitSize: bits });
|
|
1198
1244
|
}
|
|
1199
|
-
this._instance = bits === Sha256.SIZE_256 ?
|
|
1245
|
+
this._instance = bits === Sha256.SIZE_256 ? sha2_js.sha256.create() : sha2_js.sha224.create();
|
|
1200
1246
|
}
|
|
1201
1247
|
/**
|
|
1202
1248
|
* Perform Sum 256 on the block.
|
|
@@ -1284,19 +1330,19 @@ class Sha3 {
|
|
|
1284
1330
|
}
|
|
1285
1331
|
if (bits === Sha3.SIZE_224) {
|
|
1286
1332
|
// eslint-disable-next-line camelcase
|
|
1287
|
-
this._instance =
|
|
1333
|
+
this._instance = sha3_js.sha3_224.create();
|
|
1288
1334
|
}
|
|
1289
1335
|
else if (bits === Sha3.SIZE_256) {
|
|
1290
1336
|
// eslint-disable-next-line camelcase
|
|
1291
|
-
this._instance =
|
|
1337
|
+
this._instance = sha3_js.sha3_256.create();
|
|
1292
1338
|
}
|
|
1293
1339
|
else if (bits === Sha3.SIZE_384) {
|
|
1294
1340
|
// eslint-disable-next-line camelcase
|
|
1295
|
-
this._instance =
|
|
1341
|
+
this._instance = sha3_js.sha3_384.create();
|
|
1296
1342
|
}
|
|
1297
1343
|
else {
|
|
1298
1344
|
// eslint-disable-next-line camelcase
|
|
1299
|
-
this._instance =
|
|
1345
|
+
this._instance = sha3_js.sha3_512.create();
|
|
1300
1346
|
}
|
|
1301
1347
|
}
|
|
1302
1348
|
/**
|
|
@@ -1404,16 +1450,16 @@ class Sha512 {
|
|
|
1404
1450
|
throw new core.GeneralError(Sha512._CLASS_NAME, "bitSize", { bitSize: bits });
|
|
1405
1451
|
}
|
|
1406
1452
|
if (bits === Sha512.SIZE_224) {
|
|
1407
|
-
this._instance =
|
|
1453
|
+
this._instance = sha2_js.sha512_224.create();
|
|
1408
1454
|
}
|
|
1409
1455
|
else if (bits === Sha512.SIZE_256) {
|
|
1410
|
-
this._instance =
|
|
1456
|
+
this._instance = sha2_js.sha512_256.create();
|
|
1411
1457
|
}
|
|
1412
1458
|
else if (bits === Sha512.SIZE_384) {
|
|
1413
|
-
this._instance =
|
|
1459
|
+
this._instance = sha2_js.sha384.create();
|
|
1414
1460
|
}
|
|
1415
1461
|
else {
|
|
1416
|
-
this._instance =
|
|
1462
|
+
this._instance = sha2_js.sha512.create();
|
|
1417
1463
|
}
|
|
1418
1464
|
}
|
|
1419
1465
|
/**
|
|
@@ -1475,6 +1521,48 @@ class Sha512 {
|
|
|
1475
1521
|
}
|
|
1476
1522
|
}
|
|
1477
1523
|
|
|
1524
|
+
// Copyright 2024 IOTA Stiftung.
|
|
1525
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
1526
|
+
/**
|
|
1527
|
+
* Helper class for working with PEM (Privacy-Enhanced Mail) formatted data.
|
|
1528
|
+
*/
|
|
1529
|
+
class PemHelper {
|
|
1530
|
+
/**
|
|
1531
|
+
* Runtime name for the class.
|
|
1532
|
+
* @internal
|
|
1533
|
+
*/
|
|
1534
|
+
static _CLASS_NAME = "PemHelper";
|
|
1535
|
+
/**
|
|
1536
|
+
* Strip the PEM content of its headers, footers, and newlines.
|
|
1537
|
+
* @param pemContent The PEM content to strip.
|
|
1538
|
+
* @returns The stripped PEM content in bas64 format.
|
|
1539
|
+
*/
|
|
1540
|
+
static stripPemMarkers(pemContent) {
|
|
1541
|
+
core.Guards.string(PemHelper._CLASS_NAME, "pemContent", pemContent);
|
|
1542
|
+
return pemContent
|
|
1543
|
+
.replace(/-----BEGIN.*-----/, "")
|
|
1544
|
+
.replace(/-----END.*-----/, "")
|
|
1545
|
+
.replace(/\n/g, "")
|
|
1546
|
+
.trim();
|
|
1547
|
+
}
|
|
1548
|
+
/**
|
|
1549
|
+
* Format the PEM content to have a specific line length.
|
|
1550
|
+
* @param marker The marker for the PEM content, e.g. RSA PRIVATE KEY
|
|
1551
|
+
* @param base64Content The base64 content to format.
|
|
1552
|
+
* @param lineLength The length of each line in the PEM content, default is 64 characters.
|
|
1553
|
+
* @returns The formatted PEM content.
|
|
1554
|
+
*/
|
|
1555
|
+
static formatPem(marker, base64Content, lineLength = 64) {
|
|
1556
|
+
core.Guards.stringValue(PemHelper._CLASS_NAME, "marker", marker);
|
|
1557
|
+
core.Guards.stringBase64(PemHelper._CLASS_NAME, "base64Content", base64Content);
|
|
1558
|
+
const lines = [];
|
|
1559
|
+
for (let i = 0; i < base64Content.length; i += lineLength) {
|
|
1560
|
+
lines.push(base64Content.slice(i, i + lineLength));
|
|
1561
|
+
}
|
|
1562
|
+
return [`-----BEGIN ${marker}-----`, ...lines, `-----END ${marker}-----`].join("\n");
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1478
1566
|
// Copyright 2024 IOTA Stiftung.
|
|
1479
1567
|
// SPDX-License-Identifier: Apache-2.0.
|
|
1480
1568
|
/**
|
|
@@ -1493,7 +1581,7 @@ class Bip39 {
|
|
|
1493
1581
|
* @returns The random mnemonic.
|
|
1494
1582
|
* @throws Error if the length is not a multiple of 32.
|
|
1495
1583
|
*/
|
|
1496
|
-
static randomMnemonic(strength = 256, words =
|
|
1584
|
+
static randomMnemonic(strength = 256, words = english_js.wordlist) {
|
|
1497
1585
|
core.Guards.number(Bip39._CLASS_NAME, "strength", strength);
|
|
1498
1586
|
core.Guards.arrayValue(Bip39._CLASS_NAME, "words", words);
|
|
1499
1587
|
if (strength % 32 !== 0) {
|
|
@@ -1508,7 +1596,7 @@ class Bip39 {
|
|
|
1508
1596
|
* @returns The mnemonic.
|
|
1509
1597
|
* @throws Error if the length of the entropy is not a multiple of 4, or is less than 16 or greater than 32.
|
|
1510
1598
|
*/
|
|
1511
|
-
static entropyToMnemonic(entropy, words =
|
|
1599
|
+
static entropyToMnemonic(entropy, words = english_js.wordlist) {
|
|
1512
1600
|
core.Guards.uint8Array(Bip39._CLASS_NAME, "entropy", entropy);
|
|
1513
1601
|
core.Guards.arrayValue(Bip39._CLASS_NAME, "words", words);
|
|
1514
1602
|
if (entropy.length % 4 !== 0 || entropy.length < 16 || entropy.length > 32) {
|
|
@@ -1533,16 +1621,31 @@ class Bip39 {
|
|
|
1533
1621
|
* @returns The entropy.
|
|
1534
1622
|
* @throws Error if the number of words is not a multiple of 3.
|
|
1535
1623
|
*/
|
|
1536
|
-
static mnemonicToEntropy(mnemonic, words =
|
|
1624
|
+
static mnemonicToEntropy(mnemonic, words = english_js.wordlist) {
|
|
1537
1625
|
core.Guards.stringValue(Bip39._CLASS_NAME, "mnemonic", mnemonic);
|
|
1538
1626
|
core.Guards.arrayValue(Bip39._CLASS_NAME, "words", words);
|
|
1539
1627
|
return bip39__namespace.mnemonicToEntropy(mnemonic, words);
|
|
1540
1628
|
}
|
|
1629
|
+
/**
|
|
1630
|
+
* Validate the mnemonic.
|
|
1631
|
+
* @param mnemonic The mnemonic to validate.
|
|
1632
|
+
* @param wordCount The expected number of words in the mnemonic, defaults to 24.
|
|
1633
|
+
* @param words The wordlist to use, defaults to the English wordlist.
|
|
1634
|
+
* @returns True if the mnemonic is valid.
|
|
1635
|
+
*/
|
|
1636
|
+
static validateMnemonic(mnemonic, wordCount = 24, words = english_js.wordlist) {
|
|
1637
|
+
core.Guards.string(Bip39._CLASS_NAME, "mnemonic", mnemonic);
|
|
1638
|
+
core.Guards.integer(Bip39._CLASS_NAME, "wordCount", wordCount);
|
|
1639
|
+
const mnemonicSplit = mnemonic.split(/\s+/);
|
|
1640
|
+
if (mnemonicSplit.length !== wordCount) {
|
|
1641
|
+
return false;
|
|
1642
|
+
}
|
|
1643
|
+
return bip39__namespace.validateMnemonic(mnemonic, words);
|
|
1644
|
+
}
|
|
1541
1645
|
}
|
|
1542
1646
|
|
|
1543
1647
|
// Copyright 2024 IOTA Stiftung.
|
|
1544
1648
|
// SPDX-License-Identifier: Apache-2.0.
|
|
1545
|
-
/* eslint-disable no-bitwise */
|
|
1546
1649
|
/**
|
|
1547
1650
|
* Perform HOTP.
|
|
1548
1651
|
* Implementation of https://datatracker.ietf.org/doc/html/rfc4226 .
|
|
@@ -1761,6 +1864,7 @@ exports.KeyType = KeyType;
|
|
|
1761
1864
|
exports.PasswordGenerator = PasswordGenerator;
|
|
1762
1865
|
exports.PasswordValidator = PasswordValidator;
|
|
1763
1866
|
exports.Pbkdf2 = Pbkdf2;
|
|
1867
|
+
exports.PemHelper = PemHelper;
|
|
1764
1868
|
exports.Secp256k1 = Secp256k1;
|
|
1765
1869
|
exports.Sha1 = Sha1;
|
|
1766
1870
|
exports.Sha256 = Sha256;
|