@opcat-labs/opcat 1.0.1 → 1.0.3
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/.cjs2esm.json +18 -0
- package/.mocharc.yaml +1 -1
- package/CHANGELOG.md +12 -0
- package/README.md +6 -0
- package/{lib/address.js → cjs/address.cjs} +77 -72
- package/cjs/block/block.cjs +332 -0
- package/{lib/block/blockheader.js → cjs/block/blockheader.cjs} +8 -7
- package/cjs/block/index.cjs +2 -0
- package/{lib/block/merkleblock.js → cjs/block/merkleblock.cjs} +23 -15
- package/cjs/bn.cjs +3411 -0
- package/{lib/crypto/bn.js → cjs/crypto/bn.cjs} +3 -3
- package/{lib/crypto/ecdsa.js → cjs/crypto/ecdsa.cjs} +150 -14
- package/{lib/crypto/hash.node.js → cjs/crypto/hash.cjs} +13 -2
- package/cjs/crypto/index.cjs +16 -0
- package/{lib/crypto/point.js → cjs/crypto/point.cjs} +11 -4
- package/cjs/crypto/random.cjs +18 -0
- package/{lib/crypto/signature.js → cjs/crypto/signature.cjs} +158 -8
- package/{lib/encoding/base58.js → cjs/encoding/base58.cjs} +58 -2
- package/cjs/encoding/base58check.cjs +192 -0
- package/cjs/encoding/bufferreader.cjs +333 -0
- package/cjs/encoding/bufferwriter.cjs +244 -0
- package/{lib/encoding/decode-asm.js → cjs/encoding/decode-asm.cjs} +4 -4
- package/{lib/encoding/decode-hex.js → cjs/encoding/decode-hex.cjs} +1 -1
- package/cjs/encoding/index.cjs +14 -0
- package/cjs/encoding/varint.cjs +116 -0
- package/{lib/errors/index.js → cjs/errors/index.cjs} +9 -9
- package/{lib/errors/spec.js → cjs/errors/spec.cjs} +2 -2
- package/cjs/hash-cache.cjs +98 -0
- package/{lib/hdprivatekey.js → cjs/hdprivatekey.cjs} +232 -140
- package/{lib/hdpublickey.js → cjs/hdpublickey.cjs} +120 -93
- package/cjs/index.cjs +94 -0
- package/cjs/interpreter/index.cjs +2 -0
- package/cjs/interpreter/interpreter.cjs +1988 -0
- package/{lib/script/stack.js → cjs/interpreter/stack.cjs} +9 -2
- package/{lib/message/message.js → cjs/message/message.cjs} +62 -25
- package/cjs/mnemonic/index.cjs +3 -0
- package/{lib/mnemonic/mnemonic.js → cjs/mnemonic/mnemonic.cjs} +44 -13
- package/{lib/mnemonic/pbkdf2.node.js → cjs/mnemonic/pbkdf2.cjs} +9 -2
- package/cjs/mnemonic/words/index.cjs +66 -0
- package/cjs/network.cjs +13 -0
- package/cjs/networks.cjs +321 -0
- package/{lib/opcode.js → cjs/opcode.cjs} +69 -5
- package/cjs/privatekey.cjs +422 -0
- package/{lib/publickey.js → cjs/publickey.cjs} +14 -16
- package/cjs/script/index.cjs +2 -0
- package/{lib/script/script.js → cjs/script/script.cjs} +322 -67
- package/cjs/transaction/index.cjs +5 -0
- package/cjs/transaction/input/index.cjs +34 -0
- package/cjs/transaction/input/input.cjs +396 -0
- package/{lib/transaction/input/multisig.js → cjs/transaction/input/multisig.cjs} +112 -18
- package/{lib/transaction/input/publickey.js → cjs/transaction/input/publickey.cjs} +29 -19
- package/{lib/transaction/input/publickeyhash.js → cjs/transaction/input/publickeyhash.cjs} +25 -17
- package/{lib/transaction/output.js → cjs/transaction/output.cjs} +100 -15
- package/cjs/transaction/sighash.cjs +187 -0
- package/{lib/transaction/signature.js → cjs/transaction/signature.cjs} +30 -6
- package/cjs/transaction/transaction.cjs +2000 -0
- package/{lib/transaction/unspentoutput.js → cjs/transaction/unspentoutput.cjs} +5 -5
- package/cjs/util/derivation.cjs +53 -0
- package/cjs/util/index.cjs +11 -0
- package/cjs/util/js.cjs +95 -0
- package/{lib/util/preconditions.js → cjs/util/preconditions.cjs} +2 -2
- package/esm/address.js +483 -0
- package/{lib → esm}/block/block.js +82 -27
- package/esm/block/blockheader.js +296 -0
- package/esm/block/index.js +2 -0
- package/esm/block/merkleblock.js +331 -0
- package/esm/bn.js +3411 -0
- package/esm/crypto/bn.js +278 -0
- package/esm/crypto/ecdsa.js +475 -0
- package/{lib/crypto/hash.browser.js → esm/crypto/hash.js} +18 -7
- package/esm/crypto/index.js +16 -0
- package/esm/crypto/point.js +228 -0
- package/esm/crypto/random.js +18 -0
- package/esm/crypto/signature.js +475 -0
- package/esm/encoding/base58.js +167 -0
- package/esm/encoding/base58check.js +192 -0
- package/esm/encoding/bufferreader.js +333 -0
- package/esm/encoding/bufferwriter.js +243 -0
- package/esm/encoding/decode-asm.js +24 -0
- package/esm/encoding/decode-hex.js +32 -0
- package/esm/encoding/decode-script-chunks.js +43 -0
- package/esm/encoding/encode-hex.js +284 -0
- package/esm/encoding/index.js +14 -0
- package/esm/encoding/is-hex.js +7 -0
- package/esm/encoding/varint.js +116 -0
- package/esm/errors/index.js +54 -0
- package/esm/errors/spec.js +314 -0
- package/esm/hash-cache.js +98 -0
- package/esm/hdprivatekey.js +768 -0
- package/esm/hdpublickey.js +549 -0
- package/esm/index.js +66 -0
- package/esm/interpreter/index.js +2 -0
- package/{lib/script → esm/interpreter}/interpreter.js +219 -66
- package/esm/interpreter/stack.js +116 -0
- package/esm/message/message.js +228 -0
- package/esm/mnemonic/index.js +3 -0
- package/esm/mnemonic/mnemonic.js +332 -0
- package/{lib/mnemonic/pbkdf2.browser.js → esm/mnemonic/pbkdf2.js} +13 -6
- package/esm/mnemonic/words/chinese.js +2054 -0
- package/esm/mnemonic/words/english.js +2054 -0
- package/esm/mnemonic/words/french.js +2054 -0
- package/esm/mnemonic/words/index.js +66 -0
- package/esm/mnemonic/words/italian.js +2054 -0
- package/esm/mnemonic/words/japanese.js +2054 -0
- package/esm/mnemonic/words/spanish.js +2054 -0
- package/esm/network.js +13 -0
- package/{lib → esm}/networks.js +61 -120
- package/esm/opcode.js +319 -0
- package/{lib → esm}/privatekey.js +76 -28
- package/esm/publickey.js +384 -0
- package/esm/script/index.js +2 -0
- package/esm/script/script.js +1329 -0
- package/esm/script/write-i32-le.js +17 -0
- package/esm/script/write-push-data.js +35 -0
- package/esm/script/write-u16-le.js +12 -0
- package/esm/script/write-u32-le.js +16 -0
- package/esm/script/write-u64-le.js +24 -0
- package/esm/script/write-u8-le.js +8 -0
- package/esm/script/write-varint.js +46 -0
- package/esm/transaction/index.js +5 -0
- package/esm/transaction/input/index.js +33 -0
- package/{lib → esm}/transaction/input/input.js +132 -90
- package/esm/transaction/input/multisig.js +335 -0
- package/esm/transaction/input/publickey.js +108 -0
- package/esm/transaction/input/publickeyhash.js +124 -0
- package/esm/transaction/output.js +316 -0
- package/{lib → esm}/transaction/sighash.js +42 -22
- package/esm/transaction/signature.js +120 -0
- package/{lib → esm}/transaction/transaction.js +522 -163
- package/esm/transaction/unspentoutput.js +112 -0
- package/esm/util/_.js +47 -0
- package/esm/util/derivation.js +53 -0
- package/esm/util/index.js +12 -0
- package/esm/util/js.js +95 -0
- package/esm/util/preconditions.js +33 -0
- package/fixup.cjs +17 -0
- package/package.json +18 -4
- package/test/{address.js → address.cjs} +14 -43
- package/test/block/{block.js → block.cjs} +3 -5
- package/test/block/{blockheader.js → blockheader.cjs} +2 -2
- package/test/block/{merklebloack.js → merklebloack.cjs} +2 -2
- package/test/crypto/{ecdsa.js → ecdsa.cjs} +9 -9
- package/test/crypto/{hash.browser.js → hash.browser.cjs} +2 -1
- package/test/crypto/{signature.js → signature.cjs} +2 -2
- package/test/data/bitcoind/script_tests.json +5 -5
- package/test/{hashCache.js → hashCache.cjs} +2 -1
- package/test/{hdkeys.js → hdkeys.cjs} +4 -2
- package/test/{hdprivatekey.js → hdprivatekey.cjs} +7 -6
- package/test/{hdpublickey.js → hdpublickey.cjs} +2 -7
- package/test/mnemonic/{pbkdf2.test.js → pbkdf2.test.cjs} +2 -2
- package/test/{networks.js → networks.cjs} +12 -31
- package/test/{publickey.js → publickey.cjs} +2 -2
- package/test/script/{interpreter.js → interpreter.cjs} +5 -5
- package/test/script/{script.js → script.cjs} +8 -2
- package/test/transaction/{deserialize.js → deserialize.cjs} +2 -2
- package/test/transaction/input/{input.js → input.cjs} +1 -1
- package/test/transaction/input/{multisig.js → multisig.cjs} +2 -1
- package/test/transaction/input/{publickeyhash.js → publickeyhash.cjs} +1 -1
- package/test/transaction/{sighash.js → sighash.cjs} +1 -1
- package/test/transaction/{transaction.js → transaction.cjs} +2 -2
- package/tsconfig.json +13 -0
- package/types/address.d.cts +252 -0
- package/types/block/block.d.cts +139 -0
- package/types/block/blockheader.d.cts +125 -0
- package/types/block/index.d.cts +2 -0
- package/types/block/merkleblock.d.cts +95 -0
- package/types/bn.d.cts +202 -0
- package/types/crypto/bn.d.cts +2 -0
- package/types/crypto/ecdsa.d.cts +187 -0
- package/types/crypto/hash.d.cts +118 -0
- package/types/crypto/index.d.cts +7 -0
- package/types/crypto/point.d.cts +134 -0
- package/types/crypto/random.d.cts +13 -0
- package/types/crypto/signature.d.cts +160 -0
- package/types/encoding/base58.d.cts +106 -0
- package/types/encoding/base58check.d.cts +107 -0
- package/types/encoding/bufferreader.d.cts +164 -0
- package/types/encoding/bufferwriter.d.cts +126 -0
- package/types/encoding/decode-asm.d.cts +2 -0
- package/types/encoding/decode-hex.d.cts +2 -0
- package/types/encoding/decode-script-chunks.d.cts +14 -0
- package/types/encoding/encode-hex.d.cts +2 -0
- package/types/encoding/index.d.cts +6 -0
- package/types/encoding/is-hex.d.cts +2 -0
- package/types/encoding/varint.d.cts +66 -0
- package/types/errors/index.d.cts +4 -0
- package/types/errors/spec.d.cts +22 -0
- package/types/hash-cache.d.cts +65 -0
- package/types/hdprivatekey.d.cts +281 -0
- package/types/hdpublickey.d.cts +240 -0
- package/types/index.d.cts +26 -0
- package/types/interpreter/index.d.cts +2 -0
- package/types/interpreter/interpreter.d.cts +228 -0
- package/types/interpreter/stack.d.cts +35 -0
- package/types/message/message.d.cts +110 -0
- package/types/mnemonic/index.d.cts +2 -0
- package/types/mnemonic/mnemonic.d.cts +171 -0
- package/types/mnemonic/pbkdf2.d.cts +14 -0
- package/types/mnemonic/words/chinese.d.cts +2 -0
- package/types/mnemonic/words/english.d.cts +2 -0
- package/types/mnemonic/words/french.d.cts +2 -0
- package/types/mnemonic/words/index.d.cts +22 -0
- package/types/mnemonic/words/italian.d.cts +2 -0
- package/types/mnemonic/words/japanese.d.cts +2 -0
- package/types/mnemonic/words/spanish.d.cts +2 -0
- package/types/network.d.cts +11 -0
- package/types/networks.d.cts +76 -0
- package/types/opcode.d.cts +93 -0
- package/types/privatekey.d.cts +169 -0
- package/types/publickey.d.cts +202 -0
- package/types/script/index.d.cts +2 -0
- package/types/script/script.d.cts +449 -0
- package/types/script/write-i32-le.d.cts +2 -0
- package/types/script/write-push-data.d.cts +2 -0
- package/types/script/write-u16-le.d.cts +2 -0
- package/types/script/write-u32-le.d.cts +2 -0
- package/types/script/write-u64-le.d.cts +2 -0
- package/types/script/write-u8-le.d.cts +2 -0
- package/types/script/write-varint.d.cts +2 -0
- package/types/transaction/index.d.cts +2 -0
- package/types/transaction/input/index.d.cts +2 -0
- package/types/transaction/input/input.d.cts +178 -0
- package/types/transaction/input/multisig.d.cts +127 -0
- package/types/transaction/input/publickey.d.cts +44 -0
- package/types/transaction/input/publickeyhash.d.cts +45 -0
- package/types/transaction/output.d.cts +118 -0
- package/types/transaction/sighash.d.cts +61 -0
- package/types/transaction/signature.d.cts +43 -0
- package/types/transaction/transaction.d.cts +716 -0
- package/types/transaction/unspentoutput.d.cts +83 -0
- package/types/util/_.d.cts +26 -0
- package/types/util/derivation.d.cts +21 -0
- package/types/util/index.d.cts +5 -0
- package/types/util/js.d.cts +50 -0
- package/types/util/preconditions.d.cts +3 -0
- package/index.d.ts +0 -1541
- package/index.js +0 -74
- package/lib/block/index.js +0 -4
- package/lib/bn.js +0 -3423
- package/lib/crypto/hash.js +0 -2
- package/lib/crypto/random.browser.js +0 -28
- package/lib/crypto/random.js +0 -2
- package/lib/crypto/random.node.js +0 -11
- package/lib/encoding/base58check.js +0 -121
- package/lib/encoding/bufferreader.js +0 -212
- package/lib/encoding/bufferwriter.js +0 -140
- package/lib/encoding/varint.js +0 -75
- package/lib/hash-cache.js +0 -50
- package/lib/mnemonic/pbkdf2.js +0 -2
- package/lib/mnemonic/words/index.js +0 -8
- package/lib/script/index.js +0 -5
- package/lib/transaction/index.js +0 -7
- package/lib/transaction/input/index.js +0 -5
- package/lib/util/js.js +0 -90
- /package/{lib/encoding/decode-script-chunks.js → cjs/encoding/decode-script-chunks.cjs} +0 -0
- /package/{lib/encoding/encode-hex.js → cjs/encoding/encode-hex.cjs} +0 -0
- /package/{lib/encoding/is-hex.js → cjs/encoding/is-hex.cjs} +0 -0
- /package/{lib/mnemonic/words/chinese.js → cjs/mnemonic/words/chinese.cjs} +0 -0
- /package/{lib/mnemonic/words/english.js → cjs/mnemonic/words/english.cjs} +0 -0
- /package/{lib/mnemonic/words/french.js → cjs/mnemonic/words/french.cjs} +0 -0
- /package/{lib/mnemonic/words/italian.js → cjs/mnemonic/words/italian.cjs} +0 -0
- /package/{lib/mnemonic/words/japanese.js → cjs/mnemonic/words/japanese.cjs} +0 -0
- /package/{lib/mnemonic/words/spanish.js → cjs/mnemonic/words/spanish.cjs} +0 -0
- /package/{lib/script/write-i32-le.js → cjs/script/write-i32-le.cjs} +0 -0
- /package/{lib/script/write-push-data.js → cjs/script/write-push-data.cjs} +0 -0
- /package/{lib/script/write-u16-le.js → cjs/script/write-u16-le.cjs} +0 -0
- /package/{lib/script/write-u32-le.js → cjs/script/write-u32-le.cjs} +0 -0
- /package/{lib/script/write-u64-le.js → cjs/script/write-u64-le.cjs} +0 -0
- /package/{lib/script/write-u8-le.js → cjs/script/write-u8-le.cjs} +0 -0
- /package/{lib/script/write-varint.js → cjs/script/write-varint.cjs} +0 -0
- /package/{lib/util/_.js → cjs/util/_.cjs} +0 -0
- /package/test/crypto/{bn.js → bn.cjs} +0 -0
- /package/test/crypto/{hash.js → hash.cjs} +0 -0
- /package/test/crypto/{point.js → point.cjs} +0 -0
- /package/test/crypto/{random.js → random.cjs} +0 -0
- /package/test/data/{blk86756-testnet.js → blk86756-testnet.cjs} +0 -0
- /package/test/data/{merkleblocks.js → merkleblocks.cjs} +0 -0
- /package/test/encoding/{base58.js → base58.cjs} +0 -0
- /package/test/encoding/{base58check.js → base58check.cjs} +0 -0
- /package/test/encoding/{bufferreader.js → bufferreader.cjs} +0 -0
- /package/test/encoding/{bufferwriter.js → bufferwriter.cjs} +0 -0
- /package/test/encoding/{varint.js → varint.cjs} +0 -0
- /package/test/{index.js → index.cjs} +0 -0
- /package/test/message/{message.js → message.cjs} +0 -0
- /package/test/mnemonic/{mnemonic.js → mnemonic.cjs} +0 -0
- /package/test/{opcode.js → opcode.cjs} +0 -0
- /package/test/{privatekey.js → privatekey.cjs} +0 -0
- /package/test/transaction/input/{publickey.js → publickey.cjs} +0 -0
- /package/test/transaction/{output.js → output.cjs} +0 -0
- /package/test/transaction/{signature.js → signature.cjs} +0 -0
- /package/test/transaction/{unspentoutput.js → unspentoutput.cjs} +0 -0
- /package/test/util/{js.js → js.cjs} +0 -0
- /package/test/util/{preconditions.js → preconditions.cjs} +0 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import _ from '../util/_.js';
|
|
4
|
+
import PrivateKey from '../privatekey.js';
|
|
5
|
+
import PublicKey from '../publickey.js';
|
|
6
|
+
import Address from '../address.js';
|
|
7
|
+
import BufferWriter from '../encoding/bufferwriter.js';
|
|
8
|
+
import ECDSA from '../crypto/ecdsa.js';
|
|
9
|
+
import Signature from '../crypto/signature.js';
|
|
10
|
+
import Hash from '../crypto/hash.js';
|
|
11
|
+
import JSUtil from '../util/js.js';
|
|
12
|
+
import $ from '../util/preconditions.js';
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Creates a Message instance from a string or Buffer.
|
|
17
|
+
* @constructor
|
|
18
|
+
* @param {string|Buffer} message - The message content as either a string or Buffer
|
|
19
|
+
* @throws {Error} Will throw if message is not a string or Buffer
|
|
20
|
+
* @returns {Message} A new Message instance containing the message buffer
|
|
21
|
+
*/
|
|
22
|
+
function Message(message) {
|
|
23
|
+
if (!(this instanceof Message)) {
|
|
24
|
+
return new Message(message);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
$.checkArgument(
|
|
28
|
+
_.isString(message) || Buffer.isBuffer(message),
|
|
29
|
+
'First argument should be a string or Buffer',
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
if (_.isString(message)) {
|
|
33
|
+
this.messageBuffer = Buffer.from(message);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (Buffer.isBuffer(message)) {
|
|
37
|
+
this.messageBuffer = message;
|
|
38
|
+
}
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Signs a message with the given private key.
|
|
44
|
+
* @param {string|Buffer} message - The message to sign.
|
|
45
|
+
* @param {PrivateKey} privateKey - The private key used for signing.
|
|
46
|
+
* @returns {Message} The signed message instance.
|
|
47
|
+
*/
|
|
48
|
+
Message.sign = function (message, privateKey) {
|
|
49
|
+
return new Message(message).sign(privateKey);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
Message.verify = function (message, address, signature) {
|
|
53
|
+
return new Message(message).verify(address, signature);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
Message.MAGIC_BYTES = Buffer.from('Bitcoin Signed Message:\n');
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Calculates the magic hash for the message by concatenating magic bytes prefixes
|
|
60
|
+
* with the message buffer and computing a double SHA-256 hash.
|
|
61
|
+
* @returns {Buffer} The resulting 32-byte hash.
|
|
62
|
+
*/
|
|
63
|
+
Message.prototype.magicHash = function magicHash() {
|
|
64
|
+
var prefix1 = BufferWriter.varintBufNum(Message.MAGIC_BYTES.length);
|
|
65
|
+
var prefix2 = BufferWriter.varintBufNum(this.messageBuffer.length);
|
|
66
|
+
var buf = Buffer.concat([prefix1, Message.MAGIC_BYTES, prefix2, this.messageBuffer]);
|
|
67
|
+
var hash = Hash.sha256sha256(buf);
|
|
68
|
+
return hash;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Signs the message with the provided private key.
|
|
73
|
+
* @private
|
|
74
|
+
* @param {PrivateKey} privateKey - The private key instance to sign with.
|
|
75
|
+
* @returns {Buffer} The signature generated using ECDSA.
|
|
76
|
+
* @throws {Error} If the first argument is not a PrivateKey instance.
|
|
77
|
+
*/
|
|
78
|
+
Message.prototype._sign = function _sign(privateKey) {
|
|
79
|
+
$.checkArgument(
|
|
80
|
+
privateKey instanceof PrivateKey,
|
|
81
|
+
'First argument should be an instance of PrivateKey',
|
|
82
|
+
);
|
|
83
|
+
var hash = this.magicHash();
|
|
84
|
+
return ECDSA.signWithCalcI(hash, privateKey);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Will sign a message with a given bitcoin private key.
|
|
89
|
+
*
|
|
90
|
+
* @param {PrivateKey} privateKey - An instance of PrivateKey
|
|
91
|
+
* @returns {String} A base64 encoded compact signature
|
|
92
|
+
*/
|
|
93
|
+
Message.prototype.sign = function sign(privateKey) {
|
|
94
|
+
var signature = this._sign(privateKey);
|
|
95
|
+
return signature.toCompact().toString('base64');
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Verifies the message signature using the provided public key.
|
|
100
|
+
* @param {PublicKey} publicKey - The public key to verify against
|
|
101
|
+
* @param {Signature} signature - The signature to verify
|
|
102
|
+
* @returns {boolean} True if signature is valid, false otherwise
|
|
103
|
+
* @throws {Error} If arguments are not valid PublicKey/Signature instances
|
|
104
|
+
*/
|
|
105
|
+
Message.prototype._verify = function _verify(publicKey, signature) {
|
|
106
|
+
$.checkArgument(
|
|
107
|
+
publicKey instanceof PublicKey,
|
|
108
|
+
'First argument should be an instance of PublicKey',
|
|
109
|
+
);
|
|
110
|
+
$.checkArgument(
|
|
111
|
+
signature instanceof Signature,
|
|
112
|
+
'Second argument should be an instance of Signature',
|
|
113
|
+
);
|
|
114
|
+
var hash = this.magicHash();
|
|
115
|
+
var verified = ECDSA.verify(hash, signature, publicKey);
|
|
116
|
+
if (!verified) {
|
|
117
|
+
this.error = 'The signature was invalid';
|
|
118
|
+
}
|
|
119
|
+
return verified;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Will return a boolean of the signature is valid for a given bitcoin address.
|
|
124
|
+
* If it isn't the specific reason is accessible via the "error" member.
|
|
125
|
+
*
|
|
126
|
+
* @param {Address|String} bitcoinAddress - A bitcoin address
|
|
127
|
+
* @param {String} signatureString - A base64 encoded compact signature
|
|
128
|
+
* @returns {Boolean}
|
|
129
|
+
*/
|
|
130
|
+
Message.prototype.verify = function verify(bitcoinAddress, signatureString) {
|
|
131
|
+
$.checkArgument(bitcoinAddress);
|
|
132
|
+
$.checkArgument(signatureString && _.isString(signatureString));
|
|
133
|
+
|
|
134
|
+
if (_.isString(bitcoinAddress)) {
|
|
135
|
+
bitcoinAddress = Address.fromString(bitcoinAddress);
|
|
136
|
+
}
|
|
137
|
+
var signature = Signature.fromCompact(Buffer.from(signatureString, 'base64'));
|
|
138
|
+
|
|
139
|
+
// recover the public key
|
|
140
|
+
var ecdsa = new ECDSA();
|
|
141
|
+
ecdsa.hashbuf = this.magicHash();
|
|
142
|
+
ecdsa.sig = signature;
|
|
143
|
+
var publicKey = ecdsa.toPublicKey();
|
|
144
|
+
|
|
145
|
+
var signatureAddress = Address.fromPublicKey(publicKey.toBuffer(), bitcoinAddress.network);
|
|
146
|
+
|
|
147
|
+
// check that the recovered address and specified address match
|
|
148
|
+
if (bitcoinAddress.toString() !== signatureAddress.toString()) {
|
|
149
|
+
this.error = 'The signature did not match the message digest';
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return this._verify(publicKey, signature);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Instantiate a message from a message string
|
|
158
|
+
*
|
|
159
|
+
* @param {String} str - A string of the message
|
|
160
|
+
* @returns {Message} A new instance of a Message
|
|
161
|
+
*/
|
|
162
|
+
Message.fromString = function (str) {
|
|
163
|
+
return new Message(str);
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Instantiate a message from JSON
|
|
168
|
+
*
|
|
169
|
+
* @param {String} json - An JSON string or Object with keys: message
|
|
170
|
+
* @returns {Message} A new instance of a Message
|
|
171
|
+
*/
|
|
172
|
+
Message.fromJSON = function fromJSON(json) {
|
|
173
|
+
if (JSUtil.isValidJSON(json)) {
|
|
174
|
+
json = JSON.parse(json);
|
|
175
|
+
}
|
|
176
|
+
return Message.fromObject(json);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Converts the message to a plain object with hex representation.
|
|
182
|
+
* @returns {Object} An object containing the hex string of the message buffer.
|
|
183
|
+
*/
|
|
184
|
+
Message.prototype.toObject = function toObject() {
|
|
185
|
+
return {
|
|
186
|
+
messageHex: this.messageBuffer.toString('hex'),
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Creates a Message instance from an object containing a hex-encoded message.
|
|
192
|
+
* @param {Object} obj - The source object containing the message data.
|
|
193
|
+
* @param {string} obj.messageHex - Hex-encoded message string.
|
|
194
|
+
* @returns {Message} A new Message instance created from the decoded buffer.
|
|
195
|
+
*/
|
|
196
|
+
Message.fromObject = function (obj) {
|
|
197
|
+
let messageBuffer = Buffer.from(obj.messageHex, 'hex');
|
|
198
|
+
return new Message(messageBuffer);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Converts the Message instance to a JSON string representation.
|
|
204
|
+
* @returns {string} The JSON string representation of the Message object.
|
|
205
|
+
*/
|
|
206
|
+
Message.prototype.toJSON = function toJSON() {
|
|
207
|
+
return JSON.stringify(this.toObject());
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Converts the message buffer to a string representation.
|
|
213
|
+
* @returns {string} The string representation of the message buffer.
|
|
214
|
+
*/
|
|
215
|
+
Message.prototype.toString = function () {
|
|
216
|
+
return this.messageBuffer.toString();
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Custom inspect method for Message instances.
|
|
222
|
+
* @returns {string} String representation in format '<Message: [content]>'.
|
|
223
|
+
*/
|
|
224
|
+
Message.prototype.inspect = function () {
|
|
225
|
+
return '<Message: ' + this.toString() + '>';
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
export default Message;
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import BN from '../crypto/bn.js';
|
|
3
|
+
import Hash from '../crypto/hash.js';
|
|
4
|
+
import Random from '../crypto/random.js';
|
|
5
|
+
import unorm from 'unorm';
|
|
6
|
+
import _ from '../util/_.js';
|
|
7
|
+
import pbkdf2 from './pbkdf2.js';
|
|
8
|
+
import errors from '../errors/index.js';
|
|
9
|
+
import $ from '../util/preconditions.js';
|
|
10
|
+
import HDPrivateKey from '../hdprivatekey.js';
|
|
11
|
+
import Words from './words/index.js';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* This is an immutable class that represents a BIP39 Mnemonic code.
|
|
16
|
+
* See BIP39 specification for more info: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
|
|
17
|
+
* A Mnemonic code is a a group of easy to remember words used for the generation
|
|
18
|
+
* of deterministic wallets. A Mnemonic can be used to generate a seed using
|
|
19
|
+
* an optional passphrase, for later generate a HDPrivateKey.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* // generate a random mnemonic
|
|
23
|
+
* var mnemonic = new Mnemonic();
|
|
24
|
+
* var phrase = mnemonic.phrase;
|
|
25
|
+
*
|
|
26
|
+
* // use a different language
|
|
27
|
+
* var mnemonic = new Mnemonic(Mnemonic.Words.SPANISH);
|
|
28
|
+
* var xprivkey = mnemonic.toHDPrivateKey();
|
|
29
|
+
*
|
|
30
|
+
* @param {Buffer|string|number} [data] - Input data (Buffer for seed, string for phrase, or number for entropy bits)
|
|
31
|
+
* @param {Array} [wordlist] - Optional wordlist for phrase generation/validation
|
|
32
|
+
* @throws {InvalidArgument} If invalid data type provided
|
|
33
|
+
* @throws {Mnemonic.UnknownWordlist} If phrase language can't be detected
|
|
34
|
+
* @throws {Mnemonic.InvalidMnemonic} If phrase is invalid
|
|
35
|
+
* @throws {InvalidArgument} If invalid ENT value (must be >=128 and divisible by 32)
|
|
36
|
+
* @returns {Mnemonic} A new instance of Mnemonic
|
|
37
|
+
* @constructor
|
|
38
|
+
*/
|
|
39
|
+
function Mnemonic (data, wordlist) {
|
|
40
|
+
if (!(this instanceof Mnemonic)) {
|
|
41
|
+
return new Mnemonic(data, wordlist);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (_.isArray(data)) {
|
|
45
|
+
wordlist = data;
|
|
46
|
+
data = null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// handle data overloading
|
|
50
|
+
var ent, phrase, seed;
|
|
51
|
+
if (Buffer.isBuffer(data)) {
|
|
52
|
+
seed = data;
|
|
53
|
+
} else if (_.isString(data)) {
|
|
54
|
+
phrase = unorm.nfkd(data);
|
|
55
|
+
} else if (_.isNumber(data)) {
|
|
56
|
+
ent = data;
|
|
57
|
+
} else if (data) {
|
|
58
|
+
throw new errors.InvalidArgument('data', 'Must be a Buffer, a string or an integer');
|
|
59
|
+
}
|
|
60
|
+
ent = ent || 128;
|
|
61
|
+
|
|
62
|
+
// check and detect wordlist
|
|
63
|
+
wordlist = wordlist || Mnemonic._getDictionary(phrase);
|
|
64
|
+
if (phrase && !wordlist) {
|
|
65
|
+
throw new errors.Mnemonic.UnknownWordlist(phrase);
|
|
66
|
+
}
|
|
67
|
+
wordlist = wordlist || Mnemonic.Words.ENGLISH;
|
|
68
|
+
|
|
69
|
+
if (seed) {
|
|
70
|
+
phrase = Mnemonic._entropy2mnemonic(seed, wordlist);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// validate phrase and ent
|
|
74
|
+
if (phrase && !Mnemonic.isValid(phrase, wordlist)) {
|
|
75
|
+
throw new errors.Mnemonic.InvalidMnemonic(phrase);
|
|
76
|
+
}
|
|
77
|
+
if (ent % 32 !== 0 || ent < 128) {
|
|
78
|
+
throw new errors.InvalidArgument('ENT', 'Values must be ENT > 128 and ENT % 32 == 0');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
phrase = phrase || Mnemonic._mnemonic(ent, wordlist);
|
|
82
|
+
|
|
83
|
+
Object.defineProperty(this, 'wordlist', {
|
|
84
|
+
configurable: false,
|
|
85
|
+
value: wordlist,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
Object.defineProperty(this, 'phrase', {
|
|
89
|
+
configurable: false,
|
|
90
|
+
value: phrase,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Creates a new Mnemonic instance with random entropy using the specified wordlist.
|
|
96
|
+
* @param {Array} [wordlist=Mnemonic.Words.ENGLISH] - The wordlist to use for mnemonic generation (defaults to English).
|
|
97
|
+
* @returns {Mnemonic} A new Mnemonic instance with random entropy.
|
|
98
|
+
*/
|
|
99
|
+
Mnemonic.fromRandom = function (wordlist = Mnemonic.Words.ENGLISH) {
|
|
100
|
+
return new Mnemonic(wordlist);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Creates a Mnemonic instance from a mnemonic string.
|
|
105
|
+
* @param {string} mnemonic - The mnemonic phrase string.
|
|
106
|
+
* @param {string} [wordlist=Mnemonic.Words.ENGLISH] - Optional wordlist (defaults to English).
|
|
107
|
+
* @returns {Mnemonic} A new Mnemonic instance.
|
|
108
|
+
*/
|
|
109
|
+
Mnemonic.fromString = function (mnemonic, wordlist = Mnemonic.Words.ENGLISH) {
|
|
110
|
+
return new Mnemonic(mnemonic, wordlist);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Will return a boolean if the mnemonic is valid
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
*
|
|
118
|
+
* var valid = Mnemonic.isValid('lab rescue lunch elbow recall phrase perfect donkey biology guess moment husband');
|
|
119
|
+
* // true
|
|
120
|
+
*
|
|
121
|
+
* @param {String} mnemonic - The mnemonic string
|
|
122
|
+
* @param {String} [wordlist] - The wordlist used
|
|
123
|
+
* @returns {boolean}
|
|
124
|
+
*/
|
|
125
|
+
Mnemonic.isValid = function (mnemonic, wordlist) {
|
|
126
|
+
mnemonic = unorm.nfkd(mnemonic);
|
|
127
|
+
wordlist = wordlist || Mnemonic._getDictionary(mnemonic);
|
|
128
|
+
|
|
129
|
+
if (!wordlist) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
var words = mnemonic.split(' ');
|
|
134
|
+
var bin = '';
|
|
135
|
+
for (var i = 0; i < words.length; i++) {
|
|
136
|
+
var ind = wordlist.indexOf(words[i]);
|
|
137
|
+
if (ind < 0) return false;
|
|
138
|
+
bin = bin + ('00000000000' + ind.toString(2)).slice(-11);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
var cs = bin.length / 33;
|
|
142
|
+
var hashBits = bin.slice(-cs);
|
|
143
|
+
var nonhashBits = bin.slice(0, bin.length - cs);
|
|
144
|
+
var buf = Buffer.alloc(nonhashBits.length / 8);
|
|
145
|
+
for (i = 0; i < nonhashBits.length / 8; i++) {
|
|
146
|
+
buf.writeUInt8(parseInt(bin.slice(i * 8, (i + 1) * 8), 2), i);
|
|
147
|
+
}
|
|
148
|
+
var expectedHashBits = Mnemonic._entropyChecksum(buf);
|
|
149
|
+
return expectedHashBits === hashBits;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Internal function to check if a mnemonic belongs to a wordlist.
|
|
154
|
+
*
|
|
155
|
+
* @param {String} mnemonic - The mnemonic string
|
|
156
|
+
* @param {String} wordlist - The wordlist
|
|
157
|
+
* @returns {boolean}
|
|
158
|
+
* @private
|
|
159
|
+
*/
|
|
160
|
+
Mnemonic._belongsToWordlist = function (mnemonic, wordlist) {
|
|
161
|
+
var words = unorm.nfkd(mnemonic).split(' ');
|
|
162
|
+
for (var i = 0; i < words.length; i++) {
|
|
163
|
+
var ind = wordlist.indexOf(words[i]);
|
|
164
|
+
if (ind < 0) return false;
|
|
165
|
+
}
|
|
166
|
+
return true;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Internal function to detect the wordlist used to generate the mnemonic.
|
|
171
|
+
*
|
|
172
|
+
* @param {String} mnemonic - The mnemonic string
|
|
173
|
+
* @returns {Array} the wordlist or null
|
|
174
|
+
* @private
|
|
175
|
+
*/
|
|
176
|
+
Mnemonic._getDictionary = function (mnemonic) {
|
|
177
|
+
if (!mnemonic) return null;
|
|
178
|
+
|
|
179
|
+
var dicts = Object.keys(Mnemonic.Words);
|
|
180
|
+
for (var i = 0; i < dicts.length; i++) {
|
|
181
|
+
var key = dicts[i];
|
|
182
|
+
if (Mnemonic._belongsToWordlist(mnemonic, Mnemonic.Words[key])) {
|
|
183
|
+
return Mnemonic.Words[key];
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return null;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Will generate a seed based on the mnemonic and optional passphrase. Note that
|
|
191
|
+
* this seed is absolutely NOT the seed that is output by .toSeed(). These are
|
|
192
|
+
* two different seeds. The seed you want to put in here, if any, is just some
|
|
193
|
+
* random byte string. Normally you should rely on the .fromRandom() method.
|
|
194
|
+
*
|
|
195
|
+
* @param {String} [passphrase]
|
|
196
|
+
* @returns {Buffer}
|
|
197
|
+
*/
|
|
198
|
+
Mnemonic.prototype.toSeed = function (passphrase) {
|
|
199
|
+
passphrase = passphrase || '';
|
|
200
|
+
return pbkdf2(unorm.nfkd(this.phrase), unorm.nfkd('mnemonic' + passphrase), 2048, 64);
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Will generate a Mnemonic object based on a seed.
|
|
205
|
+
*
|
|
206
|
+
* @param {Buffer} [seed]
|
|
207
|
+
* @param {string} [wordlist]
|
|
208
|
+
* @returns {Mnemonic}
|
|
209
|
+
*/
|
|
210
|
+
Mnemonic.fromSeed = function (seed, wordlist) {
|
|
211
|
+
$.checkArgument(Buffer.isBuffer(seed), 'seed must be a Buffer.');
|
|
212
|
+
$.checkArgument(
|
|
213
|
+
_.isArray(wordlist) || _.isString(wordlist),
|
|
214
|
+
'wordlist must be a string or an array.',
|
|
215
|
+
);
|
|
216
|
+
return new Mnemonic(seed, wordlist);
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
*
|
|
221
|
+
* Generates a HD Private Key from a Mnemonic.
|
|
222
|
+
* Optionally receive a passphrase and bitcoin network.
|
|
223
|
+
*
|
|
224
|
+
* @param {String=} [passphrase]
|
|
225
|
+
* @param {Network|String|number=} [network] - The network: 'livenet' or 'testnet'
|
|
226
|
+
* @returns {HDPrivateKey}
|
|
227
|
+
*/
|
|
228
|
+
Mnemonic.prototype.toHDPrivateKey = function (passphrase, network) {
|
|
229
|
+
var seed = this.toSeed(passphrase);
|
|
230
|
+
return HDPrivateKey.fromSeed(seed, network);
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Will return a the string representation of the mnemonic
|
|
235
|
+
*
|
|
236
|
+
* @returns {String} Mnemonic
|
|
237
|
+
*/
|
|
238
|
+
Mnemonic.prototype.toString = function () {
|
|
239
|
+
return this.phrase;
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Will return a string formatted for the console
|
|
244
|
+
*
|
|
245
|
+
* @returns {String} Mnemonic
|
|
246
|
+
*/
|
|
247
|
+
Mnemonic.prototype.inspect = function () {
|
|
248
|
+
return '<Mnemonic: ' + this.toString() + ' >';
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Internal function to generate a random mnemonic
|
|
253
|
+
*
|
|
254
|
+
* @param {Number} ENT - Entropy size, defaults to 128
|
|
255
|
+
* @param {Array} wordlist - Array of words to generate the mnemonic
|
|
256
|
+
* @returns {String} Mnemonic string
|
|
257
|
+
* @private
|
|
258
|
+
*/
|
|
259
|
+
Mnemonic._mnemonic = function (ENT, wordlist) {
|
|
260
|
+
var buf = Random.getRandomBuffer(ENT / 8);
|
|
261
|
+
return Mnemonic._entropy2mnemonic(buf, wordlist);
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Internal function to generate mnemonic based on entropy
|
|
266
|
+
*
|
|
267
|
+
* @param {Number} entropy - Entropy buffer
|
|
268
|
+
* @param {Array} wordlist - Array of words to generate the mnemonic
|
|
269
|
+
* @returns {String} Mnemonic string
|
|
270
|
+
* @private
|
|
271
|
+
*/
|
|
272
|
+
Mnemonic._entropy2mnemonic = function (entropy, wordlist) {
|
|
273
|
+
var bin = '';
|
|
274
|
+
for (var i = 0; i < entropy.length; i++) {
|
|
275
|
+
bin = bin + ('00000000' + entropy[i].toString(2)).slice(-8);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
bin = bin + Mnemonic._entropyChecksum(entropy);
|
|
279
|
+
if (bin.length % 11 !== 0) {
|
|
280
|
+
throw new errors.InvalidEntropy(bin);
|
|
281
|
+
}
|
|
282
|
+
var mnemonic = [];
|
|
283
|
+
for (i = 0; i < bin.length / 11; i++) {
|
|
284
|
+
var wi = parseInt(bin.slice(i * 11, (i + 1) * 11), 2);
|
|
285
|
+
mnemonic.push(wordlist[wi]);
|
|
286
|
+
}
|
|
287
|
+
var ret;
|
|
288
|
+
if (wordlist === Mnemonic.Words.JAPANESE) {
|
|
289
|
+
ret = mnemonic.join('\u3000');
|
|
290
|
+
} else {
|
|
291
|
+
ret = mnemonic.join(' ');
|
|
292
|
+
}
|
|
293
|
+
return ret;
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Internal function to create checksum of entropy
|
|
298
|
+
*
|
|
299
|
+
* @param entropy
|
|
300
|
+
* @returns {string} Checksum of entropy length / 32
|
|
301
|
+
* @private
|
|
302
|
+
*/
|
|
303
|
+
Mnemonic._entropyChecksum = function (entropy) {
|
|
304
|
+
var hash = Hash.sha256(entropy);
|
|
305
|
+
var bits = entropy.length * 8;
|
|
306
|
+
var cs = bits / 32;
|
|
307
|
+
|
|
308
|
+
var hashbits = new BN(hash.toString('hex'), 16).toString(2);
|
|
309
|
+
|
|
310
|
+
// zero pad the hash bits
|
|
311
|
+
while (hashbits.length % 256 !== 0) {
|
|
312
|
+
hashbits = '0' + hashbits;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
var checksum = hashbits.slice(0, cs);
|
|
316
|
+
|
|
317
|
+
return checksum;
|
|
318
|
+
};
|
|
319
|
+
/**
|
|
320
|
+
* The list of valid mnemonic words used by the Mnemonic class.
|
|
321
|
+
* @type {Words}
|
|
322
|
+
*/
|
|
323
|
+
Mnemonic.Words = Words;
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Assigns the pbkdf2 function to Mnemonic.pbkdf2 for key derivation.
|
|
327
|
+
* @type {Function}
|
|
328
|
+
*/
|
|
329
|
+
Mnemonic.pbkdf2 = pbkdf2;
|
|
330
|
+
|
|
331
|
+
export default Mnemonic;
|
|
332
|
+
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import crypto from 'crypto';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* PDKBF2
|
|
6
|
+
* PDKBF2: Derives a key using PBKDF2 (Password-Based Key Derivation Function 2) with HMAC-SHA512.
|
|
7
7
|
* Credit to: https://github.com/stayradiated/pbkdf2-sha512
|
|
8
|
-
*
|
|
8
|
+
*
|
|
9
|
+
* @param {string|Buffer} key - The input key/password (as string or Buffer)
|
|
10
|
+
* @param {string|Buffer} salt - The salt value (as string or Buffer)
|
|
11
|
+
* @param {number} iterations - Number of iterations to perform
|
|
12
|
+
* @param {number} dkLen - Desired length of the derived key in bytes
|
|
13
|
+
* @returns {Buffer} Derived key as Buffer
|
|
14
|
+
* @throws {TypeError} If key or salt are not strings or Buffers
|
|
15
|
+
* @throws {Error} If requested key length is too long
|
|
9
16
|
*/
|
|
10
17
|
function pbkdf2(key, salt, iterations, dkLen) {
|
|
11
18
|
var hLen = 64; // SHA512 Mac length
|
|
@@ -45,12 +52,12 @@ function pbkdf2(key, salt, iterations, dkLen) {
|
|
|
45
52
|
block1[salt.length + 2] = (i >> 8) & 0xff;
|
|
46
53
|
block1[salt.length + 3] = (i >> 0) & 0xff;
|
|
47
54
|
|
|
48
|
-
U =
|
|
55
|
+
U = crypto.createHmac('sha512', key).update(block1).digest();
|
|
49
56
|
|
|
50
57
|
U.copy(T, 0, 0, hLen);
|
|
51
58
|
|
|
52
59
|
for (var j = 1; j < iterations; j++) {
|
|
53
|
-
U =
|
|
60
|
+
U = crypto.createHmac('sha512', key).update(U).digest();
|
|
54
61
|
|
|
55
62
|
for (var k = 0; k < hLen; k++) {
|
|
56
63
|
T[k] ^= U[k];
|
|
@@ -65,4 +72,4 @@ function pbkdf2(key, salt, iterations, dkLen) {
|
|
|
65
72
|
return DK;
|
|
66
73
|
}
|
|
67
74
|
|
|
68
|
-
|
|
75
|
+
export default pbkdf2;
|