@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/ecdsa.js
DELETED
|
@@ -1,426 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
var ECDSA = require('../../lib/crypto/ecdsa')
|
|
4
|
-
var Hash = require('../../lib/crypto/hash')
|
|
5
|
-
var Privkey = require('../../lib/privatekey')
|
|
6
|
-
var Pubkey = require('../../lib/publickey')
|
|
7
|
-
var Signature = require('../../lib/crypto/signature')
|
|
8
|
-
var BN = require('../../lib/crypto/bn')
|
|
9
|
-
var point = require('../../lib/crypto/point')
|
|
10
|
-
var should = require('chai').should()
|
|
11
|
-
var vectors = require('../data/ecdsa')
|
|
12
|
-
|
|
13
|
-
describe('ECDSA', function () {
|
|
14
|
-
it('instantiation', function () {
|
|
15
|
-
var ecdsa = new ECDSA()
|
|
16
|
-
should.exist(ecdsa)
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
var ecdsa = new ECDSA()
|
|
20
|
-
ecdsa.hashbuf = Hash.sha256(Buffer.from('test data'))
|
|
21
|
-
ecdsa.privkey = new Privkey(BN.fromBuffer(
|
|
22
|
-
Buffer.from('fee0a1f7afebf9d2a5a80c0c98a31c709681cce195cbcd06342b517970c0be1e', 'hex')
|
|
23
|
-
))
|
|
24
|
-
ecdsa.privkey2pubkey()
|
|
25
|
-
|
|
26
|
-
describe('#set', function () {
|
|
27
|
-
it('sets hashbuf', function () {
|
|
28
|
-
should.exist(ECDSA().set({
|
|
29
|
-
hashbuf: ecdsa.hashbuf
|
|
30
|
-
}).hashbuf)
|
|
31
|
-
})
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
describe('#calci', function () {
|
|
35
|
-
it('calculates i correctly', function () {
|
|
36
|
-
ecdsa.randomK()
|
|
37
|
-
ecdsa.sign()
|
|
38
|
-
ecdsa.calci()
|
|
39
|
-
should.exist(ecdsa.sig.i)
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
it('calulates this known i', function () {
|
|
43
|
-
var hashbuf = Hash.sha256(Buffer.from('some data'))
|
|
44
|
-
var r = new BN('71706645040721865894779025947914615666559616020894583599959600180037551395766', 10)
|
|
45
|
-
var s = new BN('109412465507152403114191008482955798903072313614214706891149785278625167723646', 10)
|
|
46
|
-
var ecdsa = new ECDSA({
|
|
47
|
-
privkey: new Privkey(BN.fromBuffer(Hash.sha256(Buffer.from('test')))),
|
|
48
|
-
hashbuf: hashbuf,
|
|
49
|
-
sig: new Signature({
|
|
50
|
-
r: r,
|
|
51
|
-
s: s
|
|
52
|
-
})
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
ecdsa.calci()
|
|
56
|
-
ecdsa.sig.i.should.equal(1)
|
|
57
|
-
})
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
describe('#fromString', function () {
|
|
61
|
-
it('round trip with fromString', function () {
|
|
62
|
-
var str = ecdsa.toString()
|
|
63
|
-
var ecdsa2 = ECDSA.fromString(str)
|
|
64
|
-
should.exist(ecdsa2.hashbuf)
|
|
65
|
-
should.exist(ecdsa2.privkey)
|
|
66
|
-
})
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
describe('#randomK', function () {
|
|
70
|
-
it('should generate a new random k when called twice in a row', function () {
|
|
71
|
-
ecdsa.randomK()
|
|
72
|
-
var k1 = ecdsa.k
|
|
73
|
-
ecdsa.randomK()
|
|
74
|
-
var k2 = ecdsa.k;
|
|
75
|
-
(k1.cmp(k2) === 0).should.equal(false)
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
it('should generate a random k that is (almost always) greater than this relatively small number', function () {
|
|
79
|
-
ecdsa.randomK()
|
|
80
|
-
var k1 = ecdsa.k
|
|
81
|
-
var k2 = new BN(Math.pow(2, 32)).mul(new BN(Math.pow(2, 32))).mul(new BN(Math.pow(2, 32)))
|
|
82
|
-
k2.gt(k1).should.equal(false)
|
|
83
|
-
})
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
describe('#deterministicK', function () {
|
|
87
|
-
it('should generate the same deterministic k', function () {
|
|
88
|
-
ecdsa.deterministicK()
|
|
89
|
-
ecdsa.k.toBuffer().toString('hex')
|
|
90
|
-
.should.equal('fcce1de7a9bcd6b2d3defade6afa1913fb9229e3b7ddf4749b55c4848b2a196e')
|
|
91
|
-
})
|
|
92
|
-
it('should generate the same deterministic k if badrs is set', function () {
|
|
93
|
-
ecdsa.deterministicK(0)
|
|
94
|
-
ecdsa.k.toBuffer().toString('hex')
|
|
95
|
-
.should.equal('fcce1de7a9bcd6b2d3defade6afa1913fb9229e3b7ddf4749b55c4848b2a196e')
|
|
96
|
-
ecdsa.deterministicK(1)
|
|
97
|
-
ecdsa.k.toBuffer().toString('hex')
|
|
98
|
-
.should.not.equal('fcce1de7a9bcd6b2d3defade6afa1913fb9229e3b7ddf4749b55c4848b2a196e')
|
|
99
|
-
ecdsa.k.toBuffer().toString('hex')
|
|
100
|
-
.should.equal('727fbcb59eb48b1d7d46f95a04991fc512eb9dbf9105628e3aec87428df28fd8')
|
|
101
|
-
})
|
|
102
|
-
it('should compute this test vector correctly', function () {
|
|
103
|
-
// test fixture from bitcoinjs
|
|
104
|
-
// https://github.com/bitcoinjs/bitcoinjs-lib/blob/10630873ebaa42381c5871e20336fbfb46564ac8/test/fixtures/ecdsa.json#L6
|
|
105
|
-
var ecdsa = new ECDSA()
|
|
106
|
-
ecdsa.hashbuf = Hash.sha256(Buffer.from('Everything should be made as simple as possible, but not simpler.'))
|
|
107
|
-
ecdsa.privkey = new Privkey(new BN(1))
|
|
108
|
-
ecdsa.privkey2pubkey()
|
|
109
|
-
ecdsa.deterministicK()
|
|
110
|
-
ecdsa.k.toBuffer().toString('hex')
|
|
111
|
-
.should.equal('ec633bd56a5774a0940cb97e27a9e4e51dc94af737596a0c5cbb3d30332d92a5')
|
|
112
|
-
ecdsa.sign()
|
|
113
|
-
ecdsa.sig.r.toString()
|
|
114
|
-
.should.equal('23362334225185207751494092901091441011938859014081160902781146257181456271561')
|
|
115
|
-
ecdsa.sig.s.toString()
|
|
116
|
-
.should.equal('50433721247292933944369538617440297985091596895097604618403996029256432099938')
|
|
117
|
-
})
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
describe('nonce reuse', function () {
|
|
121
|
-
// Signing two different messages under one nonce reveals the private key.
|
|
122
|
-
var N = point.getN()
|
|
123
|
-
var h1 = Hash.sha256(Buffer.from('pay alice 1 coin'))
|
|
124
|
-
var h2 = Hash.sha256(Buffer.from('pay bob 2 coins'))
|
|
125
|
-
|
|
126
|
-
var freshSigner = function () {
|
|
127
|
-
return ECDSA().set({
|
|
128
|
-
privkey: new Privkey(BN.fromBuffer(Buffer.from(
|
|
129
|
-
'fee0a1f7afebf9d2a5a80c0c98a31c709681cce195cbcd06342b517970c0be1e', 'hex')))
|
|
130
|
-
})
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
it('does not reuse k when one instance signs two different messages', function () {
|
|
134
|
-
var e = freshSigner()
|
|
135
|
-
var sig1 = e.set({ hashbuf: h1 }).sign().sig
|
|
136
|
-
var k1 = e.k
|
|
137
|
-
var sig2 = e.set({ hashbuf: h2 }).sign().sig
|
|
138
|
-
var k2 = e.k;
|
|
139
|
-
(k1.cmp(k2) === 0).should.equal(false)
|
|
140
|
-
sig1.r.eq(sig2.r).should.equal(false)
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
it('does not reuse k across signRandomK calls on one instance', function () {
|
|
144
|
-
var e = freshSigner()
|
|
145
|
-
var sig1 = e.set({ hashbuf: h1 }).signRandomK().sig
|
|
146
|
-
var sig2 = e.set({ hashbuf: h2 }).sign().sig
|
|
147
|
-
sig1.r.eq(sig2.r).should.equal(false)
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
it('does not leak the private key from two signatures by one instance', function () {
|
|
151
|
-
var e = freshSigner()
|
|
152
|
-
var d = e.privkey.bn
|
|
153
|
-
var sig1 = e.set({ hashbuf: h1 }).sign().sig
|
|
154
|
-
var sig2 = e.set({ hashbuf: h2 }).sign().sig
|
|
155
|
-
|
|
156
|
-
// toLowS may have flipped either s, so try every sign combination.
|
|
157
|
-
var red = BN.red(N)
|
|
158
|
-
var inv = function (x) { return x.toRed(red).redInvm().fromRed() }
|
|
159
|
-
var mul = function (a, b) { return a.toRed(red).redMul(b.toRed(red)).fromRed() }
|
|
160
|
-
var e1 = BN.fromBuffer(h1)
|
|
161
|
-
var e2 = BN.fromBuffer(h2)
|
|
162
|
-
var recovered = false
|
|
163
|
-
;[1, -1].forEach(function (f1) {
|
|
164
|
-
;[1, -1].forEach(function (f2) {
|
|
165
|
-
var S1 = f1 === 1 ? sig1.s : N.sub(sig1.s)
|
|
166
|
-
var S2 = f2 === 1 ? sig2.s : N.sub(sig2.s)
|
|
167
|
-
var diff = S1.sub(S2).umod(N)
|
|
168
|
-
if (diff.isZero()) return
|
|
169
|
-
var k = mul(e1.sub(e2).umod(N), inv(diff))
|
|
170
|
-
var guess = mul(S1.mul(k).umod(N).sub(e1).umod(N), inv(sig1.r))
|
|
171
|
-
if (guess.toString(16) === d.toString(16)) recovered = true
|
|
172
|
-
})
|
|
173
|
-
})
|
|
174
|
-
recovered.should.equal(false)
|
|
175
|
-
})
|
|
176
|
-
|
|
177
|
-
it('still honours an explicitly supplied k for a single signature', function () {
|
|
178
|
-
var k = new BN('114860389168127852803919605627759231199925249596762615988727970217268189974335', 10)
|
|
179
|
-
var a = freshSigner().set({ hashbuf: h1, k: k })
|
|
180
|
-
var b = freshSigner().set({ hashbuf: h1, k: k })
|
|
181
|
-
a.sign().sig.r.eq(b.sign().sig.r).should.equal(true)
|
|
182
|
-
a.k.eq(k).should.equal(true)
|
|
183
|
-
})
|
|
184
|
-
|
|
185
|
-
it('signs the same message deterministically across instances', function () {
|
|
186
|
-
var a = freshSigner().set({ hashbuf: h1 }).sign().sig
|
|
187
|
-
var b = freshSigner().set({ hashbuf: h1 }).sign().sig
|
|
188
|
-
a.r.eq(b.r).should.equal(true)
|
|
189
|
-
a.s.eq(b.s).should.equal(true)
|
|
190
|
-
})
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
describe('#toPublicKey', function () {
|
|
194
|
-
it('should calculate the correct public key', function () {
|
|
195
|
-
ecdsa.k = new BN('114860389168127852803919605627759231199925249596762615988727970217268189974335', 10)
|
|
196
|
-
ecdsa.sign()
|
|
197
|
-
ecdsa.sig.i = 0
|
|
198
|
-
var pubkey = ecdsa.toPublicKey()
|
|
199
|
-
pubkey.point.eq(ecdsa.pubkey.point).should.equal(true)
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
it('should calculate the correct public key for this signature with low s', function () {
|
|
203
|
-
ecdsa.k = new BN('114860389168127852803919605627759231199925249596762615988727970217268189974335', 10)
|
|
204
|
-
ecdsa.sig = Signature.fromString('3045022100ec3cfe0e335791ad278b4ec8eac93d0347' +
|
|
205
|
-
'a97877bb1d54d35d189e225c15f6650220278cf15b05ce47fb37d2233802899d94c774d5480bba9f0f2d996baa13370c43')
|
|
206
|
-
ecdsa.sig.i = 0
|
|
207
|
-
var pubkey = ecdsa.toPublicKey()
|
|
208
|
-
pubkey.point.eq(ecdsa.pubkey.point).should.equal(true)
|
|
209
|
-
})
|
|
210
|
-
|
|
211
|
-
it('should calculate the correct public key for this signature with high s', function () {
|
|
212
|
-
ecdsa.k = new BN('114860389168127852803919605627759231199925249596762615988727970217268189974335', 10)
|
|
213
|
-
ecdsa.sign()
|
|
214
|
-
ecdsa.sig = Signature.fromString('3046022100ec3cfe0e335791ad278b4ec8eac93d0347' +
|
|
215
|
-
'a97877bb1d54d35d189e225c15f665022100d8730ea4fa31b804c82ddcc7fd766269f33a079ea38e012c9238f2e2bcff34fe')
|
|
216
|
-
ecdsa.sig.i = 1
|
|
217
|
-
var pubkey = ecdsa.toPublicKey()
|
|
218
|
-
pubkey.point.eq(ecdsa.pubkey.point).should.equal(true)
|
|
219
|
-
})
|
|
220
|
-
})
|
|
221
|
-
|
|
222
|
-
describe('#sigError', function () {
|
|
223
|
-
it('should return an error if the hash is invalid', function () {
|
|
224
|
-
var ecdsa = new ECDSA()
|
|
225
|
-
ecdsa.sigError().should.equal('hashbuf must be a 32 byte buffer')
|
|
226
|
-
})
|
|
227
|
-
|
|
228
|
-
it('should return an error if r, s are invalid', function () {
|
|
229
|
-
var ecdsa = new ECDSA()
|
|
230
|
-
ecdsa.hashbuf = Hash.sha256(Buffer.from('test'))
|
|
231
|
-
var pk = Pubkey.fromDER(Buffer.from('041ff0fe0f7b15ffaa85ff9f4744d539139c252a49' +
|
|
232
|
-
'710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', 'hex'))
|
|
233
|
-
ecdsa.pubkey = pk
|
|
234
|
-
ecdsa.sig = new Signature()
|
|
235
|
-
ecdsa.sig.r = new BN(0)
|
|
236
|
-
ecdsa.sig.s = new BN(0)
|
|
237
|
-
ecdsa.sigError().should.equal('r and s not in range')
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
it('should return an error if the signature is incorrect', function () {
|
|
241
|
-
ecdsa.sig = Signature.fromString('3046022100e9915e6236695f093a4128ac2a956c40' +
|
|
242
|
-
'ed971531de2f4f41ba05fac7e2bd019c02210094e6a4a769cc7f2a8ab3db696c7cd8d56bcdbfff860a8c81de4bc6a798b90827')
|
|
243
|
-
ecdsa.sig.r = ecdsa.sig.r.add(new BN(1))
|
|
244
|
-
ecdsa.sigError().should.equal('Invalid signature')
|
|
245
|
-
})
|
|
246
|
-
})
|
|
247
|
-
|
|
248
|
-
describe('#sign', function () {
|
|
249
|
-
it('should create a valid signature', function () {
|
|
250
|
-
ecdsa.randomK()
|
|
251
|
-
ecdsa.sign()
|
|
252
|
-
ecdsa.verify().should.equal(true)
|
|
253
|
-
})
|
|
254
|
-
|
|
255
|
-
it('should should throw an error if hashbuf is not 32 bytes', function () {
|
|
256
|
-
var ecdsa2 = ECDSA().set({
|
|
257
|
-
hashbuf: ecdsa.hashbuf.slice(0, 31),
|
|
258
|
-
privkey: ecdsa.privkey
|
|
259
|
-
})
|
|
260
|
-
ecdsa2.randomK()
|
|
261
|
-
ecdsa2.sign.bind(ecdsa2).should.throw('hashbuf must be a 32 byte buffer')
|
|
262
|
-
})
|
|
263
|
-
|
|
264
|
-
it('should default to deterministicK', function () {
|
|
265
|
-
var ecdsa2 = new ECDSA(ecdsa)
|
|
266
|
-
ecdsa2.k = undefined
|
|
267
|
-
var called = 0
|
|
268
|
-
var deterministicK = ecdsa2.deterministicK.bind(ecdsa2)
|
|
269
|
-
ecdsa2.deterministicK = function () {
|
|
270
|
-
deterministicK()
|
|
271
|
-
called++
|
|
272
|
-
}
|
|
273
|
-
ecdsa2.sign()
|
|
274
|
-
called.should.equal(1)
|
|
275
|
-
})
|
|
276
|
-
|
|
277
|
-
it('should generate right K', function () {
|
|
278
|
-
var msg1 = Buffer.from('52204d20fd0131ae1afd173fd80a3a746d2dcc0cddced8c9dc3d61cc7ab6e966', 'hex')
|
|
279
|
-
var msg2 = [].reverse.call(Buffer.from(msg1))
|
|
280
|
-
var pk = Buffer.from('16f243e962c59e71e54189e67e66cf2440a1334514c09c00ddcc21632bac9808', 'hex')
|
|
281
|
-
var signature1 = ECDSA.sign(msg1, Privkey.fromBuffer(pk)).toBuffer().toString('hex')
|
|
282
|
-
var signature2 = ECDSA.sign(msg2, Privkey.fromBuffer(pk), 'little').toBuffer().toString('hex')
|
|
283
|
-
signature1.should.equal(signature2)
|
|
284
|
-
})
|
|
285
|
-
})
|
|
286
|
-
|
|
287
|
-
describe('#toString', function () {
|
|
288
|
-
it('should convert this to a string', function () {
|
|
289
|
-
var str = ecdsa.toString();
|
|
290
|
-
(typeof str === 'string').should.equal(true)
|
|
291
|
-
})
|
|
292
|
-
})
|
|
293
|
-
|
|
294
|
-
describe('signing and verification', function () {
|
|
295
|
-
describe('@sign', function () {
|
|
296
|
-
it('should produce a signature', function () {
|
|
297
|
-
var sig = ECDSA.sign(ecdsa.hashbuf, ecdsa.privkey)
|
|
298
|
-
;(sig instanceof Signature).should.equal(true)
|
|
299
|
-
})
|
|
300
|
-
|
|
301
|
-
it('should produce a signaturei', function () {
|
|
302
|
-
var sig = ECDSA.signWithCalcI(ecdsa.hashbuf, ecdsa.privkey)
|
|
303
|
-
;(sig instanceof Signature).should.equal(true)
|
|
304
|
-
should.exist(sig.i)
|
|
305
|
-
sig.toCompact().toString('base64').should.equal('IF7ucRrxMczOWYg28NkA+krY4aXx9XgT7KVglwpLEqqyIUtqBrrU5mSDQqOm0ETZ47KdQEMv121aWkxO7P1hbGk=')
|
|
306
|
-
})
|
|
307
|
-
|
|
308
|
-
it('should produce a signature', function () {
|
|
309
|
-
var sig = ECDSA.signRandomK(ecdsa.hashbuf, ecdsa.privkey)
|
|
310
|
-
;(sig instanceof Signature).should.equal(true)
|
|
311
|
-
var sig2 = ECDSA.signRandomK(ecdsa.hashbuf, ecdsa.privkey)
|
|
312
|
-
;(sig2 instanceof Signature).should.equal(true)
|
|
313
|
-
sig.toString().should.not.equal(sig2.toString())
|
|
314
|
-
})
|
|
315
|
-
|
|
316
|
-
it('should produce a signature, and be different when called twice', function () {
|
|
317
|
-
ecdsa.signRandomK()
|
|
318
|
-
should.exist(ecdsa.sig)
|
|
319
|
-
var ecdsa2 = ECDSA(ecdsa)
|
|
320
|
-
ecdsa2.signRandomK()
|
|
321
|
-
ecdsa.sig.toString().should.not.equal(ecdsa2.sig.toString())
|
|
322
|
-
})
|
|
323
|
-
})
|
|
324
|
-
|
|
325
|
-
describe('#verify', function () {
|
|
326
|
-
it('should verify a signature that was just signed', function () {
|
|
327
|
-
ecdsa.sig = Signature.fromString('3046022100e9915e6236695f093a4128ac2a956c' +
|
|
328
|
-
'40ed971531de2f4f41ba05fac7e2bd019c02210094e6a4a769cc7f2a8ab3db696c7cd8d56bcdbfff860a8c81de4bc6a798b90827')
|
|
329
|
-
ecdsa.verify().should.equal(true)
|
|
330
|
-
})
|
|
331
|
-
// 7.0: verify() returns a strict boolean, not the (always-truthy) instance.
|
|
332
|
-
// A forged signature must be REJECTED by `if (ecdsa.verify())`, which was the
|
|
333
|
-
// whole point of removing the trap.
|
|
334
|
-
it('returns a strict boolean, not the instance (7.0 trap closed)', function () {
|
|
335
|
-
ecdsa.signRandomK()
|
|
336
|
-
var result = ecdsa.verify()
|
|
337
|
-
result.should.be.a('boolean')
|
|
338
|
-
result.should.equal(true)
|
|
339
|
-
// Forge the signature: the return value itself must be falsy.
|
|
340
|
-
var forged = new ECDSA()
|
|
341
|
-
forged.hashbuf = ecdsa.hashbuf
|
|
342
|
-
forged.pubkey = ecdsa.pubkey
|
|
343
|
-
forged.sig = new Signature(ecdsa.sig.r.add(new BN(1)), ecdsa.sig.s)
|
|
344
|
-
forged.verify().should.equal(false)
|
|
345
|
-
;(!!forged.verify()).should.equal(false) // `if (forged.verify())` does NOT enter
|
|
346
|
-
})
|
|
347
|
-
it('verifyBool() remains a strict-boolean alias', function () {
|
|
348
|
-
ecdsa.signRandomK()
|
|
349
|
-
ecdsa.verifyBool().should.equal(true)
|
|
350
|
-
var forged = new ECDSA()
|
|
351
|
-
forged.hashbuf = ecdsa.hashbuf
|
|
352
|
-
forged.pubkey = ecdsa.pubkey
|
|
353
|
-
forged.sig = new Signature(ecdsa.sig.r.add(new BN(1)), ecdsa.sig.s)
|
|
354
|
-
forged.verifyBool().should.equal(false)
|
|
355
|
-
})
|
|
356
|
-
it('should verify this known good signature', function () {
|
|
357
|
-
ecdsa.signRandomK()
|
|
358
|
-
ecdsa.verify().should.equal(true)
|
|
359
|
-
})
|
|
360
|
-
it('should verify a valid signature, and unverify an invalid signature', function () {
|
|
361
|
-
var sig = ECDSA.sign(ecdsa.hashbuf, ecdsa.privkey)
|
|
362
|
-
ECDSA.verify(ecdsa.hashbuf, sig, ecdsa.pubkey).should.equal(true)
|
|
363
|
-
var fakesig = new Signature(sig.r.add(new BN(1)), sig.s)
|
|
364
|
-
ECDSA.verify(ecdsa.hashbuf, fakesig, ecdsa.pubkey).should.equal(false)
|
|
365
|
-
})
|
|
366
|
-
it('should work with big and little endian', function () {
|
|
367
|
-
var sig = ECDSA.sign(ecdsa.hashbuf, ecdsa.privkey, 'big')
|
|
368
|
-
ECDSA.verify(ecdsa.hashbuf, sig, ecdsa.pubkey, 'big').should.equal(true)
|
|
369
|
-
ECDSA.verify(ecdsa.hashbuf, sig, ecdsa.pubkey, 'little').should.equal(false)
|
|
370
|
-
sig = ECDSA.sign(ecdsa.hashbuf, ecdsa.privkey, 'little')
|
|
371
|
-
ECDSA.verify(ecdsa.hashbuf, sig, ecdsa.pubkey, 'big').should.equal(false)
|
|
372
|
-
ECDSA.verify(ecdsa.hashbuf, sig, ecdsa.pubkey, 'little').should.equal(true)
|
|
373
|
-
})
|
|
374
|
-
})
|
|
375
|
-
|
|
376
|
-
describe('vectors', function () {
|
|
377
|
-
vectors.valid.forEach(function (obj, i) {
|
|
378
|
-
it('should validate valid vector ' + i, function () {
|
|
379
|
-
var ecdsa = ECDSA().set({
|
|
380
|
-
privkey: new Privkey(BN.fromBuffer(Buffer.from(obj.d, 'hex'))),
|
|
381
|
-
k: BN.fromBuffer(Buffer.from(obj.k, 'hex')),
|
|
382
|
-
hashbuf: Hash.sha256(Buffer.from(obj.message)),
|
|
383
|
-
sig: new Signature().set({
|
|
384
|
-
r: new BN(obj.signature.r),
|
|
385
|
-
s: new BN(obj.signature.s),
|
|
386
|
-
i: obj.i
|
|
387
|
-
})
|
|
388
|
-
})
|
|
389
|
-
var ecdsa2 = ECDSA(ecdsa)
|
|
390
|
-
ecdsa2.k = undefined
|
|
391
|
-
ecdsa2.sign()
|
|
392
|
-
ecdsa2.calci()
|
|
393
|
-
ecdsa2.k.toString().should.equal(ecdsa.k.toString())
|
|
394
|
-
ecdsa2.sig.toString().should.equal(ecdsa.sig.toString())
|
|
395
|
-
ecdsa2.sig.i.should.equal(ecdsa.sig.i)
|
|
396
|
-
ecdsa.verify().should.equal(true)
|
|
397
|
-
})
|
|
398
|
-
})
|
|
399
|
-
|
|
400
|
-
vectors.invalid.sigError.forEach(function (obj, i) {
|
|
401
|
-
it('should validate invalid.sigError vector ' + i + ': ' + obj.description, function () {
|
|
402
|
-
var ecdsa = ECDSA().set({
|
|
403
|
-
pubkey: Pubkey.fromPoint(point.fromX(true, 1)),
|
|
404
|
-
sig: new Signature(new BN(obj.signature.r), new BN(obj.signature.s)),
|
|
405
|
-
hashbuf: Hash.sha256(Buffer.from(obj.message))
|
|
406
|
-
})
|
|
407
|
-
ecdsa.sigError().should.equal(obj.exception)
|
|
408
|
-
})
|
|
409
|
-
})
|
|
410
|
-
|
|
411
|
-
vectors.deterministicK.forEach(function (obj, i) {
|
|
412
|
-
it('should validate deterministicK vector ' + i, function () {
|
|
413
|
-
var hashbuf = Hash.sha256(Buffer.from(obj.message))
|
|
414
|
-
var privkey = Privkey(BN.fromBuffer(Buffer.from(obj.privkey, 'hex')), 'mainnet')
|
|
415
|
-
var ecdsa = ECDSA({
|
|
416
|
-
privkey: privkey,
|
|
417
|
-
hashbuf: hashbuf
|
|
418
|
-
})
|
|
419
|
-
ecdsa.deterministicK(0).k.toString('hex').should.equal(obj.k_bad00)
|
|
420
|
-
ecdsa.deterministicK(1).k.toString('hex').should.equal(obj.k_bad01)
|
|
421
|
-
ecdsa.deterministicK(15).k.toString('hex').should.equal(obj.k_bad15)
|
|
422
|
-
})
|
|
423
|
-
})
|
|
424
|
-
})
|
|
425
|
-
})
|
|
426
|
-
})
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
/* global describe, it */
|
|
4
|
-
|
|
5
|
-
var assert = require('assert')
|
|
6
|
-
var ec = require('../../lib/crypto/elliptic-fixed')
|
|
7
|
-
|
|
8
|
-
describe('elliptic-fixed (hardened secp256k1)', function () {
|
|
9
|
-
var key = ec.keyFromPrivate(
|
|
10
|
-
'0101010101010101010101010101010101010101010101010101010101010101', 'hex'
|
|
11
|
-
)
|
|
12
|
-
var msg = 'deadbeef'.repeat(8) // 32-byte hash, hex
|
|
13
|
-
|
|
14
|
-
it('produces low-S canonical signatures', function () {
|
|
15
|
-
for (var i = 0; i < 20; i++) {
|
|
16
|
-
var m = (i.toString(16).padStart(2, '0')).repeat(32)
|
|
17
|
-
var sig = ec.sign(m, key)
|
|
18
|
-
var halfN = ec.curve.n.ushrn(1)
|
|
19
|
-
assert.ok(sig.s.cmp(halfN) <= 0, 's must be <= n/2 (low-S)')
|
|
20
|
-
}
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
it('keeps recoveryParam consistent so the pubkey recovers correctly', function () {
|
|
24
|
-
// Regression guard: a manual s-flip without flipping recoveryParam (the
|
|
25
|
-
// pre-fix behaviour) recovers the WRONG public key whenever s was high —
|
|
26
|
-
// which is ~50% of signatures. Use buffer messages for both sign and
|
|
27
|
-
// recover so the encoding is identical on each side.
|
|
28
|
-
var pub = key.getPublic()
|
|
29
|
-
for (var i = 1; i <= 40; i++) {
|
|
30
|
-
var m = Buffer.from(i.toString(16).padStart(2, '0').repeat(32), 'hex')
|
|
31
|
-
var sig = ec.sign(m, key)
|
|
32
|
-
assert.notStrictEqual(sig.recoveryParam, null)
|
|
33
|
-
var recovered = ec.recoverPubKey(m, sig, sig.recoveryParam)
|
|
34
|
-
assert.ok(recovered.eq(pub), 'recovered pubkey must match signer (iter ' + i + ')')
|
|
35
|
-
}
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('still verifies its own canonical signatures', function () {
|
|
39
|
-
var sig = ec.sign(msg, key)
|
|
40
|
-
assert.strictEqual(ec.verify(msg, sig, key), true)
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it('rejects zero r or s', function () {
|
|
44
|
-
var sig = ec.sign(msg, key)
|
|
45
|
-
var BN = sig.r.constructor // bn.js
|
|
46
|
-
assert.strictEqual(ec.verify(msg, { r: new BN(0), s: sig.s }, key), false)
|
|
47
|
-
assert.strictEqual(ec.verify(msg, { r: sig.r, s: new BN(0) }, key), false)
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
it('rejects out-of-range r or s (>= n)', function () {
|
|
51
|
-
var sig = ec.sign(msg, key)
|
|
52
|
-
assert.strictEqual(ec.verify(msg, { r: ec.curve.n, s: sig.s }, key), false)
|
|
53
|
-
assert.strictEqual(ec.verify(msg, { r: sig.r, s: ec.curve.n }, key), false)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
it('returns false (never throws) on malformed signatures', function () {
|
|
57
|
-
assert.strictEqual(ec.verify(msg, null, key), false)
|
|
58
|
-
assert.strictEqual(ec.verify(msg, {}, key), false)
|
|
59
|
-
assert.strictEqual(ec.verify(msg, { r: 'x', s: 'y' }, key), false)
|
|
60
|
-
})
|
|
61
|
-
})
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
require('chai').should()
|
|
4
|
-
var Hash = require('../../lib/crypto/hash.browser')
|
|
5
|
-
|
|
6
|
-
describe('Hash', function () {
|
|
7
|
-
var buf = Buffer.from([0, 1, 2, 3, 253, 254, 255])
|
|
8
|
-
var str = 'test string'
|
|
9
|
-
|
|
10
|
-
describe('@sha1', function () {
|
|
11
|
-
it('calculates the hash of this buffer correctly', function () {
|
|
12
|
-
var hash = Hash.sha1(buf)
|
|
13
|
-
hash.toString('hex').should.equal('de69b8a4a5604d0486e6420db81e39eb464a17b2')
|
|
14
|
-
hash = Hash.sha1(Buffer.alloc(0))
|
|
15
|
-
hash.toString('hex').should.equal('da39a3ee5e6b4b0d3255bfef95601890afd80709')
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
it('throws an error when the input is not a buffer', function () {
|
|
19
|
-
Hash.sha1.bind(Hash, str).should.throw('Invalid Argument')
|
|
20
|
-
})
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
describe('#sha256', function () {
|
|
24
|
-
it('calculates the hash of this buffer correctly', function () {
|
|
25
|
-
var hash = Hash.sha256(buf)
|
|
26
|
-
hash.toString('hex').should.equal('6f2c7b22fd1626998287b3636089087961091de80311b9279c4033ec678a83e8')
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
it('fails when the input is not a buffer', function () {
|
|
30
|
-
Hash.sha256.bind(Hash, str).should.throw('Invalid Argument')
|
|
31
|
-
})
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
describe('#sha256hmac', function () {
|
|
35
|
-
it('computes this known big key correctly', function () {
|
|
36
|
-
var key = Buffer.from('b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad' +
|
|
37
|
-
'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad' +
|
|
38
|
-
'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad' +
|
|
39
|
-
'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad')
|
|
40
|
-
var data = Buffer.from('')
|
|
41
|
-
Hash.sha256hmac(data, key).toString('hex')
|
|
42
|
-
.should.equal('fb1f87218671f1c0c4593a88498e02b6dfe8afd814c1729e89a1f1f6600faa23')
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it('computes this known empty test vector correctly', function () {
|
|
46
|
-
var key = Buffer.from('')
|
|
47
|
-
var data = Buffer.from('')
|
|
48
|
-
Hash.sha256hmac(data, key).toString('hex')
|
|
49
|
-
.should.equal('b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad')
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
it('computes this known non-empty test vector correctly', function () {
|
|
53
|
-
var key = Buffer.from('key')
|
|
54
|
-
var data = Buffer.from('The quick brown fox jumps over the lazy dog')
|
|
55
|
-
Hash.sha256hmac(data, key).toString('hex')
|
|
56
|
-
.should.equal('f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8')
|
|
57
|
-
})
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
describe('#sha256sha256', function () {
|
|
61
|
-
it('calculates the hash of this buffer correctly', function () {
|
|
62
|
-
var hash = Hash.sha256sha256(buf)
|
|
63
|
-
hash.toString('hex').should.equal('be586c8b20dee549bdd66018c7a79e2b67bb88b7c7d428fa4c970976d2bec5ba')
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it('fails when the input is not a buffer', function () {
|
|
67
|
-
Hash.sha256sha256.bind(Hash, str).should.throw('Invalid Argument')
|
|
68
|
-
})
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
describe('#sha256ripemd160', function () {
|
|
72
|
-
it('calculates the hash of this buffer correctly', function () {
|
|
73
|
-
var hash = Hash.sha256ripemd160(buf)
|
|
74
|
-
hash.toString('hex').should.equal('7322e2bd8535e476c092934e16a6169ca9b707ec')
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
it('fails when the input is not a buffer', function () {
|
|
78
|
-
Hash.sha256ripemd160.bind(Hash, str).should.throw('Invalid Argument')
|
|
79
|
-
})
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
describe('#ripemd160', function () {
|
|
83
|
-
it('calculates the hash of this buffer correctly', function () {
|
|
84
|
-
var hash = Hash.ripemd160(buf)
|
|
85
|
-
hash.toString('hex').should.equal('fa0f4565ff776fee0034c713cbf48b5ec06b7f5c')
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it('fails when the input is not a buffer', function () {
|
|
89
|
-
Hash.ripemd160.bind(Hash, str).should.throw('Invalid Argument')
|
|
90
|
-
})
|
|
91
|
-
})
|
|
92
|
-
|
|
93
|
-
describe('#sha512', function () {
|
|
94
|
-
it('calculates the hash of this buffer correctly', function () {
|
|
95
|
-
var hash = Hash.sha512(buf)
|
|
96
|
-
hash.toString('hex')
|
|
97
|
-
.should.equal('c0530aa32048f4904ae162bc14b9eb535eab6c465e960130005fedd' +
|
|
98
|
-
'b71613e7d62aea75f7d3333ba06e805fc8e45681454524e3f8050969fe5a5f7f2392e31d0')
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
it('fails when the input is not a buffer', function () {
|
|
102
|
-
Hash.sha512.bind(Hash, str).should.throw('Invalid Argument')
|
|
103
|
-
})
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
describe('#sha512hmac', function () {
|
|
107
|
-
it('calculates this known empty test vector correctly', function () {
|
|
108
|
-
var hex = 'b936cee86c9f87aa5d3c6f2e84cb5a4239a5fe50480a6ec66b70ab5b1f4a' +
|
|
109
|
-
'c6730c6c515421b327ec1d69402e53dfb49ad7381eb067b338fd7b0cb22247225d47'
|
|
110
|
-
Hash.sha512hmac(Buffer.from([]), Buffer.from([])).toString('hex').should.equal(hex)
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
it('calculates this known non-empty test vector correctly', function () {
|
|
114
|
-
var hex = 'c40bd7c15aa493b309c940e08a73ffbd28b2e4cb729eb94480d727e4df577' +
|
|
115
|
-
'b13cc403a78e6150d83595f3b17c4cc331f12ca5952691de3735a63c1d4c69a2bac'
|
|
116
|
-
var data = Buffer.from('test1')
|
|
117
|
-
var key = Buffer.from('test2')
|
|
118
|
-
Hash.sha512hmac(data, key).toString('hex').should.equal(hex)
|
|
119
|
-
})
|
|
120
|
-
})
|
|
121
|
-
})
|