@smartledger/bsv 9.0.0 → 9.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +137 -0
- package/README.md +152 -1041
- package/STABILITY.md +134 -0
- package/bsv-gdaf.min.js +53 -48
- package/bsv-ltp.min.js +23 -18
- package/bsv-smartcontract.min.js +18 -18
- package/bsv.bundle.js +53 -48
- package/bsv.min.js +53 -48
- package/docs/MODULE_REFERENCE_COMPLETE.md +27 -27
- package/docs/advanced/UTXO_MANAGER_GUIDE.md +1 -1
- package/docs/getting-started/INSTALLATION.md +23 -23
- package/docs/getting-started/QUICK_START.md +7 -7
- package/docs/migration/FROM_BSV_1_5_6.md +5 -5
- package/docs/proposals/10.0.0-package-split.md +131 -0
- package/index.js +5 -0
- package/lib/block/merkleblock.js +19 -5
- package/lib/hdprivatekey.js +15 -0
- package/lib/script/interpreter.js +109 -1
- package/lib/smart_contract/builder.js +14 -0
- package/lib/util/deprecate.js +159 -0
- package/package.json +19 -82
- package/version.js +1 -1
- package/.mocharc.json +0 -5
- package/test/address.js +0 -629
- package/test/block/block.js +0 -239
- package/test/block/blockheader.js +0 -270
- package/test/block/merkleblock.js +0 -207
- package/test/build/bundle_crypto_shim.js +0 -104
- package/test/build/bundle_externals.js +0 -125
- package/test/build/bundle_smoke.js +0 -55
- package/test/build/esbuild_main.js +0 -65
- package/test/build/esm_wrapper.js +0 -97
- package/test/build/exports_resolution.js +0 -84
- package/test/build/version_sync.js +0 -14
- package/test/cli/smoke.js +0 -261
- package/test/consensus/base58-vectors.js +0 -120
- package/test/consensus/sv-script-vectors.js +0 -81
- package/test/consensus/sv-sighash-vectors.js +0 -51
- package/test/consensus/sv-tx-vectors.js +0 -48
- package/test/credentials-test.js +0 -332
- package/test/crypto/backend_selection.js +0 -126
- package/test/crypto/bn.js +0 -168
- package/test/crypto/ecdsa.js +0 -426
- package/test/crypto/elliptic-fixed.js +0 -61
- package/test/crypto/hash.browser.js +0 -121
- package/test/crypto/hash.js +0 -122
- package/test/crypto/point.js +0 -193
- package/test/crypto/random.js +0 -105
- package/test/crypto/security.js +0 -176
- package/test/crypto/shamir.js +0 -177
- package/test/crypto/shamir_rngcap.js +0 -29
- package/test/crypto/signature.js +0 -399
- package/test/data/bip69.json +0 -215
- package/test/data/bitcoin-sv/README.md +0 -170
- package/test/data/bitcoin-sv/base58_encode_decode.json +0 -14
- package/test/data/bitcoin-sv/base58_keys_invalid.json +0 -152
- package/test/data/bitcoin-sv/base58_keys_valid.json +0 -452
- package/test/data/bitcoin-sv/script_tests.json +0 -2591
- package/test/data/bitcoin-sv/sighash.json +0 -1003
- package/test/data/bitcoin-sv/tx_invalid.json +0 -285
- package/test/data/bitcoin-sv/tx_valid.json +0 -367
- package/test/data/bitcoind/base58_keys_invalid.json +0 -152
- package/test/data/bitcoind/base58_keys_valid.json +0 -452
- package/test/data/bitcoind/blocks.json +0 -27
- package/test/data/bitcoind/script_tests.json +0 -2244
- package/test/data/bitcoind/sig_canonical.json +0 -7
- package/test/data/bitcoind/sig_noncanonical.json +0 -22
- package/test/data/bitcoind/tx_invalid.json +0 -177
- package/test/data/bitcoind/tx_valid.json +0 -224
- package/test/data/blk86756-testnet.dat +0 -0
- package/test/data/blk86756-testnet.js +0 -12
- package/test/data/blk86756-testnet.json +0 -684
- package/test/data/brc220-batch-vector.json +0 -129
- package/test/data/ecdsa.json +0 -230
- package/test/data/merkleblocks.js +0 -486
- package/test/data/messages.json +0 -22
- package/test/data/sighash.json +0 -1004
- package/test/data/tx_creation.json +0 -85
- package/test/didweb/relationships.js +0 -144
- package/test/ecies/bitcore-ecies.js +0 -178
- package/test/ecies/electrum-ecies.js +0 -206
- package/test/encoding/base58.js +0 -131
- package/test/encoding/base58check.js +0 -145
- package/test/encoding/bufferreader.js +0 -328
- package/test/encoding/bufferwriter.js +0 -160
- package/test/encoding/varint.js +0 -104
- package/test/gdaf/anchor_no_key_leak.js +0 -146
- package/test/gdaf/anchor_spv.js +0 -163
- package/test/gdaf/canonicalization.js +0 -106
- package/test/gdaf/canonicalize.js +0 -140
- package/test/gdaf/zk_prover.js +0 -204
- package/test/hdkeys.js +0 -365
- package/test/hdprivatekey.js +0 -339
- package/test/hdpublickey.js +0 -293
- package/test/index.js +0 -16
- package/test/ltp/ids.js +0 -74
- package/test/ltp/right.js +0 -198
- package/test/ltp/verify_failclosed.js +0 -134
- package/test/message/message.js +0 -190
- package/test/mnemonic/data/fixtures.json +0 -300
- package/test/mnemonic/mnemonic.js +0 -277
- package/test/mnemonic/mocha.opts +0 -1
- package/test/mnemonic/pbkdf2.test.js +0 -43
- package/test/networks.js +0 -207
- package/test/notaryhash/batch_leaf.js +0 -140
- package/test/notaryhash/batch_vector.js +0 -282
- package/test/notaryhash/certificate.js +0 -249
- package/test/notaryhash/encoding.js +0 -186
- package/test/notaryhash/interop.js +0 -112
- package/test/notaryhash/merkle.js +0 -181
- package/test/notaryhash/script.js +0 -270
- package/test/notaryhash/verify.js +0 -342
- package/test/opcode.js +0 -186
- package/test/ordinals/bsv20.js +0 -337
- package/test/ordinals/inscription.js +0 -329
- package/test/ordinals/ordlock.js +0 -567
- package/test/privatekey.js +0 -540
- package/test/publickey.js +0 -411
- package/test/regressions.js +0 -215
- package/test/script/chronicle.js +0 -543
- package/test/script/defaults.js +0 -160
- package/test/script/genesis_limits.js +0 -203
- package/test/script/interpreter.js +0 -776
- package/test/script/script.js +0 -1259
- package/test/script/string_ops.js +0 -88
- package/test/security/fail_closed_contracts.js +0 -104
- package/test/security/threat_model_coverage.js +0 -31
- package/test/smart_contract/covenants.js +0 -207
- package/test/smart_contract/dsl_debugger.js +0 -92
- package/test/smart_contract/extract_field.js +0 -61
- package/test/smart_contract/nonenforcing_guard.js +0 -44
- package/test/smart_contract/ordinal_transfer.js +0 -71
- package/test/smart_contract/preimage.js +0 -98
- package/test/smart_contract/sighash_marketplace.js +0 -98
- package/test/smart_contract/token_generalized.js +0 -175
- package/test/spv/headerchain.js +0 -86
- package/test/spv/merkleproof.js +0 -133
- package/test/statuslist/failclosed.js +0 -78
- package/test/transaction/deserialize.js +0 -33
- package/test/transaction/input/input.js +0 -92
- package/test/transaction/input/multisig.js +0 -174
- package/test/transaction/input/multisigscripthash.js +0 -111
- package/test/transaction/input/publickey.js +0 -68
- package/test/transaction/input/publickeyhash.js +0 -59
- package/test/transaction/output.js +0 -185
- package/test/transaction/sighash.js +0 -91
- package/test/transaction/signature.js +0 -127
- package/test/transaction/transaction.js +0 -1299
- package/test/transaction/unspentoutput.js +0 -97
- package/test/types/dts_drift.js +0 -124
- package/test/types/surface_honesty.js +0 -102
- package/test/util/id.js +0 -72
- package/test/util/js.js +0 -76
- package/test/util/preconditions.js +0 -79
- package/test/vcjwt/interop.js +0 -126
package/test/crypto/hash.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
require('chai').should()
|
|
4
|
-
var bsv = require('../..')
|
|
5
|
-
var Hash = bsv.crypto.Hash
|
|
6
|
-
|
|
7
|
-
describe('Hash', function () {
|
|
8
|
-
var buf = Buffer.from([0, 1, 2, 3, 253, 254, 255])
|
|
9
|
-
var str = 'test string'
|
|
10
|
-
|
|
11
|
-
describe('@sha1', function () {
|
|
12
|
-
it('calculates the hash of this buffer correctly', function () {
|
|
13
|
-
var hash = Hash.sha1(buf)
|
|
14
|
-
hash.toString('hex').should.equal('de69b8a4a5604d0486e6420db81e39eb464a17b2')
|
|
15
|
-
hash = Hash.sha1(Buffer.alloc(0))
|
|
16
|
-
hash.toString('hex').should.equal('da39a3ee5e6b4b0d3255bfef95601890afd80709')
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
it('throws an error when the input is not a buffer', function () {
|
|
20
|
-
Hash.sha1.bind(Hash, str).should.throw('Invalid Argument')
|
|
21
|
-
})
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
describe('#sha256', function () {
|
|
25
|
-
it('calculates the hash of this buffer correctly', function () {
|
|
26
|
-
var hash = Hash.sha256(buf)
|
|
27
|
-
hash.toString('hex').should.equal('6f2c7b22fd1626998287b3636089087961091de80311b9279c4033ec678a83e8')
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
it('fails when the input is not a buffer', function () {
|
|
31
|
-
Hash.sha256.bind(Hash, str).should.throw('Invalid Argument')
|
|
32
|
-
})
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
describe('#sha256hmac', function () {
|
|
36
|
-
it('computes this known big key correctly', function () {
|
|
37
|
-
var key = Buffer.from('b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad' +
|
|
38
|
-
'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad' +
|
|
39
|
-
'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad' +
|
|
40
|
-
'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad')
|
|
41
|
-
var data = Buffer.from('')
|
|
42
|
-
Hash.sha256hmac(data, key).toString('hex')
|
|
43
|
-
.should.equal('fb1f87218671f1c0c4593a88498e02b6dfe8afd814c1729e89a1f1f6600faa23')
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
it('computes this known empty test vector correctly', function () {
|
|
47
|
-
var key = Buffer.from('')
|
|
48
|
-
var data = Buffer.from('')
|
|
49
|
-
Hash.sha256hmac(data, key).toString('hex')
|
|
50
|
-
.should.equal('b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad')
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
it('computes this known non-empty test vector correctly', function () {
|
|
54
|
-
var key = Buffer.from('key')
|
|
55
|
-
var data = Buffer.from('The quick brown fox jumps over the lazy dog')
|
|
56
|
-
Hash.sha256hmac(data, key).toString('hex')
|
|
57
|
-
.should.equal('f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8')
|
|
58
|
-
})
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
describe('#sha256sha256', function () {
|
|
62
|
-
it('calculates the hash of this buffer correctly', function () {
|
|
63
|
-
var hash = Hash.sha256sha256(buf)
|
|
64
|
-
hash.toString('hex').should.equal('be586c8b20dee549bdd66018c7a79e2b67bb88b7c7d428fa4c970976d2bec5ba')
|
|
65
|
-
})
|
|
66
|
-
|
|
67
|
-
it('fails when the input is not a buffer', function () {
|
|
68
|
-
Hash.sha256sha256.bind(Hash, str).should.throw('Invalid Argument')
|
|
69
|
-
})
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
describe('#sha256ripemd160', function () {
|
|
73
|
-
it('calculates the hash of this buffer correctly', function () {
|
|
74
|
-
var hash = Hash.sha256ripemd160(buf)
|
|
75
|
-
hash.toString('hex').should.equal('7322e2bd8535e476c092934e16a6169ca9b707ec')
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
it('fails when the input is not a buffer', function () {
|
|
79
|
-
Hash.sha256ripemd160.bind(Hash, str).should.throw('Invalid Argument')
|
|
80
|
-
})
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
describe('#ripemd160', function () {
|
|
84
|
-
it('calculates the hash of this buffer correctly', function () {
|
|
85
|
-
var hash = Hash.ripemd160(buf)
|
|
86
|
-
hash.toString('hex').should.equal('fa0f4565ff776fee0034c713cbf48b5ec06b7f5c')
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
it('fails when the input is not a buffer', function () {
|
|
90
|
-
Hash.ripemd160.bind(Hash, str).should.throw('Invalid Argument')
|
|
91
|
-
})
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
describe('#sha512', function () {
|
|
95
|
-
it('calculates the hash of this buffer correctly', function () {
|
|
96
|
-
var hash = Hash.sha512(buf)
|
|
97
|
-
hash.toString('hex')
|
|
98
|
-
.should.equal('c0530aa32048f4904ae162bc14b9eb535eab6c465e960130005fedd' +
|
|
99
|
-
'b71613e7d62aea75f7d3333ba06e805fc8e45681454524e3f8050969fe5a5f7f2392e31d0')
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
it('fails when the input is not a buffer', function () {
|
|
103
|
-
Hash.sha512.bind(Hash, str).should.throw('Invalid Argument')
|
|
104
|
-
})
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
describe('#sha512hmac', function () {
|
|
108
|
-
it('calculates this known empty test vector correctly', function () {
|
|
109
|
-
var hex = 'b936cee86c9f87aa5d3c6f2e84cb5a4239a5fe50480a6ec66b70ab5b1f4a' +
|
|
110
|
-
'c6730c6c515421b327ec1d69402e53dfb49ad7381eb067b338fd7b0cb22247225d47'
|
|
111
|
-
Hash.sha512hmac(Buffer.from([]), Buffer.from([])).toString('hex').should.equal(hex)
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
it('calculates this known non-empty test vector correctly', function () {
|
|
115
|
-
var hex = 'c40bd7c15aa493b309c940e08a73ffbd28b2e4cb729eb94480d727e4df577' +
|
|
116
|
-
'b13cc403a78e6150d83595f3b17c4cc331f12ca5952691de3735a63c1d4c69a2bac'
|
|
117
|
-
var data = Buffer.from('test1')
|
|
118
|
-
var key = Buffer.from('test2')
|
|
119
|
-
Hash.sha512hmac(data, key).toString('hex').should.equal(hex)
|
|
120
|
-
})
|
|
121
|
-
})
|
|
122
|
-
})
|
package/test/crypto/point.js
DELETED
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
var should = require('chai').should()
|
|
4
|
-
var bsv = require('../..')
|
|
5
|
-
var Point = bsv.crypto.Point
|
|
6
|
-
var BN = bsv.crypto.BN
|
|
7
|
-
|
|
8
|
-
describe('Point', function () {
|
|
9
|
-
var valid = {
|
|
10
|
-
x: 'ac242d242d23be966085a2b2b893d989f824e06c9ad0395a8a52f055ba39abb2',
|
|
11
|
-
y: '4836ab292c105a711ed10fcfd30999c31ff7c02456147747e03e739ad527c380'
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
it('should create a point', function () {
|
|
15
|
-
var p = Point(valid.x, valid.y)
|
|
16
|
-
should.exist(p)
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
it('should create a point when called with "new"', function () {
|
|
20
|
-
var p = new Point(valid.x, valid.y)
|
|
21
|
-
should.exist(p)
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
describe('#getX', function () {
|
|
25
|
-
it('should return x', function () {
|
|
26
|
-
var p = Point(valid.x, valid.y)
|
|
27
|
-
var x = p.getX()
|
|
28
|
-
x.toString('hex', 64).should.equal(valid.x)
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('should be convertable to a buffer', function () {
|
|
32
|
-
var p = Point(valid.x, valid.y)
|
|
33
|
-
var a = p.getX().toBuffer({ size: 32 })
|
|
34
|
-
a.length.should.equal(32)
|
|
35
|
-
a.should.deep.equal(Buffer.from(valid.x, 'hex'))
|
|
36
|
-
})
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
describe('#getY', function () {
|
|
40
|
-
it('should return y', function () {
|
|
41
|
-
var p = Point(valid.x, valid.y)
|
|
42
|
-
p.getY().toString('hex', 64).should.equal(valid.y)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it('should be convertable to a buffer', function () {
|
|
46
|
-
var p = Point(valid.x, valid.y)
|
|
47
|
-
var a = p.getY().toBuffer({ size: 32 })
|
|
48
|
-
a.length.should.equal(32)
|
|
49
|
-
a.should.deep.equal(Buffer.from(valid.y, 'hex'))
|
|
50
|
-
})
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
describe('#add', function () {
|
|
54
|
-
it('should accurately add g to itself', function () {
|
|
55
|
-
var p1 = Point.getG()
|
|
56
|
-
var p2 = Point.getG()
|
|
57
|
-
var p3 = p1.add(p2)
|
|
58
|
-
p3.getX().toString().should.equal('89565891926547004231252920425935692360644145829622209' +
|
|
59
|
-
'833684329913297188986597')
|
|
60
|
-
p3.getY().toString().should.equal('12158399299693830322967808612713398636155367887041628' +
|
|
61
|
-
'176798871954788371653930')
|
|
62
|
-
})
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
describe('#mul', function () {
|
|
66
|
-
it('should accurately multiply g by 2', function () {
|
|
67
|
-
var g = Point.getG()
|
|
68
|
-
var b = g.mul(new BN(2))
|
|
69
|
-
b.getX().toString().should.equal('8956589192654700423125292042593569236064414582962220983' +
|
|
70
|
-
'3684329913297188986597')
|
|
71
|
-
b.getY().toString().should.equal('1215839929969383032296780861271339863615536788704162817' +
|
|
72
|
-
'6798871954788371653930')
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
it('should accurately multiply g by n-1', function () {
|
|
76
|
-
var g = Point.getG()
|
|
77
|
-
var n = Point.getN()
|
|
78
|
-
var b = g.mul(n.sub(new BN(1)))
|
|
79
|
-
b.getX().toString().should.equal('55066263022277343669578718895168534326250603453777594175' +
|
|
80
|
-
'500187360389116729240')
|
|
81
|
-
b.getY().toString().should.equal('83121579216557378445487899878180864668798711284981320763' +
|
|
82
|
-
'518679672151497189239')
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
// not sure if this is technically accurate or not...
|
|
86
|
-
// normally, you should always multiply g by something less than n
|
|
87
|
-
// but it is the same result in OpenSSL
|
|
88
|
-
it('should accurately multiply g by n+1', function () {
|
|
89
|
-
var g = Point.getG()
|
|
90
|
-
var n = Point.getN()
|
|
91
|
-
var b = g.mul(n.add(new BN(1)))
|
|
92
|
-
b.getX().toString().should.equal('550662630222773436695787188951685343262506034537775941755' +
|
|
93
|
-
'00187360389116729240')
|
|
94
|
-
b.getY().toString().should.equal('326705100207588169780830851305070431844712733806592432759' +
|
|
95
|
-
'38904335757337482424')
|
|
96
|
-
})
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
describe('@fromX', function () {
|
|
100
|
-
it('should return g', function () {
|
|
101
|
-
var g = Point.getG()
|
|
102
|
-
var p = Point.fromX(false, g.getX())
|
|
103
|
-
g.eq(p).should.equal(true)
|
|
104
|
-
})
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
describe('@pointToCompressed', function () {
|
|
108
|
-
it('should return g', function () {
|
|
109
|
-
let g = Point.getG()
|
|
110
|
-
let pbuf = Point.pointToCompressed(g)
|
|
111
|
-
pbuf.length.should.equal(33)
|
|
112
|
-
pbuf.toString('hex').should.equal('0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798')
|
|
113
|
-
})
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
describe('#toBuffer', function () {
|
|
117
|
-
it('should return g', function () {
|
|
118
|
-
let g = Point.getG()
|
|
119
|
-
let pbuf = g.toBuffer()
|
|
120
|
-
pbuf.length.should.equal(33)
|
|
121
|
-
pbuf.toString('hex').should.equal('0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798')
|
|
122
|
-
})
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
describe('@fromBuffer', function () {
|
|
126
|
-
it('should return g', function () {
|
|
127
|
-
let buf = Buffer.from('0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', 'hex')
|
|
128
|
-
let p = Point.fromBuffer(buf)
|
|
129
|
-
p.toBuffer().toString('hex').should.equal(buf.toString('hex'))
|
|
130
|
-
})
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
describe('#toHex', function () {
|
|
134
|
-
it('should return g', function () {
|
|
135
|
-
let g = Point.getG()
|
|
136
|
-
let phex = g.toHex()
|
|
137
|
-
phex.length.should.equal(33 * 2)
|
|
138
|
-
phex.should.equal('0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798')
|
|
139
|
-
})
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
describe('@fromHex', function () {
|
|
143
|
-
it('should return g', function () {
|
|
144
|
-
let hex = '0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'
|
|
145
|
-
let p = Point.fromHex(hex)
|
|
146
|
-
p.toHex().should.equal(hex)
|
|
147
|
-
})
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
describe('#validate', function () {
|
|
151
|
-
it('should describe this point as valid', function () {
|
|
152
|
-
var p = Point(valid.x, valid.y)
|
|
153
|
-
should.exist(p.validate())
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
it('should describe this point as invalid because of zero y', function () {
|
|
157
|
-
var x = 'ac242d242d23be966085a2b2b893d989f824e06c9ad0395a8a52f055ba39abb2'
|
|
158
|
-
var y = '0000000000000000000000000000000000000000000000000000000000000000';
|
|
159
|
-
(function () {
|
|
160
|
-
Point(x, y)
|
|
161
|
-
}).should.throw('Invalid y value for curve.')
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
it('should describe this point as invalid because of invalid y', function () {
|
|
165
|
-
var x = 'ac242d242d23be966085a2b2b893d989f824e06c9ad0395a8a52f055ba39abb2'
|
|
166
|
-
var y = '00000000000000000000000000000000000000000000000000000000000000FF';
|
|
167
|
-
(function () {
|
|
168
|
-
Point(x, y)
|
|
169
|
-
}).should.throw('Invalid y value for curve.')
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
it('should describe this point as invalid because out of curve bounds', function () {
|
|
173
|
-
// point larger than max
|
|
174
|
-
var x = 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEDCE6AF48A03BBFD25E8CD0364141'
|
|
175
|
-
// calculated y of x
|
|
176
|
-
var y = 'ed3970f129bc2ca7c7c6cf92fa7da4de6a1dfc9c14da4bf056aa868d3dd74034';
|
|
177
|
-
|
|
178
|
-
(function () {
|
|
179
|
-
// set the point
|
|
180
|
-
Point(x, y)
|
|
181
|
-
}).should.throw('Point does not lie on the curve')
|
|
182
|
-
})
|
|
183
|
-
|
|
184
|
-
it('should describe this point as invalid because out of curve bounds', function () {
|
|
185
|
-
var x = '0000000000000000000000000000000000000000000000000000000000000000';
|
|
186
|
-
|
|
187
|
-
(function () {
|
|
188
|
-
// set the point
|
|
189
|
-
Point.fromX(false, x)
|
|
190
|
-
}).should.throw('Invalid X')
|
|
191
|
-
})
|
|
192
|
-
})
|
|
193
|
-
})
|
package/test/crypto/random.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
var bsv = require('../..')
|
|
4
|
-
var Random = bsv.crypto.Random
|
|
5
|
-
|
|
6
|
-
describe('Random', function () {
|
|
7
|
-
describe('@getRandomBuffer', function () {
|
|
8
|
-
it('should return a buffer', function () {
|
|
9
|
-
var bytes = Random.getRandomBuffer(8)
|
|
10
|
-
bytes.length.should.equal(8)
|
|
11
|
-
Buffer.isBuffer(bytes).should.equal(true)
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
it('should not equate two 256 bit random buffers', function () {
|
|
15
|
-
var bytes1 = Random.getRandomBuffer(32)
|
|
16
|
-
var bytes2 = Random.getRandomBuffer(32)
|
|
17
|
-
bytes1.toString('hex').should.not.equal(bytes2.toString('hex'))
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
it('should generate 100 8 byte buffers in a row that are not equal', function () {
|
|
21
|
-
var hexs = []
|
|
22
|
-
for (var i = 0; i < 100; i++) {
|
|
23
|
-
hexs[i] = Random.getRandomBuffer(8).toString('hex')
|
|
24
|
-
}
|
|
25
|
-
for (i = 0; i < 100; i++) {
|
|
26
|
-
for (var j = i + 1; j < 100; j++) {
|
|
27
|
-
hexs[i].should.not.equal(hexs[j])
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
// WebCrypto refuses more than 65,536 bytes per call. Before chunking, a request
|
|
33
|
-
// above that limit threw; a naive implementation that ignored the return size
|
|
34
|
-
// instead would hand back a zero-filled tail, which is far worse than throwing.
|
|
35
|
-
it('fills requests larger than the 65536-byte getRandomValues limit', function () {
|
|
36
|
-
var buf = Random.getRandomBuffer(70000)
|
|
37
|
-
buf.length.should.equal(70000)
|
|
38
|
-
// The tail comes from a second call — assert it is real entropy, not zero padding.
|
|
39
|
-
var tail = buf.subarray(65536)
|
|
40
|
-
tail.some(function (b) { return b !== 0 }).should.equal(true)
|
|
41
|
-
buf.subarray(0, 32).toString('hex').should.not.equal(tail.subarray(0, 32).toString('hex'))
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
it('handles the exact limit and one past it', function () {
|
|
45
|
-
Random.getRandomBuffer(65536).length.should.equal(65536)
|
|
46
|
-
Random.getRandomBuffer(65537).length.should.equal(65537)
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
// The backend is chosen by feature detection. This used to branch on
|
|
50
|
-
// `process.browser`, which is undefined in React Native, Deno, Workers and Bun —
|
|
51
|
-
// all of which then fell through to require('crypto').randomBytes. Where a partial
|
|
52
|
-
// crypto shim supplies a weak randomBytes, that produced guessable keys silently.
|
|
53
|
-
it('does not depend on process.browser', function () {
|
|
54
|
-
var saved = process.browser
|
|
55
|
-
try {
|
|
56
|
-
process.browser = undefined
|
|
57
|
-
Random.getRandomBuffer(16).length.should.equal(16)
|
|
58
|
-
process.browser = true
|
|
59
|
-
Random.getRandomBuffer(16).length.should.equal(16)
|
|
60
|
-
} finally {
|
|
61
|
-
process.browser = saved
|
|
62
|
-
}
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
it('prefers globalThis.crypto.getRandomValues when present', function () {
|
|
66
|
-
var calls = 0
|
|
67
|
-
var real = Object.getOwnPropertyDescriptor(globalThis, 'crypto')
|
|
68
|
-
try {
|
|
69
|
-
Object.defineProperty(globalThis, 'crypto', {
|
|
70
|
-
configurable: true,
|
|
71
|
-
value: {
|
|
72
|
-
getRandomValues: function (arr) {
|
|
73
|
-
calls++
|
|
74
|
-
for (var i = 0; i < arr.length; i++) arr[i] = (i * 7 + 3) & 0xff
|
|
75
|
-
return arr
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
})
|
|
79
|
-
var buf = Random.getRandomBuffer(4)
|
|
80
|
-
calls.should.equal(1)
|
|
81
|
-
buf.toString('hex').should.equal('030a1118')
|
|
82
|
-
} finally {
|
|
83
|
-
if (real) Object.defineProperty(globalThis, 'crypto', real)
|
|
84
|
-
}
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
// The throw matters as much as the detection: a key library must never return bytes
|
|
88
|
-
// it cannot vouch for. Verified in a child process because it has to remove both
|
|
89
|
-
// backends, which cannot be undone safely in-process.
|
|
90
|
-
it('throws rather than returning bytes when no CSPRNG exists', function () {
|
|
91
|
-
var out = require('child_process').spawnSync(process.execPath, ['-e', [
|
|
92
|
-
'var Module = require("module"), orig = Module._load',
|
|
93
|
-
'delete globalThis.crypto',
|
|
94
|
-
'Module._load = function (r) {',
|
|
95
|
-
' if (r === "crypto") { var e = new Error("no crypto"); e.code = "MODULE_NOT_FOUND"; throw e }',
|
|
96
|
-
' return orig.apply(this, arguments)',
|
|
97
|
-
'}',
|
|
98
|
-
'var R = require(' + JSON.stringify(require.resolve('../../lib/crypto/random.js')) + ')',
|
|
99
|
-
'try { R.getRandomBuffer(32); console.log("RETURNED") }',
|
|
100
|
-
'catch (e) { console.log("THREW") }'
|
|
101
|
-
].join('\n')], { encoding: 'utf8' })
|
|
102
|
-
out.stdout.trim().should.equal('THREW')
|
|
103
|
-
})
|
|
104
|
-
})
|
|
105
|
-
})
|
package/test/crypto/security.js
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
/* global describe, it, before */
|
|
4
|
-
|
|
5
|
-
require('chai').should()
|
|
6
|
-
var expect = require('chai').expect
|
|
7
|
-
|
|
8
|
-
var bsv = require('../../index.js')
|
|
9
|
-
var BN = bsv.crypto.BN
|
|
10
|
-
var ECDSA = bsv.crypto.ECDSA
|
|
11
|
-
var Hash = bsv.crypto.Hash
|
|
12
|
-
var Point = bsv.crypto.Point
|
|
13
|
-
var Signature = bsv.crypto.Signature
|
|
14
|
-
var SmartVerify = bsv.SmartVerify
|
|
15
|
-
|
|
16
|
-
describe('SmartLedger Security Patches', function () {
|
|
17
|
-
var privateKey, publicKey, message, hash
|
|
18
|
-
|
|
19
|
-
before(function () {
|
|
20
|
-
privateKey = new bsv.PrivateKey()
|
|
21
|
-
publicKey = privateKey.toPublicKey()
|
|
22
|
-
message = 'SmartLedger security test message'
|
|
23
|
-
hash = Hash.sha256(Buffer.from(message))
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
describe('Zero Parameter Attack Protection', function () {
|
|
27
|
-
it('Signature.validate() throws when r = 0', function () {
|
|
28
|
-
var sig = new Signature({ r: new BN(0), s: new BN(1) })
|
|
29
|
-
expect(function () { sig.validate() }).to.throw(/r component is zero/)
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('Signature.validate() throws when s = 0', function () {
|
|
33
|
-
var sig = new Signature({ r: new BN(1), s: new BN(0) })
|
|
34
|
-
expect(function () { sig.validate() }).to.throw(/s component is zero/)
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
it('smartVerify rejects (without throwing) a zero-s signature', function () {
|
|
38
|
-
var sig = new Signature({ r: new BN(1), s: new BN(0) })
|
|
39
|
-
SmartVerify.smartVerify(hash, sig, publicKey).should.equal(false)
|
|
40
|
-
})
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
describe('Canonical Signature Enforcement', function () {
|
|
44
|
-
it('freshly produced signatures are canonical (low-S)', function () {
|
|
45
|
-
var sig = ECDSA.sign(hash, privateKey)
|
|
46
|
-
sig.isCanonical().should.equal(true)
|
|
47
|
-
SmartVerify.isCanonical(sig).should.equal(true)
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
it('detects a non-canonical (high-S) signature', function () {
|
|
51
|
-
var sig = ECDSA.sign(hash, privateKey)
|
|
52
|
-
var n = Point.getN()
|
|
53
|
-
var lowS = sig.s.lte(n.shrn(1)) ? sig.s : n.sub(sig.s)
|
|
54
|
-
var highS = new Signature({ r: sig.r, s: n.sub(lowS) })
|
|
55
|
-
|
|
56
|
-
highS.isCanonical().should.equal(false)
|
|
57
|
-
SmartVerify.isCanonical(highS).should.equal(false)
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
it('toCanonical() converts a high-S signature to canonical form', function () {
|
|
61
|
-
var sig = ECDSA.sign(hash, privateKey)
|
|
62
|
-
var n = Point.getN()
|
|
63
|
-
var lowS = sig.s.lte(n.shrn(1)) ? sig.s : n.sub(sig.s)
|
|
64
|
-
var highS = new Signature({ r: sig.r, s: n.sub(lowS) })
|
|
65
|
-
|
|
66
|
-
var canonical = highS.toCanonical()
|
|
67
|
-
canonical.isCanonical().should.equal(true)
|
|
68
|
-
// Both forms verify (ECDSA is malleable in s); canonicalization does not
|
|
69
|
-
// change which key/message the signature is valid for.
|
|
70
|
-
canonical.r.cmp(highS.r).should.equal(0)
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
it('toCanonical() returns a new signature and leaves the original alone', function () {
|
|
74
|
-
var sig = ECDSA.sign(hash, privateKey)
|
|
75
|
-
var n = Point.getN()
|
|
76
|
-
var lowS = sig.s.lte(n.shrn(1)) ? sig.s : n.sub(sig.s)
|
|
77
|
-
var highS = new Signature({ r: sig.r, s: n.sub(lowS) })
|
|
78
|
-
var before = highS.s.toString()
|
|
79
|
-
|
|
80
|
-
var canonical = highS.toCanonical()
|
|
81
|
-
canonical.should.not.equal(highS)
|
|
82
|
-
highS.s.toString().should.equal(before)
|
|
83
|
-
})
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
describe('applySecurityPatches', function () {
|
|
87
|
-
var highSig = function () {
|
|
88
|
-
var sig = ECDSA.sign(hash, privateKey)
|
|
89
|
-
var n = Point.getN()
|
|
90
|
-
var lowS = sig.s.lte(n.shrn(1)) ? sig.s : n.sub(sig.s)
|
|
91
|
-
return new Signature({ r: sig.r, s: n.sub(lowS) })
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
it('accepts a canonical signature and returns it for chaining', function () {
|
|
95
|
-
var sig = ECDSA.sign(hash, privateKey)
|
|
96
|
-
sig.applySecurityPatches().should.equal(sig)
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
it('rejects a non-canonical (high-S) signature rather than rewriting it', function () {
|
|
100
|
-
// Rewriting s to n-s cannot protect against malleability: the rewritten
|
|
101
|
-
// signature verifies exactly as the original, so silently normalizing only
|
|
102
|
-
// hides from the caller that the signature was malleated.
|
|
103
|
-
var highS = highSig()
|
|
104
|
-
var before = highS.s.toString()
|
|
105
|
-
|
|
106
|
-
expect(function () { highS.applySecurityPatches() }).to.throw(/non-canonical/)
|
|
107
|
-
highS.s.toString().should.equal(before)
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
it('rejects zero and out-of-range components', function () {
|
|
111
|
-
expect(function () {
|
|
112
|
-
new Signature({ r: new BN(0), s: new BN(1) }).applySecurityPatches()
|
|
113
|
-
}).to.throw(/zero r or s/)
|
|
114
|
-
expect(function () {
|
|
115
|
-
new Signature({ r: new BN(1), s: Point.getN() }).applySecurityPatches()
|
|
116
|
-
}).to.throw(/out of range/)
|
|
117
|
-
})
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
describe('SmartVerify Enhanced Validation', function () {
|
|
121
|
-
it('accepts a valid signature', function () {
|
|
122
|
-
var sig = ECDSA.sign(hash, privateKey)
|
|
123
|
-
SmartVerify.smartVerify(hash, sig, publicKey).should.equal(true)
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
it('rejects a malleated (high-S) signature', function () {
|
|
127
|
-
var sig = ECDSA.sign(hash, privateKey)
|
|
128
|
-
var n = Point.getN()
|
|
129
|
-
var lowS = sig.s.lte(n.shrn(1)) ? sig.s : n.sub(sig.s)
|
|
130
|
-
var highS = new Signature({ r: sig.r, s: n.sub(lowS) })
|
|
131
|
-
SmartVerify.isCanonical(highS).should.equal(false)
|
|
132
|
-
SmartVerify.smartVerify(hash, highS, publicKey).should.equal(false)
|
|
133
|
-
// ...while the canonical form of the same signature still verifies.
|
|
134
|
-
SmartVerify.smartVerify(hash, new Signature({ r: sig.r, s: lowS }), publicKey).should.equal(true)
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
it('throws on an invalid (non-32-byte) message hash', function () {
|
|
138
|
-
var sig = ECDSA.sign(hash, privateKey)
|
|
139
|
-
var shortHash = Buffer.alloc(16)
|
|
140
|
-
expect(function () {
|
|
141
|
-
SmartVerify.smartVerify(shortHash, sig, publicKey)
|
|
142
|
-
}).to.throw(/32-byte/)
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
it('rejects a signature from the wrong key', function () {
|
|
146
|
-
var sig = ECDSA.sign(hash, privateKey)
|
|
147
|
-
var otherPub = new bsv.PrivateKey().toPublicKey()
|
|
148
|
-
SmartVerify.smartVerify(hash, sig, otherPub).should.equal(false)
|
|
149
|
-
})
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
describe('Integration with Original BSV', function () {
|
|
153
|
-
it('round-trips a Bitcoin message signature', function () {
|
|
154
|
-
var sig = new bsv.Message(message).sign(privateKey)
|
|
155
|
-
var verified = new bsv.Message(message).verify(publicKey.toAddress().toString(), sig)
|
|
156
|
-
verified.should.equal(true)
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
it('signs a transaction to completion', function () {
|
|
160
|
-
var utxo = {
|
|
161
|
-
txId: 'a'.repeat(64),
|
|
162
|
-
outputIndex: 0,
|
|
163
|
-
address: privateKey.toAddress().toString(),
|
|
164
|
-
script: bsv.Script.buildPublicKeyHashOut(privateKey.toAddress()).toHex(),
|
|
165
|
-
satoshis: 100000
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
var transaction = new bsv.Transaction()
|
|
169
|
-
.from(utxo)
|
|
170
|
-
.to(privateKey.toAddress(), 50000)
|
|
171
|
-
.sign(privateKey)
|
|
172
|
-
|
|
173
|
-
transaction.isFullySigned().should.equal(true)
|
|
174
|
-
})
|
|
175
|
-
})
|
|
176
|
-
})
|