@smartledger/bsv 8.3.1 → 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.
Files changed (169) hide show
  1. package/CHANGELOG.md +228 -0
  2. package/README.md +152 -1031
  3. package/STABILITY.md +134 -0
  4. package/bsv-gdaf.min.js +58 -53
  5. package/bsv-ltp.min.js +23 -18
  6. package/bsv-script-helper.min.js +1 -1
  7. package/bsv-smartcontract.min.js +21 -21
  8. package/bsv.bundle.js +58 -53
  9. package/bsv.d.ts +0 -4
  10. package/bsv.min.js +58 -53
  11. package/docs/BRC220_BATCH_LEAF_AMENDMENT.md +82 -7
  12. package/docs/MODULE_REFERENCE_COMPLETE.md +27 -27
  13. package/docs/README.md +2 -1
  14. package/docs/THREAT_MODEL.md +10 -2
  15. package/docs/advanced/UTXO_MANAGER_GUIDE.md +1 -1
  16. package/docs/getting-started/INSTALLATION.md +23 -23
  17. package/docs/getting-started/QUICK_START.md +7 -7
  18. package/docs/migration/FROM_BSV_1_5_6.md +5 -5
  19. package/docs/proposals/10.0.0-package-split.md +131 -0
  20. package/index.js +15 -26
  21. package/lib/block/merkleblock.js +19 -5
  22. package/lib/covenant/helpers.js +34 -35
  23. package/lib/covenant/pushtx.js +2 -2
  24. package/lib/custom-script-helper.js +0 -16
  25. package/lib/hdprivatekey.js +15 -0
  26. package/lib/ordinals/ordlock.js +1 -1
  27. package/lib/script/interpreter.js +109 -1
  28. package/lib/smart_contract/builder.js +14 -0
  29. package/lib/smart_contract/debugger.js +2 -2
  30. package/lib/smart_contract/dsl.js +2 -2
  31. package/lib/smart_contract/index.js +0 -3
  32. package/lib/smart_contract/locks.js +1 -41
  33. package/lib/smart_contract/pels.js +1 -1
  34. package/lib/smart_contract/token.js +1 -1
  35. package/lib/util/deprecate.js +159 -0
  36. package/package.json +19 -82
  37. package/tools/gen-brc220-batch-vector.js +205 -0
  38. package/version.js +1 -1
  39. package/.mocharc.json +0 -5
  40. package/test/address.js +0 -629
  41. package/test/block/block.js +0 -239
  42. package/test/block/blockheader.js +0 -270
  43. package/test/block/merkleblock.js +0 -207
  44. package/test/build/bundle_crypto_shim.js +0 -104
  45. package/test/build/bundle_externals.js +0 -125
  46. package/test/build/bundle_smoke.js +0 -55
  47. package/test/build/esbuild_main.js +0 -65
  48. package/test/build/esm_wrapper.js +0 -73
  49. package/test/build/exports_resolution.js +0 -84
  50. package/test/build/version_sync.js +0 -14
  51. package/test/cli/smoke.js +0 -261
  52. package/test/consensus/base58-vectors.js +0 -120
  53. package/test/consensus/sv-script-vectors.js +0 -81
  54. package/test/consensus/sv-sighash-vectors.js +0 -51
  55. package/test/consensus/sv-tx-vectors.js +0 -48
  56. package/test/credentials-test.js +0 -332
  57. package/test/crypto/backend_selection.js +0 -126
  58. package/test/crypto/bn.js +0 -168
  59. package/test/crypto/ecdsa.js +0 -426
  60. package/test/crypto/elliptic-fixed.js +0 -61
  61. package/test/crypto/hash.browser.js +0 -121
  62. package/test/crypto/hash.js +0 -122
  63. package/test/crypto/point.js +0 -193
  64. package/test/crypto/random.js +0 -105
  65. package/test/crypto/security.js +0 -176
  66. package/test/crypto/shamir.js +0 -177
  67. package/test/crypto/shamir_rngcap.js +0 -29
  68. package/test/crypto/signature.js +0 -399
  69. package/test/data/bip69.json +0 -215
  70. package/test/data/bitcoin-sv/README.md +0 -170
  71. package/test/data/bitcoin-sv/base58_encode_decode.json +0 -14
  72. package/test/data/bitcoin-sv/base58_keys_invalid.json +0 -152
  73. package/test/data/bitcoin-sv/base58_keys_valid.json +0 -452
  74. package/test/data/bitcoin-sv/script_tests.json +0 -2591
  75. package/test/data/bitcoin-sv/sighash.json +0 -1003
  76. package/test/data/bitcoin-sv/tx_invalid.json +0 -285
  77. package/test/data/bitcoin-sv/tx_valid.json +0 -367
  78. package/test/data/bitcoind/base58_keys_invalid.json +0 -152
  79. package/test/data/bitcoind/base58_keys_valid.json +0 -452
  80. package/test/data/bitcoind/blocks.json +0 -27
  81. package/test/data/bitcoind/script_tests.json +0 -2244
  82. package/test/data/bitcoind/sig_canonical.json +0 -7
  83. package/test/data/bitcoind/sig_noncanonical.json +0 -22
  84. package/test/data/bitcoind/tx_invalid.json +0 -177
  85. package/test/data/bitcoind/tx_valid.json +0 -224
  86. package/test/data/blk86756-testnet.dat +0 -0
  87. package/test/data/blk86756-testnet.js +0 -12
  88. package/test/data/blk86756-testnet.json +0 -684
  89. package/test/data/ecdsa.json +0 -230
  90. package/test/data/merkleblocks.js +0 -486
  91. package/test/data/messages.json +0 -22
  92. package/test/data/sighash.json +0 -1004
  93. package/test/data/tx_creation.json +0 -85
  94. package/test/didweb/relationships.js +0 -144
  95. package/test/ecies/bitcore-ecies.js +0 -178
  96. package/test/ecies/electrum-ecies.js +0 -206
  97. package/test/encoding/base58.js +0 -131
  98. package/test/encoding/base58check.js +0 -145
  99. package/test/encoding/bufferreader.js +0 -328
  100. package/test/encoding/bufferwriter.js +0 -160
  101. package/test/encoding/varint.js +0 -104
  102. package/test/gdaf/anchor_no_key_leak.js +0 -146
  103. package/test/gdaf/anchor_spv.js +0 -163
  104. package/test/gdaf/canonicalization.js +0 -106
  105. package/test/gdaf/canonicalize.js +0 -140
  106. package/test/gdaf/zk_prover.js +0 -204
  107. package/test/hdkeys.js +0 -365
  108. package/test/hdprivatekey.js +0 -339
  109. package/test/hdpublickey.js +0 -293
  110. package/test/index.js +0 -16
  111. package/test/ltp/ids.js +0 -74
  112. package/test/ltp/right.js +0 -198
  113. package/test/ltp/verify_failclosed.js +0 -134
  114. package/test/message/message.js +0 -190
  115. package/test/mnemonic/data/fixtures.json +0 -300
  116. package/test/mnemonic/mnemonic.js +0 -277
  117. package/test/mnemonic/mocha.opts +0 -1
  118. package/test/mnemonic/pbkdf2.test.js +0 -43
  119. package/test/networks.js +0 -207
  120. package/test/notaryhash/batch_leaf.js +0 -140
  121. package/test/notaryhash/certificate.js +0 -249
  122. package/test/notaryhash/encoding.js +0 -186
  123. package/test/notaryhash/interop.js +0 -112
  124. package/test/notaryhash/merkle.js +0 -181
  125. package/test/notaryhash/script.js +0 -270
  126. package/test/notaryhash/verify.js +0 -342
  127. package/test/opcode.js +0 -186
  128. package/test/ordinals/bsv20.js +0 -337
  129. package/test/ordinals/inscription.js +0 -319
  130. package/test/ordinals/ordlock.js +0 -613
  131. package/test/privatekey.js +0 -540
  132. package/test/publickey.js +0 -411
  133. package/test/regressions.js +0 -215
  134. package/test/script/chronicle.js +0 -543
  135. package/test/script/defaults.js +0 -160
  136. package/test/script/genesis_limits.js +0 -203
  137. package/test/script/interpreter.js +0 -776
  138. package/test/script/script.js +0 -1259
  139. package/test/script/string_ops.js +0 -88
  140. package/test/security/fail_closed_contracts.js +0 -104
  141. package/test/security/threat_model_coverage.js +0 -31
  142. package/test/smart_contract/covenants.js +0 -245
  143. package/test/smart_contract/dsl_debugger.js +0 -101
  144. package/test/smart_contract/extract_field.js +0 -61
  145. package/test/smart_contract/nonenforcing_guard.js +0 -44
  146. package/test/smart_contract/ordinal_transfer.js +0 -81
  147. package/test/smart_contract/preimage.js +0 -98
  148. package/test/smart_contract/sighash_marketplace.js +0 -108
  149. package/test/smart_contract/token_generalized.js +0 -185
  150. package/test/spv/headerchain.js +0 -86
  151. package/test/spv/merkleproof.js +0 -133
  152. package/test/statuslist/failclosed.js +0 -78
  153. package/test/transaction/deserialize.js +0 -33
  154. package/test/transaction/input/input.js +0 -92
  155. package/test/transaction/input/multisig.js +0 -174
  156. package/test/transaction/input/multisigscripthash.js +0 -111
  157. package/test/transaction/input/publickey.js +0 -68
  158. package/test/transaction/input/publickeyhash.js +0 -59
  159. package/test/transaction/output.js +0 -185
  160. package/test/transaction/sighash.js +0 -91
  161. package/test/transaction/signature.js +0 -127
  162. package/test/transaction/transaction.js +0 -1299
  163. package/test/transaction/unspentoutput.js +0 -97
  164. package/test/types/dts_drift.js +0 -124
  165. package/test/types/surface_honesty.js +0 -102
  166. package/test/util/id.js +0 -72
  167. package/test/util/js.js +0 -76
  168. package/test/util/preconditions.js +0 -79
  169. package/test/vcjwt/interop.js +0 -126
