@opcat-labs/opcat 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mocharc.yaml +3 -0
- package/index.d.ts +1541 -0
- package/index.js +74 -0
- package/lib/address.js +478 -0
- package/lib/block/block.js +277 -0
- package/lib/block/blockheader.js +295 -0
- package/lib/block/index.js +4 -0
- package/lib/block/merkleblock.js +323 -0
- package/lib/bn.js +3423 -0
- package/lib/crypto/bn.js +278 -0
- package/lib/crypto/ecdsa.js +339 -0
- package/lib/crypto/hash.browser.js +171 -0
- package/lib/crypto/hash.js +2 -0
- package/lib/crypto/hash.node.js +171 -0
- package/lib/crypto/point.js +221 -0
- package/lib/crypto/random.browser.js +28 -0
- package/lib/crypto/random.js +2 -0
- package/lib/crypto/random.node.js +11 -0
- package/lib/crypto/signature.js +325 -0
- package/lib/encoding/base58.js +111 -0
- package/lib/encoding/base58check.js +121 -0
- package/lib/encoding/bufferreader.js +212 -0
- package/lib/encoding/bufferwriter.js +140 -0
- package/lib/encoding/decode-asm.js +24 -0
- package/lib/encoding/decode-hex.js +32 -0
- package/lib/encoding/decode-script-chunks.js +43 -0
- package/lib/encoding/encode-hex.js +284 -0
- package/lib/encoding/is-hex.js +7 -0
- package/lib/encoding/varint.js +75 -0
- package/lib/errors/index.js +54 -0
- package/lib/errors/spec.js +314 -0
- package/lib/hash-cache.js +50 -0
- package/lib/hdprivatekey.js +678 -0
- package/lib/hdpublickey.js +525 -0
- package/lib/message/message.js +191 -0
- package/lib/mnemonic/mnemonic.js +303 -0
- package/lib/mnemonic/pbkdf2.browser.js +68 -0
- package/lib/mnemonic/pbkdf2.js +2 -0
- package/lib/mnemonic/pbkdf2.node.js +68 -0
- package/lib/mnemonic/words/chinese.js +2054 -0
- package/lib/mnemonic/words/english.js +2054 -0
- package/lib/mnemonic/words/french.js +2054 -0
- package/lib/mnemonic/words/index.js +8 -0
- package/lib/mnemonic/words/italian.js +2054 -0
- package/lib/mnemonic/words/japanese.js +2054 -0
- package/lib/mnemonic/words/spanish.js +2054 -0
- package/lib/networks.js +379 -0
- package/lib/opcode.js +255 -0
- package/lib/privatekey.js +374 -0
- package/lib/publickey.js +386 -0
- package/lib/script/index.js +5 -0
- package/lib/script/interpreter.js +1834 -0
- package/lib/script/script.js +1074 -0
- package/lib/script/stack.js +109 -0
- package/lib/script/write-i32-le.js +17 -0
- package/lib/script/write-push-data.js +35 -0
- package/lib/script/write-u16-le.js +12 -0
- package/lib/script/write-u32-le.js +16 -0
- package/lib/script/write-u64-le.js +24 -0
- package/lib/script/write-u8-le.js +8 -0
- package/lib/script/write-varint.js +46 -0
- package/lib/transaction/index.js +7 -0
- package/lib/transaction/input/index.js +5 -0
- package/lib/transaction/input/input.js +354 -0
- package/lib/transaction/input/multisig.js +242 -0
- package/lib/transaction/input/publickey.js +100 -0
- package/lib/transaction/input/publickeyhash.js +118 -0
- package/lib/transaction/output.js +231 -0
- package/lib/transaction/sighash.js +167 -0
- package/lib/transaction/signature.js +97 -0
- package/lib/transaction/transaction.js +1639 -0
- package/lib/transaction/unspentoutput.js +113 -0
- package/lib/util/_.js +47 -0
- package/lib/util/js.js +90 -0
- package/lib/util/preconditions.js +33 -0
- package/package.json +26 -0
- package/test/address.js +509 -0
- package/test/block/block.js +251 -0
- package/test/block/blockheader.js +275 -0
- package/test/block/merklebloack.js +211 -0
- package/test/crypto/bn.js +177 -0
- package/test/crypto/ecdsa.js +391 -0
- package/test/crypto/hash.browser.js +135 -0
- package/test/crypto/hash.js +136 -0
- package/test/crypto/point.js +224 -0
- package/test/crypto/random.js +32 -0
- package/test/crypto/signature.js +409 -0
- package/test/data/bip69.json +215 -0
- package/test/data/bitcoind/base58_keys_invalid.json +52 -0
- package/test/data/bitcoind/base58_keys_valid.json +335 -0
- package/test/data/bitcoind/blocks.json +22 -0
- package/test/data/bitcoind/script_tests.json +3822 -0
- package/test/data/bitcoind/sig_canonical.json +7 -0
- package/test/data/bitcoind/sig_noncanonical.json +36 -0
- package/test/data/bitcoind/tx_invalid.json +445 -0
- package/test/data/bitcoind/tx_valid.json +44 -0
- package/test/data/blk86756-testnet.dat +0 -0
- package/test/data/blk86756-testnet.js +14 -0
- package/test/data/blk86756-testnet.json +684 -0
- package/test/data/block.hex +1 -0
- package/test/data/ecdsa.json +230 -0
- package/test/data/merkleblocks.js +488 -0
- package/test/data/messages.json +22 -0
- package/test/data/sighash.json +12 -0
- package/test/data/tx_creation.json +95 -0
- package/test/encoding/base58.js +131 -0
- package/test/encoding/base58check.js +136 -0
- package/test/encoding/bufferreader.js +337 -0
- package/test/encoding/bufferwriter.js +172 -0
- package/test/encoding/varint.js +104 -0
- package/test/hashCache.js +67 -0
- package/test/hdkeys.js +445 -0
- package/test/hdprivatekey.js +332 -0
- package/test/hdpublickey.js +304 -0
- package/test/index.js +16 -0
- package/test/message/message.js +204 -0
- package/test/mnemonic/data/fixtures.json +300 -0
- package/test/mnemonic/mnemonic.js +259 -0
- package/test/mnemonic/mocha.opts +1 -0
- package/test/mnemonic/pbkdf2.test.js +59 -0
- package/test/networks.js +159 -0
- package/test/opcode.js +161 -0
- package/test/privatekey.js +439 -0
- package/test/publickey.js +554 -0
- package/test/script/interpreter.js +734 -0
- package/test/script/script.js +1437 -0
- package/test/transaction/deserialize.js +34 -0
- package/test/transaction/input/input.js +90 -0
- package/test/transaction/input/multisig.js +90 -0
- package/test/transaction/input/publickey.js +68 -0
- package/test/transaction/input/publickeyhash.js +51 -0
- package/test/transaction/output.js +185 -0
- package/test/transaction/sighash.js +65 -0
- package/test/transaction/signature.js +114 -0
- package/test/transaction/transaction.js +1109 -0
- package/test/transaction/unspentoutput.js +110 -0
- package/test/util/js.js +76 -0
- package/test/util/preconditions.js +79 -0
|
@@ -0,0 +1,391 @@
|
|
|
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(
|
|
22
|
+
BN.fromBuffer(
|
|
23
|
+
Buffer.from('fee0a1f7afebf9d2a5a80c0c98a31c709681cce195cbcd06342b517970c0be1e', 'hex'),
|
|
24
|
+
),
|
|
25
|
+
);
|
|
26
|
+
ecdsa.privkey2pubkey();
|
|
27
|
+
|
|
28
|
+
describe('#set', function () {
|
|
29
|
+
it('sets hashbuf', function () {
|
|
30
|
+
should.exist(
|
|
31
|
+
ECDSA().set({
|
|
32
|
+
hashbuf: ecdsa.hashbuf,
|
|
33
|
+
}).hashbuf,
|
|
34
|
+
);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
describe('#calci', function () {
|
|
39
|
+
it('calculates i correctly', function () {
|
|
40
|
+
ecdsa.randomK();
|
|
41
|
+
ecdsa.sign();
|
|
42
|
+
ecdsa.calci();
|
|
43
|
+
should.exist(ecdsa.sig.i);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('calulates this known i', function () {
|
|
47
|
+
var hashbuf = Hash.sha256(Buffer.from('some data'));
|
|
48
|
+
var r = new BN(
|
|
49
|
+
'71706645040721865894779025947914615666559616020894583599959600180037551395766',
|
|
50
|
+
10,
|
|
51
|
+
);
|
|
52
|
+
var s = new BN(
|
|
53
|
+
'109412465507152403114191008482955798903072313614214706891149785278625167723646',
|
|
54
|
+
10,
|
|
55
|
+
);
|
|
56
|
+
var ecdsa = new ECDSA({
|
|
57
|
+
privkey: new Privkey(BN.fromBuffer(Hash.sha256(Buffer.from('test')))),
|
|
58
|
+
hashbuf: hashbuf,
|
|
59
|
+
sig: new Signature({
|
|
60
|
+
r: r,
|
|
61
|
+
s: s,
|
|
62
|
+
}),
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
ecdsa.calci();
|
|
66
|
+
ecdsa.sig.i.should.equal(1);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('#fromString', function () {
|
|
71
|
+
it('round trip with fromString', function () {
|
|
72
|
+
var str = ecdsa.toString();
|
|
73
|
+
var ecdsa2 = ECDSA.fromString(str);
|
|
74
|
+
should.exist(ecdsa2.hashbuf);
|
|
75
|
+
should.exist(ecdsa2.privkey);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('#randomK', function () {
|
|
80
|
+
it('should generate a new random k when called twice in a row', function () {
|
|
81
|
+
ecdsa.randomK();
|
|
82
|
+
var k1 = ecdsa.k;
|
|
83
|
+
ecdsa.randomK();
|
|
84
|
+
var k2 = ecdsa.k;
|
|
85
|
+
(k1.cmp(k2) === 0).should.equal(false);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('should generate a random k that is (almost always) greater than this relatively small number', function () {
|
|
89
|
+
ecdsa.randomK();
|
|
90
|
+
var k1 = ecdsa.k;
|
|
91
|
+
var k2 = new BN(Math.pow(2, 32)).mul(new BN(Math.pow(2, 32))).mul(new BN(Math.pow(2, 32)));
|
|
92
|
+
k2.gt(k1).should.equal(false);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('#deterministicK', function () {
|
|
97
|
+
it('should generate the same deterministic k', function () {
|
|
98
|
+
ecdsa.deterministicK();
|
|
99
|
+
ecdsa.k
|
|
100
|
+
.toBuffer()
|
|
101
|
+
.toString('hex')
|
|
102
|
+
.should.equal('fcce1de7a9bcd6b2d3defade6afa1913fb9229e3b7ddf4749b55c4848b2a196e');
|
|
103
|
+
});
|
|
104
|
+
it('should generate the same deterministic k if badrs is set', function () {
|
|
105
|
+
ecdsa.deterministicK(0);
|
|
106
|
+
ecdsa.k
|
|
107
|
+
.toBuffer()
|
|
108
|
+
.toString('hex')
|
|
109
|
+
.should.equal('fcce1de7a9bcd6b2d3defade6afa1913fb9229e3b7ddf4749b55c4848b2a196e');
|
|
110
|
+
ecdsa.deterministicK(1);
|
|
111
|
+
ecdsa.k
|
|
112
|
+
.toBuffer()
|
|
113
|
+
.toString('hex')
|
|
114
|
+
.should.not.equal('fcce1de7a9bcd6b2d3defade6afa1913fb9229e3b7ddf4749b55c4848b2a196e');
|
|
115
|
+
ecdsa.k
|
|
116
|
+
.toBuffer()
|
|
117
|
+
.toString('hex')
|
|
118
|
+
.should.equal('727fbcb59eb48b1d7d46f95a04991fc512eb9dbf9105628e3aec87428df28fd8');
|
|
119
|
+
});
|
|
120
|
+
it('should compute this test vector correctly', function () {
|
|
121
|
+
// test fixture from bitcoinjs
|
|
122
|
+
// https://github.com/bitcoinjs/bitcoinjs-lib/blob/10630873ebaa42381c5871e20336fbfb46564ac8/test/fixtures/ecdsa.json#L6
|
|
123
|
+
var ecdsa = new ECDSA();
|
|
124
|
+
ecdsa.hashbuf = Hash.sha256(
|
|
125
|
+
Buffer.from('Everything should be made as simple as possible, but not simpler.'),
|
|
126
|
+
);
|
|
127
|
+
ecdsa.privkey = new Privkey(new BN(1));
|
|
128
|
+
ecdsa.privkey2pubkey();
|
|
129
|
+
ecdsa.deterministicK();
|
|
130
|
+
ecdsa.k
|
|
131
|
+
.toBuffer()
|
|
132
|
+
.toString('hex')
|
|
133
|
+
.should.equal('ec633bd56a5774a0940cb97e27a9e4e51dc94af737596a0c5cbb3d30332d92a5');
|
|
134
|
+
ecdsa.sign();
|
|
135
|
+
ecdsa.sig.r
|
|
136
|
+
.toString()
|
|
137
|
+
.should.equal(
|
|
138
|
+
'23362334225185207751494092901091441011938859014081160902781146257181456271561',
|
|
139
|
+
);
|
|
140
|
+
ecdsa.sig.s
|
|
141
|
+
.toString()
|
|
142
|
+
.should.equal(
|
|
143
|
+
'50433721247292933944369538617440297985091596895097604618403996029256432099938',
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
describe('#toPublicKey', function () {
|
|
149
|
+
it('should calculate the correct public key', function () {
|
|
150
|
+
ecdsa.k = new BN(
|
|
151
|
+
'114860389168127852803919605627759231199925249596762615988727970217268189974335',
|
|
152
|
+
10,
|
|
153
|
+
);
|
|
154
|
+
ecdsa.sign();
|
|
155
|
+
ecdsa.sig.i = 0;
|
|
156
|
+
var pubkey = ecdsa.toPublicKey();
|
|
157
|
+
pubkey.point.eq(ecdsa.pubkey.point).should.equal(true);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('should calculate the correct public key for this signature with low s', function () {
|
|
161
|
+
ecdsa.k = new BN(
|
|
162
|
+
'114860389168127852803919605627759231199925249596762615988727970217268189974335',
|
|
163
|
+
10,
|
|
164
|
+
);
|
|
165
|
+
ecdsa.sig = Signature.fromString(
|
|
166
|
+
'3045022100ec3cfe0e335791ad278b4ec8eac93d0347' +
|
|
167
|
+
'a97877bb1d54d35d189e225c15f6650220278cf15b05ce47fb37d2233802899d94c774d5480bba9f0f2d996baa13370c43',
|
|
168
|
+
);
|
|
169
|
+
ecdsa.sig.i = 0;
|
|
170
|
+
var pubkey = ecdsa.toPublicKey();
|
|
171
|
+
pubkey.point.eq(ecdsa.pubkey.point).should.equal(true);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('should calculate the correct public key for this signature with high s', function () {
|
|
175
|
+
ecdsa.k = new BN(
|
|
176
|
+
'114860389168127852803919605627759231199925249596762615988727970217268189974335',
|
|
177
|
+
10,
|
|
178
|
+
);
|
|
179
|
+
ecdsa.sign();
|
|
180
|
+
ecdsa.sig = Signature.fromString(
|
|
181
|
+
'3046022100ec3cfe0e335791ad278b4ec8eac93d0347' +
|
|
182
|
+
'a97877bb1d54d35d189e225c15f665022100d8730ea4fa31b804c82ddcc7fd766269f33a079ea38e012c9238f2e2bcff34fe',
|
|
183
|
+
);
|
|
184
|
+
ecdsa.sig.i = 1;
|
|
185
|
+
var pubkey = ecdsa.toPublicKey();
|
|
186
|
+
pubkey.point.eq(ecdsa.pubkey.point).should.equal(true);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
describe('#sigError', function () {
|
|
191
|
+
it('should return an error if the hash is invalid', function () {
|
|
192
|
+
var ecdsa = new ECDSA();
|
|
193
|
+
ecdsa.sigError().should.equal('hashbuf must be a 32 byte buffer');
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('should return an error if r, s are invalid', function () {
|
|
197
|
+
var ecdsa = new ECDSA();
|
|
198
|
+
ecdsa.hashbuf = Hash.sha256(Buffer.from('test'));
|
|
199
|
+
var pk = Pubkey.fromDER(
|
|
200
|
+
Buffer.from(
|
|
201
|
+
'041ff0fe0f7b15ffaa85ff9f4744d539139c252a49' +
|
|
202
|
+
'710fb053bb9f2b933173ff9a7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341',
|
|
203
|
+
'hex',
|
|
204
|
+
),
|
|
205
|
+
);
|
|
206
|
+
ecdsa.pubkey = pk;
|
|
207
|
+
ecdsa.sig = new Signature();
|
|
208
|
+
ecdsa.sig.r = new BN(0);
|
|
209
|
+
ecdsa.sig.s = new BN(0);
|
|
210
|
+
ecdsa.sigError().should.equal('r and s not in range');
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('should return an error if the signature is incorrect', function () {
|
|
214
|
+
ecdsa.sig = Signature.fromString(
|
|
215
|
+
'3046022100e9915e6236695f093a4128ac2a956c40' +
|
|
216
|
+
'ed971531de2f4f41ba05fac7e2bd019c02210094e6a4a769cc7f2a8ab3db696c7cd8d56bcdbfff860a8c81de4bc6a798b90827',
|
|
217
|
+
);
|
|
218
|
+
ecdsa.sig.r = ecdsa.sig.r.add(new BN(1));
|
|
219
|
+
ecdsa.sigError().should.equal('Invalid signature');
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
describe('#sign', function () {
|
|
224
|
+
it('should create a valid signature', function () {
|
|
225
|
+
ecdsa.randomK();
|
|
226
|
+
ecdsa.sign();
|
|
227
|
+
ecdsa.verify().verified.should.equal(true);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('should should throw an error if hashbuf is not 32 bytes', function () {
|
|
231
|
+
var ecdsa2 = ECDSA().set({
|
|
232
|
+
hashbuf: ecdsa.hashbuf.slice(0, 31),
|
|
233
|
+
privkey: ecdsa.privkey,
|
|
234
|
+
});
|
|
235
|
+
ecdsa2.randomK();
|
|
236
|
+
ecdsa2.sign.bind(ecdsa2).should.throw('hashbuf must be a 32 byte buffer');
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
it('should default to deterministicK', function () {
|
|
240
|
+
var ecdsa2 = new ECDSA(ecdsa);
|
|
241
|
+
ecdsa2.k = undefined;
|
|
242
|
+
var called = 0;
|
|
243
|
+
var deterministicK = ecdsa2.deterministicK.bind(ecdsa2);
|
|
244
|
+
ecdsa2.deterministicK = function () {
|
|
245
|
+
deterministicK();
|
|
246
|
+
called++;
|
|
247
|
+
};
|
|
248
|
+
ecdsa2.sign();
|
|
249
|
+
called.should.equal(1);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it('should generate right K', function () {
|
|
253
|
+
var msg1 = Buffer.from(
|
|
254
|
+
'52204d20fd0131ae1afd173fd80a3a746d2dcc0cddced8c9dc3d61cc7ab6e966',
|
|
255
|
+
'hex',
|
|
256
|
+
);
|
|
257
|
+
var msg2 = [].reverse.call(Buffer.from(msg1));
|
|
258
|
+
var pk = Buffer.from(
|
|
259
|
+
'16f243e962c59e71e54189e67e66cf2440a1334514c09c00ddcc21632bac9808',
|
|
260
|
+
'hex',
|
|
261
|
+
);
|
|
262
|
+
var signature1 = ECDSA.sign(msg1, Privkey.fromBuffer(pk)).toBuffer().toString('hex');
|
|
263
|
+
var signature2 = ECDSA.sign(msg2, Privkey.fromBuffer(pk), 'little')
|
|
264
|
+
.toBuffer()
|
|
265
|
+
.toString('hex');
|
|
266
|
+
signature1.should.equal(signature2);
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
describe('#toString', function () {
|
|
271
|
+
it('should convert this to a string', function () {
|
|
272
|
+
var str = ecdsa.toString();
|
|
273
|
+
(typeof str === 'string').should.equal(true);
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
|
|
277
|
+
describe('signing and verification', function () {
|
|
278
|
+
describe('@sign', function () {
|
|
279
|
+
it('should produce a signature', function () {
|
|
280
|
+
var sig = ECDSA.sign(ecdsa.hashbuf, ecdsa.privkey);
|
|
281
|
+
(sig instanceof Signature).should.equal(true);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it('should produce a signaturei', function () {
|
|
285
|
+
var sig = ECDSA.signWithCalcI(ecdsa.hashbuf, ecdsa.privkey);
|
|
286
|
+
(sig instanceof Signature).should.equal(true);
|
|
287
|
+
should.exist(sig.i);
|
|
288
|
+
sig
|
|
289
|
+
.toCompact()
|
|
290
|
+
.toString('base64')
|
|
291
|
+
.should.equal(
|
|
292
|
+
'IF7ucRrxMczOWYg28NkA+krY4aXx9XgT7KVglwpLEqqyIUtqBrrU5mSDQqOm0ETZ47KdQEMv121aWkxO7P1hbGk=',
|
|
293
|
+
);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('should produce a signature', function () {
|
|
297
|
+
var sig = ECDSA.signRandomK(ecdsa.hashbuf, ecdsa.privkey);
|
|
298
|
+
(sig instanceof Signature).should.equal(true);
|
|
299
|
+
var sig2 = ECDSA.signRandomK(ecdsa.hashbuf, ecdsa.privkey);
|
|
300
|
+
(sig2 instanceof Signature).should.equal(true);
|
|
301
|
+
sig.toString().should.not.equal(sig2.toString());
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('should produce a signature, and be different when called twice', function () {
|
|
305
|
+
ecdsa.signRandomK();
|
|
306
|
+
should.exist(ecdsa.sig);
|
|
307
|
+
var ecdsa2 = ECDSA(ecdsa);
|
|
308
|
+
ecdsa2.signRandomK();
|
|
309
|
+
ecdsa.sig.toString().should.not.equal(ecdsa2.sig.toString());
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
describe('#verify', function () {
|
|
314
|
+
it('should verify a signature that was just signed', function () {
|
|
315
|
+
ecdsa.sig = Signature.fromString(
|
|
316
|
+
'3046022100e9915e6236695f093a4128ac2a956c' +
|
|
317
|
+
'40ed971531de2f4f41ba05fac7e2bd019c02210094e6a4a769cc7f2a8ab3db696c7cd8d56bcdbfff860a8c81de4bc6a798b90827',
|
|
318
|
+
);
|
|
319
|
+
ecdsa.verify().verified.should.equal(true);
|
|
320
|
+
});
|
|
321
|
+
it('should verify this known good signature', function () {
|
|
322
|
+
ecdsa.signRandomK();
|
|
323
|
+
ecdsa.verify().verified.should.equal(true);
|
|
324
|
+
});
|
|
325
|
+
it('should verify a valid signature, and unverify an invalid signature', function () {
|
|
326
|
+
var sig = ECDSA.sign(ecdsa.hashbuf, ecdsa.privkey);
|
|
327
|
+
ECDSA.verify(ecdsa.hashbuf, sig, ecdsa.pubkey).should.equal(true);
|
|
328
|
+
var fakesig = new Signature(sig.r.add(new BN(1)), sig.s);
|
|
329
|
+
ECDSA.verify(ecdsa.hashbuf, fakesig, ecdsa.pubkey).should.equal(false);
|
|
330
|
+
});
|
|
331
|
+
it('should work with big and little endian', function () {
|
|
332
|
+
var sig = ECDSA.sign(ecdsa.hashbuf, ecdsa.privkey, 'big');
|
|
333
|
+
ECDSA.verify(ecdsa.hashbuf, sig, ecdsa.pubkey, 'big').should.equal(true);
|
|
334
|
+
ECDSA.verify(ecdsa.hashbuf, sig, ecdsa.pubkey, 'little').should.equal(false);
|
|
335
|
+
sig = ECDSA.sign(ecdsa.hashbuf, ecdsa.privkey, 'little');
|
|
336
|
+
ECDSA.verify(ecdsa.hashbuf, sig, ecdsa.pubkey, 'big').should.equal(false);
|
|
337
|
+
ECDSA.verify(ecdsa.hashbuf, sig, ecdsa.pubkey, 'little').should.equal(true);
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
describe('vectors', function () {
|
|
342
|
+
vectors.valid.forEach(function (obj, i) {
|
|
343
|
+
it('should validate valid vector ' + i, function () {
|
|
344
|
+
var ecdsa = ECDSA().set({
|
|
345
|
+
privkey: new Privkey(BN.fromBuffer(Buffer.from(obj.d, 'hex'))),
|
|
346
|
+
k: BN.fromBuffer(Buffer.from(obj.k, 'hex')),
|
|
347
|
+
hashbuf: Hash.sha256(Buffer.from(obj.message)),
|
|
348
|
+
sig: new Signature().set({
|
|
349
|
+
r: new BN(obj.signature.r),
|
|
350
|
+
s: new BN(obj.signature.s),
|
|
351
|
+
i: obj.i,
|
|
352
|
+
}),
|
|
353
|
+
});
|
|
354
|
+
var ecdsa2 = ECDSA(ecdsa);
|
|
355
|
+
ecdsa2.k = undefined;
|
|
356
|
+
ecdsa2.sign();
|
|
357
|
+
ecdsa2.calci();
|
|
358
|
+
ecdsa2.k.toString().should.equal(ecdsa.k.toString());
|
|
359
|
+
ecdsa2.sig.toString().should.equal(ecdsa.sig.toString());
|
|
360
|
+
ecdsa2.sig.i.should.equal(ecdsa.sig.i);
|
|
361
|
+
ecdsa.verify().verified.should.equal(true);
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
vectors.invalid.sigError.forEach(function (obj, i) {
|
|
366
|
+
it('should validate invalid.sigError vector ' + i + ': ' + obj.description, function () {
|
|
367
|
+
var ecdsa = ECDSA().set({
|
|
368
|
+
pubkey: Pubkey.fromPoint(point.fromX(true, 1)),
|
|
369
|
+
sig: new Signature(new BN(obj.signature.r), new BN(obj.signature.s)),
|
|
370
|
+
hashbuf: Hash.sha256(Buffer.from(obj.message)),
|
|
371
|
+
});
|
|
372
|
+
ecdsa.sigError().should.equal(obj.exception);
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
vectors.deterministicK.forEach(function (obj, i) {
|
|
377
|
+
it('should validate deterministicK vector ' + i, function () {
|
|
378
|
+
var hashbuf = Hash.sha256(Buffer.from(obj.message));
|
|
379
|
+
var privkey = Privkey(BN.fromBuffer(Buffer.from(obj.privkey, 'hex')), 'mainnet');
|
|
380
|
+
var ecdsa = ECDSA({
|
|
381
|
+
privkey: privkey,
|
|
382
|
+
hashbuf: hashbuf,
|
|
383
|
+
});
|
|
384
|
+
ecdsa.deterministicK(0).k.toString('hex').should.equal(obj.k_bad00);
|
|
385
|
+
ecdsa.deterministicK(1).k.toString('hex').should.equal(obj.k_bad01);
|
|
386
|
+
ecdsa.deterministicK(15).k.toString('hex').should.equal(obj.k_bad15);
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
});
|
|
391
|
+
});
|
|
@@ -0,0 +1,135 @@
|
|
|
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
|
|
27
|
+
.toString('hex')
|
|
28
|
+
.should.equal('6f2c7b22fd1626998287b3636089087961091de80311b9279c4033ec678a83e8');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('fails when the input is not a buffer', function () {
|
|
32
|
+
Hash.sha256.bind(Hash, str).should.throw('Invalid Argument');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('#sha256hmac', function () {
|
|
37
|
+
it('computes this known big key correctly', function () {
|
|
38
|
+
var key = Buffer.from(
|
|
39
|
+
'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad' +
|
|
40
|
+
'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad' +
|
|
41
|
+
'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad' +
|
|
42
|
+
'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad',
|
|
43
|
+
);
|
|
44
|
+
var data = Buffer.from('');
|
|
45
|
+
Hash.sha256hmac(data, key)
|
|
46
|
+
.toString('hex')
|
|
47
|
+
.should.equal('fb1f87218671f1c0c4593a88498e02b6dfe8afd814c1729e89a1f1f6600faa23');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('computes this known empty test vector correctly', function () {
|
|
51
|
+
var key = Buffer.from('');
|
|
52
|
+
var data = Buffer.from('');
|
|
53
|
+
Hash.sha256hmac(data, key)
|
|
54
|
+
.toString('hex')
|
|
55
|
+
.should.equal('b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('computes this known non-empty test vector correctly', function () {
|
|
59
|
+
var key = Buffer.from('key');
|
|
60
|
+
var data = Buffer.from('The quick brown fox jumps over the lazy dog');
|
|
61
|
+
Hash.sha256hmac(data, key)
|
|
62
|
+
.toString('hex')
|
|
63
|
+
.should.equal('f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8');
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('#sha256sha256', function () {
|
|
68
|
+
it('calculates the hash of this buffer correctly', function () {
|
|
69
|
+
var hash = Hash.sha256sha256(buf);
|
|
70
|
+
hash
|
|
71
|
+
.toString('hex')
|
|
72
|
+
.should.equal('be586c8b20dee549bdd66018c7a79e2b67bb88b7c7d428fa4c970976d2bec5ba');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('fails when the input is not a buffer', function () {
|
|
76
|
+
Hash.sha256sha256.bind(Hash, str).should.throw('Invalid Argument');
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
describe('#sha256ripemd160', function () {
|
|
81
|
+
it('calculates the hash of this buffer correctly', function () {
|
|
82
|
+
var hash = Hash.sha256ripemd160(buf);
|
|
83
|
+
hash.toString('hex').should.equal('7322e2bd8535e476c092934e16a6169ca9b707ec');
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('fails when the input is not a buffer', function () {
|
|
87
|
+
Hash.sha256ripemd160.bind(Hash, str).should.throw('Invalid Argument');
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe('#ripemd160', function () {
|
|
92
|
+
it('calculates the hash of this buffer correctly', function () {
|
|
93
|
+
var hash = Hash.ripemd160(buf);
|
|
94
|
+
hash.toString('hex').should.equal('fa0f4565ff776fee0034c713cbf48b5ec06b7f5c');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('fails when the input is not a buffer', function () {
|
|
98
|
+
Hash.ripemd160.bind(Hash, str).should.throw('Invalid Argument');
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
describe('#sha512', function () {
|
|
103
|
+
it('calculates the hash of this buffer correctly', function () {
|
|
104
|
+
var hash = Hash.sha512(buf);
|
|
105
|
+
hash
|
|
106
|
+
.toString('hex')
|
|
107
|
+
.should.equal(
|
|
108
|
+
'c0530aa32048f4904ae162bc14b9eb535eab6c465e960130005fedd' +
|
|
109
|
+
'b71613e7d62aea75f7d3333ba06e805fc8e45681454524e3f8050969fe5a5f7f2392e31d0',
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('fails when the input is not a buffer', function () {
|
|
114
|
+
Hash.sha512.bind(Hash, str).should.throw('Invalid Argument');
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
describe('#sha512hmac', function () {
|
|
119
|
+
it('calculates this known empty test vector correctly', function () {
|
|
120
|
+
var hex =
|
|
121
|
+
'b936cee86c9f87aa5d3c6f2e84cb5a4239a5fe50480a6ec66b70ab5b1f4a' +
|
|
122
|
+
'c6730c6c515421b327ec1d69402e53dfb49ad7381eb067b338fd7b0cb22247225d47';
|
|
123
|
+
Hash.sha512hmac(Buffer.from([]), Buffer.from([])).toString('hex').should.equal(hex);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('calculates this known non-empty test vector correctly', function () {
|
|
127
|
+
var hex =
|
|
128
|
+
'c40bd7c15aa493b309c940e08a73ffbd28b2e4cb729eb94480d727e4df577' +
|
|
129
|
+
'b13cc403a78e6150d83595f3b17c4cc331f12ca5952691de3735a63c1d4c69a2bac';
|
|
130
|
+
var data = Buffer.from('test1');
|
|
131
|
+
var key = Buffer.from('test2');
|
|
132
|
+
Hash.sha512hmac(data, key).toString('hex').should.equal(hex);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
});
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
require('chai').should();
|
|
4
|
+
var opcat = require('../..');
|
|
5
|
+
var Hash = opcat.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
|
|
28
|
+
.toString('hex')
|
|
29
|
+
.should.equal('6f2c7b22fd1626998287b3636089087961091de80311b9279c4033ec678a83e8');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('fails when the input is not a buffer', function () {
|
|
33
|
+
Hash.sha256.bind(Hash, str).should.throw('Invalid Argument');
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe('#sha256hmac', function () {
|
|
38
|
+
it('computes this known big key correctly', function () {
|
|
39
|
+
var key = Buffer.from(
|
|
40
|
+
'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad' +
|
|
41
|
+
'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad' +
|
|
42
|
+
'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad' +
|
|
43
|
+
'b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad',
|
|
44
|
+
);
|
|
45
|
+
var data = Buffer.from('');
|
|
46
|
+
Hash.sha256hmac(data, key)
|
|
47
|
+
.toString('hex')
|
|
48
|
+
.should.equal('fb1f87218671f1c0c4593a88498e02b6dfe8afd814c1729e89a1f1f6600faa23');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('computes this known empty test vector correctly', function () {
|
|
52
|
+
var key = Buffer.from('');
|
|
53
|
+
var data = Buffer.from('');
|
|
54
|
+
Hash.sha256hmac(data, key)
|
|
55
|
+
.toString('hex')
|
|
56
|
+
.should.equal('b613679a0814d9ec772f95d778c35fc5ff1697c493715653c6c712144292c5ad');
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('computes this known non-empty test vector correctly', function () {
|
|
60
|
+
var key = Buffer.from('key');
|
|
61
|
+
var data = Buffer.from('The quick brown fox jumps over the lazy dog');
|
|
62
|
+
Hash.sha256hmac(data, key)
|
|
63
|
+
.toString('hex')
|
|
64
|
+
.should.equal('f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8');
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
describe('#sha256sha256', function () {
|
|
69
|
+
it('calculates the hash of this buffer correctly', function () {
|
|
70
|
+
var hash = Hash.sha256sha256(buf);
|
|
71
|
+
hash
|
|
72
|
+
.toString('hex')
|
|
73
|
+
.should.equal('be586c8b20dee549bdd66018c7a79e2b67bb88b7c7d428fa4c970976d2bec5ba');
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('fails when the input is not a buffer', function () {
|
|
77
|
+
Hash.sha256sha256.bind(Hash, str).should.throw('Invalid Argument');
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('#sha256ripemd160', function () {
|
|
82
|
+
it('calculates the hash of this buffer correctly', function () {
|
|
83
|
+
var hash = Hash.sha256ripemd160(buf);
|
|
84
|
+
hash.toString('hex').should.equal('7322e2bd8535e476c092934e16a6169ca9b707ec');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('fails when the input is not a buffer', function () {
|
|
88
|
+
Hash.sha256ripemd160.bind(Hash, str).should.throw('Invalid Argument');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe('#ripemd160', function () {
|
|
93
|
+
it('calculates the hash of this buffer correctly', function () {
|
|
94
|
+
var hash = Hash.ripemd160(buf);
|
|
95
|
+
hash.toString('hex').should.equal('fa0f4565ff776fee0034c713cbf48b5ec06b7f5c');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('fails when the input is not a buffer', function () {
|
|
99
|
+
Hash.ripemd160.bind(Hash, str).should.throw('Invalid Argument');
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe('#sha512', function () {
|
|
104
|
+
it('calculates the hash of this buffer correctly', function () {
|
|
105
|
+
var hash = Hash.sha512(buf);
|
|
106
|
+
hash
|
|
107
|
+
.toString('hex')
|
|
108
|
+
.should.equal(
|
|
109
|
+
'c0530aa32048f4904ae162bc14b9eb535eab6c465e960130005fedd' +
|
|
110
|
+
'b71613e7d62aea75f7d3333ba06e805fc8e45681454524e3f8050969fe5a5f7f2392e31d0',
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('fails when the input is not a buffer', function () {
|
|
115
|
+
Hash.sha512.bind(Hash, str).should.throw('Invalid Argument');
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe('#sha512hmac', function () {
|
|
120
|
+
it('calculates this known empty test vector correctly', function () {
|
|
121
|
+
var hex =
|
|
122
|
+
'b936cee86c9f87aa5d3c6f2e84cb5a4239a5fe50480a6ec66b70ab5b1f4a' +
|
|
123
|
+
'c6730c6c515421b327ec1d69402e53dfb49ad7381eb067b338fd7b0cb22247225d47';
|
|
124
|
+
Hash.sha512hmac(Buffer.from([]), Buffer.from([])).toString('hex').should.equal(hex);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('calculates this known non-empty test vector correctly', function () {
|
|
128
|
+
var hex =
|
|
129
|
+
'c40bd7c15aa493b309c940e08a73ffbd28b2e4cb729eb94480d727e4df577' +
|
|
130
|
+
'b13cc403a78e6150d83595f3b17c4cc331f12ca5952691de3735a63c1d4c69a2bac';
|
|
131
|
+
var data = Buffer.from('test1');
|
|
132
|
+
var key = Buffer.from('test2');
|
|
133
|
+
Hash.sha512hmac(data, key).toString('hex').should.equal(hex);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
});
|