@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.
Files changed (138) hide show
  1. package/.mocharc.yaml +3 -0
  2. package/index.d.ts +1541 -0
  3. package/index.js +74 -0
  4. package/lib/address.js +478 -0
  5. package/lib/block/block.js +277 -0
  6. package/lib/block/blockheader.js +295 -0
  7. package/lib/block/index.js +4 -0
  8. package/lib/block/merkleblock.js +323 -0
  9. package/lib/bn.js +3423 -0
  10. package/lib/crypto/bn.js +278 -0
  11. package/lib/crypto/ecdsa.js +339 -0
  12. package/lib/crypto/hash.browser.js +171 -0
  13. package/lib/crypto/hash.js +2 -0
  14. package/lib/crypto/hash.node.js +171 -0
  15. package/lib/crypto/point.js +221 -0
  16. package/lib/crypto/random.browser.js +28 -0
  17. package/lib/crypto/random.js +2 -0
  18. package/lib/crypto/random.node.js +11 -0
  19. package/lib/crypto/signature.js +325 -0
  20. package/lib/encoding/base58.js +111 -0
  21. package/lib/encoding/base58check.js +121 -0
  22. package/lib/encoding/bufferreader.js +212 -0
  23. package/lib/encoding/bufferwriter.js +140 -0
  24. package/lib/encoding/decode-asm.js +24 -0
  25. package/lib/encoding/decode-hex.js +32 -0
  26. package/lib/encoding/decode-script-chunks.js +43 -0
  27. package/lib/encoding/encode-hex.js +284 -0
  28. package/lib/encoding/is-hex.js +7 -0
  29. package/lib/encoding/varint.js +75 -0
  30. package/lib/errors/index.js +54 -0
  31. package/lib/errors/spec.js +314 -0
  32. package/lib/hash-cache.js +50 -0
  33. package/lib/hdprivatekey.js +678 -0
  34. package/lib/hdpublickey.js +525 -0
  35. package/lib/message/message.js +191 -0
  36. package/lib/mnemonic/mnemonic.js +303 -0
  37. package/lib/mnemonic/pbkdf2.browser.js +68 -0
  38. package/lib/mnemonic/pbkdf2.js +2 -0
  39. package/lib/mnemonic/pbkdf2.node.js +68 -0
  40. package/lib/mnemonic/words/chinese.js +2054 -0
  41. package/lib/mnemonic/words/english.js +2054 -0
  42. package/lib/mnemonic/words/french.js +2054 -0
  43. package/lib/mnemonic/words/index.js +8 -0
  44. package/lib/mnemonic/words/italian.js +2054 -0
  45. package/lib/mnemonic/words/japanese.js +2054 -0
  46. package/lib/mnemonic/words/spanish.js +2054 -0
  47. package/lib/networks.js +379 -0
  48. package/lib/opcode.js +255 -0
  49. package/lib/privatekey.js +374 -0
  50. package/lib/publickey.js +386 -0
  51. package/lib/script/index.js +5 -0
  52. package/lib/script/interpreter.js +1834 -0
  53. package/lib/script/script.js +1074 -0
  54. package/lib/script/stack.js +109 -0
  55. package/lib/script/write-i32-le.js +17 -0
  56. package/lib/script/write-push-data.js +35 -0
  57. package/lib/script/write-u16-le.js +12 -0
  58. package/lib/script/write-u32-le.js +16 -0
  59. package/lib/script/write-u64-le.js +24 -0
  60. package/lib/script/write-u8-le.js +8 -0
  61. package/lib/script/write-varint.js +46 -0
  62. package/lib/transaction/index.js +7 -0
  63. package/lib/transaction/input/index.js +5 -0
  64. package/lib/transaction/input/input.js +354 -0
  65. package/lib/transaction/input/multisig.js +242 -0
  66. package/lib/transaction/input/publickey.js +100 -0
  67. package/lib/transaction/input/publickeyhash.js +118 -0
  68. package/lib/transaction/output.js +231 -0
  69. package/lib/transaction/sighash.js +167 -0
  70. package/lib/transaction/signature.js +97 -0
  71. package/lib/transaction/transaction.js +1639 -0
  72. package/lib/transaction/unspentoutput.js +113 -0
  73. package/lib/util/_.js +47 -0
  74. package/lib/util/js.js +90 -0
  75. package/lib/util/preconditions.js +33 -0
  76. package/package.json +26 -0
  77. package/test/address.js +509 -0
  78. package/test/block/block.js +251 -0
  79. package/test/block/blockheader.js +275 -0
  80. package/test/block/merklebloack.js +211 -0
  81. package/test/crypto/bn.js +177 -0
  82. package/test/crypto/ecdsa.js +391 -0
  83. package/test/crypto/hash.browser.js +135 -0
  84. package/test/crypto/hash.js +136 -0
  85. package/test/crypto/point.js +224 -0
  86. package/test/crypto/random.js +32 -0
  87. package/test/crypto/signature.js +409 -0
  88. package/test/data/bip69.json +215 -0
  89. package/test/data/bitcoind/base58_keys_invalid.json +52 -0
  90. package/test/data/bitcoind/base58_keys_valid.json +335 -0
  91. package/test/data/bitcoind/blocks.json +22 -0
  92. package/test/data/bitcoind/script_tests.json +3822 -0
  93. package/test/data/bitcoind/sig_canonical.json +7 -0
  94. package/test/data/bitcoind/sig_noncanonical.json +36 -0
  95. package/test/data/bitcoind/tx_invalid.json +445 -0
  96. package/test/data/bitcoind/tx_valid.json +44 -0
  97. package/test/data/blk86756-testnet.dat +0 -0
  98. package/test/data/blk86756-testnet.js +14 -0
  99. package/test/data/blk86756-testnet.json +684 -0
  100. package/test/data/block.hex +1 -0
  101. package/test/data/ecdsa.json +230 -0
  102. package/test/data/merkleblocks.js +488 -0
  103. package/test/data/messages.json +22 -0
  104. package/test/data/sighash.json +12 -0
  105. package/test/data/tx_creation.json +95 -0
  106. package/test/encoding/base58.js +131 -0
  107. package/test/encoding/base58check.js +136 -0
  108. package/test/encoding/bufferreader.js +337 -0
  109. package/test/encoding/bufferwriter.js +172 -0
  110. package/test/encoding/varint.js +104 -0
  111. package/test/hashCache.js +67 -0
  112. package/test/hdkeys.js +445 -0
  113. package/test/hdprivatekey.js +332 -0
  114. package/test/hdpublickey.js +304 -0
  115. package/test/index.js +16 -0
  116. package/test/message/message.js +204 -0
  117. package/test/mnemonic/data/fixtures.json +300 -0
  118. package/test/mnemonic/mnemonic.js +259 -0
  119. package/test/mnemonic/mocha.opts +1 -0
  120. package/test/mnemonic/pbkdf2.test.js +59 -0
  121. package/test/networks.js +159 -0
  122. package/test/opcode.js +161 -0
  123. package/test/privatekey.js +439 -0
  124. package/test/publickey.js +554 -0
  125. package/test/script/interpreter.js +734 -0
  126. package/test/script/script.js +1437 -0
  127. package/test/transaction/deserialize.js +34 -0
  128. package/test/transaction/input/input.js +90 -0
  129. package/test/transaction/input/multisig.js +90 -0
  130. package/test/transaction/input/publickey.js +68 -0
  131. package/test/transaction/input/publickeyhash.js +51 -0
  132. package/test/transaction/output.js +185 -0
  133. package/test/transaction/sighash.js +65 -0
  134. package/test/transaction/signature.js +114 -0
  135. package/test/transaction/transaction.js +1109 -0
  136. package/test/transaction/unspentoutput.js +110 -0
  137. package/test/util/js.js +76 -0
  138. package/test/util/preconditions.js +79 -0