package/test/ltp/ids.js DELETED
@@ -1,74 +0,0 @@
1
- 'use strict'
2
-
3
- /* global describe, it */
4
-
5
- require('chai').should()
6
- var expect = require('chai').expect
7
-
8
- var bsv = require('../../index.js')
9
-
10
- var UUID_V4 = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/
11
-
12
- // A token id is covered by the credential's signature, keys the registry's
13
- // registration/revocation maps, and feeds proof material — so it must be
14
- // unpredictable, not merely distinct.
15
- describe('LTP identifiers', function () {
16
- var generators = [
17
- { name: 'Right._generateUUID', fn: function () { return bsv.LTP.Right._generateUUID() }, format: UUID_V4 },
18
- { name: 'Obligation._generateUUID', fn: function () { return bsv.LTP.Obligation._generateUUID() }, format: UUID_V4 },
19
- { name: 'Registry._generateRegistryId', fn: function () { return bsv.LTP.Registry._generateRegistryId() }, format: /^reg_[0-9a-f]{16}$/ },
20
- { name: 'Registry._generateAuditId', fn: function () { return bsv.LTP.Registry._generateAuditId() }, format: /^audit_[0-9a-f]{32}$/ },
21
- { name: 'Claim._generateBatchId', fn: function () { return bsv.LTP.Claim._generateBatchId() }, format: /^[0-9a-f]{16}$/ }
22
- ]
23
-
24
- var withFrozenMathRandom = function (fn) {
25
- var original = Math.random
26
- Math.random = function () { return 0.5 }
27
- try { return fn() } finally { Math.random = original }
28
- }
29
-
30
- generators.forEach(function (g) {
31
- describe(g.name, function () {
32
- it('keeps its documented format', function () {
33
- g.fn().should.match(g.format)
34
- })
35
-
36
- it('does not repeat', function () {
37
- var seen = {}
38
- for (var i = 0; i < 500; i++) {
39
- var id = g.fn()
40
- expect(seen[id], 'duplicate id: ' + id).to.equal(undefined)
41
- seen[id] = true
42
- }
43
- })
44
-
45
- it('does not draw from the engine PRNG', function () {
46
- withFrozenMathRandom(function () {
47
- var seen = {}
48
- for (var i = 0; i < 100; i++) {
49
- var id = g.fn()
50
- expect(seen[id], 'id is predictable from the engine PRNG: ' + id).to.equal(undefined)
51
- seen[id] = true
52
- }
53
- })
54
- })
55
- })
56
- })
57
-
58
- it('issues unpredictable ids on real tokens', function () {
59
- var type = Object.values(bsv.LTP.Right.RightTypes)[0]
60
- var ids = {}
61
- for (var i = 0; i < 25; i++) {
62
- var token = bsv.LTP.Right.create(
63
- type,
64
- 'did:example:issuer',
65
- 'did:example:subject',
66
- { description: 'test right' }
67
- )
68
- token.id.should.match(/^urn:uuid:/)
69
- token.id.replace('urn:uuid:', '').should.match(UUID_V4)
70
- expect(ids[token.id], 'duplicate token id').to.equal(undefined)
71
- ids[token.id] = true
72
- }
73
- })
74
- })
package/test/ltp/right.js DELETED
@@ -1,198 +0,0 @@
1
- 'use strict'
2
-
3
- /* global describe, it */
4
-
5
- // Regression tests for LTP right-token creation, signing, transfer and the
6
- // instance LTP#createRightToken path. These guard three defects fixed together:
7
- // 1. lib/ltp/right.js defined `_signToken` twice; the second definition
8
- // shadowed the working one and referenced an undefined `hash` — every
9
- // prepareRightToken / transfer / reissue / obligation signing threw
10
- // "hash is not defined". The second definition is the detached-JWS builder
11
- // and is now `_createJWS(hash, signature)`.
12
- // 2. lib/ltp/index.js#createRightToken called the non-existent
13
- // `LTPRight.create(...)`. `RightToken.create` now exists (build-only).
14
- // 3. lib/ltp/index.js#createRightToken signed via the non-existent
15
- // `LTPProof.createSignature`; it now signs via `RightToken._signToken`.
16
-
17
- var expect = require('chai').expect
18
- var bsv = require('../../')
19
-
20
- var LTP = bsv.LTP
21
- var RightToken = LTP.Right
22
-
23
- function newDid () {
24
- var key = bsv.PrivateKey.fromRandom()
25
- return { key: key, did: 'did:key:' + key.toPublicKey().toString() }
26
- }
27
-
28
- describe('LTP right-token signing (regression)', function () {
29
- it('prepareRightToken produces a signed token with a JWS proof and tokenHash', function () {
30
- var issuer = newDid()
31
- var result = RightToken.prepareRightToken(
32
- 'EquityShare', issuer.did, issuer.did,
33
- { spv: 'spv-001', units: 1000000 }, issuer.key, { jurisdiction: 'US-DE' }
34
- )
35
- expect(result.success).to.equal(true)
36
- expect(result.rightToken).to.be.an('object')
37
- expect(result.rightToken.proof).to.be.an('object')
38
- expect(result.rightToken.proof.jws).to.be.a('string').with.length.greaterThan(0)
39
- expect(result.rightToken.tokenHash).to.match(/^[0-9a-f]{64}$/)
40
- })
41
-
42
- it('a prepared right token passes verification (hash integrity)', function () {
43
- var issuer = newDid()
44
- var result = RightToken.prepareRightToken(
45
- 'PropertyTitle', issuer.did, issuer.did,
46
- { parcel: '123 Main St' }, issuer.key, {}
47
- )
48
- expect(result.success).to.equal(true)
49
- var verification = RightToken.prepareRightTokenVerification(result.rightToken, {})
50
- expect(verification.success).to.equal(true)
51
- expect(verification.verification.valid).to.equal(true)
52
- })
53
-
54
- it('RightToken.create builds an unsigned token structure', function () {
55
- var issuer = newDid()
56
- var token = RightToken.create(
57
- 'EquityShare', issuer.did, issuer.did, { spv: 'spv-001' }, issuer.key, {}
58
- )
59
- expect(token).to.be.an('object')
60
- expect(token.credentialSubject.rightType).to.equal('EquityShare')
61
- expect(token.proof).to.equal(undefined)
62
- })
63
-
64
- it('rejects an invalid right type', function () {
65
- var issuer = newDid()
66
- expect(function () {
67
- RightToken.create('NotAType', issuer.did, issuer.did, {}, issuer.key, {})
68
- }).to.throw(/Invalid right type/)
69
- })
70
-
71
- it('prepareRightTokenTransfer signs a transfer to a new owner', function () {
72
- var issuer = newDid()
73
- var created = RightToken.prepareRightToken(
74
- 'EquityShare', issuer.did, issuer.did, { spv: 'spv-001', units: 1000000 }, issuer.key, {}
75
- )
76
- expect(created.success).to.equal(true)
77
- var buyer = newDid()
78
- var transfer = RightToken.prepareRightTokenTransfer(created.rightToken, buyer.did, issuer.key, {})
79
- expect(transfer.success).to.equal(true)
80
- })
81
-
82
- it('LTP#createRightToken (instance) returns a signed, verifiable token', function () {
83
- var issuer = newDid()
84
- var ltp = new LTP()
85
- var res = ltp.createRightToken(
86
- { type: 'EquityShare', owner: issuer.did, spv: 'spv-001', units: 1000000 },
87
- issuer.key, {}
88
- )
89
- expect(res.success).to.equal(true)
90
- expect(res.token.proof.jws).to.be.a('string').with.length.greaterThan(0)
91
- expect(res.token.tokenHash).to.match(/^[0-9a-f]{64}$/)
92
-
93
- var verification = RightToken.prepareRightTokenVerification(res.token, {})
94
- expect(verification.verification.valid).to.equal(true)
95
- })
96
- })
97
-
98
- // Guards for the LTP.prototype wrappers that shared the prior "prepare* vs
99
- // create*" naming mismatch. Before the fix verifyToken called the missing
100
- // LTPProof.verifySignature, transferRight called the missing LTPRight.transfer
101
- // + LTPProof.createSignature, createObligation called the missing
102
- // LTPRight.createObligation, and createSelectiveDisclosure /
103
- // createLegalValidityProof called missing LTPProof.create* entrypoints — all
104
- // threw. RightToken.verifyToken is the new public-key signature verifier.
105
- describe('LTP instance token operations (regression)', function () {
106
- function signedRight () {
107
- var issuer = newDid()
108
- var ltp = new LTP()
109
- var res = ltp.createRightToken(
110
- { type: 'EquityShare', owner: issuer.did, spv: 'spv-001', units: 1000000 },
111
- issuer.key, {}
112
- )
113
- expect(res.success).to.equal(true)
114
- return { issuer: issuer, ltp: ltp, token: res.token }
115
- }
116
-
117
- it('RightToken.verifyToken accepts a token signed by the matching key', function () {
118
- var ctx = signedRight()
119
- var result = RightToken.verifyToken(ctx.token, ctx.issuer.key.toPublicKey().toString())
120
- expect(result.valid).to.equal(true)
121
- expect(result.errors).to.deep.equal([])
122
- })
123
-
124
- it('RightToken.verifyToken rejects a wrong public key', function () {
125
- var ctx = signedRight()
126
- var stranger = newDid()
127
- var result = RightToken.verifyToken(ctx.token, stranger.key.toPublicKey().toString())
128
- expect(result.valid).to.equal(false)
129
- })
130
-
131
- it('RightToken.verifyToken rejects a tampered token', function () {
132
- var ctx = signedRight()
133
- ctx.token.credentialSubject.units = 2
134
- var result = RightToken.verifyToken(ctx.token, ctx.issuer.key.toPublicKey().toString())
135
- expect(result.valid).to.equal(false)
136
- })
137
-
138
- it('LTP#verifyToken validates an instance-created right token', function () {
139
- var ctx = signedRight()
140
- var result = ctx.ltp.verifyToken(ctx.token, ctx.issuer.key.toPublicKey().toString())
141
- expect(result.valid).to.equal(true)
142
- })
143
-
144
- it('LTP#transferRight produces a signed token owned by the new owner', function () {
145
- var ctx = signedRight()
146
- var buyer = newDid()
147
- var res = ctx.ltp.transferRight(ctx.token, buyer.did, ctx.issuer.key, {})
148
- expect(res.success).to.equal(true)
149
- expect(res.token.credentialSubject.id).to.equal(buyer.did)
150
- expect(res.token.proof.jws).to.be.a('string').with.length.greaterThan(0)
151
- expect(res.transferProof).to.be.an('object')
152
- // New token is signed by the transferring (current) owner's key.
153
- var check = RightToken.verifyToken(res.token, ctx.issuer.key.toPublicKey().toString())
154
- expect(check.valid).to.equal(true)
155
- })
156
-
157
- it('LTP#transferRight refuses a non-transferable token', function () {
158
- var issuer = newDid()
159
- var ltp = new LTP()
160
- var created = ltp.createRightToken(
161
- { type: 'EquityShare', owner: issuer.did, spv: 'spv-001' },
162
- issuer.key, { transferable: false }
163
- )
164
- expect(created.success).to.equal(true)
165
- var buyer = newDid()
166
- var res = ltp.transferRight(created.token, buyer.did, issuer.key, {})
167
- expect(res.success).to.equal(false)
168
- })
169
-
170
- it('LTP#createObligation produces a signed correlative obligation', function () {
171
- var ctx = signedRight()
172
- var obligor = newDid()
173
- var res = ctx.ltp.createObligation(
174
- ctx.token,
175
- { obligor: obligor.did, description: 'deliver shares', dueDate: '2030-01-01' },
176
- ctx.issuer.key
177
- )
178
- expect(res.success).to.equal(true)
179
- expect(res.obligation.proof.jws).to.be.a('string').with.length.greaterThan(0)
180
- expect(res.obligation.credentialSubject.correlativeRight).to.equal(ctx.token.id)
181
- expect(res.rightTokenId).to.equal(ctx.token.id)
182
- })
183
-
184
- it('LTP#createSelectiveDisclosure builds a disclosure proof', function () {
185
- var ctx = signedRight()
186
- var res = ctx.ltp.createSelectiveDisclosure(ctx.token, ['credentialSubject.rightType'], 'nonce-123')
187
- expect(res.success).to.equal(true)
188
- expect(res.proof).to.be.an('object')
189
- expect(res.proof.type).to.equal('LegalTokenSelectiveDisclosure')
190
- })
191
-
192
- it('LTP#createLegalValidityProof builds a validity proof', function () {
193
- var ctx = signedRight()
194
- var res = ctx.ltp.createLegalValidityProof(ctx.token, { name: 'US-DE', requirements: [] }, 'nonce-456')
195
- expect(res.success).to.equal(true)
196
- expect(res.proof).to.be.an('object')
197
- })
198
- })
@@ -1,134 +0,0 @@
1
- 'use strict'
2
-
3
- /* global describe, it */
4
-
5
- // Regression guard for the C1–C4 fail-open verification bugs. Before the fix,
6
- // LTP signature verification returned the ECDSA instance (always truthy) or
7
- // skipped the JWS check entirely (a `// TODO`), so a forged token verified as
8
- // valid. These tests feed known-bad signatures/issuers and assert valid===false.
9
-
10
- var expect = require('chai').expect
11
- var bsv = require('../../')
12
-
13
- var LTP = bsv.LTP
14
- var RightToken = LTP.Right
15
- var Obligation = LTP.Obligation
16
-
17
- function newDid () {
18
- var key = bsv.PrivateKey.fromRandom()
19
- return { key: key, did: 'did:key:' + key.toPublicKey().toString() }
20
- }
21
-
22
- describe('LTP verification fails closed (C1–C4 regression)', function () {
23
- it('a genuinely signed right token still verifies as valid', function () {
24
- var issuer = newDid()
25
- var result = RightToken.prepareRightToken(
26
- 'EquityShare', issuer.did, issuer.did,
27
- { spv: 'spv-001', units: 1000 }, issuer.key, {}
28
- )
29
- expect(result.success).to.equal(true)
30
- var v = RightToken.prepareRightTokenVerification(result.rightToken, {})
31
- expect(v.verification.valid, JSON.stringify(v.verification.errors)).to.equal(true)
32
- })
33
-
34
- it('a tampered JWS signature is rejected (C4)', function () {
35
- var issuer = newDid()
36
- var result = RightToken.prepareRightToken(
37
- 'EquityShare', issuer.did, issuer.did, { spv: 'x' }, issuer.key, {}
38
- )
39
- var token = result.rightToken
40
- // Flip the signature: replace it with a signature over different data by a
41
- // different key, re-encoded as a valid-looking JWS.
42
- var attacker = newDid()
43
- var parts = token.proof.jws.split('.')
44
- var bogusSig = bsv.crypto.ECDSA.sign(
45
- bsv.crypto.Hash.sha256(Buffer.from('not the token')), attacker.key
46
- )
47
- token.proof.jws = parts[0] + '.' + parts[1] + '.' + bogusSig.toDER().toString('base64url')
48
-
49
- var v = RightToken.prepareRightTokenVerification(token, {})
50
- expect(v.verification.valid).to.equal(false)
51
- })
52
-
53
- it('a token re-signed by an attacker but attributed to the victim issuer is rejected (C4 binding)', function () {
54
- var victim = newDid()
55
- var attacker = newDid()
56
- var result = RightToken.prepareRightToken(
57
- 'PropertyTitle', victim.did, victim.did, { parcel: '1 Main' }, victim.key, {}
58
- )
59
- var token = result.rightToken
60
- // Attacker re-signs the exact token hash with THEIR key, but leaves issuer =
61
- // victim. Verification must bind to the victim issuer key and reject.
62
- var sig = bsv.crypto.ECDSA.sign(
63
- bsv.crypto.Hash.sha256(Buffer.from(RightToken._canonicalizeToken(token))), attacker.key
64
- )
65
- var parts = token.proof.jws.split('.')
66
- token.proof.jws = parts[0] + '.' + parts[1] + '.' + sig.toDER().toString('base64url')
67
-
68
- var v = RightToken.prepareRightTokenVerification(token, {})
69
- expect(v.verification.valid).to.equal(false)
70
- })
71
-
72
- it('prepareRightTokenTransfer rejects a transfer signed by a non-owner (ownership binding)', function () {
73
- var owner = newDid()
74
- var attacker = newDid()
75
- var res = RightToken.prepareRightToken(
76
- 'EquityShare', owner.did, owner.did, { spv: 't-1' }, owner.key, {}
77
- )
78
- var token = res.rightToken
79
- // Attacker tries to transfer a token they do not own → must be refused.
80
- var bad = RightToken.prepareRightTokenTransfer(token, attacker.did, attacker.key, {})
81
- expect(bad.success).to.equal(false)
82
- // The genuine owner can transfer.
83
- var good = RightToken.prepareRightTokenTransfer(token, attacker.did, owner.key, {})
84
- expect(good.success, JSON.stringify(good.error)).to.equal(true)
85
- })
86
-
87
- it('verifyOwnership rejects a signature by the wrong key (C2)', function () {
88
- var owner = newDid()
89
- var attacker = newDid()
90
- var Resolver = require('../../lib/gdaf/did-resolver')
91
- var did = 'did:smartledger:' + owner.key.toPublicKey().toString()
92
- var msg = 'transfer authorization'
93
- // Signature by attacker, checked against owner's DID → must be false.
94
- var badSig = bsv.crypto.ECDSA.sign(bsv.crypto.Hash.sha256(Buffer.from(msg)), attacker.key)
95
- expect(Resolver.verifyOwnership(did, badSig.toString(), msg)).to.equal(false)
96
- })
97
-
98
- it('verifyAnchor refuses to fabricate success without a chain provider (C3)', async function () {
99
- var Anchor = require('../../lib/gdaf/smartledger-anchor')
100
- var threw = false
101
- try {
102
- await Anchor.verifyAnchor('deadbeef', 'cafe')
103
- } catch (e) {
104
- threw = true
105
- }
106
- expect(threw).to.equal(true)
107
- })
108
-
109
- it('a genuinely signed obligation token still verifies as valid', function () {
110
- var issuer = newDid()
111
- var ob = Obligation.prepareObligationToken(
112
- 'PaymentObligation', issuer.did, issuer.did, { amount: 1 }, issuer.key, {}
113
- )
114
- expect(ob.success).to.equal(true)
115
- var v = Obligation.prepareObligationVerification(ob.obligationToken, {})
116
- expect(v.verification.valid, JSON.stringify(v.verification && v.verification.errors)).to.equal(true)
117
- })
118
-
119
- it('a tampered obligation signature is rejected (C4)', function () {
120
- var issuer = newDid()
121
- var attacker = newDid()
122
- var ob = Obligation.prepareObligationToken(
123
- 'PaymentObligation', issuer.did, issuer.did, { amount: 1 }, issuer.key, {}
124
- )
125
- var tok = ob.obligationToken
126
- var sig = bsv.crypto.ECDSA.sign(
127
- bsv.crypto.Hash.sha256(Buffer.from('forged')), attacker.key
128
- )
129
- var parts = tok.proof.jws.split('.')
130
- tok.proof.jws = parts[0] + '.' + parts[1] + '.' + sig.toDER().toString('base64url')
131
- var v = Obligation.prepareObligationVerification(tok, {})
132
- expect(v.verification.valid).to.equal(false)
133
- })
134
- })
@@ -1,190 +0,0 @@
1
- 'use strict'
2
-
3
- var chai = require('chai')
4
- var expect = chai.expect
5
- var should = chai.should()
6
-
7
- var bsv = require('../../')
8
- var Address = bsv.Address
9
- var Signature = bsv.crypto.Signature
10
- var PrivateKey = bsv.PrivateKey
11
- var Message = require('../../lib/message')
12
-
13
- describe('Message', function () {
14
- var address = 'n1ZCYg9YXtB5XCZazLxSmPDa8iwJRZHhGx'
15
- var badAddress = 'mmRcrB5fTwgxaFJmVLNtaG8SV454y1E3kC'
16
- var privateKey = bsv.PrivateKey.fromWIF('cPBn5A4ikZvBTQ8D7NnvHZYCAxzDZ5Z2TSGW2LkyPiLxqYaJPBW4')
17
- var text = 'hello, world'
18
- var textBuffer = Buffer.from('hello, world')
19
- var bufferData = Buffer.from('H/DIn8uA1scAuKLlCx+/9LnAcJtwQQ0PmcPrJUq90aboLv3fH5fFvY+vmbfOSFEtGarznYli6ShPr9RXwY9UrIY=', 'base64')
20
- var signatureString = 'H/DIn8uA1scAuKLlCx+/9LnAcJtwQQ0PmcPrJUq90aboLv3fH5fFvY+vmbfOSFEtGarznYli6ShPr9RXwY9UrIY='
21
-
22
- var badSignatureString = 'H69qZ4mbZCcvXk7CWjptD5ypnYVLvQ3eMXLM8+1gX21SLH/GaFnAjQrDn37+TDw79i9zHhbiMMwhtvTwnPigZ6k='
23
-
24
- var signature = Signature.fromCompact(Buffer.from(signatureString, 'base64'))
25
- var badSignature = Signature.fromCompact(Buffer.from(badSignatureString, 'base64'))
26
-
27
- var publicKey = privateKey.toPublicKey()
28
-
29
- it('will error with incorrect message type', function () {
30
- expect(function () {
31
- return new Message(new Date())
32
- }).to.throw('First argument should be a string')
33
- })
34
-
35
- it('will instantiate without "new"', function () {
36
- var message = Message(text)
37
- should.exist(message)
38
- })
39
-
40
- var signature2
41
- var signature3
42
-
43
- it('can sign a message', function () {
44
- var message2 = new Message(text)
45
- signature2 = message2._sign(privateKey)
46
- signature3 = Message(text).sign(privateKey)
47
- should.exist(signature2)
48
- should.exist(signature3)
49
- })
50
-
51
- it('can sign a message (buffer representation of utf-8 string)', function () {
52
- var messageBuf = new Message(textBuffer)
53
- var signatureBuffer1 = messageBuf.sign(privateKey)
54
- var signatureBuffer2 = Message(textBuffer).sign(privateKey)
55
- should.exist(signatureBuffer1)
56
- should.exist(signatureBuffer2)
57
- var verified = messageBuf.verify(address, signatureBuffer1.toString()) && messageBuf.verify(address, signatureBuffer2.toString())
58
- verified.should.equal(true)
59
- })
60
-
61
- it('can sign a message (buffer representation of arbitrary data)', function () {
62
- var messageBuf = new Message(bufferData)
63
- var signatureBuffer1 = messageBuf.sign(privateKey)
64
- var signatureBuffer2 = Message(bufferData).sign(privateKey)
65
- should.exist(signatureBuffer1)
66
- should.exist(signatureBuffer2)
67
- var verified = messageBuf.verify(address, signatureBuffer1.toString()) && messageBuf.verify(address, signatureBuffer2.toString())
68
- verified.should.equal(true)
69
- })
70
-
71
- it('sign will error with incorrect private key argument', function () {
72
- expect(function () {
73
- var message3 = new Message(text)
74
- return message3.sign('not a private key')
75
- }).to.throw('First argument should be an instance of PrivateKey')
76
- })
77
-
78
- it('can verify a message with signature', function () {
79
- var message4 = new Message(text)
80
- var verified = message4._verify(publicKey, signature2)
81
- verified.should.equal(true)
82
- })
83
-
84
- it('can verify a message with existing signature', function () {
85
- var message5 = new Message(text)
86
- var verified = message5._verify(publicKey, signature)
87
- verified.should.equal(true)
88
- })
89
-
90
- it('verify will error with incorrect public key argument', function () {
91
- expect(function () {
92
- var message6 = new Message(text)
93
- return message6._verify('not a public key', signature)
94
- }).to.throw('First argument should be an instance of PublicKey')
95
- })
96
-
97
- it('verify will error with incorrect signature argument', function () {
98
- expect(function () {
99
- var message7 = new Message(text)
100
- return message7._verify(publicKey, 'not a signature')
101
- }).to.throw('Second argument should be an instance of Signature')
102
- })
103
-
104
- it('verify will correctly identify a bad signature', function () {
105
- var message8 = new Message(text)
106
- var verified = message8._verify(publicKey, badSignature)
107
- should.exist(message8.error)
108
- verified.should.equal(false)
109
- })
110
-
111
- it('can verify a message with address and generated signature string', function () {
112
- var message9 = new Message(text)
113
- var verified = message9.verify(address, signature3)
114
- should.not.exist(message9.error)
115
- verified.should.equal(true)
116
- })
117
-
118
- it('will not verify with address mismatch', function () {
119
- var message10 = new Message(text)
120
- var verified = message10.verify(badAddress, signatureString)
121
- should.exist(message10.error)
122
- verified.should.equal(false)
123
- })
124
-
125
- it('will verify with an uncompressed pubkey', function () {
126
- var privateKey = new bsv.PrivateKey('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss')
127
- var message = new Message('This is an example of a signed message.')
128
- var signature = message.sign(privateKey)
129
- var verified = message.verify(privateKey.toAddress(), signature)
130
- verified.should.equal(true)
131
- })
132
-
133
- it('can chain methods', function () {
134
- var verified = Message(text).verify(address, signatureString)
135
- verified.should.equal(true)
136
- })
137
-
138
- describe('@sign', function () {
139
- it('should sign and verify', function () {
140
- var privateKey = PrivateKey.fromString('L3nrwRssVKMkScjejmmu6kmq4hSuUApJnFdW1hGvBP69jnQuKYCh')
141
- var address = privateKey.toAddress()
142
- var message = 'this is the message that I want to sign'
143
- var sig = Message.sign(message, privateKey)
144
- sig.toString().should.equal('II5uoh3m0yQ+/5va+1acFQhPaEdTnFFiG/PiKpoC+kpgHbmIk3aWHQ6tyPGgNCUmKlSfwzcP6qVAxuUt0PwDzpg=')
145
- var verify = Message.verify(message, address, sig)
146
- verify.should.equal(true)
147
- })
148
- })
149
-
150
- describe('#json', function () {
151
- it('roundtrip to-from-to', function () {
152
- var json = new Message(text).toJSON()
153
- var message = Message.fromJSON(json)
154
- message.toString().should.equal(Buffer.from(text).toString())
155
- })
156
-
157
- it('checks that the string parameter is valid JSON', function () {
158
- expect(function () {
159
- return Message.fromJSON('¹')
160
- }).to.throw()
161
- })
162
- })
163
-
164
- describe('#toString', function () {
165
- it('message string', function () {
166
- var message = new Message(text)
167
- message.toString().should.equal(text)
168
- })
169
-
170
- it('roundtrip to-from-to', function () {
171
- var str = new Message(text).toString()
172
- var message = Message.fromString(str)
173
- message.toString().should.equal(text)
174
- })
175
- })
176
-
177
- describe('#inspect', function () {
178
- it('should output formatted output correctly', function () {
179
- var message = new Message(text)
180
- var output = '<Message: ' + text + '>'
181
- message.inspect().should.equal(output)
182
- })
183
- })
184
-
185
- it('accepts Address for verification', function () {
186
- var verified = Message(text)
187
- .verify(new Address(address), signatureString)
188
- verified.should.equal(true)
189
- })
190
- })