@opcat-labs/opcat 1.0.0
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/.mocharc.yaml +3 -0
- package/index.d.ts +1541 -0
- package/index.js +74 -0
- package/lib/address.js +478 -0
- package/lib/block/block.js +277 -0
- package/lib/block/blockheader.js +295 -0
- package/lib/block/index.js +4 -0
- package/lib/block/merkleblock.js +323 -0
- package/lib/bn.js +3423 -0
- package/lib/crypto/bn.js +278 -0
- package/lib/crypto/ecdsa.js +339 -0
- package/lib/crypto/hash.browser.js +171 -0
- package/lib/crypto/hash.js +2 -0
- package/lib/crypto/hash.node.js +171 -0
- package/lib/crypto/point.js +221 -0
- package/lib/crypto/random.browser.js +28 -0
- package/lib/crypto/random.js +2 -0
- package/lib/crypto/random.node.js +11 -0
- package/lib/crypto/signature.js +325 -0
- package/lib/encoding/base58.js +111 -0
- package/lib/encoding/base58check.js +121 -0
- package/lib/encoding/bufferreader.js +212 -0
- package/lib/encoding/bufferwriter.js +140 -0
- package/lib/encoding/decode-asm.js +24 -0
- package/lib/encoding/decode-hex.js +32 -0
- package/lib/encoding/decode-script-chunks.js +43 -0
- package/lib/encoding/encode-hex.js +284 -0
- package/lib/encoding/is-hex.js +7 -0
- package/lib/encoding/varint.js +75 -0
- package/lib/errors/index.js +54 -0
- package/lib/errors/spec.js +314 -0
- package/lib/hash-cache.js +50 -0
- package/lib/hdprivatekey.js +678 -0
- package/lib/hdpublickey.js +525 -0
- package/lib/message/message.js +191 -0
- package/lib/mnemonic/mnemonic.js +303 -0
- package/lib/mnemonic/pbkdf2.browser.js +68 -0
- package/lib/mnemonic/pbkdf2.js +2 -0
- package/lib/mnemonic/pbkdf2.node.js +68 -0
- package/lib/mnemonic/words/chinese.js +2054 -0
- package/lib/mnemonic/words/english.js +2054 -0
- package/lib/mnemonic/words/french.js +2054 -0
- package/lib/mnemonic/words/index.js +8 -0
- package/lib/mnemonic/words/italian.js +2054 -0
- package/lib/mnemonic/words/japanese.js +2054 -0
- package/lib/mnemonic/words/spanish.js +2054 -0
- package/lib/networks.js +379 -0
- package/lib/opcode.js +255 -0
- package/lib/privatekey.js +374 -0
- package/lib/publickey.js +386 -0
- package/lib/script/index.js +5 -0
- package/lib/script/interpreter.js +1834 -0
- package/lib/script/script.js +1074 -0
- package/lib/script/stack.js +109 -0
- package/lib/script/write-i32-le.js +17 -0
- package/lib/script/write-push-data.js +35 -0
- package/lib/script/write-u16-le.js +12 -0
- package/lib/script/write-u32-le.js +16 -0
- package/lib/script/write-u64-le.js +24 -0
- package/lib/script/write-u8-le.js +8 -0
- package/lib/script/write-varint.js +46 -0
- package/lib/transaction/index.js +7 -0
- package/lib/transaction/input/index.js +5 -0
- package/lib/transaction/input/input.js +354 -0
- package/lib/transaction/input/multisig.js +242 -0
- package/lib/transaction/input/publickey.js +100 -0
- package/lib/transaction/input/publickeyhash.js +118 -0
- package/lib/transaction/output.js +231 -0
- package/lib/transaction/sighash.js +167 -0
- package/lib/transaction/signature.js +97 -0
- package/lib/transaction/transaction.js +1639 -0
- package/lib/transaction/unspentoutput.js +113 -0
- package/lib/util/_.js +47 -0
- package/lib/util/js.js +90 -0
- package/lib/util/preconditions.js +33 -0
- package/package.json +26 -0
- package/test/address.js +509 -0
- package/test/block/block.js +251 -0
- package/test/block/blockheader.js +275 -0
- package/test/block/merklebloack.js +211 -0
- package/test/crypto/bn.js +177 -0
- package/test/crypto/ecdsa.js +391 -0
- package/test/crypto/hash.browser.js +135 -0
- package/test/crypto/hash.js +136 -0
- package/test/crypto/point.js +224 -0
- package/test/crypto/random.js +32 -0
- package/test/crypto/signature.js +409 -0
- package/test/data/bip69.json +215 -0
- package/test/data/bitcoind/base58_keys_invalid.json +52 -0
- package/test/data/bitcoind/base58_keys_valid.json +335 -0
- package/test/data/bitcoind/blocks.json +22 -0
- package/test/data/bitcoind/script_tests.json +3822 -0
- package/test/data/bitcoind/sig_canonical.json +7 -0
- package/test/data/bitcoind/sig_noncanonical.json +36 -0
- package/test/data/bitcoind/tx_invalid.json +445 -0
- package/test/data/bitcoind/tx_valid.json +44 -0
- package/test/data/blk86756-testnet.dat +0 -0
- package/test/data/blk86756-testnet.js +14 -0
- package/test/data/blk86756-testnet.json +684 -0
- package/test/data/block.hex +1 -0
- package/test/data/ecdsa.json +230 -0
- package/test/data/merkleblocks.js +488 -0
- package/test/data/messages.json +22 -0
- package/test/data/sighash.json +12 -0
- package/test/data/tx_creation.json +95 -0
- package/test/encoding/base58.js +131 -0
- package/test/encoding/base58check.js +136 -0
- package/test/encoding/bufferreader.js +337 -0
- package/test/encoding/bufferwriter.js +172 -0
- package/test/encoding/varint.js +104 -0
- package/test/hashCache.js +67 -0
- package/test/hdkeys.js +445 -0
- package/test/hdprivatekey.js +332 -0
- package/test/hdpublickey.js +304 -0
- package/test/index.js +16 -0
- package/test/message/message.js +204 -0
- package/test/mnemonic/data/fixtures.json +300 -0
- package/test/mnemonic/mnemonic.js +259 -0
- package/test/mnemonic/mocha.opts +1 -0
- package/test/mnemonic/pbkdf2.test.js +59 -0
- package/test/networks.js +159 -0
- package/test/opcode.js +161 -0
- package/test/privatekey.js +439 -0
- package/test/publickey.js +554 -0
- package/test/script/interpreter.js +734 -0
- package/test/script/script.js +1437 -0
- package/test/transaction/deserialize.js +34 -0
- package/test/transaction/input/input.js +90 -0
- package/test/transaction/input/multisig.js +90 -0
- package/test/transaction/input/publickey.js +68 -0
- package/test/transaction/input/publickeyhash.js +51 -0
- package/test/transaction/output.js +185 -0
- package/test/transaction/sighash.js +65 -0
- package/test/transaction/signature.js +114 -0
- package/test/transaction/transaction.js +1109 -0
- package/test/transaction/unspentoutput.js +110 -0
- package/test/util/js.js +76 -0
- package/test/util/preconditions.js +79 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var hash = require('hash.js');
|
|
4
|
+
var $ = require('../util/preconditions');
|
|
5
|
+
|
|
6
|
+
var Hash = module.exports;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A SHA or SHA1 hash, which is always 160 bits or 20 bytes long.
|
|
10
|
+
*
|
|
11
|
+
* See:
|
|
12
|
+
* https://en.wikipedia.org/wiki/SHA-1
|
|
13
|
+
*
|
|
14
|
+
* @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
|
|
15
|
+
* @returns {Buffer} The hash in the form of a buffer.
|
|
16
|
+
*/
|
|
17
|
+
Hash.sha1 = function (buf) {
|
|
18
|
+
$.checkArgument(Buffer.isBuffer(buf));
|
|
19
|
+
return Buffer.from(hash.sha1().update(buf).digest('hex'), 'hex');
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
Hash.sha1.blocksize = 512;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* A SHA256 hash, which is always 256 bits or 32 bytes long.
|
|
26
|
+
*
|
|
27
|
+
* See:
|
|
28
|
+
* https://www.movable-type.co.uk/scripts/sha256.html
|
|
29
|
+
*
|
|
30
|
+
* @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
|
|
31
|
+
* @returns {Buffer} The hash in the form of a buffer.
|
|
32
|
+
*/
|
|
33
|
+
Hash.sha256 = function (buf) {
|
|
34
|
+
$.checkArgument(Buffer.isBuffer(buf));
|
|
35
|
+
return Buffer.from(hash.sha256().update(buf).digest('hex'), 'hex');
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
Hash.sha256.blocksize = 512;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A double SHA256 hash, which is always 256 bits or 32 bytes bytes long. This
|
|
42
|
+
* hash function is commonly used inside Bitcoin, particularly for the hash of a
|
|
43
|
+
* block and the hash of a transaction.
|
|
44
|
+
*
|
|
45
|
+
* See:
|
|
46
|
+
* https://www.movable-type.co.uk/scripts/sha256.html
|
|
47
|
+
*
|
|
48
|
+
* @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
|
|
49
|
+
* @returns {Buffer} The hash in the form of a buffer.
|
|
50
|
+
*/
|
|
51
|
+
Hash.sha256sha256 = function (buf) {
|
|
52
|
+
$.checkArgument(Buffer.isBuffer(buf));
|
|
53
|
+
return Hash.sha256(Hash.sha256(buf));
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* A RIPEMD160 hash, which is always 160 bits or 20 bytes long.
|
|
58
|
+
*
|
|
59
|
+
* See:
|
|
60
|
+
* https://en.wikipedia.org/wiki/RIPEMD
|
|
61
|
+
*
|
|
62
|
+
* @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
|
|
63
|
+
* @returns {Buffer} The hash in the form of a buffer.
|
|
64
|
+
*/
|
|
65
|
+
Hash.ripemd160 = function (buf) {
|
|
66
|
+
$.checkArgument(Buffer.isBuffer(buf));
|
|
67
|
+
return Buffer.from(hash.ripemd160().update(buf).digest('hex'), 'hex');
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* A RIPEMD160 hash of a SHA256 hash, which is always 160 bits or 20 bytes long.
|
|
71
|
+
* This value is commonly used inside Bitcoin, particularly for Bitcoin
|
|
72
|
+
* addresses.
|
|
73
|
+
*
|
|
74
|
+
* See:
|
|
75
|
+
* https://en.wikipedia.org/wiki/RIPEMD
|
|
76
|
+
*
|
|
77
|
+
* @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
|
|
78
|
+
* @returns {Buffer} The hash in the form of a buffer.
|
|
79
|
+
*/
|
|
80
|
+
Hash.sha256ripemd160 = function (buf) {
|
|
81
|
+
$.checkArgument(Buffer.isBuffer(buf));
|
|
82
|
+
return Hash.ripemd160(Hash.sha256(buf));
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* A SHA512 hash, which is always 512 bits or 64 bytes long.
|
|
87
|
+
*
|
|
88
|
+
* See:
|
|
89
|
+
* https://en.wikipedia.org/wiki/SHA-2
|
|
90
|
+
*
|
|
91
|
+
* @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
|
|
92
|
+
* @returns {Buffer} The hash in the form of a buffer.
|
|
93
|
+
*/
|
|
94
|
+
Hash.sha512 = function (buf) {
|
|
95
|
+
$.checkArgument(Buffer.isBuffer(buf));
|
|
96
|
+
return Buffer.from(hash.sha512().update(buf).digest('hex'), 'hex');
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
Hash.sha512.blocksize = 1024;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* A way to do HMAC using any underlying hash function. If you ever find that
|
|
103
|
+
* you want to hash two pieces of data together, you should use HMAC instead of
|
|
104
|
+
* just using a hash function. Rather than doing hash(data1 + data2) you should
|
|
105
|
+
* do HMAC(data1, data2). Actually, rather than use HMAC directly, we recommend
|
|
106
|
+
* you use either sha256hmac or sha515hmac provided below.
|
|
107
|
+
*
|
|
108
|
+
* See:
|
|
109
|
+
* https://en.wikipedia.org/wiki/Length_extension_attack
|
|
110
|
+
* https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks
|
|
111
|
+
*
|
|
112
|
+
* @param {function} hashf Which hash function to use.
|
|
113
|
+
* @param {Buffer} data Data, which can be any size.
|
|
114
|
+
* @param {Buffer} key Key, which can be any size.
|
|
115
|
+
* @returns {Buffer} The HMAC in the form of a buffer.
|
|
116
|
+
*/
|
|
117
|
+
Hash.hmac = function (hashf, data, key) {
|
|
118
|
+
// http://en.wikipedia.org/wiki/Hash-based_message_authentication_code
|
|
119
|
+
// http://tools.ietf.org/html/rfc4868#section-2
|
|
120
|
+
$.checkArgument(Buffer.isBuffer(data));
|
|
121
|
+
$.checkArgument(Buffer.isBuffer(key));
|
|
122
|
+
$.checkArgument(hashf.blocksize);
|
|
123
|
+
|
|
124
|
+
var blocksize = hashf.blocksize / 8;
|
|
125
|
+
|
|
126
|
+
if (key.length > blocksize) {
|
|
127
|
+
key = hashf(key);
|
|
128
|
+
} else if (key < blocksize) {
|
|
129
|
+
var fill = Buffer.alloc(blocksize);
|
|
130
|
+
fill.fill(0);
|
|
131
|
+
key.copy(fill);
|
|
132
|
+
key = fill;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
var oKey = Buffer.alloc(blocksize);
|
|
136
|
+
oKey.fill(0x5c);
|
|
137
|
+
|
|
138
|
+
var iKey = Buffer.alloc(blocksize);
|
|
139
|
+
iKey.fill(0x36);
|
|
140
|
+
|
|
141
|
+
var oKeyPad = Buffer.alloc(blocksize);
|
|
142
|
+
var iKeyPad = Buffer.alloc(blocksize);
|
|
143
|
+
for (var i = 0; i < blocksize; i++) {
|
|
144
|
+
oKeyPad[i] = oKey[i] ^ key[i];
|
|
145
|
+
iKeyPad[i] = iKey[i] ^ key[i];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return hashf(Buffer.concat([oKeyPad, hashf(Buffer.concat([iKeyPad, data]))]));
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* A SHA256 HMAC.
|
|
153
|
+
*
|
|
154
|
+
* @param {Buffer} data Data, which can be any size.
|
|
155
|
+
* @param {Buffer} key Key, which can be any size.
|
|
156
|
+
* @returns {Buffer} The HMAC in the form of a buffer.
|
|
157
|
+
*/
|
|
158
|
+
Hash.sha256hmac = function (data, key) {
|
|
159
|
+
return Hash.hmac(Hash.sha256, data, key);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* A SHA512 HMAC.
|
|
164
|
+
*
|
|
165
|
+
* @param {Buffer} data Data, which can be any size.
|
|
166
|
+
* @param {Buffer} key Key, which can be any size.
|
|
167
|
+
* @returns {Buffer} The HMAC in the form of a buffer.
|
|
168
|
+
*/
|
|
169
|
+
Hash.sha512hmac = function (data, key) {
|
|
170
|
+
return Hash.hmac(Hash.sha512, data, key);
|
|
171
|
+
};
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var crypto = require('crypto');
|
|
4
|
+
var $ = require('../util/preconditions');
|
|
5
|
+
|
|
6
|
+
var Hash = module.exports;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A SHA or SHA1 hash, which is always 160 bits or 20 bytes long.
|
|
10
|
+
*
|
|
11
|
+
* See:
|
|
12
|
+
* https://en.wikipedia.org/wiki/SHA-1
|
|
13
|
+
*
|
|
14
|
+
* @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
|
|
15
|
+
* @returns {Buffer} The hash in the form of a buffer.
|
|
16
|
+
*/
|
|
17
|
+
Hash.sha1 = function (buf) {
|
|
18
|
+
$.checkArgument(Buffer.isBuffer(buf));
|
|
19
|
+
return crypto.createHash('sha1').update(buf).digest();
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
Hash.sha1.blocksize = 512;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* A SHA256 hash, which is always 256 bits or 32 bytes long.
|
|
26
|
+
*
|
|
27
|
+
* See:
|
|
28
|
+
* https://www.movable-type.co.uk/scripts/sha256.html
|
|
29
|
+
*
|
|
30
|
+
* @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
|
|
31
|
+
* @returns {Buffer} The hash in the form of a buffer.
|
|
32
|
+
*/
|
|
33
|
+
Hash.sha256 = function (buf) {
|
|
34
|
+
$.checkArgument(Buffer.isBuffer(buf));
|
|
35
|
+
return crypto.createHash('sha256').update(buf).digest();
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
Hash.sha256.blocksize = 512;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A double SHA256 hash, which is always 256 bits or 32 bytes bytes long. This
|
|
42
|
+
* hash function is commonly used inside Bitcoin, particularly for the hash of a
|
|
43
|
+
* block and the hash of a transaction.
|
|
44
|
+
*
|
|
45
|
+
* See:
|
|
46
|
+
* https://www.movable-type.co.uk/scripts/sha256.html
|
|
47
|
+
*
|
|
48
|
+
* @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
|
|
49
|
+
* @returns {Buffer} The hash in the form of a buffer.
|
|
50
|
+
*/
|
|
51
|
+
Hash.sha256sha256 = function (buf) {
|
|
52
|
+
$.checkArgument(Buffer.isBuffer(buf));
|
|
53
|
+
return Hash.sha256(Hash.sha256(buf));
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* A RIPEMD160 hash, which is always 160 bits or 20 bytes long.
|
|
58
|
+
*
|
|
59
|
+
* See:
|
|
60
|
+
* https://en.wikipedia.org/wiki/RIPEMD
|
|
61
|
+
*
|
|
62
|
+
* @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
|
|
63
|
+
* @returns {Buffer} The hash in the form of a buffer.
|
|
64
|
+
*/
|
|
65
|
+
Hash.ripemd160 = function (buf) {
|
|
66
|
+
$.checkArgument(Buffer.isBuffer(buf));
|
|
67
|
+
return crypto.createHash('ripemd160').update(buf).digest();
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* A RIPEMD160 hash of a SHA256 hash, which is always 160 bits or 20 bytes long.
|
|
71
|
+
* This value is commonly used inside Bitcoin, particularly for Bitcoin
|
|
72
|
+
* addresses.
|
|
73
|
+
*
|
|
74
|
+
* See:
|
|
75
|
+
* https://en.wikipedia.org/wiki/RIPEMD
|
|
76
|
+
*
|
|
77
|
+
* @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
|
|
78
|
+
* @returns {Buffer} The hash in the form of a buffer.
|
|
79
|
+
*/
|
|
80
|
+
Hash.sha256ripemd160 = function (buf) {
|
|
81
|
+
$.checkArgument(Buffer.isBuffer(buf));
|
|
82
|
+
return Hash.ripemd160(Hash.sha256(buf));
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* A SHA512 hash, which is always 512 bits or 64 bytes long.
|
|
87
|
+
*
|
|
88
|
+
* See:
|
|
89
|
+
* https://en.wikipedia.org/wiki/SHA-2
|
|
90
|
+
*
|
|
91
|
+
* @param {Buffer} buf Data, a.k.a. pre-image, which can be any size.
|
|
92
|
+
* @returns {Buffer} The hash in the form of a buffer.
|
|
93
|
+
*/
|
|
94
|
+
Hash.sha512 = function (buf) {
|
|
95
|
+
$.checkArgument(Buffer.isBuffer(buf));
|
|
96
|
+
return crypto.createHash('sha512').update(buf).digest();
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
Hash.sha512.blocksize = 1024;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* A way to do HMAC using any underlying hash function. If you ever find that
|
|
103
|
+
* you want to hash two pieces of data together, you should use HMAC instead of
|
|
104
|
+
* just using a hash function. Rather than doing hash(data1 + data2) you should
|
|
105
|
+
* do HMAC(data1, data2). Actually, rather than use HMAC directly, we recommend
|
|
106
|
+
* you use either sha256hmac or sha515hmac provided below.
|
|
107
|
+
*
|
|
108
|
+
* See:
|
|
109
|
+
* https://en.wikipedia.org/wiki/Length_extension_attack
|
|
110
|
+
* https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks
|
|
111
|
+
*
|
|
112
|
+
* @param {function} hashf Which hash function to use.
|
|
113
|
+
* @param {Buffer} data Data, which can be any size.
|
|
114
|
+
* @param {Buffer} key Key, which can be any size.
|
|
115
|
+
* @returns {Buffer} The HMAC in the form of a buffer.
|
|
116
|
+
*/
|
|
117
|
+
Hash.hmac = function (hashf, data, key) {
|
|
118
|
+
// http://en.wikipedia.org/wiki/Hash-based_message_authentication_code
|
|
119
|
+
// http://tools.ietf.org/html/rfc4868#section-2
|
|
120
|
+
$.checkArgument(Buffer.isBuffer(data));
|
|
121
|
+
$.checkArgument(Buffer.isBuffer(key));
|
|
122
|
+
$.checkArgument(hashf.blocksize);
|
|
123
|
+
|
|
124
|
+
var blocksize = hashf.blocksize / 8;
|
|
125
|
+
|
|
126
|
+
if (key.length > blocksize) {
|
|
127
|
+
key = hashf(key);
|
|
128
|
+
} else if (key < blocksize) {
|
|
129
|
+
var fill = Buffer.alloc(blocksize);
|
|
130
|
+
fill.fill(0);
|
|
131
|
+
key.copy(fill);
|
|
132
|
+
key = fill;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
var oKey = Buffer.alloc(blocksize);
|
|
136
|
+
oKey.fill(0x5c);
|
|
137
|
+
|
|
138
|
+
var iKey = Buffer.alloc(blocksize);
|
|
139
|
+
iKey.fill(0x36);
|
|
140
|
+
|
|
141
|
+
var oKeyPad = Buffer.alloc(blocksize);
|
|
142
|
+
var iKeyPad = Buffer.alloc(blocksize);
|
|
143
|
+
for (var i = 0; i < blocksize; i++) {
|
|
144
|
+
oKeyPad[i] = oKey[i] ^ key[i];
|
|
145
|
+
iKeyPad[i] = iKey[i] ^ key[i];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return hashf(Buffer.concat([oKeyPad, hashf(Buffer.concat([iKeyPad, data]))]));
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* A SHA256 HMAC.
|
|
153
|
+
*
|
|
154
|
+
* @param {Buffer} data Data, which can be any size.
|
|
155
|
+
* @param {Buffer} key Key, which can be any size.
|
|
156
|
+
* @returns {Buffer} The HMAC in the form of a buffer.
|
|
157
|
+
*/
|
|
158
|
+
Hash.sha256hmac = function (data, key) {
|
|
159
|
+
return Hash.hmac(Hash.sha256, data, key);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* A SHA512 HMAC.
|
|
164
|
+
*
|
|
165
|
+
* @param {Buffer} data Data, which can be any size.
|
|
166
|
+
* @param {Buffer} key Key, which can be any size.
|
|
167
|
+
* @returns {Buffer} The HMAC in the form of a buffer.
|
|
168
|
+
*/
|
|
169
|
+
Hash.sha512hmac = function (data, key) {
|
|
170
|
+
return Hash.hmac(Hash.sha512, data, key);
|
|
171
|
+
};
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var BN = require('./bn');
|
|
4
|
+
var elliptic = require('elliptic');
|
|
5
|
+
var EC = elliptic.ec;
|
|
6
|
+
var ec = new EC('secp256k1');
|
|
7
|
+
var ecPoint = ec.curve.point.bind(ec.curve);
|
|
8
|
+
var ecPointFromX = ec.curve.pointFromX.bind(ec.curve);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Instantiate a valid secp256k1 Point from the X and Y coordinates. This class
|
|
12
|
+
* is just an extension of the secp256k1 code from the library "elliptic" by
|
|
13
|
+
* Fedor Indutny. It includes a few extra features that are useful in Bitcoin.
|
|
14
|
+
*
|
|
15
|
+
* @param {BN|String} x - The X coordinate
|
|
16
|
+
* @param {BN|String} y - The Y coordinate
|
|
17
|
+
* @link https://github.com/indutny/elliptic
|
|
18
|
+
* @augments elliptic.curve.point
|
|
19
|
+
* @throws {Error} A validation error if exists
|
|
20
|
+
* @returns {Point} An instance of Point
|
|
21
|
+
* @constructor
|
|
22
|
+
*/
|
|
23
|
+
var Point = function Point(x, y, isRed) {
|
|
24
|
+
try {
|
|
25
|
+
var point = ecPoint(x, y, isRed);
|
|
26
|
+
} catch (e) {
|
|
27
|
+
throw new Error('Invalid Point');
|
|
28
|
+
}
|
|
29
|
+
point.validate();
|
|
30
|
+
return point;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
Point.prototype = Object.getPrototypeOf(ec.curve.point());
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
*
|
|
37
|
+
* Instantiate a valid secp256k1 Point from only the X coordinate. This is
|
|
38
|
+
* useful to rederive a full point from the compressed form of a point.
|
|
39
|
+
*
|
|
40
|
+
* @param {boolean} odd - If the Y coordinate is odd
|
|
41
|
+
* @param {BN|String} x - The X coordinate
|
|
42
|
+
* @throws {Error} A validation error if exists
|
|
43
|
+
* @returns {Point} An instance of Point
|
|
44
|
+
*/
|
|
45
|
+
Point.fromX = function fromX(odd, x) {
|
|
46
|
+
try {
|
|
47
|
+
var point = ecPointFromX(x, odd);
|
|
48
|
+
} catch (e) {
|
|
49
|
+
throw new Error('Invalid X');
|
|
50
|
+
}
|
|
51
|
+
point.validate();
|
|
52
|
+
return point;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* Will return a secp256k1 ECDSA base point.
|
|
58
|
+
*
|
|
59
|
+
* @link https://en.bitcoin.it/wiki/Secp256k1
|
|
60
|
+
* @returns {Point} An instance of the base point.
|
|
61
|
+
*/
|
|
62
|
+
Point.getG = function getG() {
|
|
63
|
+
return ec.curve.g;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
*
|
|
68
|
+
* Will return the max of range of valid private keys as governed by the
|
|
69
|
+
* secp256k1 ECDSA standard.
|
|
70
|
+
*
|
|
71
|
+
* @link https://en.bitcoin.it/wiki/Private_key#Range_of_valid_ECDSA_private_keys
|
|
72
|
+
* @returns {BN} A BN instance of the number of points on the curve
|
|
73
|
+
*/
|
|
74
|
+
Point.getN = function getN() {
|
|
75
|
+
return new BN(ec.curve.n.toArray());
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
if (!Point.prototype._getX) {
|
|
79
|
+
Point.prototype._getX = Point.prototype.getX;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Will return the X coordinate of the Point.
|
|
84
|
+
*
|
|
85
|
+
* @returns {BN} A BN instance of the X coordinate
|
|
86
|
+
*/
|
|
87
|
+
Point.prototype.getX = function getX() {
|
|
88
|
+
return new BN(this._getX().toArray());
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
if (!Point.prototype._getY) {
|
|
92
|
+
Point.prototype._getY = Point.prototype.getY;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Will return the Y coordinate of the Point.
|
|
97
|
+
*
|
|
98
|
+
* @returns {BN} A BN instance of the Y coordinate
|
|
99
|
+
*/
|
|
100
|
+
Point.prototype.getY = function getY() {
|
|
101
|
+
return new BN(this._getY().toArray());
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Will determine if the point is valid.
|
|
106
|
+
*
|
|
107
|
+
* @link https://www.iacr.org/archive/pkc2003/25670211/25670211.pdf
|
|
108
|
+
* @throws {Error} A validation error if exists
|
|
109
|
+
* @returns {Point} An instance of the same Point
|
|
110
|
+
*/
|
|
111
|
+
Point.prototype.validate = function validate() {
|
|
112
|
+
if (this.isInfinity()) {
|
|
113
|
+
throw new Error('Point cannot be equal to Infinity');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
var p2;
|
|
117
|
+
try {
|
|
118
|
+
p2 = ecPointFromX(this.getX(), this.getY().isOdd());
|
|
119
|
+
} catch (e) {
|
|
120
|
+
throw new Error('Point does not lie on the curve');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (p2.y.cmp(this.y) !== 0) {
|
|
124
|
+
throw new Error('Invalid y value for curve.');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// todo: needs test case
|
|
128
|
+
if (!this.mul(Point.getN()).isInfinity()) {
|
|
129
|
+
throw new Error('Point times N must be infinity');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return this;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* A "compressed" format point is the X part of the (X, Y) point plus an extra
|
|
137
|
+
* bit (which takes an entire byte) to indicate whether the Y value is odd or
|
|
138
|
+
* not. Storing points this way takes a bit less space, but requires a bit more
|
|
139
|
+
* computation to rederive the full point.
|
|
140
|
+
*
|
|
141
|
+
* @param {Point} point An instance of Point.
|
|
142
|
+
* @returns {Buffer} A compressed point in the form of a buffer.
|
|
143
|
+
*/
|
|
144
|
+
Point.pointToCompressed = function pointToCompressed(point) {
|
|
145
|
+
var xbuf = point.getX().toBuffer({ size: 32 });
|
|
146
|
+
var ybuf = point.getY().toBuffer({ size: 32 });
|
|
147
|
+
|
|
148
|
+
var prefix;
|
|
149
|
+
var odd = ybuf[ybuf.length - 1] % 2;
|
|
150
|
+
if (odd) {
|
|
151
|
+
prefix = Buffer.from([0x03]);
|
|
152
|
+
} else {
|
|
153
|
+
prefix = Buffer.from([0x02]);
|
|
154
|
+
}
|
|
155
|
+
return Buffer.concat([prefix, xbuf]);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Converts a compressed buffer into a point.
|
|
160
|
+
*
|
|
161
|
+
* @param {Buffer} buf A compressed point.
|
|
162
|
+
* @returns {Point} A Point.
|
|
163
|
+
*/
|
|
164
|
+
Point.pointFromCompressed = function (buf) {
|
|
165
|
+
if (buf.length !== 33) {
|
|
166
|
+
throw new Error('invalid buffer length');
|
|
167
|
+
}
|
|
168
|
+
let prefix = buf[0];
|
|
169
|
+
let odd;
|
|
170
|
+
if (prefix === 0x03) {
|
|
171
|
+
odd = true;
|
|
172
|
+
} else if (prefix === 0x02) {
|
|
173
|
+
odd = false;
|
|
174
|
+
} else {
|
|
175
|
+
throw new Error('invalid value of compressed prefix');
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
let xbuf = buf.slice(1, 33);
|
|
179
|
+
let x = BN.fromBuffer(xbuf);
|
|
180
|
+
return Point.fromX(odd, x);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Convert point to a compressed buffer.
|
|
185
|
+
*
|
|
186
|
+
* @returns {Buffer} A compressed point.
|
|
187
|
+
*/
|
|
188
|
+
Point.prototype.toBuffer = function () {
|
|
189
|
+
return Point.pointToCompressed(this);
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Convert point to a compressed hex string.
|
|
194
|
+
*
|
|
195
|
+
* @returns {string} A compressed point as a hex string.
|
|
196
|
+
*/
|
|
197
|
+
Point.prototype.toHex = function () {
|
|
198
|
+
return this.toBuffer().toString('hex');
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Converts a compressed buffer into a point.
|
|
203
|
+
*
|
|
204
|
+
* @param {Buffer} buf A compressed point.
|
|
205
|
+
* @returns {Point} A Point.
|
|
206
|
+
*/
|
|
207
|
+
Point.fromBuffer = function (buf) {
|
|
208
|
+
return Point.pointFromCompressed(buf);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Converts a compressed buffer into a point.
|
|
213
|
+
*
|
|
214
|
+
* @param {Buffer} hex A compressed point as a hex string.
|
|
215
|
+
* @returns {Point} A Point.
|
|
216
|
+
*/
|
|
217
|
+
Point.fromHex = function (hex) {
|
|
218
|
+
return Point.fromBuffer(Buffer.from(hex, 'hex'));
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
module.exports = Point;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function Random() {}
|
|
4
|
+
|
|
5
|
+
/* secure random bytes that sometimes throws an error due to lack of entropy */
|
|
6
|
+
Random.getRandomBuffer = function (size) {
|
|
7
|
+
if (!window.crypto && !window.msCrypto) {
|
|
8
|
+
throw new Error('window.crypto not available');
|
|
9
|
+
}
|
|
10
|
+
var crypto;
|
|
11
|
+
|
|
12
|
+
if (window.crypto && window.crypto.getRandomValues) {
|
|
13
|
+
crypto = window.crypto;
|
|
14
|
+
} else if (window.msCrypto && window.msCrypto.getRandomValues) {
|
|
15
|
+
// internet explorer
|
|
16
|
+
crypto = window.msCrypto;
|
|
17
|
+
} else {
|
|
18
|
+
throw new Error('window.crypto.getRandomValues not available');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
var bbuf = new Uint8Array(size);
|
|
22
|
+
crypto.getRandomValues(bbuf);
|
|
23
|
+
var buf = Buffer.from(bbuf);
|
|
24
|
+
|
|
25
|
+
return buf;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
module.exports = Random;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function Random() {}
|
|
4
|
+
|
|
5
|
+
/* secure random bytes that sometimes throws an error due to lack of entropy */
|
|
6
|
+
Random.getRandomBuffer = function (size) {
|
|
7
|
+
var crypto = require('crypto');
|
|
8
|
+
return crypto.randomBytes(size);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
module.exports = Random;
|