smartledger-bsv 3.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 (76) hide show
  1. package/LICENSE +36 -0
  2. package/README.md +305 -0
  3. package/SECURITY.md +75 -0
  4. package/bsv-ecies.min.js +12 -0
  5. package/bsv-message.min.js +10 -0
  6. package/bsv-mnemonic.min.js +12 -0
  7. package/bsv.d.ts +440 -0
  8. package/bsv.min.js +37 -0
  9. package/ecies/index.js +1 -0
  10. package/index.js +101 -0
  11. package/lib/address.js +526 -0
  12. package/lib/block/block.js +277 -0
  13. package/lib/block/blockheader.js +294 -0
  14. package/lib/block/index.js +4 -0
  15. package/lib/block/merkleblock.js +316 -0
  16. package/lib/crypto/bn.js +278 -0
  17. package/lib/crypto/ecdsa.js +330 -0
  18. package/lib/crypto/elliptic-fixed.js +74 -0
  19. package/lib/crypto/hash.browser.js +171 -0
  20. package/lib/crypto/hash.js +2 -0
  21. package/lib/crypto/hash.node.js +171 -0
  22. package/lib/crypto/point.js +217 -0
  23. package/lib/crypto/random.js +37 -0
  24. package/lib/crypto/signature.js +410 -0
  25. package/lib/crypto/smartledger_verify.js +109 -0
  26. package/lib/ecies/bitcore-ecies.js +163 -0
  27. package/lib/ecies/electrum-ecies.js +175 -0
  28. package/lib/ecies/errors.js +16 -0
  29. package/lib/ecies/index.js +1 -0
  30. package/lib/encoding/base58.js +108 -0
  31. package/lib/encoding/base58check.js +112 -0
  32. package/lib/encoding/bufferreader.js +200 -0
  33. package/lib/encoding/bufferwriter.js +150 -0
  34. package/lib/encoding/varint.js +71 -0
  35. package/lib/errors/index.js +57 -0
  36. package/lib/errors/spec.js +184 -0
  37. package/lib/hdprivatekey.js +655 -0
  38. package/lib/hdpublickey.js +509 -0
  39. package/lib/message/index.js +4 -0
  40. package/lib/message/message.js +181 -0
  41. package/lib/mnemonic/errors.js +18 -0
  42. package/lib/mnemonic/index.js +4 -0
  43. package/lib/mnemonic/mnemonic.js +304 -0
  44. package/lib/mnemonic/pbkdf2.js +68 -0
  45. package/lib/mnemonic/words/chinese.js +5 -0
  46. package/lib/mnemonic/words/english.js +5 -0
  47. package/lib/mnemonic/words/french.js +5 -0
  48. package/lib/mnemonic/words/index.js +8 -0
  49. package/lib/mnemonic/words/italian.js +5 -0
  50. package/lib/mnemonic/words/japanese.js +5 -0
  51. package/lib/mnemonic/words/spanish.js +5 -0
  52. package/lib/networks.js +392 -0
  53. package/lib/opcode.js +248 -0
  54. package/lib/privatekey.js +373 -0
  55. package/lib/publickey.js +387 -0
  56. package/lib/script/index.js +3 -0
  57. package/lib/script/interpreter.js +1807 -0
  58. package/lib/script/script.js +1153 -0
  59. package/lib/transaction/index.js +7 -0
  60. package/lib/transaction/input/index.js +6 -0
  61. package/lib/transaction/input/input.js +202 -0
  62. package/lib/transaction/input/multisig.js +220 -0
  63. package/lib/transaction/input/multisigscripthash.js +189 -0
  64. package/lib/transaction/input/publickey.js +96 -0
  65. package/lib/transaction/input/publickeyhash.js +103 -0
  66. package/lib/transaction/output.js +192 -0
  67. package/lib/transaction/sighash.js +288 -0
  68. package/lib/transaction/signature.js +88 -0
  69. package/lib/transaction/transaction.js +1208 -0
  70. package/lib/transaction/unspentoutput.js +97 -0
  71. package/lib/util/_.js +44 -0
  72. package/lib/util/js.js +91 -0
  73. package/lib/util/preconditions.js +34 -0
  74. package/message/index.js +1 -0
  75. package/mnemonic/index.js +1 -0
  76. package/package.json +86 -0
