hypercore 11.16.2 → 11.17.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/README.md +31 -29
- package/index.js +212 -127
- package/lib/audit.js +17 -6
- package/lib/bit-interlude.js +17 -7
- package/lib/bitfield.js +72 -52
- package/lib/caps.js +5 -1
- package/lib/copy-prologue.js +14 -10
- package/lib/core.js +109 -56
- package/lib/default-encryption.js +14 -28
- package/lib/download.js +10 -10
- package/lib/fully-remote-proof.js +3 -3
- package/lib/hotswap-queue.js +5 -5
- package/lib/info.js +4 -4
- package/lib/merkle-tree.js +143 -104
- package/lib/messages.js +163 -143
- package/lib/multisig.js +19 -12
- package/lib/mutex.js +9 -7
- package/lib/receiver-queue.js +6 -6
- package/lib/remote-bitfield.js +30 -32
- package/lib/replicator.js +383 -265
- package/lib/session-state.js +112 -75
- package/lib/streams.js +16 -16
- package/lib/verifier.js +69 -43
- package/package.json +5 -3
package/lib/verifier.js
CHANGED
|
@@ -10,7 +10,12 @@ const multisig = require('./multisig')
|
|
|
10
10
|
const caps = require('./caps')
|
|
11
11
|
|
|
12
12
|
class Signer {
|
|
13
|
-
constructor
|
|
13
|
+
constructor(
|
|
14
|
+
manifestHash,
|
|
15
|
+
version,
|
|
16
|
+
index,
|
|
17
|
+
{ signature = 'ed25519', publicKey, namespace = caps.DEFAULT_NAMESPACE } = {}
|
|
18
|
+
) {
|
|
14
19
|
if (!publicKey) throw BAD_ARGUMENT('public key is required for a signer')
|
|
15
20
|
if (signature !== 'ed25519') throw BAD_ARGUMENT('Only Ed25519 signatures are supported')
|
|
16
21
|
|
|
@@ -22,36 +27,40 @@ class Signer {
|
|
|
22
27
|
this.namespace = namespace
|
|
23
28
|
}
|
|
24
29
|
|
|
25
|
-
_ctx
|
|
30
|
+
_ctx() {
|
|
26
31
|
return this.version === 0 ? this.namespace : this.manifestHash
|
|
27
32
|
}
|
|
28
33
|
|
|
29
|
-
verify
|
|
34
|
+
verify(batch, signature) {
|
|
30
35
|
return crypto.verify(batch.signable(this._ctx()), signature, this.publicKey)
|
|
31
36
|
}
|
|
32
37
|
|
|
33
|
-
sign
|
|
38
|
+
sign(batch, keyPair) {
|
|
34
39
|
return crypto.sign(batch.signable(this._ctx()), keyPair.secretKey)
|
|
35
40
|
}
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
class CompatSigner extends Signer {
|
|
39
|
-
constructor
|
|
44
|
+
constructor(index, signer, legacy) {
|
|
40
45
|
super(null, 0, index, signer)
|
|
41
46
|
this.legacy = legacy
|
|
42
47
|
}
|
|
43
48
|
|
|
44
|
-
verify
|
|
49
|
+
verify(batch, signature) {
|
|
45
50
|
return crypto.verify(batch.signableCompat(this.legacy), signature, this.publicKey)
|
|
46
51
|
}
|
|
47
52
|
|
|
48
|
-
sign
|
|
53
|
+
sign(batch, keyPair) {
|
|
49
54
|
return crypto.sign(batch.signableCompat(this.legacy), keyPair.secretKey)
|
|
50
55
|
}
|
|
51
56
|
}
|
|
52
57
|
|
|
53
58
|
module.exports = class Verifier {
|
|
54
|
-
constructor
|
|
59
|
+
constructor(
|
|
60
|
+
manifestHash,
|
|
61
|
+
manifest,
|
|
62
|
+
{ compat = isCompat(manifestHash, manifest), legacy = false } = {}
|
|
63
|
+
) {
|
|
55
64
|
const self = this
|
|
56
65
|
|
|
57
66
|
this.manifestHash = manifestHash
|
|
@@ -62,16 +71,16 @@ module.exports = class Verifier {
|
|
|
62
71
|
this.quorum = this.compat ? 1 : defaultQuorum(manifest)
|
|
63
72
|
|
|
64
73
|
this.signers = manifest.signers ? manifest.signers.map(createSigner) : []
|
|
65
|
-
this.prologue = this.compat ? null :
|
|
74
|
+
this.prologue = this.compat ? null : manifest.prologue || null
|
|
66
75
|
|
|
67
|
-
function createSigner
|
|
76
|
+
function createSigner(signer, index) {
|
|
68
77
|
return self.compat
|
|
69
78
|
? new CompatSigner(index, signer, legacy)
|
|
70
79
|
: new Signer(manifestHash, self.version, index, signer)
|
|
71
80
|
}
|
|
72
81
|
}
|
|
73
82
|
|
|
74
|
-
_verifyCompat
|
|
83
|
+
_verifyCompat(batch, signature) {
|
|
75
84
|
if (!signature) return false
|
|
76
85
|
|
|
77
86
|
if (this.compat || (!this.allowPatch && this.signers.length === 1)) {
|
|
@@ -81,7 +90,7 @@ module.exports = class Verifier {
|
|
|
81
90
|
return this._verifyMulti(batch, signature)
|
|
82
91
|
}
|
|
83
92
|
|
|
84
|
-
_inflate
|
|
93
|
+
_inflate(signature) {
|
|
85
94
|
if (this.version >= 1) return multisig.inflate(signature)
|
|
86
95
|
const { proofs, patch } = multisig.inflatev0(signature)
|
|
87
96
|
|
|
@@ -91,7 +100,7 @@ module.exports = class Verifier {
|
|
|
91
100
|
}
|
|
92
101
|
}
|
|
93
102
|
|
|
94
|
-
_verifyMulti
|
|
103
|
+
_verifyMulti(batch, signature) {
|
|
95
104
|
if (!signature || this.quorum === 0) return false
|
|
96
105
|
|
|
97
106
|
const { proofs, patch } = this._inflate(signature)
|
|
@@ -109,7 +118,14 @@ module.exports = class Verifier {
|
|
|
109
118
|
tree = batch.clone()
|
|
110
119
|
|
|
111
120
|
const upgrade = generateUpgrade(nodes, batch.length, inp.patch)
|
|
112
|
-
const proof = {
|
|
121
|
+
const proof = {
|
|
122
|
+
fork: tree.fork,
|
|
123
|
+
block: null,
|
|
124
|
+
hash: null,
|
|
125
|
+
seek: null,
|
|
126
|
+
upgrade,
|
|
127
|
+
manifest: null
|
|
128
|
+
}
|
|
113
129
|
|
|
114
130
|
try {
|
|
115
131
|
if (!tree.verifyUpgrade(proof)) return false
|
|
@@ -128,7 +144,7 @@ module.exports = class Verifier {
|
|
|
128
144
|
return true
|
|
129
145
|
}
|
|
130
146
|
|
|
131
|
-
verify
|
|
147
|
+
verify(batch, signature) {
|
|
132
148
|
if (this.version === 0) {
|
|
133
149
|
return this._verifyCompat(batch, signature)
|
|
134
150
|
}
|
|
@@ -141,7 +157,7 @@ module.exports = class Verifier {
|
|
|
141
157
|
}
|
|
142
158
|
|
|
143
159
|
// TODO: better api for this that is more ... multisig-ey
|
|
144
|
-
sign
|
|
160
|
+
sign(batch, keyPair) {
|
|
145
161
|
if (!keyPair || !keyPair.secretKey) throw BAD_ARGUMENT('No key pair was passed')
|
|
146
162
|
|
|
147
163
|
for (const s of this.signers) {
|
|
@@ -155,45 +171,47 @@ module.exports = class Verifier {
|
|
|
155
171
|
throw BAD_ARGUMENT('Public key is not a declared signer')
|
|
156
172
|
}
|
|
157
173
|
|
|
158
|
-
assemble
|
|
174
|
+
assemble(inputs) {
|
|
159
175
|
return this.version === 0 ? multisig.assemblev0(inputs) : multisig.assemble(inputs)
|
|
160
176
|
}
|
|
161
177
|
|
|
162
|
-
static manifestHash
|
|
178
|
+
static manifestHash(manifest) {
|
|
163
179
|
return manifestHash(manifest)
|
|
164
180
|
}
|
|
165
181
|
|
|
166
|
-
static encodeManifest
|
|
182
|
+
static encodeManifest(manifest) {
|
|
167
183
|
return c.encode(m.manifest, manifest)
|
|
168
184
|
}
|
|
169
185
|
|
|
170
|
-
static decodeManifest
|
|
186
|
+
static decodeManifest(manifest) {
|
|
171
187
|
return c.decode(m.manifest, manifest)
|
|
172
188
|
}
|
|
173
189
|
|
|
174
|
-
static defaultSignerManifest
|
|
190
|
+
static defaultSignerManifest(publicKey) {
|
|
175
191
|
return {
|
|
176
192
|
version: 1,
|
|
177
193
|
hash: 'blake2b',
|
|
178
194
|
allowPatch: false,
|
|
179
195
|
quorum: 1,
|
|
180
|
-
signers: [
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
196
|
+
signers: [
|
|
197
|
+
{
|
|
198
|
+
signature: 'ed25519',
|
|
199
|
+
namespace: caps.DEFAULT_NAMESPACE,
|
|
200
|
+
publicKey
|
|
201
|
+
}
|
|
202
|
+
],
|
|
185
203
|
prologue: null,
|
|
186
204
|
linked: null,
|
|
187
205
|
userData: null
|
|
188
206
|
}
|
|
189
207
|
}
|
|
190
208
|
|
|
191
|
-
static fromManifest
|
|
209
|
+
static fromManifest(manifest, opts) {
|
|
192
210
|
const m = this.createManifest(manifest)
|
|
193
211
|
return new this(manifestHash(m), m, opts)
|
|
194
212
|
}
|
|
195
213
|
|
|
196
|
-
static createManifest
|
|
214
|
+
static createManifest(inp) {
|
|
197
215
|
if (!inp) return null
|
|
198
216
|
|
|
199
217
|
const manifest = {
|
|
@@ -210,7 +228,10 @@ module.exports = class Verifier {
|
|
|
210
228
|
if (inp.hash && inp.hash !== 'blake2b') throw BAD_ARGUMENT('Only Blake2b hashes are supported')
|
|
211
229
|
|
|
212
230
|
if (inp.prologue) {
|
|
213
|
-
if (
|
|
231
|
+
if (
|
|
232
|
+
!(b4a.isBuffer(inp.prologue.hash) && inp.prologue.hash.byteLength === 32) ||
|
|
233
|
+
!(inp.prologue.length >= 0)
|
|
234
|
+
) {
|
|
214
235
|
throw BAD_ARGUMENT('Invalid prologue')
|
|
215
236
|
}
|
|
216
237
|
|
|
@@ -237,36 +258,40 @@ module.exports = class Verifier {
|
|
|
237
258
|
return manifest
|
|
238
259
|
}
|
|
239
260
|
|
|
240
|
-
static isValidManifest
|
|
261
|
+
static isValidManifest(key, manifest) {
|
|
241
262
|
return b4a.equals(key, manifestHash(manifest))
|
|
242
263
|
}
|
|
243
264
|
|
|
244
|
-
static isCompat
|
|
265
|
+
static isCompat(key, manifest) {
|
|
245
266
|
return isCompat(key, manifest)
|
|
246
267
|
}
|
|
247
268
|
|
|
248
|
-
static sign
|
|
269
|
+
static sign(manifest, batch, keyPair, opts) {
|
|
249
270
|
return Verifier.fromManifest(manifest, opts).sign(batch, keyPair)
|
|
250
271
|
}
|
|
251
272
|
}
|
|
252
273
|
|
|
253
|
-
function toMap
|
|
274
|
+
function toMap(nodes) {
|
|
254
275
|
const m = new Map()
|
|
255
276
|
for (const node of nodes) m.set(node.index, node)
|
|
256
277
|
return m
|
|
257
278
|
}
|
|
258
279
|
|
|
259
|
-
function isCompat
|
|
260
|
-
return !!(
|
|
280
|
+
function isCompat(key, manifest) {
|
|
281
|
+
return !!(
|
|
282
|
+
manifest &&
|
|
283
|
+
manifest.signers.length === 1 &&
|
|
284
|
+
b4a.equals(key, manifest.signers[0].publicKey)
|
|
285
|
+
)
|
|
261
286
|
}
|
|
262
287
|
|
|
263
|
-
function defaultQuorum
|
|
288
|
+
function defaultQuorum(man) {
|
|
264
289
|
if (typeof man.quorum === 'number') return man.quorum
|
|
265
290
|
if (!man.signers || !man.signers.length) return 0
|
|
266
291
|
return (man.signers.length >> 1) + 1
|
|
267
292
|
}
|
|
268
293
|
|
|
269
|
-
function generateUpgrade
|
|
294
|
+
function generateUpgrade(patch, start, length) {
|
|
270
295
|
const upgrade = { start, length, nodes: null, additionalNodes: [], signature: null }
|
|
271
296
|
|
|
272
297
|
const from = start * 2
|
|
@@ -300,7 +325,7 @@ function generateUpgrade (patch, start, length) {
|
|
|
300
325
|
return upgrade
|
|
301
326
|
}
|
|
302
327
|
|
|
303
|
-
function parseSigner
|
|
328
|
+
function parseSigner(signer) {
|
|
304
329
|
validateSigner(signer)
|
|
305
330
|
return {
|
|
306
331
|
signature: 'ed25519',
|
|
@@ -309,12 +334,13 @@ function parseSigner (signer) {
|
|
|
309
334
|
}
|
|
310
335
|
}
|
|
311
336
|
|
|
312
|
-
function validateSigner
|
|
337
|
+
function validateSigner(signer) {
|
|
313
338
|
if (!signer || !signer.publicKey) throw BAD_ARGUMENT('Signer missing public key')
|
|
314
|
-
if (signer.signature && signer.signature !== 'ed25519')
|
|
339
|
+
if (signer.signature && signer.signature !== 'ed25519')
|
|
340
|
+
throw BAD_ARGUMENT('Only Ed25519 signatures are supported')
|
|
315
341
|
}
|
|
316
342
|
|
|
317
|
-
function manifestHash
|
|
343
|
+
function manifestHash(manifest) {
|
|
318
344
|
const state = { start: 0, end: 32, buffer: null }
|
|
319
345
|
m.manifest.preencode(state, manifest)
|
|
320
346
|
state.buffer = b4a.allocUnsafe(state.end)
|
|
@@ -323,7 +349,7 @@ function manifestHash (manifest) {
|
|
|
323
349
|
return crypto.hash(state.buffer)
|
|
324
350
|
}
|
|
325
351
|
|
|
326
|
-
function proofToVersion1
|
|
352
|
+
function proofToVersion1(proof) {
|
|
327
353
|
return {
|
|
328
354
|
signer: proof.signer,
|
|
329
355
|
signature: proof.signature,
|
|
@@ -331,7 +357,7 @@ function proofToVersion1 (proof) {
|
|
|
331
357
|
}
|
|
332
358
|
}
|
|
333
359
|
|
|
334
|
-
function getManifestVersion
|
|
360
|
+
function getManifestVersion(inp) {
|
|
335
361
|
if (typeof inp.version === 'number') return inp.version
|
|
336
362
|
if (inp.linked && inp.linked.length) return 2
|
|
337
363
|
if (inp.userData) return 2
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hypercore",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.17.0",
|
|
4
4
|
"description": "Hypercore is a secure, distributed append-only log",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"
|
|
7
|
+
"format": "prettier --write .",
|
|
8
|
+
"test": "prettier --check . && brittle test/all.js",
|
|
8
9
|
"test:bare": "bare test/all.js",
|
|
9
10
|
"test:generate": "brittle -r test/all.js test/*.js"
|
|
10
11
|
},
|
|
@@ -68,11 +69,12 @@
|
|
|
68
69
|
"brittle": "^3.0.0",
|
|
69
70
|
"debugging-stream": "^3.1.0",
|
|
70
71
|
"hyperswarm": "^4.3.6",
|
|
72
|
+
"prettier": "^3.6.2",
|
|
73
|
+
"prettier-config-holepunch": "^2.0.0",
|
|
71
74
|
"rache": "^1.0.0",
|
|
72
75
|
"range-parser": "^1.2.1",
|
|
73
76
|
"resolve-reject-promise": "^1.1.0",
|
|
74
77
|
"speedometer": "^1.1.0",
|
|
75
|
-
"standard": "^17.0.0",
|
|
76
78
|
"test-tmp": "^1.0.2",
|
|
77
79
|
"tiny-byte-size": "^1.1.0",
|
|
78
80
|
"udx-native": "^1.6.1",
|