@@ -0,0 +1,278 @@
1
+ 'use strict';
2
+
3
+ var BN = require('../bn');
4
+ var $ = require('../util/preconditions');
5
+ var _ = require('../util/_');
6
+
7
+ var reversebuf = function (buf) {
8
+ var buf2 = Buffer.alloc(buf.length);
9
+ for (var i = 0; i < buf.length; i++) {
10
+ buf2[i] = buf[buf.length - 1 - i];
11
+ }
12
+ return buf2;
13
+ };
14
+
15
+ BN.Zero = new BN(0);
16
+ BN.One = new BN(1);
17
+ BN.Minus1 = new BN(-1);
18
+
19
+ /**
20
+ * Convert a number into a big number.
21
+ *
22
+ * @param {number} n Any positive or negative integer.
23
+ */
24
+ BN.fromNumber = function (n) {
25
+ $.checkArgument(_.isNumber(n));
26
+ return BN.fromString(n.toString(16), 16)
27
+ };
28
+
29
+ /**
30
+ * Convert a string number into a big number.
31
+ *
32
+ * @param {string} str Any positive or negative integer formatted as a string.
33
+ * @param {number} base The base of the number, defaults to 10.
34
+ */
35
+ BN.fromString = function (str, base) {
36
+ $.checkArgument(_.isString(str));
37
+ return new BN(str, base);
38
+ };
39
+
40
+ /**
41
+ * Convert a buffer (such as a 256 bit binary private key) into a big number.
42
+ * Sometimes these numbers can be formatted either as 'big endian' or 'little
43
+ * endian', and so there is an opts parameter that lets you specify which
44
+ * endianness is specified.
45
+ *
46
+ * @param {Buffer} buf A buffer number, such as a 256 bit hash or key.
47
+ * @param {Object} opts With a property 'endian' that can be either 'big' or 'little'. Defaults big endian (most significant digit first).
48
+ */
49
+ BN.fromBuffer = function (buf, opts) {
50
+ if (typeof opts !== 'undefined' && opts.endian === 'little') {
51
+ buf = reversebuf(buf);
52
+ }
53
+ var hex = buf.toString('hex');
54
+ var bn = new BN(hex, 16);
55
+ return bn;
56
+ };
57
+
58
+ /**
59
+ * Instantiate a BigNumber from a "signed magnitude buffer". (a buffer where the
60
+ * most significant bit represents the sign (0 = positive, 1 = negative)
61
+ *
62
+ * @param {Buffer} buf A buffer number, such as a 256 bit hash or key.
63
+ * @param {Object} opts With a property 'endian' that can be either 'big' or 'little'. Defaults big endian (most significant digit first).
64
+ */
65
+ BN.fromSM = function (buf, opts) {
66
+ var ret;
67
+ if (buf.length === 0) {
68
+ return BN.fromBuffer(Buffer.from([0]));
69
+ }
70
+
71
+ var endian = 'big';
72
+ if (opts) {
73
+ endian = opts.endian;
74
+ }
75
+ if (endian === 'little') {
76
+ buf = reversebuf(buf);
77
+ }
78
+
79
+ if (buf[0] & 0x80) {
80
+ buf[0] = buf[0] & 0x7f;
81
+ ret = BN.fromBuffer(buf);
82
+ ret.neg().copy(ret);
83
+ } else {
84
+ ret = BN.fromBuffer(buf);
85
+ }
86
+ return ret;
87
+ };
88
+
89
+ /**
90
+ * Convert a big number into a number.
91
+ */
92
+ BN.prototype.toNumber = function () {
93
+ return parseInt(this.toString(10), 10);
94
+ };
95
+
96
+ /**
97
+ * Convert a big number into a buffer. This is somewhat ambiguous, so there is
98
+ * an opts parameter that let's you specify the endianness or the size.
99
+ * opts.endian can be either 'big' or 'little' and opts.size can be any
100
+ * sufficiently large number of bytes. If you always want to create a 32 byte
101
+ * big endian number, then specify opts = { endian: 'big', size: 32 }
102
+ *
103
+ * @param {Object} opts Defaults to { endian: 'big', size: 32 }
104
+ */
105
+ BN.prototype.toBuffer = function (opts) {
106
+ var buf, hex;
107
+ if (opts && opts.size) {
108
+ hex = this.toString(16, 2);
109
+ var natlen = hex.length / 2;
110
+ buf = Buffer.from(hex, 'hex');
111
+
112
+ if (natlen === opts.size) {
113
+ // buf = buf
114
+ } else if (natlen > opts.size) {
115
+ buf = BN.trim(buf, natlen);
116
+ } else if (natlen < opts.size) {
117
+ buf = BN.pad(buf, natlen, opts.size);
118
+ }
119
+ } else {
120
+ hex = this.toString(16, 2);
121
+ buf = Buffer.from(hex, 'hex');
122
+ }
123
+
124
+ if (typeof opts !== 'undefined' && opts.endian === 'little') {
125
+ buf = reversebuf(buf);
126
+ }
127
+
128
+ return buf;
129
+ };
130
+
131
+ /**
132
+ * For big numbers that are either positive or negative, you can convert to
133
+ * "sign magnitude" format whereby the first bit specifies whether the number is
134
+ * positive or negative.
135
+ */
136
+ BN.prototype.toSMBigEndian = function () {
137
+ var buf;
138
+ if (this.cmp(BN.Zero) === -1) {
139
+ buf = this.neg().toBuffer();
140
+ if (buf[0] & 0x80) {
141
+ buf = Buffer.concat([Buffer.from([0x80]), buf]);
142
+ } else {
143
+ buf[0] = buf[0] | 0x80;
144
+ }
145
+ } else {
146
+ buf = this.toBuffer();
147
+ if (buf[0] & 0x80) {
148
+ buf = Buffer.concat([Buffer.from([0x00]), buf]);
149
+ }
150
+ }
151
+
152
+ if ((buf.length === 1) & (buf[0] === 0)) {
153
+ buf = Buffer.from([]);
154
+ }
155
+ return buf;
156
+ };
157
+
158
+ /**
159
+ * For big numbers that are either positive or negative, you can convert to
160
+ * "sign magnitude" format whereby the first bit specifies whether the number is
161
+ * positive or negative.
162
+ *
163
+ * @param {Object} opts Defaults to { endian: 'big' }
164
+ */
165
+ BN.prototype.toSM = function (opts) {
166
+ var endian = opts ? opts.endian : 'big';
167
+ var buf = this.toSMBigEndian();
168
+
169
+ if (endian === 'little') {
170
+ buf = reversebuf(buf);
171
+ }
172
+ return buf;
173
+ };
174
+
175
+ /**
176
+ * Create a BN from a "ScriptNum": This is analogous to the constructor for
177
+ * CScriptNum in bitcoind. Many ops in bitcoind's script interpreter use
178
+ * CScriptNum, which is not really a proper bignum. Instead, an error is thrown
179
+ * if trying to input a number bigger than 4 bytes. We copy that behavior here.
180
+ * A third argument, `size`, is provided to extend the hard limit of 4 bytes, as
181
+ * some usages require more than 4 bytes.
182
+ *
183
+ * @param {Buffer} buf A buffer of a number.
184
+ * @param {boolean} fRequireMinimal Whether to require minimal size encoding.
185
+ * @param {number} size The maximum size.
186
+ */
187
+ BN.fromScriptNumBuffer = function (buf, fRequireMinimal, size) {
188
+ var nMaxNumSize = size || Number.MAX_SAFE_INTEGER;
189
+ $.checkArgument(buf.length <= nMaxNumSize, new Error('script number overflow'));
190
+ if (fRequireMinimal && buf.length > 0) {
191
+ // Check that the number is encoded with the minimum possible
192
+ // number of bytes.
193
+ //
194
+ // If the most-significant-byte - excluding the sign bit - is zero
195
+ // then we're not minimal. Note how this test also rejects the
196
+ // negative-zero encoding, 0x80.
197
+ if ((buf[buf.length - 1] & 0x7f) === 0) {
198
+ // One exception: if there's more than one byte and the most
199
+ // significant bit of the second-most-significant-byte is set
200
+ // it would conflict with the sign bit. An example of this case
201
+ // is +-255, which encode to 0xff00 and 0xff80 respectively.
202
+ // (big-endian).
203
+ if (buf.length <= 1 || (buf[buf.length - 2] & 0x80) === 0) {
204
+ throw new Error('non-minimally encoded script number');
205
+ }
206
+ }
207
+ }
208
+ return BN.fromSM(buf, {
209
+ endian: 'little',
210
+ });
211
+ };
212
+
213
+ /**
214
+ * The corollary to the above, with the notable exception that we do not throw
215
+ * an error if the output is larger than four bytes. (Which can happen if
216
+ * performing a numerical operation that results in an overflow to more than 4
217
+ * bytes).
218
+ */
219
+ BN.prototype.toScriptNumBuffer = function () {
220
+ return this.toSM({
221
+ endian: 'little',
222
+ });
223
+ };
224
+
225
+ /**
226
+ * Trims a buffer if it starts with zeros.
227
+ *
228
+ * @param {Buffer} buf A buffer formatted number.
229
+ * @param {number} natlen The natural length of the number.
230
+ */
231
+ BN.trim = function (buf, natlen) {
232
+ return buf.slice(natlen - buf.length, buf.length);
233
+ };
234
+
235
+ /**
236
+ * Adds extra zeros to the start of a number.
237
+ *
238
+ * @param {Buffer} buf A buffer formatted number.
239
+ * @param {number} natlen The natural length of the number.
240
+ * @param {number} size How big to pad the number in bytes.
241
+ */
242
+ BN.pad = function (buf, natlen, size) {
243
+ var rbuf = Buffer.alloc(size);
244
+ for (var i = 0; i < buf.length; i++) {
245
+ rbuf[rbuf.length - 1 - i] = buf[buf.length - 1 - i];
246
+ }
247
+ for (i = 0; i < size - natlen; i++) {
248
+ rbuf[i] = 0;
249
+ }
250
+ return rbuf;
251
+ };
252
+ /**
253
+ * Convert a big number into a hex string. This is somewhat ambiguous, so there
254
+ * is an opts parameter that let's you specify the endianness or the size.
255
+ * opts.endian can be either 'big' or 'little' and opts.size can be any
256
+ * sufficiently large number of bytes. If you always want to create a 32 byte
257
+ * big endian number, then specify opts = { endian: 'big', size: 32 }
258
+ *
259
+ * @param {Object} opts Defaults to { endian: 'big', size: 32 }
260
+ */
261
+ BN.prototype.toHex = function (...args) {
262
+ return this.toBuffer(...args).toString('hex');
263
+ };
264
+
265
+ /**
266
+ * Convert a hex string (such as a 256 bit binary private key) into a big
267
+ * number. Sometimes these numbers can be formatted either as 'big endian' or
268
+ * 'little endian', and so there is an opts parameter that lets you specify
269
+ * which endianness is specified.
270
+ *
271
+ * @param {Buffer} buf A buffer number, such as a 256 bit hash or key.
272
+ * @param {Object} opts With a property 'endian' that can be either 'big' or 'little'. Defaults big endian (most significant digit first).
273
+ */
274
+ BN.fromHex = function (hex, ...args) {
275
+ return BN.fromBuffer(Buffer.from(hex, 'hex'), ...args);
276
+ };
277
+
278
+ module.exports = BN;
@@ -0,0 +1,339 @@
1
+ 'use strict';
2
+
3
+ var BN = require('./bn');
4
+ var Point = require('./point');
5
+ var Signature = require('./signature');
6
+ var PublicKey = require('../publickey');
7
+ var Random = require('./random');
8
+ var Hash = require('./hash');
9
+ var _ = require('../util/_');
10
+ var $ = require('../util/preconditions');
11
+
12
+ var ECDSA = function ECDSA(obj) {
13
+ if (!(this instanceof ECDSA)) {
14
+ return new ECDSA(obj);
15
+ }
16
+ if (obj) {
17
+ this.set(obj);
18
+ }
19
+ };
20
+
21
+ ECDSA.prototype.set = function (obj) {
22
+ this.hashbuf = obj.hashbuf || this.hashbuf;
23
+ this.endian = obj.endian || this.endian; // the endianness of hashbuf
24
+ this.privkey = obj.privkey || this.privkey;
25
+ this.pubkey = obj.pubkey || (this.privkey ? this.privkey.publicKey : this.pubkey);
26
+ this.sig = obj.sig || this.sig;
27
+ this.k = obj.k || this.k;
28
+ this.verified = obj.verified || this.verified;
29
+ return this;
30
+ };
31
+
32
+ ECDSA.prototype.privkey2pubkey = function () {
33
+ this.pubkey = this.privkey.toPublicKey();
34
+ };
35
+
36
+ ECDSA.prototype.calci = function () {
37
+ for (var i = 0; i < 4; i++) {
38
+ this.sig.i = i;
39
+ var Qprime;
40
+ try {
41
+ Qprime = this.toPublicKey();
42
+ } catch (e) {
43
+ console.error(e);
44
+ continue;
45
+ }
46
+
47
+ if (Qprime.point.eq(this.pubkey.point)) {
48
+ this.sig.compressed = this.pubkey.compressed;
49
+ return this;
50
+ }
51
+ }
52
+
53
+ this.sig.i = undefined;
54
+ throw new Error('Unable to find valid recovery factor');
55
+ };
56
+
57
+ ECDSA.fromString = function (str) {
58
+ var obj = JSON.parse(str);
59
+ return new ECDSA(obj);
60
+ };
61
+
62
+ ECDSA.prototype.randomK = function () {
63
+ var N = Point.getN();
64
+ var k;
65
+ do {
66
+ k = BN.fromBuffer(Random.getRandomBuffer(32));
67
+ } while (!(k.lt(N) && k.gt(BN.Zero)));
68
+ this.k = k;
69
+ return this;
70
+ };
71
+
72
+ // https://tools.ietf.org/html/rfc6979#section-3.2
73
+ ECDSA.prototype.deterministicK = function (badrs) {
74
+ // if r or s were invalid when this function was used in signing,
75
+ // we do not want to actually compute r, s here for efficiency, so,
76
+ // we can increment badrs. explained at end of RFC 6979 section 3.2
77
+ if (_.isUndefined(badrs)) {
78
+ badrs = 0;
79
+ }
80
+ var v = Buffer.alloc(32);
81
+ v.fill(0x01);
82
+ var k = Buffer.alloc(32);
83
+ k.fill(0x00);
84
+ var x = this.privkey.bn.toBuffer({
85
+ size: 32,
86
+ });
87
+ var hashbuf = this.endian === 'little' ? Buffer.from(this.hashbuf).reverse() : this.hashbuf;
88
+ k = Hash.sha256hmac(Buffer.concat([v, Buffer.from([0x00]), x, hashbuf]), k);
89
+ v = Hash.sha256hmac(v, k);
90
+ k = Hash.sha256hmac(Buffer.concat([v, Buffer.from([0x01]), x, hashbuf]), k);
91
+ v = Hash.sha256hmac(v, k);
92
+ v = Hash.sha256hmac(v, k);
93
+ var T = BN.fromBuffer(v);
94
+ var N = Point.getN();
95
+
96
+ // also explained in 3.2, we must ensure T is in the proper range (0, N)
97
+ for (var i = 0; i < badrs || !(T.lt(N) && T.gt(BN.Zero)); i++) {
98
+ k = Hash.sha256hmac(Buffer.concat([v, Buffer.from([0x00])]), k);
99
+ v = Hash.sha256hmac(v, k);
100
+ v = Hash.sha256hmac(v, k);
101
+ T = BN.fromBuffer(v);
102
+ }
103
+
104
+ this.k = T;
105
+ return this;
106
+ };
107
+
108
+ // Information about public key recovery:
109
+ // https://bitcointalk.org/index.php?topic=6430.0
110
+ // http://stackoverflow.com/questions/19665491/how-do-i-get-an-ecdsa-public-key-from-just-a-bitcoin-signature-sec1-4-1-6-k
111
+ ECDSA.prototype.toPublicKey = function () {
112
+ var i = this.sig.i;
113
+ $.checkArgument(
114
+ i === 0 || i === 1 || i === 2 || i === 3,
115
+ new Error('i must be equal to 0, 1, 2, or 3'),
116
+ );
117
+
118
+ var e = BN.fromBuffer(this.hashbuf);
119
+ var r = this.sig.r;
120
+ var s = this.sig.s;
121
+
122
+ // A set LSB signifies that the y-coordinate is odd
123
+ var isYOdd = i & 1;
124
+
125
+ // The more significant bit specifies whether we should use the
126
+ // first or second candidate key.
127
+ var isSecondKey = i >> 1;
128
+
129
+ var n = Point.getN();
130
+ var G = Point.getG();
131
+
132
+ // 1.1 Let x = r + jn
133
+ var x = isSecondKey ? r.add(n) : r;
134
+ var R = Point.fromX(isYOdd, x);
135
+
136
+ // 1.4 Check that nR is at infinity
137
+ var nR = R.mul(n);
138
+
139
+ if (!nR.isInfinity()) {
140
+ throw new Error('nR is not a valid curve point');
141
+ }
142
+
143
+ // Compute -e from e
144
+ var eNeg = e.neg().umod(n);
145
+
146
+ // 1.6.1 Compute Q = r^-1 (sR - eG)
147
+ // Q = r^-1 (sR + -eG)
148
+ var rInv = r.invm(n);
149
+
150
+ // var Q = R.multiplyTwo(s, G, eNeg).mul(rInv);
151
+ var Q = R.mul(s).add(G.mul(eNeg)).mul(rInv);
152
+
153
+ var pubkey = PublicKey.fromPoint(Q, this.sig.compressed);
154
+
155
+ return pubkey;
156
+ };
157
+
158
+ ECDSA.prototype.sigError = function () {
159
+ if (!Buffer.isBuffer(this.hashbuf) || this.hashbuf.length !== 32) {
160
+ return 'hashbuf must be a 32 byte buffer';
161
+ }
162
+
163
+ var r = this.sig.r;
164
+ var s = this.sig.s;
165
+ if (!(r.gt(BN.Zero) && r.lt(Point.getN())) || !(s.gt(BN.Zero) && s.lt(Point.getN()))) {
166
+ return 'r and s not in range';
167
+ }
168
+
169
+ var e = BN.fromBuffer(
170
+ this.hashbuf,
171
+ this.endian
172
+ ? {
173
+ endian: this.endian,
174
+ }
175
+ : undefined,
176
+ );
177
+ var n = Point.getN();
178
+ var sinv = s.invm(n);
179
+ var u1 = sinv.mul(e).umod(n);
180
+ var u2 = sinv.mul(r).umod(n);
181
+
182
+ var p = Point.getG().mulAdd(u1, this.pubkey.point, u2);
183
+ if (p.isInfinity()) {
184
+ return 'p is infinity';
185
+ }
186
+
187
+ if (p.getX().umod(n).cmp(r) !== 0) {
188
+ return 'Invalid signature';
189
+ } else {
190
+ return false;
191
+ }
192
+ };
193
+
194
+ ECDSA.toLowS = function (s) {
195
+ // enforce low s
196
+ // see BIP 62, "low S values in signatures"
197
+ if (
198
+ s.gt(
199
+ BN.fromBuffer(
200
+ Buffer.from('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0', 'hex'),
201
+ ),
202
+ )
203
+ ) {
204
+ s = Point.getN().sub(s);
205
+ }
206
+ return s;
207
+ };
208
+
209
+ ECDSA.prototype._findSignature = function (d, e) {
210
+ var N = Point.getN();
211
+ var G = Point.getG();
212
+ // try different values of k until r, s are valid
213
+ var badrs = 0;
214
+ var k, Q, r, s;
215
+ do {
216
+ if (!this.k || badrs > 0) {
217
+ this.deterministicK(badrs);
218
+ }
219
+ badrs++;
220
+ k = this.k;
221
+ Q = G.mul(k);
222
+ r = new BN(1).mul(Q.x.umod(N));
223
+ s = k
224
+ .invm(N)
225
+ .mul(e.add(d.mul(r)))
226
+ .umod(N);
227
+ } while (r.cmp(BN.Zero) <= 0 || s.cmp(BN.Zero) <= 0);
228
+
229
+ s = ECDSA.toLowS(s);
230
+ return {
231
+ s: s,
232
+ r: r,
233
+ };
234
+ };
235
+
236
+ ECDSA.prototype.sign = function () {
237
+ var hashbuf = this.hashbuf;
238
+ var privkey = this.privkey;
239
+ var d = privkey.bn;
240
+
241
+ $.checkState(hashbuf && privkey && d, new Error('invalid parameters'));
242
+ $.checkState(
243
+ Buffer.isBuffer(hashbuf) && hashbuf.length === 32,
244
+ new Error('hashbuf must be a 32 byte buffer'),
245
+ );
246
+
247
+ var e = BN.fromBuffer(
248
+ hashbuf,
249
+ this.endian
250
+ ? {
251
+ endian: this.endian,
252
+ }
253
+ : undefined,
254
+ );
255
+
256
+ var obj = this._findSignature(d, e);
257
+ obj.compressed = this.pubkey.compressed;
258
+
259
+ this.sig = new Signature(obj);
260
+ return this;
261
+ };
262
+
263
+ ECDSA.prototype.signRandomK = function () {
264
+ this.randomK();
265
+ return this.sign();
266
+ };
267
+
268
+ ECDSA.prototype.toString = function () {
269
+ var obj = {};
270
+ if (this.hashbuf) {
271
+ obj.hashbuf = this.hashbuf.toString('hex');
272
+ }
273
+ if (this.privkey) {
274
+ obj.privkey = this.privkey.toString();
275
+ }
276
+ if (this.pubkey) {
277
+ obj.pubkey = this.pubkey.toString();
278
+ }
279
+ if (this.sig) {
280
+ obj.sig = this.sig.toString();
281
+ }
282
+ if (this.k) {
283
+ obj.k = this.k.toString();
284
+ }
285
+ return JSON.stringify(obj);
286
+ };
287
+
288
+ ECDSA.prototype.verify = function () {
289
+ if (!this.sigError()) {
290
+ this.verified = true;
291
+ } else {
292
+ this.verified = false;
293
+ }
294
+ return this;
295
+ };
296
+
297
+ ECDSA.sign = function (hashbuf, privkey, endian) {
298
+ return ECDSA()
299
+ .set({
300
+ hashbuf: hashbuf,
301
+ endian: endian,
302
+ privkey: privkey,
303
+ })
304
+ .sign().sig;
305
+ };
306
+
307
+ ECDSA.signWithCalcI = function (hashbuf, privkey, endian) {
308
+ return ECDSA()
309
+ .set({
310
+ hashbuf: hashbuf,
311
+ endian: endian,
312
+ privkey: privkey,
313
+ })
314
+ .sign()
315
+ .calci().sig;
316
+ };
317
+
318
+ ECDSA.signRandomK = function (hashbuf, privkey, endian) {
319
+ return ECDSA()
320
+ .set({
321
+ hashbuf: hashbuf,
322
+ endian: endian,
323
+ privkey: privkey,
324
+ })
325
+ .signRandomK().sig;
326
+ };
327
+
328
+ ECDSA.verify = function (hashbuf, sig, pubkey, endian) {
329
+ return ECDSA()
330
+ .set({
331
+ hashbuf: hashbuf,
332
+ endian: endian,
333
+ sig: sig,
334
+ pubkey: pubkey,
335
+ })
336
+ .verify().verified;
337
+ };
338
+
339
+ module.exports = ECDSA;