@opcat-labs/opcat 1.0.0 → 1.0.2

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 (293) hide show
  1. package/.cjs2esm.json +18 -0
  2. package/.mocharc.yaml +1 -1
  3. package/CHANGELOG.md +13 -0
  4. package/README.md +6 -0
  5. package/{lib/address.js → cjs/address.cjs} +77 -72
  6. package/cjs/block/block.cjs +332 -0
  7. package/{lib/block/blockheader.js → cjs/block/blockheader.cjs} +8 -7
  8. package/cjs/block/index.cjs +2 -0
  9. package/{lib/block/merkleblock.js → cjs/block/merkleblock.cjs} +23 -15
  10. package/cjs/bn.cjs +3411 -0
  11. package/{lib/crypto/bn.js → cjs/crypto/bn.cjs} +3 -3
  12. package/{lib/crypto/ecdsa.js → cjs/crypto/ecdsa.cjs} +150 -14
  13. package/{lib/crypto/hash.node.js → cjs/crypto/hash.cjs} +13 -2
  14. package/cjs/crypto/index.cjs +16 -0
  15. package/{lib/crypto/point.js → cjs/crypto/point.cjs} +11 -4
  16. package/cjs/crypto/random.cjs +18 -0
  17. package/{lib/crypto/signature.js → cjs/crypto/signature.cjs} +158 -8
  18. package/{lib/encoding/base58.js → cjs/encoding/base58.cjs} +58 -2
  19. package/cjs/encoding/base58check.cjs +192 -0
  20. package/cjs/encoding/bufferreader.cjs +333 -0
  21. package/cjs/encoding/bufferwriter.cjs +244 -0
  22. package/{lib/encoding/decode-asm.js → cjs/encoding/decode-asm.cjs} +4 -4
  23. package/{lib/encoding/decode-hex.js → cjs/encoding/decode-hex.cjs} +1 -1
  24. package/cjs/encoding/index.cjs +14 -0
  25. package/cjs/encoding/varint.cjs +116 -0
  26. package/{lib/errors/index.js → cjs/errors/index.cjs} +9 -9
  27. package/{lib/errors/spec.js → cjs/errors/spec.cjs} +2 -2
  28. package/cjs/hash-cache.cjs +98 -0
  29. package/{lib/hdprivatekey.js → cjs/hdprivatekey.cjs} +232 -140
  30. package/{lib/hdpublickey.js → cjs/hdpublickey.cjs} +120 -93
  31. package/cjs/index.cjs +94 -0
  32. package/cjs/interpreter/index.cjs +2 -0
  33. package/cjs/interpreter/interpreter.cjs +1988 -0
  34. package/{lib/script/stack.js → cjs/interpreter/stack.cjs} +9 -2
  35. package/{lib/message/message.js → cjs/message/message.cjs} +62 -25
  36. package/cjs/mnemonic/index.cjs +3 -0
  37. package/{lib/mnemonic/mnemonic.js → cjs/mnemonic/mnemonic.cjs} +44 -13
  38. package/{lib/mnemonic/pbkdf2.node.js → cjs/mnemonic/pbkdf2.cjs} +9 -2
  39. package/cjs/mnemonic/words/index.cjs +66 -0
  40. package/cjs/network.cjs +13 -0
  41. package/cjs/networks.cjs +321 -0
  42. package/{lib/opcode.js → cjs/opcode.cjs} +69 -5
  43. package/cjs/privatekey.cjs +422 -0
  44. package/{lib/publickey.js → cjs/publickey.cjs} +14 -16
  45. package/cjs/script/index.cjs +2 -0
  46. package/{lib/script/script.js → cjs/script/script.cjs} +322 -67
  47. package/cjs/transaction/index.cjs +5 -0
  48. package/cjs/transaction/input/index.cjs +34 -0
  49. package/cjs/transaction/input/input.cjs +396 -0
  50. package/{lib/transaction/input/multisig.js → cjs/transaction/input/multisig.cjs} +112 -18
  51. package/{lib/transaction/input/publickey.js → cjs/transaction/input/publickey.cjs} +29 -19
  52. package/{lib/transaction/input/publickeyhash.js → cjs/transaction/input/publickeyhash.cjs} +25 -17
  53. package/{lib/transaction/output.js → cjs/transaction/output.cjs} +100 -15
  54. package/cjs/transaction/sighash.cjs +187 -0
  55. package/{lib/transaction/signature.js → cjs/transaction/signature.cjs} +30 -6
  56. package/cjs/transaction/transaction.cjs +2000 -0
  57. package/{lib/transaction/unspentoutput.js → cjs/transaction/unspentoutput.cjs} +5 -5
  58. package/cjs/util/derivation.cjs +53 -0
  59. package/cjs/util/index.cjs +11 -0
  60. package/cjs/util/js.cjs +95 -0
  61. package/{lib/util/preconditions.js → cjs/util/preconditions.cjs} +2 -2
  62. package/esm/address.js +483 -0
  63. package/{lib → esm}/block/block.js +82 -27
  64. package/esm/block/blockheader.js +296 -0
  65. package/esm/block/index.js +2 -0
  66. package/esm/block/merkleblock.js +331 -0
  67. package/esm/bn.js +3411 -0
  68. package/esm/crypto/bn.js +278 -0
  69. package/esm/crypto/ecdsa.js +475 -0
  70. package/{lib/crypto/hash.browser.js → esm/crypto/hash.js} +18 -7
  71. package/esm/crypto/index.js +16 -0
  72. package/esm/crypto/point.js +228 -0
  73. package/esm/crypto/random.js +18 -0
  74. package/esm/crypto/signature.js +475 -0
  75. package/esm/encoding/base58.js +167 -0
  76. package/esm/encoding/base58check.js +192 -0
  77. package/esm/encoding/bufferreader.js +333 -0
  78. package/esm/encoding/bufferwriter.js +243 -0
  79. package/esm/encoding/decode-asm.js +24 -0
  80. package/esm/encoding/decode-hex.js +32 -0
  81. package/esm/encoding/decode-script-chunks.js +43 -0
  82. package/esm/encoding/encode-hex.js +284 -0
  83. package/esm/encoding/index.js +14 -0
  84. package/esm/encoding/is-hex.js +7 -0
  85. package/esm/encoding/varint.js +116 -0
  86. package/esm/errors/index.js +54 -0
  87. package/esm/errors/spec.js +314 -0
  88. package/esm/hash-cache.js +98 -0
  89. package/esm/hdprivatekey.js +768 -0
  90. package/esm/hdpublickey.js +549 -0
  91. package/esm/index.js +66 -0
  92. package/esm/interpreter/index.js +2 -0
  93. package/{lib/script → esm/interpreter}/interpreter.js +219 -66
  94. package/esm/interpreter/stack.js +116 -0
  95. package/esm/message/message.js +228 -0
  96. package/esm/mnemonic/index.js +3 -0
  97. package/esm/mnemonic/mnemonic.js +332 -0
  98. package/{lib/mnemonic/pbkdf2.browser.js → esm/mnemonic/pbkdf2.js} +13 -6
  99. package/esm/mnemonic/words/chinese.js +2054 -0
  100. package/esm/mnemonic/words/english.js +2054 -0
  101. package/esm/mnemonic/words/french.js +2054 -0
  102. package/esm/mnemonic/words/index.js +66 -0
  103. package/esm/mnemonic/words/italian.js +2054 -0
  104. package/esm/mnemonic/words/japanese.js +2054 -0
  105. package/esm/mnemonic/words/spanish.js +2054 -0
  106. package/esm/network.js +13 -0
  107. package/{lib → esm}/networks.js +61 -120
  108. package/esm/opcode.js +319 -0
  109. package/{lib → esm}/privatekey.js +76 -28
  110. package/esm/publickey.js +384 -0
  111. package/esm/script/index.js +2 -0
  112. package/esm/script/script.js +1329 -0
  113. package/esm/script/write-i32-le.js +17 -0
  114. package/esm/script/write-push-data.js +35 -0
  115. package/esm/script/write-u16-le.js +12 -0
  116. package/esm/script/write-u32-le.js +16 -0
  117. package/esm/script/write-u64-le.js +24 -0
  118. package/esm/script/write-u8-le.js +8 -0
  119. package/esm/script/write-varint.js +46 -0
  120. package/esm/transaction/index.js +5 -0
  121. package/esm/transaction/input/index.js +33 -0
  122. package/{lib → esm}/transaction/input/input.js +132 -90
  123. package/esm/transaction/input/multisig.js +335 -0
  124. package/esm/transaction/input/publickey.js +108 -0
  125. package/esm/transaction/input/publickeyhash.js +124 -0
  126. package/esm/transaction/output.js +316 -0
  127. package/{lib → esm}/transaction/sighash.js +42 -22
  128. package/esm/transaction/signature.js +120 -0
  129. package/{lib → esm}/transaction/transaction.js +522 -163
  130. package/esm/transaction/unspentoutput.js +112 -0
  131. package/esm/util/_.js +47 -0
  132. package/esm/util/derivation.js +53 -0
  133. package/esm/util/index.js +12 -0
  134. package/esm/util/js.js +95 -0
  135. package/esm/util/preconditions.js +33 -0
  136. package/fixup.cjs +17 -0
  137. package/package.json +40 -26
  138. package/test/{address.js → address.cjs} +14 -43
  139. package/test/block/{block.js → block.cjs} +3 -5
  140. package/test/block/{blockheader.js → blockheader.cjs} +2 -2
  141. package/test/block/{merklebloack.js → merklebloack.cjs} +2 -2
  142. package/test/crypto/{ecdsa.js → ecdsa.cjs} +9 -9
  143. package/test/crypto/{hash.browser.js → hash.browser.cjs} +2 -1
  144. package/test/crypto/{signature.js → signature.cjs} +2 -2
  145. package/test/data/bitcoind/script_tests.json +5 -5
  146. package/test/{hashCache.js → hashCache.cjs} +2 -1
  147. package/test/{hdkeys.js → hdkeys.cjs} +4 -2
  148. package/test/{hdprivatekey.js → hdprivatekey.cjs} +7 -6
  149. package/test/{hdpublickey.js → hdpublickey.cjs} +2 -7
  150. package/test/mnemonic/{pbkdf2.test.js → pbkdf2.test.cjs} +2 -2
  151. package/test/{networks.js → networks.cjs} +12 -31
  152. package/test/{publickey.js → publickey.cjs} +2 -2
  153. package/test/script/{interpreter.js → interpreter.cjs} +5 -5
  154. package/test/script/{script.js → script.cjs} +8 -2
  155. package/test/transaction/{deserialize.js → deserialize.cjs} +2 -2
  156. package/test/transaction/input/{input.js → input.cjs} +1 -1
  157. package/test/transaction/input/{multisig.js → multisig.cjs} +2 -1
  158. package/test/transaction/input/{publickeyhash.js → publickeyhash.cjs} +1 -1
  159. package/test/transaction/{sighash.js → sighash.cjs} +1 -1
  160. package/test/transaction/{transaction.js → transaction.cjs} +2 -2
  161. package/tsconfig.json +13 -0
  162. package/types/address.d.cts +252 -0
  163. package/types/block/block.d.cts +139 -0
  164. package/types/block/blockheader.d.cts +125 -0
  165. package/types/block/index.d.cts +2 -0
  166. package/types/block/merkleblock.d.cts +95 -0
  167. package/types/bn.d.cts +202 -0
  168. package/types/crypto/bn.d.cts +2 -0
  169. package/types/crypto/ecdsa.d.cts +187 -0
  170. package/types/crypto/hash.d.cts +118 -0
  171. package/types/crypto/index.d.cts +7 -0
  172. package/types/crypto/point.d.cts +134 -0
  173. package/types/crypto/random.d.cts +13 -0
  174. package/types/crypto/signature.d.cts +160 -0
  175. package/types/encoding/base58.d.cts +106 -0
  176. package/types/encoding/base58check.d.cts +107 -0
  177. package/types/encoding/bufferreader.d.cts +164 -0
  178. package/types/encoding/bufferwriter.d.cts +126 -0
  179. package/types/encoding/decode-asm.d.cts +2 -0
  180. package/types/encoding/decode-hex.d.cts +2 -0
  181. package/types/encoding/decode-script-chunks.d.cts +14 -0
  182. package/types/encoding/encode-hex.d.cts +2 -0
  183. package/types/encoding/index.d.cts +6 -0
  184. package/types/encoding/is-hex.d.cts +2 -0
  185. package/types/encoding/varint.d.cts +66 -0
  186. package/types/errors/index.d.cts +4 -0
  187. package/types/errors/spec.d.cts +22 -0
  188. package/types/hash-cache.d.cts +65 -0
  189. package/types/hdprivatekey.d.cts +281 -0
  190. package/types/hdpublickey.d.cts +240 -0
  191. package/types/index.d.cts +26 -0
  192. package/types/interpreter/index.d.cts +2 -0
  193. package/types/interpreter/interpreter.d.cts +228 -0
  194. package/types/interpreter/stack.d.cts +35 -0
  195. package/types/message/message.d.cts +110 -0
  196. package/types/mnemonic/index.d.cts +2 -0
  197. package/types/mnemonic/mnemonic.d.cts +171 -0
  198. package/types/mnemonic/pbkdf2.d.cts +14 -0
  199. package/types/mnemonic/words/chinese.d.cts +2 -0
  200. package/types/mnemonic/words/english.d.cts +2 -0
  201. package/types/mnemonic/words/french.d.cts +2 -0
  202. package/types/mnemonic/words/index.d.cts +22 -0
  203. package/types/mnemonic/words/italian.d.cts +2 -0
  204. package/types/mnemonic/words/japanese.d.cts +2 -0
  205. package/types/mnemonic/words/spanish.d.cts +2 -0
  206. package/types/network.d.cts +11 -0
  207. package/types/networks.d.cts +76 -0
  208. package/types/opcode.d.cts +93 -0
  209. package/types/privatekey.d.cts +169 -0
  210. package/types/publickey.d.cts +202 -0
  211. package/types/script/index.d.cts +2 -0
  212. package/types/script/script.d.cts +449 -0
  213. package/types/script/write-i32-le.d.cts +2 -0
  214. package/types/script/write-push-data.d.cts +2 -0
  215. package/types/script/write-u16-le.d.cts +2 -0
  216. package/types/script/write-u32-le.d.cts +2 -0
  217. package/types/script/write-u64-le.d.cts +2 -0
  218. package/types/script/write-u8-le.d.cts +2 -0
  219. package/types/script/write-varint.d.cts +2 -0
  220. package/types/transaction/index.d.cts +2 -0
  221. package/types/transaction/input/index.d.cts +2 -0
  222. package/types/transaction/input/input.d.cts +178 -0
  223. package/types/transaction/input/multisig.d.cts +127 -0
  224. package/types/transaction/input/publickey.d.cts +44 -0
  225. package/types/transaction/input/publickeyhash.d.cts +45 -0
  226. package/types/transaction/output.d.cts +118 -0
  227. package/types/transaction/sighash.d.cts +61 -0
  228. package/types/transaction/signature.d.cts +43 -0
  229. package/types/transaction/transaction.d.cts +716 -0
  230. package/types/transaction/unspentoutput.d.cts +83 -0
  231. package/types/util/_.d.cts +26 -0
  232. package/types/util/derivation.d.cts +21 -0
  233. package/types/util/index.d.cts +5 -0
  234. package/types/util/js.d.cts +50 -0
  235. package/types/util/preconditions.d.cts +3 -0
  236. package/index.d.ts +0 -1541
  237. package/index.js +0 -74
  238. package/lib/block/index.js +0 -4
  239. package/lib/bn.js +0 -3423
  240. package/lib/crypto/hash.js +0 -2
  241. package/lib/crypto/random.browser.js +0 -28
  242. package/lib/crypto/random.js +0 -2
  243. package/lib/crypto/random.node.js +0 -11
  244. package/lib/encoding/base58check.js +0 -121
  245. package/lib/encoding/bufferreader.js +0 -212
  246. package/lib/encoding/bufferwriter.js +0 -140
  247. package/lib/encoding/varint.js +0 -75
  248. package/lib/hash-cache.js +0 -50
  249. package/lib/mnemonic/pbkdf2.js +0 -2
  250. package/lib/mnemonic/words/index.js +0 -8
  251. package/lib/script/index.js +0 -5
  252. package/lib/transaction/index.js +0 -7
  253. package/lib/transaction/input/index.js +0 -5
  254. package/lib/util/js.js +0 -90
  255. /package/{lib/encoding/decode-script-chunks.js → cjs/encoding/decode-script-chunks.cjs} +0 -0
  256. /package/{lib/encoding/encode-hex.js → cjs/encoding/encode-hex.cjs} +0 -0
  257. /package/{lib/encoding/is-hex.js → cjs/encoding/is-hex.cjs} +0 -0
  258. /package/{lib/mnemonic/words/chinese.js → cjs/mnemonic/words/chinese.cjs} +0 -0
  259. /package/{lib/mnemonic/words/english.js → cjs/mnemonic/words/english.cjs} +0 -0
  260. /package/{lib/mnemonic/words/french.js → cjs/mnemonic/words/french.cjs} +0 -0
  261. /package/{lib/mnemonic/words/italian.js → cjs/mnemonic/words/italian.cjs} +0 -0
  262. /package/{lib/mnemonic/words/japanese.js → cjs/mnemonic/words/japanese.cjs} +0 -0
  263. /package/{lib/mnemonic/words/spanish.js → cjs/mnemonic/words/spanish.cjs} +0 -0
  264. /package/{lib/script/write-i32-le.js → cjs/script/write-i32-le.cjs} +0 -0
  265. /package/{lib/script/write-push-data.js → cjs/script/write-push-data.cjs} +0 -0
  266. /package/{lib/script/write-u16-le.js → cjs/script/write-u16-le.cjs} +0 -0
  267. /package/{lib/script/write-u32-le.js → cjs/script/write-u32-le.cjs} +0 -0
  268. /package/{lib/script/write-u64-le.js → cjs/script/write-u64-le.cjs} +0 -0
  269. /package/{lib/script/write-u8-le.js → cjs/script/write-u8-le.cjs} +0 -0
  270. /package/{lib/script/write-varint.js → cjs/script/write-varint.cjs} +0 -0
  271. /package/{lib/util/_.js → cjs/util/_.cjs} +0 -0
  272. /package/test/crypto/{bn.js → bn.cjs} +0 -0
  273. /package/test/crypto/{hash.js → hash.cjs} +0 -0
  274. /package/test/crypto/{point.js → point.cjs} +0 -0
  275. /package/test/crypto/{random.js → random.cjs} +0 -0
  276. /package/test/data/{blk86756-testnet.js → blk86756-testnet.cjs} +0 -0
  277. /package/test/data/{merkleblocks.js → merkleblocks.cjs} +0 -0
  278. /package/test/encoding/{base58.js → base58.cjs} +0 -0
  279. /package/test/encoding/{base58check.js → base58check.cjs} +0 -0
  280. /package/test/encoding/{bufferreader.js → bufferreader.cjs} +0 -0
  281. /package/test/encoding/{bufferwriter.js → bufferwriter.cjs} +0 -0
  282. /package/test/encoding/{varint.js → varint.cjs} +0 -0
  283. /package/test/{index.js → index.cjs} +0 -0
  284. /package/test/message/{message.js → message.cjs} +0 -0
  285. /package/test/mnemonic/{mnemonic.js → mnemonic.cjs} +0 -0
  286. /package/test/{opcode.js → opcode.cjs} +0 -0
  287. /package/test/{privatekey.js → privatekey.cjs} +0 -0
  288. /package/test/transaction/input/{publickey.js → publickey.cjs} +0 -0
  289. /package/test/transaction/{output.js → output.cjs} +0 -0
  290. /package/test/transaction/{signature.js → signature.cjs} +0 -0
  291. /package/test/transaction/{unspentoutput.js → unspentoutput.cjs} +0 -0
  292. /package/test/util/{js.js → js.cjs} +0 -0
  293. /package/test/util/{preconditions.js → preconditions.cjs} +0 -0
