@opcat-labs/opcat 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cjs2esm.json +18 -0
- package/.mocharc.yaml +1 -1
- package/CHANGELOG.md +12 -0
- package/README.md +6 -0
- package/{lib/address.js → cjs/address.cjs} +77 -72
- package/cjs/block/block.cjs +332 -0
- package/{lib/block/blockheader.js → cjs/block/blockheader.cjs} +8 -7
- package/cjs/block/index.cjs +2 -0
- package/{lib/block/merkleblock.js → cjs/block/merkleblock.cjs} +23 -15
- package/cjs/bn.cjs +3411 -0
- package/{lib/crypto/bn.js → cjs/crypto/bn.cjs} +3 -3
- package/{lib/crypto/ecdsa.js → cjs/crypto/ecdsa.cjs} +150 -14
- package/{lib/crypto/hash.node.js → cjs/crypto/hash.cjs} +13 -2
- package/cjs/crypto/index.cjs +16 -0
- package/{lib/crypto/point.js → cjs/crypto/point.cjs} +11 -4
- package/cjs/crypto/random.cjs +18 -0
- package/{lib/crypto/signature.js → cjs/crypto/signature.cjs} +158 -8
- package/{lib/encoding/base58.js → cjs/encoding/base58.cjs} +58 -2
- package/cjs/encoding/base58check.cjs +192 -0
- package/cjs/encoding/bufferreader.cjs +333 -0
- package/cjs/encoding/bufferwriter.cjs +244 -0
- package/{lib/encoding/decode-asm.js → cjs/encoding/decode-asm.cjs} +4 -4
- package/{lib/encoding/decode-hex.js → cjs/encoding/decode-hex.cjs} +1 -1
- package/cjs/encoding/index.cjs +14 -0
- package/cjs/encoding/varint.cjs +116 -0
- package/{lib/errors/index.js → cjs/errors/index.cjs} +9 -9
- package/{lib/errors/spec.js → cjs/errors/spec.cjs} +2 -2
- package/cjs/hash-cache.cjs +98 -0
- package/{lib/hdprivatekey.js → cjs/hdprivatekey.cjs} +232 -140
- package/{lib/hdpublickey.js → cjs/hdpublickey.cjs} +120 -93
- package/cjs/index.cjs +94 -0
- package/cjs/interpreter/index.cjs +2 -0
- package/cjs/interpreter/interpreter.cjs +1988 -0
- package/{lib/script/stack.js → cjs/interpreter/stack.cjs} +9 -2
- package/{lib/message/message.js → cjs/message/message.cjs} +62 -25
- package/cjs/mnemonic/index.cjs +3 -0
- package/{lib/mnemonic/mnemonic.js → cjs/mnemonic/mnemonic.cjs} +44 -13
- package/{lib/mnemonic/pbkdf2.node.js → cjs/mnemonic/pbkdf2.cjs} +9 -2
- package/cjs/mnemonic/words/index.cjs +66 -0
- package/cjs/network.cjs +13 -0
- package/cjs/networks.cjs +321 -0
- package/{lib/opcode.js → cjs/opcode.cjs} +69 -5
- package/cjs/privatekey.cjs +422 -0
- package/{lib/publickey.js → cjs/publickey.cjs} +14 -16
- package/cjs/script/index.cjs +2 -0
- package/{lib/script/script.js → cjs/script/script.cjs} +322 -67
- package/cjs/transaction/index.cjs +5 -0
- package/cjs/transaction/input/index.cjs +34 -0
- package/cjs/transaction/input/input.cjs +396 -0
- package/{lib/transaction/input/multisig.js → cjs/transaction/input/multisig.cjs} +112 -18
- package/{lib/transaction/input/publickey.js → cjs/transaction/input/publickey.cjs} +29 -19
- package/{lib/transaction/input/publickeyhash.js → cjs/transaction/input/publickeyhash.cjs} +25 -17
- package/{lib/transaction/output.js → cjs/transaction/output.cjs} +100 -15
- package/cjs/transaction/sighash.cjs +187 -0
- package/{lib/transaction/signature.js → cjs/transaction/signature.cjs} +30 -6
- package/cjs/transaction/transaction.cjs +2000 -0
- package/{lib/transaction/unspentoutput.js → cjs/transaction/unspentoutput.cjs} +5 -5
- package/cjs/util/derivation.cjs +53 -0
- package/cjs/util/index.cjs +11 -0
- package/cjs/util/js.cjs +95 -0
- package/{lib/util/preconditions.js → cjs/util/preconditions.cjs} +2 -2
- package/esm/address.js +483 -0
- package/{lib → esm}/block/block.js +82 -27
- package/esm/block/blockheader.js +296 -0
- package/esm/block/index.js +2 -0
- package/esm/block/merkleblock.js +331 -0
- package/esm/bn.js +3411 -0
- package/esm/crypto/bn.js +278 -0
- package/esm/crypto/ecdsa.js +475 -0
- package/{lib/crypto/hash.browser.js → esm/crypto/hash.js} +18 -7
- package/esm/crypto/index.js +16 -0
- package/esm/crypto/point.js +228 -0
- package/esm/crypto/random.js +18 -0
- package/esm/crypto/signature.js +475 -0
- package/esm/encoding/base58.js +167 -0
- package/esm/encoding/base58check.js +192 -0
- package/esm/encoding/bufferreader.js +333 -0
- package/esm/encoding/bufferwriter.js +243 -0
- package/esm/encoding/decode-asm.js +24 -0
- package/esm/encoding/decode-hex.js +32 -0
- package/esm/encoding/decode-script-chunks.js +43 -0
- package/esm/encoding/encode-hex.js +284 -0
- package/esm/encoding/index.js +14 -0
- package/esm/encoding/is-hex.js +7 -0
- package/esm/encoding/varint.js +116 -0
- package/esm/errors/index.js +54 -0
- package/esm/errors/spec.js +314 -0
- package/esm/hash-cache.js +98 -0
- package/esm/hdprivatekey.js +768 -0
- package/esm/hdpublickey.js +549 -0
- package/esm/index.js +66 -0
- package/esm/interpreter/index.js +2 -0
- package/{lib/script → esm/interpreter}/interpreter.js +219 -66
- package/esm/interpreter/stack.js +116 -0
- package/esm/message/message.js +228 -0
- package/esm/mnemonic/index.js +3 -0
- package/esm/mnemonic/mnemonic.js +332 -0
- package/{lib/mnemonic/pbkdf2.browser.js → esm/mnemonic/pbkdf2.js} +13 -6
- package/esm/mnemonic/words/chinese.js +2054 -0
- package/esm/mnemonic/words/english.js +2054 -0
- package/esm/mnemonic/words/french.js +2054 -0
- package/esm/mnemonic/words/index.js +66 -0
- package/esm/mnemonic/words/italian.js +2054 -0
- package/esm/mnemonic/words/japanese.js +2054 -0
- package/esm/mnemonic/words/spanish.js +2054 -0
- package/esm/network.js +13 -0
- package/{lib → esm}/networks.js +61 -120
- package/esm/opcode.js +319 -0
- package/{lib → esm}/privatekey.js +76 -28
- package/esm/publickey.js +384 -0
- package/esm/script/index.js +2 -0
- package/esm/script/script.js +1329 -0
- package/esm/script/write-i32-le.js +17 -0
- package/esm/script/write-push-data.js +35 -0
- package/esm/script/write-u16-le.js +12 -0
- package/esm/script/write-u32-le.js +16 -0
- package/esm/script/write-u64-le.js +24 -0
- package/esm/script/write-u8-le.js +8 -0
- package/esm/script/write-varint.js +46 -0
- package/esm/transaction/index.js +5 -0
- package/esm/transaction/input/index.js +33 -0
- package/{lib → esm}/transaction/input/input.js +132 -90
- package/esm/transaction/input/multisig.js +335 -0
- package/esm/transaction/input/publickey.js +108 -0
- package/esm/transaction/input/publickeyhash.js +124 -0
- package/esm/transaction/output.js +316 -0
- package/{lib → esm}/transaction/sighash.js +42 -22
- package/esm/transaction/signature.js +120 -0
- package/{lib → esm}/transaction/transaction.js +522 -163
- package/esm/transaction/unspentoutput.js +112 -0
- package/esm/util/_.js +47 -0
- package/esm/util/derivation.js +53 -0
- package/esm/util/index.js +12 -0
- package/esm/util/js.js +95 -0
- package/esm/util/preconditions.js +33 -0
- package/fixup.cjs +17 -0
- package/package.json +18 -4
- package/test/{address.js → address.cjs} +14 -43
- package/test/block/{block.js → block.cjs} +3 -5
- package/test/block/{blockheader.js → blockheader.cjs} +2 -2
- package/test/block/{merklebloack.js → merklebloack.cjs} +2 -2
- package/test/crypto/{ecdsa.js → ecdsa.cjs} +9 -9
- package/test/crypto/{hash.browser.js → hash.browser.cjs} +2 -1
- package/test/crypto/{signature.js → signature.cjs} +2 -2
- package/test/data/bitcoind/script_tests.json +5 -5
- package/test/{hashCache.js → hashCache.cjs} +2 -1
- package/test/{hdkeys.js → hdkeys.cjs} +4 -2
- package/test/{hdprivatekey.js → hdprivatekey.cjs} +7 -6
- package/test/{hdpublickey.js → hdpublickey.cjs} +2 -7
- package/test/mnemonic/{pbkdf2.test.js → pbkdf2.test.cjs} +2 -2
- package/test/{networks.js → networks.cjs} +12 -31
- package/test/{publickey.js → publickey.cjs} +2 -2
- package/test/script/{interpreter.js → interpreter.cjs} +5 -5
- package/test/script/{script.js → script.cjs} +8 -2
- package/test/transaction/{deserialize.js → deserialize.cjs} +2 -2
- package/test/transaction/input/{input.js → input.cjs} +1 -1
- package/test/transaction/input/{multisig.js → multisig.cjs} +2 -1
- package/test/transaction/input/{publickeyhash.js → publickeyhash.cjs} +1 -1
- package/test/transaction/{sighash.js → sighash.cjs} +1 -1
- package/test/transaction/{transaction.js → transaction.cjs} +2 -2
- package/tsconfig.json +13 -0
- package/types/address.d.cts +252 -0
- package/types/block/block.d.cts +139 -0
- package/types/block/blockheader.d.cts +125 -0
- package/types/block/index.d.cts +2 -0
- package/types/block/merkleblock.d.cts +95 -0
- package/types/bn.d.cts +202 -0
- package/types/crypto/bn.d.cts +2 -0
- package/types/crypto/ecdsa.d.cts +187 -0
- package/types/crypto/hash.d.cts +118 -0
- package/types/crypto/index.d.cts +7 -0
- package/types/crypto/point.d.cts +134 -0
- package/types/crypto/random.d.cts +13 -0
- package/types/crypto/signature.d.cts +160 -0
- package/types/encoding/base58.d.cts +106 -0
- package/types/encoding/base58check.d.cts +107 -0
- package/types/encoding/bufferreader.d.cts +164 -0
- package/types/encoding/bufferwriter.d.cts +126 -0
- package/types/encoding/decode-asm.d.cts +2 -0
- package/types/encoding/decode-hex.d.cts +2 -0
- package/types/encoding/decode-script-chunks.d.cts +14 -0
- package/types/encoding/encode-hex.d.cts +2 -0
- package/types/encoding/index.d.cts +6 -0
- package/types/encoding/is-hex.d.cts +2 -0
- package/types/encoding/varint.d.cts +66 -0
- package/types/errors/index.d.cts +4 -0
- package/types/errors/spec.d.cts +22 -0
- package/types/hash-cache.d.cts +65 -0
- package/types/hdprivatekey.d.cts +281 -0
- package/types/hdpublickey.d.cts +240 -0
- package/types/index.d.cts +26 -0
- package/types/interpreter/index.d.cts +2 -0
- package/types/interpreter/interpreter.d.cts +228 -0
- package/types/interpreter/stack.d.cts +35 -0
- package/types/message/message.d.cts +110 -0
- package/types/mnemonic/index.d.cts +2 -0
- package/types/mnemonic/mnemonic.d.cts +171 -0
- package/types/mnemonic/pbkdf2.d.cts +14 -0
- package/types/mnemonic/words/chinese.d.cts +2 -0
- package/types/mnemonic/words/english.d.cts +2 -0
- package/types/mnemonic/words/french.d.cts +2 -0
- package/types/mnemonic/words/index.d.cts +22 -0
- package/types/mnemonic/words/italian.d.cts +2 -0
- package/types/mnemonic/words/japanese.d.cts +2 -0
- package/types/mnemonic/words/spanish.d.cts +2 -0
- package/types/network.d.cts +11 -0
- package/types/networks.d.cts +76 -0
- package/types/opcode.d.cts +93 -0
- package/types/privatekey.d.cts +169 -0
- package/types/publickey.d.cts +202 -0
- package/types/script/index.d.cts +2 -0
- package/types/script/script.d.cts +449 -0
- package/types/script/write-i32-le.d.cts +2 -0
- package/types/script/write-push-data.d.cts +2 -0
- package/types/script/write-u16-le.d.cts +2 -0
- package/types/script/write-u32-le.d.cts +2 -0
- package/types/script/write-u64-le.d.cts +2 -0
- package/types/script/write-u8-le.d.cts +2 -0
- package/types/script/write-varint.d.cts +2 -0
- package/types/transaction/index.d.cts +2 -0
- package/types/transaction/input/index.d.cts +2 -0
- package/types/transaction/input/input.d.cts +178 -0
- package/types/transaction/input/multisig.d.cts +127 -0
- package/types/transaction/input/publickey.d.cts +44 -0
- package/types/transaction/input/publickeyhash.d.cts +45 -0
- package/types/transaction/output.d.cts +118 -0
- package/types/transaction/sighash.d.cts +61 -0
- package/types/transaction/signature.d.cts +43 -0
- package/types/transaction/transaction.d.cts +716 -0
- package/types/transaction/unspentoutput.d.cts +83 -0
- package/types/util/_.d.cts +26 -0
- package/types/util/derivation.d.cts +21 -0
- package/types/util/index.d.cts +5 -0
- package/types/util/js.d.cts +50 -0
- package/types/util/preconditions.d.cts +3 -0
- package/index.d.ts +0 -1541
- package/index.js +0 -74
- package/lib/block/index.js +0 -4
- package/lib/bn.js +0 -3423
- package/lib/crypto/hash.js +0 -2
- package/lib/crypto/random.browser.js +0 -28
- package/lib/crypto/random.js +0 -2
- package/lib/crypto/random.node.js +0 -11
- package/lib/encoding/base58check.js +0 -121
- package/lib/encoding/bufferreader.js +0 -212
- package/lib/encoding/bufferwriter.js +0 -140
- package/lib/encoding/varint.js +0 -75
- package/lib/hash-cache.js +0 -50
- package/lib/mnemonic/pbkdf2.js +0 -2
- package/lib/mnemonic/words/index.js +0 -8
- package/lib/script/index.js +0 -5
- package/lib/transaction/index.js +0 -7
- package/lib/transaction/input/index.js +0 -5
- package/lib/util/js.js +0 -90
- /package/{lib/encoding/decode-script-chunks.js → cjs/encoding/decode-script-chunks.cjs} +0 -0
- /package/{lib/encoding/encode-hex.js → cjs/encoding/encode-hex.cjs} +0 -0
- /package/{lib/encoding/is-hex.js → cjs/encoding/is-hex.cjs} +0 -0
- /package/{lib/mnemonic/words/chinese.js → cjs/mnemonic/words/chinese.cjs} +0 -0
- /package/{lib/mnemonic/words/english.js → cjs/mnemonic/words/english.cjs} +0 -0
- /package/{lib/mnemonic/words/french.js → cjs/mnemonic/words/french.cjs} +0 -0
- /package/{lib/mnemonic/words/italian.js → cjs/mnemonic/words/italian.cjs} +0 -0
- /package/{lib/mnemonic/words/japanese.js → cjs/mnemonic/words/japanese.cjs} +0 -0
- /package/{lib/mnemonic/words/spanish.js → cjs/mnemonic/words/spanish.cjs} +0 -0
- /package/{lib/script/write-i32-le.js → cjs/script/write-i32-le.cjs} +0 -0
- /package/{lib/script/write-push-data.js → cjs/script/write-push-data.cjs} +0 -0
- /package/{lib/script/write-u16-le.js → cjs/script/write-u16-le.cjs} +0 -0
- /package/{lib/script/write-u32-le.js → cjs/script/write-u32-le.cjs} +0 -0
- /package/{lib/script/write-u64-le.js → cjs/script/write-u64-le.cjs} +0 -0
- /package/{lib/script/write-u8-le.js → cjs/script/write-u8-le.cjs} +0 -0
- /package/{lib/script/write-varint.js → cjs/script/write-varint.cjs} +0 -0
- /package/{lib/util/_.js → cjs/util/_.cjs} +0 -0
- /package/test/crypto/{bn.js → bn.cjs} +0 -0
- /package/test/crypto/{hash.js → hash.cjs} +0 -0
- /package/test/crypto/{point.js → point.cjs} +0 -0
- /package/test/crypto/{random.js → random.cjs} +0 -0
- /package/test/data/{blk86756-testnet.js → blk86756-testnet.cjs} +0 -0
- /package/test/data/{merkleblocks.js → merkleblocks.cjs} +0 -0
- /package/test/encoding/{base58.js → base58.cjs} +0 -0
- /package/test/encoding/{base58check.js → base58check.cjs} +0 -0
- /package/test/encoding/{bufferreader.js → bufferreader.cjs} +0 -0
- /package/test/encoding/{bufferwriter.js → bufferwriter.cjs} +0 -0
- /package/test/encoding/{varint.js → varint.cjs} +0 -0
- /package/test/{index.js → index.cjs} +0 -0
- /package/test/message/{message.js → message.cjs} +0 -0
- /package/test/mnemonic/{mnemonic.js → mnemonic.cjs} +0 -0
- /package/test/{opcode.js → opcode.cjs} +0 -0
- /package/test/{privatekey.js → privatekey.cjs} +0 -0
- /package/test/transaction/input/{publickey.js → publickey.cjs} +0 -0
- /package/test/transaction/{output.js → output.cjs} +0 -0
- /package/test/transaction/{signature.js → signature.cjs} +0 -0
- /package/test/transaction/{unspentoutput.js → unspentoutput.cjs} +0 -0
- /package/test/util/{js.js → js.cjs} +0 -0
- /package/test/util/{preconditions.js → preconditions.cjs} +0 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import BN from './bn.js';
|
|
4
|
+
import elliptic from '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
|
+
function Point(x, y, isRed) {
|
|
24
|
+
try {
|
|
25
|
+
var point = ecPoint(x, y, isRed);
|
|
26
|
+
} catch (_) {
|
|
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
|
+
* @static
|
|
45
|
+
*/
|
|
46
|
+
Point.fromX = function fromX(odd, x) {
|
|
47
|
+
try {
|
|
48
|
+
var point = ecPointFromX(x, odd);
|
|
49
|
+
} catch (e) {
|
|
50
|
+
throw new Error('Invalid X');
|
|
51
|
+
}
|
|
52
|
+
point.validate();
|
|
53
|
+
return point;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* Will return a secp256k1 ECDSA base point.
|
|
59
|
+
*
|
|
60
|
+
* @link https://en.bitcoin.it/wiki/Secp256k1
|
|
61
|
+
* @returns {Point} An instance of the base point.
|
|
62
|
+
* @static
|
|
63
|
+
*/
|
|
64
|
+
Point.getG = function getG() {
|
|
65
|
+
return ec.curve.g;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
*
|
|
70
|
+
* Will return the max of range of valid private keys as governed by the
|
|
71
|
+
* secp256k1 ECDSA standard.
|
|
72
|
+
*
|
|
73
|
+
* @link https://en.bitcoin.it/wiki/Private_key#Range_of_valid_ECDSA_private_keys
|
|
74
|
+
* @returns {BN} A BN instance of the number of points on the curve
|
|
75
|
+
* @static
|
|
76
|
+
*/
|
|
77
|
+
Point.getN = function getN() {
|
|
78
|
+
return new BN(ec.curve.n.toArray());
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
if (!Point.prototype._getX) {
|
|
82
|
+
Point.prototype._getX = Point.prototype.getX;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Will return the X coordinate of the Point.
|
|
87
|
+
*
|
|
88
|
+
* @returns {BN} A BN instance of the X coordinate
|
|
89
|
+
*/
|
|
90
|
+
Point.prototype.getX = function getX() {
|
|
91
|
+
return new BN(this._getX().toArray());
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
if (!Point.prototype._getY) {
|
|
95
|
+
Point.prototype._getY = Point.prototype.getY;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Will return the Y coordinate of the Point.
|
|
100
|
+
*
|
|
101
|
+
* @returns {BN} A BN instance of the Y coordinate
|
|
102
|
+
*/
|
|
103
|
+
Point.prototype.getY = function getY() {
|
|
104
|
+
return new BN(this._getY().toArray());
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Will determine if the point is valid.
|
|
109
|
+
*
|
|
110
|
+
* @link https://www.iacr.org/archive/pkc2003/25670211/25670211.pdf
|
|
111
|
+
* @throws {Error} A validation error if exists
|
|
112
|
+
* @returns {Point} An instance of the same Point
|
|
113
|
+
*/
|
|
114
|
+
Point.prototype.validate = function validate() {
|
|
115
|
+
if (this.isInfinity()) {
|
|
116
|
+
throw new Error('Point cannot be equal to Infinity');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
var p2;
|
|
120
|
+
try {
|
|
121
|
+
p2 = ecPointFromX(this.getX(), this.getY().isOdd());
|
|
122
|
+
} catch (_) {
|
|
123
|
+
throw new Error('Point does not lie on the curve');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (p2.y.cmp(this.y) !== 0) {
|
|
127
|
+
throw new Error('Invalid y value for curve.');
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// todo: needs test case
|
|
131
|
+
if (!this.mul(Point.getN()).isInfinity()) {
|
|
132
|
+
throw new Error('Point times N must be infinity');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return this;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* A "compressed" format point is the X part of the (X, Y) point plus an extra
|
|
140
|
+
* bit (which takes an entire byte) to indicate whether the Y value is odd or
|
|
141
|
+
* not. Storing points this way takes a bit less space, but requires a bit more
|
|
142
|
+
* computation to rederive the full point.
|
|
143
|
+
*
|
|
144
|
+
* @param {Point} point An instance of Point.
|
|
145
|
+
* @returns {Buffer} A compressed point in the form of a buffer.
|
|
146
|
+
* @static
|
|
147
|
+
*/
|
|
148
|
+
Point.pointToCompressed = function pointToCompressed(point) {
|
|
149
|
+
var xbuf = point.getX().toBuffer({ size: 32 });
|
|
150
|
+
var ybuf = point.getY().toBuffer({ size: 32 });
|
|
151
|
+
|
|
152
|
+
var prefix;
|
|
153
|
+
var odd = ybuf[ybuf.length - 1] % 2;
|
|
154
|
+
if (odd) {
|
|
155
|
+
prefix = Buffer.from([0x03]);
|
|
156
|
+
} else {
|
|
157
|
+
prefix = Buffer.from([0x02]);
|
|
158
|
+
}
|
|
159
|
+
return Buffer.concat([prefix, xbuf]);
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Converts a compressed buffer into a point.
|
|
164
|
+
*
|
|
165
|
+
* @param {Buffer} buf A compressed point.
|
|
166
|
+
* @returns {Point} A Point.
|
|
167
|
+
* @static
|
|
168
|
+
*/
|
|
169
|
+
Point.pointFromCompressed = function (buf) {
|
|
170
|
+
if (buf.length !== 33) {
|
|
171
|
+
throw new Error('invalid buffer length');
|
|
172
|
+
}
|
|
173
|
+
let prefix = buf[0];
|
|
174
|
+
let odd;
|
|
175
|
+
if (prefix === 0x03) {
|
|
176
|
+
odd = true;
|
|
177
|
+
} else if (prefix === 0x02) {
|
|
178
|
+
odd = false;
|
|
179
|
+
} else {
|
|
180
|
+
throw new Error('invalid value of compressed prefix');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
let xbuf = buf.slice(1, 33);
|
|
184
|
+
let x = BN.fromBuffer(xbuf);
|
|
185
|
+
return Point.fromX(odd, x);
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Convert point to a compressed buffer.
|
|
190
|
+
*
|
|
191
|
+
* @returns {Buffer} A compressed point.
|
|
192
|
+
*/
|
|
193
|
+
Point.prototype.toBuffer = function () {
|
|
194
|
+
return Point.pointToCompressed(this);
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Convert point to a compressed hex string.
|
|
199
|
+
*
|
|
200
|
+
* @returns {string} A compressed point as a hex string.
|
|
201
|
+
*/
|
|
202
|
+
Point.prototype.toHex = function () {
|
|
203
|
+
return this.toBuffer().toString('hex');
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Converts a compressed buffer into a point.
|
|
208
|
+
*
|
|
209
|
+
* @param {Buffer} buf A compressed point.
|
|
210
|
+
* @returns {Point} A Point.
|
|
211
|
+
* @static
|
|
212
|
+
*/
|
|
213
|
+
Point.fromBuffer = function (buf) {
|
|
214
|
+
return Point.pointFromCompressed(buf);
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Converts a compressed buffer into a point.
|
|
219
|
+
*
|
|
220
|
+
* @param {Buffer} hex A compressed point as a hex string.
|
|
221
|
+
* @returns {Point} A Point.
|
|
222
|
+
* @static
|
|
223
|
+
*/
|
|
224
|
+
Point.fromHex = function (hex) {
|
|
225
|
+
return Point.fromBuffer(Buffer.from(hex, 'hex'));
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
export default Point;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import crypto from 'crypto';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A utility class for generating random values.
|
|
6
|
+
*/
|
|
7
|
+
function Random() { }
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Generates a cryptographically secure random buffer of the specified size.
|
|
11
|
+
* @param {number} size - The number of bytes to generate.
|
|
12
|
+
* @returns {Buffer} A buffer filled with cryptographically secure random bytes.
|
|
13
|
+
*/
|
|
14
|
+
Random.getRandomBuffer = function (size) {
|
|
15
|
+
return crypto.randomBytes(size);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default Random;
|
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import BN from './bn.js';
|
|
4
|
+
import _ from '../util/_.js';
|
|
5
|
+
import $ from '../util/preconditions.js';
|
|
6
|
+
import JSUtil from '../util/js.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new Signature instance from BN values or an object.
|
|
10
|
+
* @constructor
|
|
11
|
+
* @param {BN|Object} r - Either a BN instance for the r value or an object containing r and s properties.
|
|
12
|
+
* @param {BN} [s] - The s value (required if r is a BN instance).
|
|
13
|
+
*/
|
|
14
|
+
function Signature(r, s) {
|
|
15
|
+
if (!(this instanceof Signature)) {
|
|
16
|
+
return new Signature(r, s);
|
|
17
|
+
}
|
|
18
|
+
if (r instanceof BN) {
|
|
19
|
+
this.set({
|
|
20
|
+
r: r,
|
|
21
|
+
s: s,
|
|
22
|
+
});
|
|
23
|
+
} else if (r) {
|
|
24
|
+
var obj = r;
|
|
25
|
+
this.set(obj);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Sets signature properties from an object.
|
|
31
|
+
* @param {Object} obj - Object containing signature properties
|
|
32
|
+
* @param {Buffer} [obj.r] - r value
|
|
33
|
+
* @param {Buffer} [obj.s] - s value
|
|
34
|
+
* @param {number} [obj.i] - Public key recovery parameter (0-3)
|
|
35
|
+
* @param {boolean} [obj.compressed] - Whether recovered pubkey is compressed
|
|
36
|
+
* @param {number} [obj.nhashtype] - Hash type
|
|
37
|
+
* @returns {Signature} Returns the signature instance for chaining
|
|
38
|
+
*/
|
|
39
|
+
Signature.prototype.set = function (obj) {
|
|
40
|
+
this.r = obj.r || this.r || undefined;
|
|
41
|
+
this.s = obj.s || this.s || undefined;
|
|
42
|
+
|
|
43
|
+
this.i = typeof obj.i !== 'undefined' ? obj.i : this.i; // public key recovery parameter in range [0, 3]
|
|
44
|
+
this.compressed = typeof obj.compressed !== 'undefined' ? obj.compressed : this.compressed; // whether the recovered pubkey is compressed
|
|
45
|
+
this.nhashtype = obj.nhashtype || this.nhashtype || undefined;
|
|
46
|
+
return this;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Creates a Signature instance from a compact ECDSA signature buffer.
|
|
51
|
+
* @param {Buffer} buf - The compact signature buffer (65 bytes).
|
|
52
|
+
* @returns {Signature} The parsed signature object.
|
|
53
|
+
* @throws {Error} If the input is invalid (not a Buffer, wrong length, or invalid recovery param).
|
|
54
|
+
* @static
|
|
55
|
+
*/
|
|
56
|
+
Signature.fromCompact = function (buf) {
|
|
57
|
+
$.checkArgument(Buffer.isBuffer(buf), 'Argument is expected to be a Buffer');
|
|
58
|
+
|
|
59
|
+
var sig = new Signature();
|
|
60
|
+
|
|
61
|
+
var compressed = true;
|
|
62
|
+
var i = buf.slice(0, 1)[0] - 27 - 4;
|
|
63
|
+
if (i < 0) {
|
|
64
|
+
compressed = false;
|
|
65
|
+
i = i + 4;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
var b2 = buf.slice(1, 33);
|
|
69
|
+
var b3 = buf.slice(33, 65);
|
|
70
|
+
|
|
71
|
+
$.checkArgument(i === 0 || i === 1 || i === 2 || i === 3, new Error('i must be 0, 1, 2, or 3'));
|
|
72
|
+
$.checkArgument(b2.length === 32, new Error('r must be 32 bytes'));
|
|
73
|
+
$.checkArgument(b3.length === 32, new Error('s must be 32 bytes'));
|
|
74
|
+
|
|
75
|
+
sig.compressed = compressed;
|
|
76
|
+
sig.i = i;
|
|
77
|
+
sig.r = BN.fromBuffer(b2);
|
|
78
|
+
sig.s = BN.fromBuffer(b3);
|
|
79
|
+
|
|
80
|
+
return sig;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Creates a Signature instance from a DER-encoded or raw buffer.
|
|
85
|
+
* @param {Buffer} buf - The input buffer containing DER-encoded or raw signature data
|
|
86
|
+
* @param {boolean} [strict] - Whether to enforce strict DER parsing rules
|
|
87
|
+
* @returns {Signature} A new Signature instance with parsed r and s values
|
|
88
|
+
* @static
|
|
89
|
+
*/
|
|
90
|
+
Signature.fromDER = Signature.fromBuffer = function (buf, strict) {
|
|
91
|
+
var obj = Signature.parseDER(buf, strict);
|
|
92
|
+
var sig = new Signature();
|
|
93
|
+
|
|
94
|
+
sig.r = obj.r;
|
|
95
|
+
sig.s = obj.s;
|
|
96
|
+
|
|
97
|
+
return sig;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// The format used in a tx
|
|
101
|
+
/**
|
|
102
|
+
* Converts a transaction-format signature buffer to a Signature object.
|
|
103
|
+
* @param {Buffer} buf - The signature buffer in transaction format (DER + hash type byte)
|
|
104
|
+
* @returns {Signature} The parsed Signature object with nhashtype property set
|
|
105
|
+
* @static
|
|
106
|
+
*/
|
|
107
|
+
Signature.fromTxFormat = function (buf) {
|
|
108
|
+
var nhashtype = buf.readUInt8(buf.length - 1);
|
|
109
|
+
var derbuf = buf.slice(0, buf.length - 1);
|
|
110
|
+
var sig = Signature.fromDER(derbuf, false);
|
|
111
|
+
sig.nhashtype = nhashtype;
|
|
112
|
+
return sig;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Creates a Signature instance from a hex-encoded string.
|
|
117
|
+
* @param {string} str - Hex-encoded signature string
|
|
118
|
+
* @returns {Signature} Signature instance parsed from DER format
|
|
119
|
+
* @static
|
|
120
|
+
*/
|
|
121
|
+
Signature.fromString = function (str) {
|
|
122
|
+
var buf = Buffer.from(str, 'hex');
|
|
123
|
+
return Signature.fromDER(buf);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Parses a DER formatted signature buffer into its components.
|
|
129
|
+
* In order to mimic the non-strict DER encoding of OpenSSL, set strict = false.
|
|
130
|
+
* @param {Buffer} buf - The DER formatted signature buffer to parse
|
|
131
|
+
* @param {boolean} [strict=true] - Whether to perform strict length validation
|
|
132
|
+
* @returns {Object} An object containing the parsed signature components:
|
|
133
|
+
* - header: The DER header byte (0x30)
|
|
134
|
+
* - length: The total length of the signature components
|
|
135
|
+
* - rheader: The R component header byte (0x02)
|
|
136
|
+
* - rlength: The length of the R component
|
|
137
|
+
* - rneg: Whether R is negative
|
|
138
|
+
* - rbuf: The R component buffer
|
|
139
|
+
* - r: The R component as a BN
|
|
140
|
+
* - sheader: The S component header byte (0x02)
|
|
141
|
+
* - slength: The length of the S component
|
|
142
|
+
* - sneg: Whether S is negative
|
|
143
|
+
* - sbuf: The S component buffer
|
|
144
|
+
* - s: The S component as a BN
|
|
145
|
+
* @throws {Error} If the buffer is not valid DER format or length checks fail
|
|
146
|
+
* @static
|
|
147
|
+
*/
|
|
148
|
+
Signature.parseDER = function (buf, strict) {
|
|
149
|
+
$.checkArgument(Buffer.isBuffer(buf), new Error('DER formatted signature should be a buffer'));
|
|
150
|
+
if (_.isUndefined(strict)) {
|
|
151
|
+
strict = true;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
var header = buf[0];
|
|
155
|
+
$.checkArgument(header === 0x30, new Error('Header byte should be 0x30'));
|
|
156
|
+
|
|
157
|
+
var length = buf[1];
|
|
158
|
+
var buflength = buf.slice(2).length;
|
|
159
|
+
$.checkArgument(
|
|
160
|
+
!strict || length === buflength,
|
|
161
|
+
new Error('Length byte should length of what follows'),
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
length = length < buflength ? length : buflength;
|
|
165
|
+
|
|
166
|
+
var rheader = buf[2 + 0];
|
|
167
|
+
$.checkArgument(rheader === 0x02, new Error('Integer byte for r should be 0x02'));
|
|
168
|
+
|
|
169
|
+
var rlength = buf[2 + 1];
|
|
170
|
+
var rbuf = buf.slice(2 + 2, 2 + 2 + rlength);
|
|
171
|
+
var r = BN.fromBuffer(rbuf);
|
|
172
|
+
var rneg = buf[2 + 1 + 1] === 0x00;
|
|
173
|
+
$.checkArgument(rlength === rbuf.length, new Error('Length of r incorrect'));
|
|
174
|
+
|
|
175
|
+
var sheader = buf[2 + 2 + rlength + 0];
|
|
176
|
+
$.checkArgument(sheader === 0x02, new Error('Integer byte for s should be 0x02'));
|
|
177
|
+
|
|
178
|
+
var slength = buf[2 + 2 + rlength + 1];
|
|
179
|
+
var sbuf = buf.slice(2 + 2 + rlength + 2, 2 + 2 + rlength + 2 + slength);
|
|
180
|
+
var s = BN.fromBuffer(sbuf);
|
|
181
|
+
var sneg = buf[2 + 2 + rlength + 2 + 2] === 0x00;
|
|
182
|
+
$.checkArgument(slength === sbuf.length, new Error('Length of s incorrect'));
|
|
183
|
+
|
|
184
|
+
var sumlength = 2 + 2 + rlength + 2 + slength;
|
|
185
|
+
$.checkArgument(length === sumlength - 2, new Error('Length of signature incorrect'));
|
|
186
|
+
|
|
187
|
+
var obj = {
|
|
188
|
+
header: header,
|
|
189
|
+
length: length,
|
|
190
|
+
rheader: rheader,
|
|
191
|
+
rlength: rlength,
|
|
192
|
+
rneg: rneg,
|
|
193
|
+
rbuf: rbuf,
|
|
194
|
+
r: r,
|
|
195
|
+
sheader: sheader,
|
|
196
|
+
slength: slength,
|
|
197
|
+
sneg: sneg,
|
|
198
|
+
sbuf: sbuf,
|
|
199
|
+
s: s,
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
return obj;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Converts the signature to a compact format.
|
|
207
|
+
* @param {number} [i] - The recovery ID (0, 1, 2, or 3). Defaults to the instance's `i` value.
|
|
208
|
+
* @param {boolean} [compressed] - Whether the signature is compressed. Defaults to the instance's `compressed` value.
|
|
209
|
+
* @returns {Buffer} - The compact signature as a Buffer (1 byte recovery ID + 32 bytes r + 32 bytes s).
|
|
210
|
+
* @throws {Error} - If `i` is not 0, 1, 2, or 3.
|
|
211
|
+
*/
|
|
212
|
+
Signature.prototype.toCompact = function (i, compressed) {
|
|
213
|
+
i = typeof i === 'number' ? i : this.i;
|
|
214
|
+
compressed = typeof compressed === 'boolean' ? compressed : this.compressed;
|
|
215
|
+
|
|
216
|
+
if (!(i === 0 || i === 1 || i === 2 || i === 3)) {
|
|
217
|
+
throw new Error('i must be equal to 0, 1, 2, or 3');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
var val = i + 27 + 4;
|
|
221
|
+
if (compressed === false) {
|
|
222
|
+
val = val - 4;
|
|
223
|
+
}
|
|
224
|
+
var b1 = Buffer.from([val]);
|
|
225
|
+
var b2 = this.r.toBuffer({
|
|
226
|
+
size: 32,
|
|
227
|
+
});
|
|
228
|
+
var b3 = this.s.toBuffer({
|
|
229
|
+
size: 32,
|
|
230
|
+
});
|
|
231
|
+
return Buffer.concat([b1, b2, b3]);
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Converts the signature to DER format.
|
|
236
|
+
* Handles negative values by prepending a zero byte if necessary.
|
|
237
|
+
*
|
|
238
|
+
* @returns {Buffer} The DER-encoded signature.
|
|
239
|
+
*/
|
|
240
|
+
Signature.prototype.toBuffer = Signature.prototype.toDER = function () {
|
|
241
|
+
var rnbuf = this.r.toBuffer();
|
|
242
|
+
var snbuf = this.s.toBuffer();
|
|
243
|
+
|
|
244
|
+
var rneg = !!(rnbuf[0] & 0x80);
|
|
245
|
+
var sneg = !!(snbuf[0] & 0x80);
|
|
246
|
+
|
|
247
|
+
var rbuf = rneg ? Buffer.concat([Buffer.from([0x00]), rnbuf]) : rnbuf;
|
|
248
|
+
var sbuf = sneg ? Buffer.concat([Buffer.from([0x00]), snbuf]) : snbuf;
|
|
249
|
+
|
|
250
|
+
var rlength = rbuf.length;
|
|
251
|
+
var slength = sbuf.length;
|
|
252
|
+
var length = 2 + rlength + 2 + slength;
|
|
253
|
+
var rheader = 0x02;
|
|
254
|
+
var sheader = 0x02;
|
|
255
|
+
var header = 0x30;
|
|
256
|
+
|
|
257
|
+
var der = Buffer.concat([
|
|
258
|
+
Buffer.from([header, length, rheader, rlength]),
|
|
259
|
+
rbuf,
|
|
260
|
+
Buffer.from([sheader, slength]),
|
|
261
|
+
sbuf,
|
|
262
|
+
]);
|
|
263
|
+
return der;
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Converts the signature to a hexadecimal string representation.
|
|
268
|
+
* @returns {string} The DER-encoded signature in hexadecimal format.
|
|
269
|
+
*/
|
|
270
|
+
Signature.prototype.toString = function () {
|
|
271
|
+
var buf = this.toDER();
|
|
272
|
+
return buf.toString('hex');
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* This function is translated from bitcoind's IsDERSignature and is used in
|
|
277
|
+
* the script interpreter. This "DER" format actually includes an extra byte,
|
|
278
|
+
* the nhashtype, at the end. It is really the tx format, not DER format.
|
|
279
|
+
*
|
|
280
|
+
* A canonical signature exists of: [30] [total len] [02] [len R] [R] [02] [len S] [S] [hashtype]
|
|
281
|
+
* Where R and S are not negative (their first byte has its highest bit not set), and not
|
|
282
|
+
* excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,
|
|
283
|
+
* in which case a single 0 byte is necessary and even required).
|
|
284
|
+
*
|
|
285
|
+
* See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
|
|
286
|
+
*
|
|
287
|
+
* @param {Buffer} buf - The buffer containing the signature to verify
|
|
288
|
+
* @returns {boolean} True if the signature is valid DER-encoded, false otherwise
|
|
289
|
+
* @static
|
|
290
|
+
*/
|
|
291
|
+
Signature.isTxDER = function (buf) {
|
|
292
|
+
if (buf.length < 9) {
|
|
293
|
+
// Non-canonical signature: too short
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
if (buf.length > 73) {
|
|
297
|
+
// Non-canonical signature: too long
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
if (buf[0] !== 0x30) {
|
|
301
|
+
// Non-canonical signature: wrong type
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
if (buf[1] !== buf.length - 3) {
|
|
305
|
+
// Non-canonical signature: wrong length marker
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
var nLenR = buf[3];
|
|
309
|
+
if (5 + nLenR >= buf.length) {
|
|
310
|
+
// Non-canonical signature: S length misplaced
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
var nLenS = buf[5 + nLenR];
|
|
314
|
+
if (nLenR + nLenS + 7 !== buf.length) {
|
|
315
|
+
// Non-canonical signature: R+S length mismatch
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
var R = buf.slice(4);
|
|
320
|
+
if (buf[4 - 2] !== 0x02) {
|
|
321
|
+
// Non-canonical signature: R value type mismatch
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
if (nLenR === 0) {
|
|
325
|
+
// Non-canonical signature: R length is zero
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
if (R[0] & 0x80) {
|
|
329
|
+
// Non-canonical signature: R value negative
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
if (nLenR > 1 && R[0] === 0x00 && !(R[1] & 0x80)) {
|
|
333
|
+
// Non-canonical signature: R value excessively padded
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
var S = buf.slice(6 + nLenR);
|
|
338
|
+
if (buf[6 + nLenR - 2] !== 0x02) {
|
|
339
|
+
// Non-canonical signature: S value type mismatch
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
if (nLenS === 0) {
|
|
343
|
+
// Non-canonical signature: S length is zero
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
if (S[0] & 0x80) {
|
|
347
|
+
// Non-canonical signature: S value negative
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
if (nLenS > 1 && S[0] === 0x00 && !(S[1] & 0x80)) {
|
|
351
|
+
// Non-canonical signature: S value excessively padded
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
return true;
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Checks if the signature's S value is within the valid range (low-S).
|
|
360
|
+
* See also ECDSA signature algorithm which enforces this.
|
|
361
|
+
* See also BIP 62, "low S values in signatures"
|
|
362
|
+
* @returns {boolean} True if S is between 1 and the upper bound (0x7F...A0), false otherwise.
|
|
363
|
+
*/
|
|
364
|
+
Signature.prototype.hasLowS = function () {
|
|
365
|
+
if (
|
|
366
|
+
this.s.lt(new BN(1)) ||
|
|
367
|
+
this.s.gt(new BN('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0', 'hex'))
|
|
368
|
+
) {
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
return true;
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Checks if the signature has a defined hashtype.
|
|
377
|
+
* - Validates that nhashtype is a natural number
|
|
378
|
+
* - Accepts with or without Signature.SIGHASH_ANYONECANPAY by ignoring the bit
|
|
379
|
+
* - Verifies the hashtype is between SIGHASH_ALL and SIGHASH_SINGLE
|
|
380
|
+
* @returns {boolean} True if the hashtype is valid, false otherwise
|
|
381
|
+
*/
|
|
382
|
+
Signature.prototype.hasDefinedHashtype = function () {
|
|
383
|
+
if (!JSUtil.isNaturalNumber(this.nhashtype)) {
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
// accept with or without Signature.SIGHASH_ANYONECANPAY by ignoring the bit
|
|
387
|
+
var temp = this.nhashtype & 0x1f;
|
|
388
|
+
if (temp < Signature.SIGHASH_ALL || temp > Signature.SIGHASH_SINGLE) {
|
|
389
|
+
return false;
|
|
390
|
+
}
|
|
391
|
+
return true;
|
|
392
|
+
};
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Converts the signature to transaction format by concatenating the DER-encoded signature
|
|
396
|
+
* with the hash type byte.
|
|
397
|
+
* @returns {Buffer} The signature in transaction format (DER + hash type byte).
|
|
398
|
+
*/
|
|
399
|
+
Signature.prototype.toTxFormat = function () {
|
|
400
|
+
var derbuf = this.toDER();
|
|
401
|
+
var buf = Buffer.alloc(1);
|
|
402
|
+
buf.writeUInt8(this.nhashtype, 0);
|
|
403
|
+
return Buffer.concat([derbuf, buf]);
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Signature hash type for signing all inputs/outputs (default).
|
|
408
|
+
* @constant {number}
|
|
409
|
+
* @default 0x01
|
|
410
|
+
*/
|
|
411
|
+
Signature.SIGHASH_ALL = 0x01;
|
|
412
|
+
/**
|
|
413
|
+
* Flag indicating that no outputs are signed (only inputs are signed).
|
|
414
|
+
* Used in signature hashing to specify which parts of the transaction are included in the hash.
|
|
415
|
+
* @constant {number}
|
|
416
|
+
* @default 0x02
|
|
417
|
+
*/
|
|
418
|
+
Signature.SIGHASH_NONE = 0x02;
|
|
419
|
+
/**
|
|
420
|
+
* Signature hash type for single input signing (0x03).
|
|
421
|
+
* @constant {number}
|
|
422
|
+
* @default 0x03
|
|
423
|
+
*/
|
|
424
|
+
Signature.SIGHASH_SINGLE = 0x03;
|
|
425
|
+
/**
|
|
426
|
+
* Bit flag indicating that only the current input is signed (others can be modified).
|
|
427
|
+
* Used in Bitcoin signature hashing (SIGHASH type).
|
|
428
|
+
* @constant {number}
|
|
429
|
+
* @default 0x80
|
|
430
|
+
*/
|
|
431
|
+
Signature.SIGHASH_ANYONECANPAY = 0x80;
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Signature hash type for signing all inputs/outputs (default).
|
|
435
|
+
* @constant {number}
|
|
436
|
+
* @default 0x01
|
|
437
|
+
*/
|
|
438
|
+
Signature.ALL = Signature.SIGHASH_ALL
|
|
439
|
+
/**
|
|
440
|
+
* Flag indicating that no outputs are signed (only inputs are signed).
|
|
441
|
+
* Used in signature hashing to specify which parts of the transaction are included in the hash.
|
|
442
|
+
* @constant {number}
|
|
443
|
+
* @default 0x02
|
|
444
|
+
*/
|
|
445
|
+
Signature.NONE = Signature.SIGHASH_NONE
|
|
446
|
+
/**
|
|
447
|
+
* Signature hash type for single input signing (0x03).
|
|
448
|
+
* @constant {number}
|
|
449
|
+
* @default 0x03
|
|
450
|
+
*/
|
|
451
|
+
Signature.SINGLE = Signature.SIGHASH_SINGLE
|
|
452
|
+
/**
|
|
453
|
+
* Bitwise flag combination for signature hash types:
|
|
454
|
+
* SIGHASH_ALL (default) with ANYONECANPAY modifier.
|
|
455
|
+
* Allows anyone to add inputs to the transaction.
|
|
456
|
+
* @constant {number}
|
|
457
|
+
* @default 0x81
|
|
458
|
+
*/
|
|
459
|
+
Signature.ANYONECANPAY_ALL = Signature.SIGHASH_ALL | Signature.SIGHASH_ANYONECANPAY
|
|
460
|
+
/**
|
|
461
|
+
* Bitwise flag combination for a signature that allows anyone to pay (no output locking)
|
|
462
|
+
* and doesn't commit to any outputs (SIGHASH_NONE).
|
|
463
|
+
* @constant {number}
|
|
464
|
+
* @default 0x82
|
|
465
|
+
*/
|
|
466
|
+
Signature.ANYONECANPAY_NONE = Signature.SIGHASH_NONE | Signature.SIGHASH_ANYONECANPAY
|
|
467
|
+
/**
|
|
468
|
+
* Bitwise flag combination for signature allowing anyone to pay (SIGHASH_ANYONECANPAY)
|
|
469
|
+
* with single output mode (SIGHASH_SINGLE).
|
|
470
|
+
* @constant {number}
|
|
471
|
+
* @default 0x83
|
|
472
|
+
*/
|
|
473
|
+
Signature.ANYONECANPAY_SINGLE = Signature.SIGHASH_SINGLE | Signature.SIGHASH_ANYONECANPAY
|
|
474
|
+
|
|
475
|
+
export default Signature;
|