@@ -0,0 +1,509 @@
1
+ 'use strict'
2
+
3
+ var _ = require('./util/_')
4
+ var $ = require('./util/preconditions')
5
+
6
+ var BN = require('./crypto/bn')
7
+ var Base58 = require('./encoding/base58')
8
+ var Base58Check = require('./encoding/base58check')
9
+ var Hash = require('./crypto/hash')
10
+ var HDPrivateKey = require('./hdprivatekey')
11
+ var Network = require('./networks')
12
+ var Point = require('./crypto/point')
13
+ var PublicKey = require('./publickey')
14
+
15
+ var bsvErrors = require('./errors')
16
+ var errors = bsvErrors
17
+ var hdErrors = bsvErrors.HDPublicKey
18
+ var assert = require('assert')
19
+
20
+ var JSUtil = require('./util/js')
21
+
22
+ /**
23
+ * The representation of an hierarchically derived public key.
24
+ *
25
+ * See https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
26
+ *
27
+ * @constructor
28
+ * @param {Object|string|Buffer} arg
29
+ */
30
+ function HDPublicKey (arg) {
31
+ if (arg instanceof HDPublicKey) {
32
+ return arg
33
+ }
34
+ if (!(this instanceof HDPublicKey)) {
35
+ return new HDPublicKey(arg)
36
+ }
37
+ if (arg) {
38
+ if (_.isString(arg) || Buffer.isBuffer(arg)) {
39
+ var error = HDPublicKey.getSerializedError(arg)
40
+ if (!error) {
41
+ return this._buildFromSerialized(arg)
42
+ } else if (Buffer.isBuffer(arg) && !HDPublicKey.getSerializedError(arg.toString())) {
43
+ return this._buildFromSerialized(arg.toString())
44
+ } else {
45
+ if (error instanceof hdErrors.ArgumentIsPrivateExtended) {
46
+ return new HDPrivateKey(arg).hdPublicKey
47
+ }
48
+ throw error
49
+ }
50
+ } else {
51
+ if (_.isObject(arg)) {
52
+ if (arg instanceof HDPrivateKey) {
53
+ return this._buildFromPrivate(arg)
54
+ } else {
55
+ return this._buildFromObject(arg)
56
+ }
57
+ } else {
58
+ throw new hdErrors.UnrecognizedArgument(arg)
59
+ }
60
+ }
61
+ } else {
62
+ throw new hdErrors.MustSupplyArgument()
63
+ }
64
+ }
65
+
66
+ HDPublicKey.fromHDPrivateKey = function (hdPrivateKey) {
67
+ return new HDPublicKey(hdPrivateKey)
68
+ }
69
+
70
+ /**
71
+ * Verifies that a given path is valid.
72
+ *
73
+ * @param {string|number} arg
74
+ * @return {boolean}
75
+ */
76
+ HDPublicKey.isValidPath = function (arg) {
77
+ if (_.isString(arg)) {
78
+ var indexes = HDPrivateKey._getDerivationIndexes(arg)
79
+ return indexes !== null && _.every(indexes, HDPublicKey.isValidPath)
80
+ }
81
+
82
+ if (_.isNumber(arg)) {
83
+ return arg >= 0 && arg < HDPublicKey.Hardened
84
+ }
85
+
86
+ return false
87
+ }
88
+
89
+ /**
90
+ * WARNING: This method is deprecated. Use deriveChild instead.
91
+ *
92
+ *
93
+ * Get a derivated child based on a string or number.
94
+ *
95
+ * If the first argument is a string, it's parsed as the full path of
96
+ * derivation. Valid values for this argument include "m" (which returns the
97
+ * same public key), "m/0/1/40/2/1000".
98
+ *
99
+ * Note that hardened keys can't be derived from a public extended key.
100
+ *
101
+ * If the first argument is a number, the child with that index will be
102
+ * derived. See the example usage for clarification.
103
+ *
104
+ * @example
105
+ * ```javascript
106
+ * var parent = new HDPublicKey('xpub...');
107
+ * var child_0_1_2 = parent.derive(0).derive(1).derive(2);
108
+ * var copy_of_child_0_1_2 = parent.derive("m/0/1/2");
109
+ * assert(child_0_1_2.xprivkey === copy_of_child_0_1_2);
110
+ * ```
111
+ *
112
+ * @param {string|number} arg
113
+ */
114
+ HDPublicKey.prototype.derive = function () {
115
+ throw new Error('derive has been deprecated. use deriveChild or, for the old way, deriveNonCompliantChild.')
116
+ }
117
+
118
+ /**
119
+ * WARNING: This method will not be officially supported until v1.0.0.
120
+ *
121
+ *
122
+ * Get a derivated child based on a string or number.
123
+ *
124
+ * If the first argument is a string, it's parsed as the full path of
125
+ * derivation. Valid values for this argument include "m" (which returns the
126
+ * same public key), "m/0/1/40/2/1000".
127
+ *
128
+ * Note that hardened keys can't be derived from a public extended key.
129
+ *
130
+ * If the first argument is a number, the child with that index will be
131
+ * derived. See the example usage for clarification.
132
+ *
133
+ * @example
134
+ * ```javascript
135
+ * var parent = new HDPublicKey('xpub...');
136
+ * var child_0_1_2 = parent.deriveChild(0).deriveChild(1).deriveChild(2);
137
+ * var copy_of_child_0_1_2 = parent.deriveChild("m/0/1/2");
138
+ * assert(child_0_1_2.xprivkey === copy_of_child_0_1_2);
139
+ * ```
140
+ *
141
+ * @param {string|number} arg
142
+ */
143
+ HDPublicKey.prototype.deriveChild = function (arg, hardened) {
144
+ if (_.isNumber(arg)) {
145
+ return this._deriveWithNumber(arg, hardened)
146
+ } else if (_.isString(arg)) {
147
+ return this._deriveFromString(arg)
148
+ } else {
149
+ throw new hdErrors.InvalidDerivationArgument(arg)
150
+ }
151
+ }
152
+
153
+ HDPublicKey.prototype._deriveWithNumber = function (index, hardened) {
154
+ if (index >= HDPublicKey.Hardened || hardened) {
155
+ throw new hdErrors.InvalidIndexCantDeriveHardened()
156
+ }
157
+ if (index < 0) {
158
+ throw new hdErrors.InvalidPath(index)
159
+ }
160
+
161
+ var indexBuffer = JSUtil.integerAsBuffer(index)
162
+ var data = Buffer.concat([this.publicKey.toBuffer(), indexBuffer])
163
+ var hash = Hash.sha512hmac(data, this._buffers.chainCode)
164
+ var leftPart = BN.fromBuffer(hash.slice(0, 32), { size: 32 })
165
+ var chainCode = hash.slice(32, 64)
166
+
167
+ var publicKey
168
+ try {
169
+ publicKey = PublicKey.fromPoint(Point.getG().mul(leftPart).add(this.publicKey.point))
170
+ } catch (e) {
171
+ return this._deriveWithNumber(index + 1)
172
+ }
173
+
174
+ var derived = new HDPublicKey({
175
+ network: this.network,
176
+ depth: this.depth + 1,
177
+ parentFingerPrint: this.fingerPrint,
178
+ childIndex: index,
179
+ chainCode: chainCode,
180
+ publicKey: publicKey
181
+ })
182
+
183
+ return derived
184
+ }
185
+
186
+ HDPublicKey.prototype._deriveFromString = function (path) {
187
+ if (_.includes(path, "'")) {
188
+ throw new hdErrors.InvalidIndexCantDeriveHardened()
189
+ } else if (!HDPublicKey.isValidPath(path)) {
190
+ throw new hdErrors.InvalidPath(path)
191
+ }
192
+
193
+ var indexes = HDPrivateKey._getDerivationIndexes(path)
194
+ var derived = indexes.reduce(function (prev, index) {
195
+ return prev._deriveWithNumber(index)
196
+ }, this)
197
+
198
+ return derived
199
+ }
200
+
201
+ /**
202
+ * Verifies that a given serialized public key in base58 with checksum format
203
+ * is valid.
204
+ *
205
+ * @param {string|Buffer} data - the serialized public key
206
+ * @param {string|Network=} network - optional, if present, checks that the
207
+ * network provided matches the network serialized.
208
+ * @return {boolean}
209
+ */
210
+ HDPublicKey.isValidSerialized = function (data, network) {
211
+ return _.isNull(HDPublicKey.getSerializedError(data, network))
212
+ }
213
+
214
+ /**
215
+ * Checks what's the error that causes the validation of a serialized public key
216
+ * in base58 with checksum to fail.
217
+ *
218
+ * @param {string|Buffer} data - the serialized public key
219
+ * @param {string|Network=} network - optional, if present, checks that the
220
+ * network provided matches the network serialized.
221
+ * @return {errors|null}
222
+ */
223
+ HDPublicKey.getSerializedError = function (data, network) {
224
+ if (!(_.isString(data) || Buffer.isBuffer(data))) {
225
+ return new hdErrors.UnrecognizedArgument('expected buffer or string')
226
+ }
227
+ if (!Base58.validCharacters(data)) {
228
+ return new errors.InvalidB58Char('(unknown)', data)
229
+ }
230
+ try {
231
+ data = Base58Check.decode(data)
232
+ } catch (e) {
233
+ return new errors.InvalidB58Checksum(data)
234
+ }
235
+ if (data.length !== HDPublicKey.DataSize) {
236
+ return new hdErrors.InvalidLength(data)
237
+ }
238
+ if (!_.isUndefined(network)) {
239
+ var error = HDPublicKey._validateNetwork(data, network)
240
+ if (error) {
241
+ return error
242
+ }
243
+ }
244
+ var version = data.readUInt32BE(0)
245
+ if (version === Network.livenet.xprivkey || version === Network.testnet.xprivkey) {
246
+ return new hdErrors.ArgumentIsPrivateExtended()
247
+ }
248
+ return null
249
+ }
250
+
251
+ HDPublicKey._validateNetwork = function (data, networkArg) {
252
+ var network = Network.get(networkArg)
253
+ if (!network) {
254
+ return new errors.InvalidNetworkArgument(networkArg)
255
+ }
256
+ var version = data.slice(HDPublicKey.VersionStart, HDPublicKey.VersionEnd)
257
+ if (version.readUInt32BE(0) !== network.xpubkey) {
258
+ return new errors.InvalidNetwork(version)
259
+ }
260
+ return null
261
+ }
262
+
263
+ HDPublicKey.prototype._buildFromPrivate = function (arg) {
264
+ var args = _.clone(arg._buffers)
265
+ var point = Point.getG().mul(BN.fromBuffer(args.privateKey))
266
+ args.publicKey = Point.pointToCompressed(point)
267
+ args.version = JSUtil.integerAsBuffer(Network.get(args.version.readUInt32BE(0)).xpubkey)
268
+ args.privateKey = undefined
269
+ args.checksum = undefined
270
+ args.xprivkey = undefined
271
+ return this._buildFromBuffers(args)
272
+ }
273
+
274
+ HDPublicKey.prototype._buildFromObject = function (arg) {
275
+ // TODO: Type validation
276
+ var buffers = {
277
+ version: arg.network ? JSUtil.integerAsBuffer(Network.get(arg.network).xpubkey) : arg.version,
278
+ depth: _.isNumber(arg.depth) ? Buffer.from([arg.depth & 0xff]) : arg.depth,
279
+ parentFingerPrint: _.isNumber(arg.parentFingerPrint) ? JSUtil.integerAsBuffer(arg.parentFingerPrint) : arg.parentFingerPrint,
280
+ childIndex: _.isNumber(arg.childIndex) ? JSUtil.integerAsBuffer(arg.childIndex) : arg.childIndex,
281
+ chainCode: _.isString(arg.chainCode) ? Buffer.from(arg.chainCode, 'hex') : arg.chainCode,
282
+ publicKey: _.isString(arg.publicKey) ? Buffer.from(arg.publicKey, 'hex')
283
+ : Buffer.isBuffer(arg.publicKey) ? arg.publicKey : arg.publicKey.toBuffer(),
284
+ checksum: _.isNumber(arg.checksum) ? JSUtil.integerAsBuffer(arg.checksum) : arg.checksum
285
+ }
286
+ return this._buildFromBuffers(buffers)
287
+ }
288
+
289
+ HDPublicKey.prototype._buildFromSerialized = function (arg) {
290
+ var decoded = Base58Check.decode(arg)
291
+ var buffers = {
292
+ version: decoded.slice(HDPublicKey.VersionStart, HDPublicKey.VersionEnd),
293
+ depth: decoded.slice(HDPublicKey.DepthStart, HDPublicKey.DepthEnd),
294
+ parentFingerPrint: decoded.slice(HDPublicKey.ParentFingerPrintStart,
295
+ HDPublicKey.ParentFingerPrintEnd),
296
+ childIndex: decoded.slice(HDPublicKey.ChildIndexStart, HDPublicKey.ChildIndexEnd),
297
+ chainCode: decoded.slice(HDPublicKey.ChainCodeStart, HDPublicKey.ChainCodeEnd),
298
+ publicKey: decoded.slice(HDPublicKey.PublicKeyStart, HDPublicKey.PublicKeyEnd),
299
+ checksum: decoded.slice(HDPublicKey.ChecksumStart, HDPublicKey.ChecksumEnd),
300
+ xpubkey: arg
301
+ }
302
+ return this._buildFromBuffers(buffers)
303
+ }
304
+
305
+ /**
306
+ * Receives a object with buffers in all the properties and populates the
307
+ * internal structure
308
+ *
309
+ * @param {Object} arg
310
+ * @param {buffer.Buffer} arg.version
311
+ * @param {buffer.Buffer} arg.depth
312
+ * @param {buffer.Buffer} arg.parentFingerPrint
313
+ * @param {buffer.Buffer} arg.childIndex
314
+ * @param {buffer.Buffer} arg.chainCode
315
+ * @param {buffer.Buffer} arg.publicKey
316
+ * @param {buffer.Buffer} arg.checksum
317
+ * @param {string=} arg.xpubkey - if set, don't recalculate the base58
318
+ * representation
319
+ * @return {HDPublicKey} this
320
+ */
321
+ HDPublicKey.prototype._buildFromBuffers = function (arg) {
322
+ HDPublicKey._validateBufferArguments(arg)
323
+
324
+ JSUtil.defineImmutable(this, {
325
+ _buffers: arg
326
+ })
327
+
328
+ var sequence = [
329
+ arg.version, arg.depth, arg.parentFingerPrint, arg.childIndex, arg.chainCode,
330
+ arg.publicKey
331
+ ]
332
+ var concat = Buffer.concat(sequence)
333
+ var checksum = Base58Check.checksum(concat)
334
+ if (!arg.checksum || !arg.checksum.length) {
335
+ arg.checksum = checksum
336
+ } else {
337
+ if (arg.checksum.toString('hex') !== checksum.toString('hex')) {
338
+ throw new errors.InvalidB58Checksum(concat, checksum)
339
+ }
340
+ }
341
+ var network = Network.get(arg.version.readUInt32BE(0))
342
+
343
+ var xpubkey
344
+ xpubkey = Base58Check.encode(Buffer.concat(sequence))
345
+ arg.xpubkey = Buffer.from(xpubkey)
346
+
347
+ var publicKey = new PublicKey(arg.publicKey, { network: network })
348
+ var size = HDPublicKey.ParentFingerPrintSize
349
+ var fingerPrint = Hash.sha256ripemd160(publicKey.toBuffer()).slice(0, size)
350
+
351
+ JSUtil.defineImmutable(this, {
352
+ xpubkey: xpubkey,
353
+ network: network,
354
+ depth: arg.depth[0],
355
+ publicKey: publicKey,
356
+ fingerPrint: fingerPrint
357
+ })
358
+
359
+ return this
360
+ }
361
+
362
+ HDPublicKey._validateBufferArguments = function (arg) {
363
+ var checkBuffer = function (name, size) {
364
+ var buff = arg[name]
365
+ assert(Buffer.isBuffer(buff), name + ' argument is not a buffer, it\'s ' + typeof buff)
366
+ assert(
367
+ buff.length === size,
368
+ name + ' has not the expected size: found ' + buff.length + ', expected ' + size
369
+ )
370
+ }
371
+ checkBuffer('version', HDPublicKey.VersionSize)
372
+ checkBuffer('depth', HDPublicKey.DepthSize)
373
+ checkBuffer('parentFingerPrint', HDPublicKey.ParentFingerPrintSize)
374
+ checkBuffer('childIndex', HDPublicKey.ChildIndexSize)
375
+ checkBuffer('chainCode', HDPublicKey.ChainCodeSize)
376
+ checkBuffer('publicKey', HDPublicKey.PublicKeySize)
377
+ if (arg.checksum && arg.checksum.length) {
378
+ checkBuffer('checksum', HDPublicKey.CheckSumSize)
379
+ }
380
+ }
381
+
382
+ HDPublicKey.fromString = function (arg) {
383
+ $.checkArgument(_.isString(arg), 'No valid string was provided')
384
+ return new HDPublicKey(arg)
385
+ }
386
+
387
+ HDPublicKey.fromObject = function (arg) {
388
+ $.checkArgument(_.isObject(arg), 'No valid argument was provided')
389
+ return new HDPublicKey(arg)
390
+ }
391
+
392
+ /**
393
+ * Returns the base58 checked representation of the public key
394
+ * @return {string} a string starting with "xpub..." in livenet
395
+ */
396
+ HDPublicKey.prototype.toString = function () {
397
+ return this.xpubkey
398
+ }
399
+
400
+ /**
401
+ * Returns the console representation of this extended public key.
402
+ * @return string
403
+ */
404
+ HDPublicKey.prototype.inspect = function () {
405
+ return '<HDPublicKey: ' + this.xpubkey + '>'
406
+ }
407
+
408
+ /**
409
+ * Returns a plain JavaScript object with information to reconstruct a key.
410
+ *
411
+ * Fields are: <ul>
412
+ * <li> network: 'livenet' or 'testnet'
413
+ * <li> depth: a number from 0 to 255, the depth to the master extended key
414
+ * <li> fingerPrint: a number of 32 bits taken from the hash of the public key
415
+ * <li> fingerPrint: a number of 32 bits taken from the hash of this key's
416
+ * <li> parent's public key
417
+ * <li> childIndex: index with which this key was derived
418
+ * <li> chainCode: string in hexa encoding used for derivation
419
+ * <li> publicKey: string, hexa encoded, in compressed key format
420
+ * <li> checksum: this._buffers.checksum.readUInt32BE(0),
421
+ * <li> xpubkey: the string with the base58 representation of this extended key
422
+ * <li> checksum: the base58 checksum of xpubkey
423
+ * </ul>
424
+ */
425
+ HDPublicKey.prototype.toObject = HDPublicKey.prototype.toJSON = function toObject () {
426
+ return {
427
+ network: Network.get(this._buffers.version.readUInt32BE(0)).name,
428
+ depth: this._buffers.depth[0],
429
+ fingerPrint: this.fingerPrint.readUInt32BE(0),
430
+ parentFingerPrint: this._buffers.parentFingerPrint.readUInt32BE(0),
431
+ childIndex: this._buffers.childIndex.readUInt32BE(0),
432
+ chainCode: this._buffers.chainCode.toString('hex'),
433
+ publicKey: this.publicKey.toString(),
434
+ checksum: this._buffers.checksum.readUInt32BE(0),
435
+ xpubkey: this.xpubkey
436
+ }
437
+ }
438
+
439
+ /**
440
+ * Create a HDPublicKey from a buffer argument
441
+ *
442
+ * @param {Buffer} arg
443
+ * @return {HDPublicKey}
444
+ */
445
+ HDPublicKey.fromBuffer = function (arg) {
446
+ return new HDPublicKey(arg)
447
+ }
448
+
449
+ /**
450
+ * Create a HDPublicKey from a hex string argument
451
+ *
452
+ * @param {Buffer} arg
453
+ * @return {HDPublicKey}
454
+ */
455
+ HDPublicKey.fromHex = function (hex) {
456
+ return HDPublicKey.fromBuffer(Buffer.from(hex, 'hex'))
457
+ }
458
+
459
+ /**
460
+ * Return a buffer representation of the xpubkey
461
+ *
462
+ * @return {Buffer}
463
+ */
464
+ HDPublicKey.prototype.toBuffer = function () {
465
+ return Buffer.from(this._buffers.xpubkey)
466
+ }
467
+
468
+ /**
469
+ * Return a hex string representation of the xpubkey
470
+ *
471
+ * @return {Buffer}
472
+ */
473
+ HDPublicKey.prototype.toHex = function () {
474
+ return this.toBuffer().toString('hex')
475
+ }
476
+
477
+ HDPublicKey.Hardened = 0x80000000
478
+ HDPublicKey.RootElementAlias = ['m', 'M']
479
+
480
+ HDPublicKey.VersionSize = 4
481
+ HDPublicKey.DepthSize = 1
482
+ HDPublicKey.ParentFingerPrintSize = 4
483
+ HDPublicKey.ChildIndexSize = 4
484
+ HDPublicKey.ChainCodeSize = 32
485
+ HDPublicKey.PublicKeySize = 33
486
+ HDPublicKey.CheckSumSize = 4
487
+
488
+ HDPublicKey.DataSize = 78
489
+ HDPublicKey.SerializedByteSize = 82
490
+
491
+ HDPublicKey.VersionStart = 0
492
+ HDPublicKey.VersionEnd = HDPublicKey.VersionStart + HDPublicKey.VersionSize
493
+ HDPublicKey.DepthStart = HDPublicKey.VersionEnd
494
+ HDPublicKey.DepthEnd = HDPublicKey.DepthStart + HDPublicKey.DepthSize
495
+ HDPublicKey.ParentFingerPrintStart = HDPublicKey.DepthEnd
496
+ HDPublicKey.ParentFingerPrintEnd = HDPublicKey.ParentFingerPrintStart + HDPublicKey.ParentFingerPrintSize
497
+ HDPublicKey.ChildIndexStart = HDPublicKey.ParentFingerPrintEnd
498
+ HDPublicKey.ChildIndexEnd = HDPublicKey.ChildIndexStart + HDPublicKey.ChildIndexSize
499
+ HDPublicKey.ChainCodeStart = HDPublicKey.ChildIndexEnd
500
+ HDPublicKey.ChainCodeEnd = HDPublicKey.ChainCodeStart + HDPublicKey.ChainCodeSize
501
+ HDPublicKey.PublicKeyStart = HDPublicKey.ChainCodeEnd
502
+ HDPublicKey.PublicKeyEnd = HDPublicKey.PublicKeyStart + HDPublicKey.PublicKeySize
503
+ HDPublicKey.ChecksumStart = HDPublicKey.PublicKeyEnd
504
+ HDPublicKey.ChecksumEnd = HDPublicKey.ChecksumStart + HDPublicKey.CheckSumSize
505
+
506
+ assert(HDPublicKey.PublicKeyEnd === HDPublicKey.DataSize)
507
+ assert(HDPublicKey.ChecksumEnd === HDPublicKey.SerializedByteSize)
508
+
509
+ module.exports = HDPublicKey
@@ -0,0 +1,4 @@
1
+ var bsv = require('../../')
2
+ bsv.Message = require('./message')
3
+
4
+ module.exports = bsv.Message
@@ -0,0 +1,181 @@
1
+ 'use strict'
2
+
3
+ var bsv = require('../../')
4
+ var _ = bsv.deps._
5
+ var PrivateKey = bsv.PrivateKey
6
+ var PublicKey = bsv.PublicKey
7
+ var Address = bsv.Address
8
+ var BufferWriter = bsv.encoding.BufferWriter
9
+ var ECDSA = bsv.crypto.ECDSA
10
+ var Signature = bsv.crypto.Signature
11
+ var sha256sha256 = bsv.crypto.Hash.sha256sha256
12
+ var JSUtil = bsv.util.js
13
+ var $ = bsv.util.preconditions
14
+
15
+ /**
16
+ * constructs a new message to sign and verify.
17
+ *
18
+ * @param {String} message
19
+ * @returns {Message}
20
+ */
21
+ var Message = function Message (message) {
22
+ if (!(this instanceof Message)) {
23
+ return new Message(message)
24
+ }
25
+
26
+ $.checkArgument(_.isString(message) || Buffer.isBuffer(message), 'First argument should be a string or Buffer')
27
+
28
+ if (_.isString(message)) {
29
+ this.messageBuffer = Buffer.from(message)
30
+ }
31
+
32
+ if (Buffer.isBuffer(message)) {
33
+ this.messageBuffer = message
34
+ }
35
+ return this
36
+ }
37
+
38
+ Message.sign = function (message, privateKey) {
39
+ return new Message(message).sign(privateKey)
40
+ }
41
+
42
+ Message.verify = function (message, address, signature) {
43
+ return new Message(message).verify(address, signature)
44
+ }
45
+
46
+ Message.MAGIC_BYTES = Buffer.from('Bitcoin Signed Message:\n')
47
+
48
+ Message.prototype.magicHash = function magicHash () {
49
+ var prefix1 = BufferWriter.varintBufNum(Message.MAGIC_BYTES.length)
50
+ var prefix2 = BufferWriter.varintBufNum(this.messageBuffer.length)
51
+ var buf = Buffer.concat([prefix1, Message.MAGIC_BYTES, prefix2, this.messageBuffer])
52
+ var hash = sha256sha256(buf)
53
+ return hash
54
+ }
55
+
56
+ Message.prototype._sign = function _sign (privateKey) {
57
+ $.checkArgument(privateKey instanceof PrivateKey,
58
+ 'First argument should be an instance of PrivateKey')
59
+ var hash = this.magicHash()
60
+ return ECDSA.signWithCalcI(hash, privateKey)
61
+ }
62
+
63
+ /**
64
+ * Will sign a message with a given bitcoin private key.
65
+ *
66
+ * @param {PrivateKey} privateKey - An instance of PrivateKey
67
+ * @returns {String} A base64 encoded compact signature
68
+ */
69
+ Message.prototype.sign = function sign (privateKey) {
70
+ var signature = this._sign(privateKey)
71
+ return signature.toCompact().toString('base64')
72
+ }
73
+
74
+ Message.prototype._verify = function _verify (publicKey, signature) {
75
+ $.checkArgument(publicKey instanceof PublicKey, 'First argument should be an instance of PublicKey')
76
+ $.checkArgument(signature instanceof Signature, 'Second argument should be an instance of Signature')
77
+ var hash = this.magicHash()
78
+ var verified = ECDSA.verify(hash, signature, publicKey)
79
+ if (!verified) {
80
+ this.error = 'The signature was invalid'
81
+ }
82
+ return verified
83
+ }
84
+
85
+ /**
86
+ * Will return a boolean of the signature is valid for a given bitcoin address.
87
+ * If it isn't the specific reason is accessible via the "error" member.
88
+ *
89
+ * @param {Address|String} bitcoinAddress - A bitcoin address
90
+ * @param {String} signatureString - A base64 encoded compact signature
91
+ * @returns {Boolean}
92
+ */
93
+ Message.prototype.verify = function verify (bitcoinAddress, signatureString) {
94
+ $.checkArgument(bitcoinAddress)
95
+ $.checkArgument(signatureString && _.isString(signatureString))
96
+
97
+ if (_.isString(bitcoinAddress)) {
98
+ bitcoinAddress = Address.fromString(bitcoinAddress)
99
+ }
100
+ var signature = Signature.fromCompact(Buffer.from(signatureString, 'base64'))
101
+
102
+ // recover the public key
103
+ var ecdsa = new ECDSA()
104
+ ecdsa.hashbuf = this.magicHash()
105
+ ecdsa.sig = signature
106
+ var publicKey = ecdsa.toPublicKey()
107
+
108
+ var signatureAddress = Address.fromPublicKey(publicKey, bitcoinAddress.network)
109
+
110
+ // check that the recovered address and specified address match
111
+ if (bitcoinAddress.toString() !== signatureAddress.toString()) {
112
+ this.error = 'The signature did not match the message digest'
113
+ return false
114
+ }
115
+
116
+ return this._verify(publicKey, signature)
117
+ }
118
+
119
+ /**
120
+ * Instantiate a message from a message string
121
+ *
122
+ * @param {String} str - A string of the message
123
+ * @returns {Message} A new instance of a Message
124
+ */
125
+ Message.fromString = function (str) {
126
+ return new Message(str)
127
+ }
128
+
129
+ /**
130
+ * Instantiate a message from JSON
131
+ *
132
+ * @param {String} json - An JSON string or Object with keys: message
133
+ * @returns {Message} A new instance of a Message
134
+ */
135
+ Message.fromJSON = function fromJSON (json) {
136
+ if (JSUtil.isValidJSON(json)) {
137
+ json = JSON.parse(json)
138
+ }
139
+ return Message.fromObject(json)
140
+ }
141
+
142
+ /**
143
+ * @returns {Object} A plain object with the message information
144
+ */
145
+ Message.prototype.toObject = function toObject () {
146
+ return {
147
+ messageHex: this.messageBuffer.toString('hex')
148
+ }
149
+ }
150
+
151
+ Message.fromObject = function (obj) {
152
+ let messageBuffer = Buffer.from(obj.messageHex, 'hex')
153
+ return new Message(messageBuffer)
154
+ }
155
+
156
+ /**
157
+ * @returns {String} A JSON representation of the message information
158
+ */
159
+ Message.prototype.toJSON = function toJSON () {
160
+ return JSON.stringify(this.toObject())
161
+ }
162
+
163
+ /**
164
+ * Will return a the string representation of the message
165
+ *
166
+ * @returns {String} Message
167
+ */
168
+ Message.prototype.toString = function () {
169
+ return this.messageBuffer.toString()
170
+ }
171
+
172
+ /**
173
+ * Will return a string formatted for the console
174
+ *
175
+ * @returns {String} Message
176
+ */
177
+ Message.prototype.inspect = function () {
178
+ return '<Message: ' + this.toString() + '>'
179
+ }
180
+
181
+ module.exports = Message
@@ -0,0 +1,18 @@
1
+ 'use strict'
2
+
3
+ var spec = {
4
+ name: 'Mnemonic',
5
+ message: 'Internal Error on bsv-mnemonic module {0}',
6
+ errors: [{
7
+ name: 'InvalidEntropy',
8
+ message: 'Entropy length must be an even multiple of 11 bits: {0}'
9
+ }, {
10
+ name: 'UnknownWordlist',
11
+ message: 'Could not detect the used word list: {0}'
12
+ }, {
13
+ name: 'InvalidMnemonic',
14
+ message: 'Mnemonic string is invalid: {0}'
15
+ }]
16
+ }
17
+
18
+ module.exports = require('../../').errors.extend(spec)