@@ -0,0 +1,475 @@
1
+ 'use strict';
2
+
3
+ import BN from './bn.js';
4
+ import Point from './point.js';
5
+ import Signature from './signature.js';
6
+ import PublicKey from '../publickey.js';
7
+ import Random from './random.js';
8
+ import Hash from './hash.js';
9
+ import _ from '../util/_.js';
10
+ import $ from '../util/preconditions.js';
11
+
12
+ /**
13
+ * Creates an ECDSA instance.
14
+ * @constructor
15
+ * @param {Object} [obj] - Optional object containing properties to initialize the instance.
16
+ */
17
+ function ECDSA(obj) {
18
+ if (!(this instanceof ECDSA)) {
19
+ return new ECDSA(obj);
20
+ }
21
+ if (obj) {
22
+ this.set(obj);
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Updates the ECDSA instance properties with provided values.
28
+ * @param {Object} obj - Object containing properties to update
29
+ * @param {Buffer} [obj.hashbuf] - Hash buffer
30
+ * @param {string} [obj.endian] - Endianness of hashbuf
31
+ * @param {PrivateKey} [obj.privkey] - Private key
32
+ * @param {PublicKey} [obj.pubkey] - Public key (derived from privkey if not provided)
33
+ * @param {Signature} [obj.sig] - Signature
34
+ * @param {BigInteger} [obj.k] - Random number k
35
+ * @param {boolean} [obj.verified] - Verification status
36
+ * @returns {ECDSA} Returns the updated ECDSA instance
37
+ */
38
+ ECDSA.prototype.set = function (obj) {
39
+ this.hashbuf = obj.hashbuf || this.hashbuf;
40
+ this.endian = obj.endian || this.endian; // the endianness of hashbuf
41
+ this.privkey = obj.privkey || this.privkey;
42
+ this.pubkey = obj.pubkey || (this.privkey ? this.privkey.publicKey : this.pubkey);
43
+ this.sig = obj.sig || this.sig;
44
+ this.k = obj.k || this.k;
45
+ this.verified = obj.verified || this.verified;
46
+ return this;
47
+ };
48
+
49
+ /**
50
+ * Converts the private key to a public key and stores it in the `pubkey` property.
51
+ */
52
+ ECDSA.prototype.privkey2pubkey = function () {
53
+ this.pubkey = this.privkey.toPublicKey();
54
+ };
55
+
56
+ /**
57
+ * Calculates the recovery factor (i) for ECDSA signature verification.
58
+ * Iterates through possible recovery factors (0-3) to find the one that
59
+ * reconstructs the correct public key from the signature.
60
+ *
61
+ * @returns {ECDSA} Returns the instance with updated signature properties if successful.
62
+ * @throws {Error} Throws if no valid recovery factor is found after all iterations.
63
+ */
64
+ ECDSA.prototype.calci = function () {
65
+ for (var i = 0; i < 4; i++) {
66
+ this.sig.i = i;
67
+ var Qprime;
68
+ try {
69
+ Qprime = this.toPublicKey();
70
+ } catch (e) {
71
+ console.error(e);
72
+ continue;
73
+ }
74
+
75
+ if (Qprime.point.eq(this.pubkey.point)) {
76
+ this.sig.compressed = this.pubkey.compressed;
77
+ return this;
78
+ }
79
+ }
80
+
81
+ this.sig.i = undefined;
82
+ throw new Error('Unable to find valid recovery factor');
83
+ };
84
+
85
+ /**
86
+ * Creates an ECDSA instance from a JSON string representation.
87
+ * @param {string} str - JSON string containing ECDSA parameters.
88
+ * @returns {ECDSA} New ECDSA instance initialized with parsed data.
89
+ */
90
+ ECDSA.fromString = function (str) {
91
+ var obj = JSON.parse(str);
92
+ return new ECDSA(obj);
93
+ };
94
+
95
+ /**
96
+ * Generates a random value `k` for ECDSA signing.
97
+ * The value is generated within the range (0, N) where N is the curve order.
98
+ * The generated `k` is stored in the instance and returned for chaining.
99
+ */
100
+ ECDSA.prototype.randomK = function () {
101
+ var N = Point.getN();
102
+ var k;
103
+ do {
104
+ k = BN.fromBuffer(Random.getRandomBuffer(32));
105
+ } while (!(k.lt(N) && k.gt(BN.Zero)));
106
+ this.k = k;
107
+ return this;
108
+ };
109
+
110
+
111
+ /**
112
+ * Generates a deterministic K value for ECDSA signing as per RFC 6979.
113
+ * See:
114
+ * https://tools.ietf.org/html/rfc6979#section-3.2
115
+ * Handles invalid r/s cases by incrementing badrs counter and regenerating K.
116
+ * @param {number} [badrs=0] - Counter for invalid r/s cases (default: 0)
117
+ * @returns {ECDSA} Returns the ECDSA instance for chaining
118
+ */
119
+ ECDSA.prototype.deterministicK = function (badrs) {
120
+ // if r or s were invalid when this function was used in signing,
121
+ // we do not want to actually compute r, s here for efficiency, so,
122
+ // we can increment badrs. explained at end of RFC 6979 section 3.2
123
+ if (_.isUndefined(badrs)) {
124
+ badrs = 0;
125
+ }
126
+ var v = Buffer.alloc(32);
127
+ v.fill(0x01);
128
+ var k = Buffer.alloc(32);
129
+ k.fill(0x00);
130
+ var x = this.privkey.bn.toBuffer({
131
+ size: 32,
132
+ });
133
+ var hashbuf = this.endian === 'little' ? Buffer.from(this.hashbuf).reverse() : this.hashbuf;
134
+ k = Hash.sha256hmac(Buffer.concat([v, Buffer.from([0x00]), x, hashbuf]), k);
135
+ v = Hash.sha256hmac(v, k);
136
+ k = Hash.sha256hmac(Buffer.concat([v, Buffer.from([0x01]), x, hashbuf]), k);
137
+ v = Hash.sha256hmac(v, k);
138
+ v = Hash.sha256hmac(v, k);
139
+ var T = BN.fromBuffer(v);
140
+ var N = Point.getN();
141
+
142
+ // also explained in 3.2, we must ensure T is in the proper range (0, N)
143
+ for (var i = 0; i < badrs || !(T.lt(N) && T.gt(BN.Zero)); i++) {
144
+ k = Hash.sha256hmac(Buffer.concat([v, Buffer.from([0x00])]), k);
145
+ v = Hash.sha256hmac(v, k);
146
+ v = Hash.sha256hmac(v, k);
147
+ T = BN.fromBuffer(v);
148
+ }
149
+
150
+ this.k = T;
151
+ return this;
152
+ };
153
+
154
+ /**
155
+ * Converts an ECDSA signature to its corresponding public key.
156
+ *
157
+ * The method follows the ECDSA public key recovery process:
158
+ * 1. Validates the recovery parameter `i` (must be 0-3)
159
+ * 2. Derives the public key point Q using the formula: Q = r⁻¹(sR - eG)
160
+ * 3. Validates the derived curve point
161
+ *
162
+ * see:
163
+ * https://bitcointalk.org/index.php?topic=6430.0
164
+ * http://stackoverflow.com/questions/19665491/how-do-i-get-an-ecdsa-public-key-from-just-a-bitcoin-signature-sec1-4-1-6-k
165
+ * @returns {PublicKey} The recovered public key
166
+ * @throws {Error} If recovery parameter is invalid or derived point is invalid
167
+ */
168
+ ECDSA.prototype.toPublicKey = function () {
169
+ var i = this.sig.i;
170
+ $.checkArgument(
171
+ i === 0 || i === 1 || i === 2 || i === 3,
172
+ new Error('i must be equal to 0, 1, 2, or 3'),
173
+ );
174
+
175
+ var e = BN.fromBuffer(this.hashbuf);
176
+ var r = this.sig.r;
177
+ var s = this.sig.s;
178
+
179
+ // A set LSB signifies that the y-coordinate is odd
180
+ var isYOdd = i & 1;
181
+
182
+ // The more significant bit specifies whether we should use the
183
+ // first or second candidate key.
184
+ var isSecondKey = i >> 1;
185
+
186
+ var n = Point.getN();
187
+ var G = Point.getG();
188
+
189
+ // 1.1 Let x = r + jn
190
+ var x = isSecondKey ? r.add(n) : r;
191
+ var R = Point.fromX(isYOdd, x);
192
+
193
+ // 1.4 Check that nR is at infinity
194
+ var nR = R.mul(n);
195
+
196
+ if (!nR.isInfinity()) {
197
+ throw new Error('nR is not a valid curve point');
198
+ }
199
+
200
+ // Compute -e from e
201
+ var eNeg = e.neg().umod(n);
202
+
203
+ // 1.6.1 Compute Q = r^-1 (sR - eG)
204
+ // Q = r^-1 (sR + -eG)
205
+ var rInv = r.invm(n);
206
+
207
+ // var Q = R.multiplyTwo(s, G, eNeg).mul(rInv);
208
+ var Q = R.mul(s).add(G.mul(eNeg)).mul(rInv);
209
+
210
+ var pubkey = PublicKey.fromPoint(Q, this.sig.compressed);
211
+
212
+ return pubkey;
213
+ };
214
+
215
+ /**
216
+ * Validates an ECDSA signature and returns an error message if invalid.
217
+ * Checks:
218
+ * - hashbuf is a 32-byte buffer
219
+ * - r and s values are within valid range
220
+ * - Signature verification against public key
221
+ * @returns {string|boolean} Error message if invalid, false if valid
222
+ */
223
+ ECDSA.prototype.sigError = function () {
224
+ if (!Buffer.isBuffer(this.hashbuf) || this.hashbuf.length !== 32) {
225
+ return 'hashbuf must be a 32 byte buffer';
226
+ }
227
+
228
+ var r = this.sig.r;
229
+ var s = this.sig.s;
230
+ if (!(r.gt(BN.Zero) && r.lt(Point.getN())) || !(s.gt(BN.Zero) && s.lt(Point.getN()))) {
231
+ return 'r and s not in range';
232
+ }
233
+
234
+ var e = BN.fromBuffer(
235
+ this.hashbuf,
236
+ this.endian
237
+ ? {
238
+ endian: this.endian,
239
+ }
240
+ : undefined,
241
+ );
242
+ var n = Point.getN();
243
+ var sinv = s.invm(n);
244
+ var u1 = sinv.mul(e).umod(n);
245
+ var u2 = sinv.mul(r).umod(n);
246
+
247
+ var p = Point.getG().mulAdd(u1, this.pubkey.point, u2);
248
+ if (p.isInfinity()) {
249
+ return 'p is infinity';
250
+ }
251
+
252
+ if (p.getX().umod(n).cmp(r) !== 0) {
253
+ return 'Invalid signature';
254
+ } else {
255
+ return false;
256
+ }
257
+ };
258
+
259
+ /**
260
+ * Converts the signature `s` value to its low-S form to comply with BIP 62.
261
+ * This prevents signature malleability by ensuring `s` is not greater than half the curve order.
262
+ * @param {BN} s - The signature `s` value as a big number.
263
+ * @returns {BN} The low-S normalized value.
264
+ * @static
265
+ */
266
+ ECDSA.toLowS = function (s) {
267
+ // enforce low s
268
+ // see BIP 62, "low S values in signatures"
269
+ if (
270
+ s.gt(
271
+ BN.fromBuffer(
272
+ Buffer.from('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0', 'hex'),
273
+ ),
274
+ )
275
+ ) {
276
+ s = Point.getN().sub(s);
277
+ }
278
+ return s;
279
+ };
280
+
281
+ /**
282
+ * Finds a valid ECDSA signature (r, s) for the given private key `d` and message hash `e`.
283
+ * Uses deterministic k-value generation if initial attempts fail.
284
+ *
285
+ * @param {BN} d - Private key as a big number.
286
+ * @param {BN} e - Message hash as a big number.
287
+ * @returns {Object} Signature object with properties `r` and `s` (big numbers).
288
+ * @throws Will throw if unable to find valid signature after multiple attempts.
289
+ */
290
+ ECDSA.prototype._findSignature = function (d, e) {
291
+ var N = Point.getN();
292
+ var G = Point.getG();
293
+ // try different values of k until r, s are valid
294
+ var badrs = 0;
295
+ var k, Q, r, s;
296
+ do {
297
+ if (!this.k || badrs > 0) {
298
+ this.deterministicK(badrs);
299
+ }
300
+ badrs++;
301
+ k = this.k;
302
+ Q = G.mul(k);
303
+ r = new BN(1).mul(Q.x.umod(N));
304
+ s = k
305
+ .invm(N)
306
+ .mul(e.add(d.mul(r)))
307
+ .umod(N);
308
+ } while (r.cmp(BN.Zero) <= 0 || s.cmp(BN.Zero) <= 0);
309
+
310
+ s = ECDSA.toLowS(s);
311
+ return {
312
+ s: s,
313
+ r: r,
314
+ };
315
+ };
316
+
317
+ /**
318
+ * Signs a message using ECDSA.
319
+ *
320
+ * @param {Buffer} hashbuf - 32-byte buffer containing the hash of the message to sign.
321
+ * @param {PrivateKey} privkey - Private key used for signing.
322
+ * @returns {ECDSA} Returns the instance for chaining.
323
+ * @throws {Error} Throws if parameters are invalid or hashbuf is not a 32-byte buffer.
324
+ */
325
+ ECDSA.prototype.sign = function () {
326
+ var hashbuf = this.hashbuf;
327
+ var privkey = this.privkey;
328
+ var d = privkey.bn;
329
+
330
+ $.checkState(hashbuf && privkey && d, new Error('invalid parameters'));
331
+ $.checkState(
332
+ Buffer.isBuffer(hashbuf) && hashbuf.length === 32,
333
+ new Error('hashbuf must be a 32 byte buffer'),
334
+ );
335
+
336
+ var e = BN.fromBuffer(
337
+ hashbuf,
338
+ this.endian
339
+ ? {
340
+ endian: this.endian,
341
+ }
342
+ : undefined,
343
+ );
344
+
345
+ var obj = this._findSignature(d, e);
346
+ obj.compressed = this.pubkey.compressed;
347
+
348
+ this.sig = new Signature(obj);
349
+ return this;
350
+ };
351
+
352
+ /**
353
+ * Signs the message using a randomly generated k value.
354
+ *
355
+ * @returns The signature object containing r and s values.
356
+ */
357
+ ECDSA.prototype.signRandomK = function () {
358
+ this.randomK();
359
+ return this.sign();
360
+ };
361
+
362
+ /**
363
+ * Converts the ECDSA instance to a JSON string representation.
364
+ * Includes hash buffer, private key, public key, signature, and k value if present.
365
+ * Each property is converted to a string format (hex for hashbuf, toString() for others).
366
+ * @returns {string} JSON string containing the ECDSA instance properties
367
+ */
368
+ ECDSA.prototype.toString = function () {
369
+ var obj = {};
370
+ if (this.hashbuf) {
371
+ obj.hashbuf = this.hashbuf.toString('hex');
372
+ }
373
+ if (this.privkey) {
374
+ obj.privkey = this.privkey.toString();
375
+ }
376
+ if (this.pubkey) {
377
+ obj.pubkey = this.pubkey.toString();
378
+ }
379
+ if (this.sig) {
380
+ obj.sig = this.sig.toString();
381
+ }
382
+ if (this.k) {
383
+ obj.k = this.k.toString();
384
+ }
385
+ return JSON.stringify(obj);
386
+ };
387
+
388
+ /**
389
+ * Verifies the ECDSA signature and updates the `verified` property.
390
+ * @returns {ECDSA} The current instance for chaining.
391
+ */
392
+ ECDSA.prototype.verify = function () {
393
+ if (!this.sigError()) {
394
+ this.verified = true;
395
+ } else {
396
+ this.verified = false;
397
+ }
398
+ return this;
399
+ };
400
+
401
+ /**
402
+ * Signs a message hash using ECDSA with the given private key.
403
+ * @param {Buffer} hashbuf - The hash of the message to sign
404
+ * @param {PrivateKey} privkey - The private key to sign with
405
+ * @param {string} [endian] - Endianness of the input/output (optional)
406
+ * @returns {Signature} The ECDSA signature
407
+ */
408
+ ECDSA.sign = function (hashbuf, privkey, endian) {
409
+ return ECDSA()
410
+ .set({
411
+ hashbuf: hashbuf,
412
+ endian: endian,
413
+ privkey: privkey,
414
+ })
415
+ .sign().sig;
416
+ };
417
+
418
+ /**
419
+ * Signs a hash buffer with a private key and calculates the 'i' value.
420
+ * @param {Buffer} hashbuf - The hash buffer to sign.
421
+ * @param {Buffer} privkey - The private key used for signing.
422
+ * @param {string} [endian] - The endianness of the input data (optional).
423
+ * @returns {Buffer} The resulting signature.
424
+ * @static
425
+ */
426
+ ECDSA.signWithCalcI = function (hashbuf, privkey, endian) {
427
+ return ECDSA()
428
+ .set({
429
+ hashbuf: hashbuf,
430
+ endian: endian,
431
+ privkey: privkey,
432
+ })
433
+ .sign()
434
+ .calci().sig;
435
+ };
436
+
437
+ /**
438
+ * Signs a message hash using ECDSA with a randomly generated K value.
439
+ * @param {Buffer} hashbuf - The message hash to sign.
440
+ * @param {Buffer} privkey - The private key used for signing.
441
+ * @param {string} [endian] - The endianness of the input/output (default: 'big').
442
+ * @returns {Buffer} The generated ECDSA signature.
443
+ * @static
444
+ */
445
+ ECDSA.signRandomK = function (hashbuf, privkey, endian) {
446
+ return ECDSA()
447
+ .set({
448
+ hashbuf: hashbuf,
449
+ endian: endian,
450
+ privkey: privkey,
451
+ })
452
+ .signRandomK().sig;
453
+ };
454
+
455
+ /**
456
+ * Verifies an ECDSA signature against a hash and public key.
457
+ * @param {Buffer} hashbuf - The hash buffer to verify against.
458
+ * @param {Signature} sig - The signature to verify.
459
+ * @param {PublicKey} pubkey - The public key to verify with.
460
+ * @param {string} [endian] - The endianness of the input data (optional).
461
+ * @returns {boolean} True if the signature is valid, false otherwise.
462
+ * @static
463
+ */
464
+ ECDSA.verify = function (hashbuf, sig, pubkey, endian) {
465
+ return ECDSA()
466
+ .set({
467
+ hashbuf: hashbuf,
468
+ endian: endian,
469
+ sig: sig,
470
+ pubkey: pubkey,
471
+ })
472
+ .verify().verified;
473
+ };
474
+
475
+ export default ECDSA;
@@ -1,9 +1,17 @@
1
1
  'use strict';
2
2
 
3
- var hash = require('hash.js');
4
- var $ = require('../util/preconditions');
3
+ import crypto from 'crypto';
4
+ import $ from '../util/preconditions.js';
5
5
 
6
- var Hash = module.exports;
6
+ /**
7
+ * Represents a hash utility class.
8
+ * @constructor
9
+ */
10
+ function Hash() {
11
+ if (!(this instanceof Hash)) {
12
+ return new Hash();
13
+ }
14
+ }
7
15
 
8
16
  /**
9
17
  * A SHA or SHA1 hash, which is always 160 bits or 20 bytes long.
@@ -16,7 +24,7 @@ var Hash = module.exports;
16
24
  */
17
25
  Hash.sha1 = function (buf) {
18
26
  $.checkArgument(Buffer.isBuffer(buf));
19
- return Buffer.from(hash.sha1().update(buf).digest('hex'), 'hex');
27
+ return crypto.createHash('sha1').update(buf).digest();
20
28
  };
21
29
 
22
30
  Hash.sha1.blocksize = 512;
@@ -32,7 +40,7 @@ Hash.sha1.blocksize = 512;
32
40
  */
33
41
  Hash.sha256 = function (buf) {
34
42
  $.checkArgument(Buffer.isBuffer(buf));
35
- return Buffer.from(hash.sha256().update(buf).digest('hex'), 'hex');
43
+ return crypto.createHash('sha256').update(buf).digest();
36
44
  };
37
45
 
38
46
  Hash.sha256.blocksize = 512;
@@ -64,7 +72,7 @@ Hash.sha256sha256 = function (buf) {
64
72
  */
65
73
  Hash.ripemd160 = function (buf) {
66
74
  $.checkArgument(Buffer.isBuffer(buf));
67
- return Buffer.from(hash.ripemd160().update(buf).digest('hex'), 'hex');
75
+ return crypto.createHash('ripemd160').update(buf).digest();
68
76
  };
69
77
  /**
70
78
  * A RIPEMD160 hash of a SHA256 hash, which is always 160 bits or 20 bytes long.
@@ -93,7 +101,7 @@ Hash.sha256ripemd160 = function (buf) {
93
101
  */
94
102
  Hash.sha512 = function (buf) {
95
103
  $.checkArgument(Buffer.isBuffer(buf));
96
- return Buffer.from(hash.sha512().update(buf).digest('hex'), 'hex');
104
+ return crypto.createHash('sha512').update(buf).digest();
97
105
  };
98
106
 
99
107
  Hash.sha512.blocksize = 1024;
@@ -169,3 +177,6 @@ Hash.sha256hmac = function (data, key) {
169
177
  Hash.sha512hmac = function (data, key) {
170
178
  return Hash.hmac(Hash.sha512, data, key);
171
179
  };
180
+
181
+
182
+ export default Hash;
@@ -0,0 +1,16 @@
1
+ import BN from './bn.js';
2
+ import ECDSA from './ecdsa.js';
3
+ import Hash from './hash.js';
4
+ import Random from './random.js';
5
+ import Point from './point.js';
6
+ import Signature from './signature.js';
7
+
8
+ export default {
9
+ BN: BN,
10
+ ECDSA: ECDSA,
11
+ Hash: Hash,
12
+ Random: Random,
13
+ Point: Point,
14
+ Signature: Signature
15
+ };
16
+