hypercore 10.32.8 → 10.33.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/lib/caps.js +6 -6
- package/lib/core.js +5 -6
- package/lib/merkle-tree.js +2 -2
- package/lib/verifier.js +42 -19
- package/package.json +1 -1
package/lib/caps.js
CHANGED
|
@@ -25,11 +25,11 @@ exports.replicate = function (isInitiator, key, handshakeHash) {
|
|
|
25
25
|
return out
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
exports.treeSignable = function (
|
|
28
|
+
exports.treeSignable = function (manifestHash, treeHash, length, fork) {
|
|
29
29
|
const state = { start: 0, end: 112, buffer: b4a.allocUnsafe(112) }
|
|
30
|
-
c.
|
|
31
|
-
c.
|
|
32
|
-
c.
|
|
30
|
+
c.fixed32.encode(state, TREE)
|
|
31
|
+
c.fixed32.encode(state, manifestHash)
|
|
32
|
+
c.fixed32.encode(state, treeHash)
|
|
33
33
|
c.uint64.encode(state, length)
|
|
34
34
|
c.uint64.encode(state, fork)
|
|
35
35
|
return state.buffer
|
|
@@ -38,8 +38,8 @@ exports.treeSignable = function (namespace, hash, length, fork) {
|
|
|
38
38
|
exports.treeSignableCompat = function (hash, length, fork, noHeader) {
|
|
39
39
|
const end = noHeader ? 48 : 80
|
|
40
40
|
const state = { start: 0, end, buffer: b4a.allocUnsafe(end) }
|
|
41
|
-
if (!noHeader) c.
|
|
42
|
-
c.
|
|
41
|
+
if (!noHeader) c.fixed32.encode(state, TREE) // ultra legacy mode, kill in future major
|
|
42
|
+
c.fixed32.encode(state, hash)
|
|
43
43
|
c.uint64.encode(state, length)
|
|
44
44
|
c.uint64.encode(state, fork)
|
|
45
45
|
return state.buffer
|
package/lib/core.js
CHANGED
|
@@ -158,7 +158,7 @@ module.exports = class Core {
|
|
|
158
158
|
while (bitfield.get(header.hints.contiguousLength)) header.hints.contiguousLength++
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
const verifier = header.manifest ? new Verifier(header.
|
|
161
|
+
const verifier = header.manifest ? new Verifier(header.key, header.manifest, { crypto, legacy }) : null
|
|
162
162
|
|
|
163
163
|
for (const e of entries) {
|
|
164
164
|
if (e.userData) {
|
|
@@ -197,13 +197,12 @@ module.exports = class Core {
|
|
|
197
197
|
if (!manifest && b4a.equals(keyPair.publicKey, this.header.key)) manifest = Verifier.defaultSignerManifest(this.header.key)
|
|
198
198
|
if (!manifest) return
|
|
199
199
|
|
|
200
|
-
const
|
|
201
|
-
const verifier = new Verifier(manifest, { compat, crypto: this.crypto, legacy: this._legacy })
|
|
200
|
+
const verifier = new Verifier(this.header.key, manifest, { crypto: this.crypto, legacy: this._legacy })
|
|
202
201
|
|
|
203
202
|
if (verifier.prologue) this.tree.setPrologue(verifier.prologue)
|
|
204
203
|
|
|
205
|
-
this.compat = compat
|
|
206
204
|
this.header.manifest = manifest
|
|
205
|
+
this.compat = verifier.compat
|
|
207
206
|
this.verifier = verifier
|
|
208
207
|
this._manifestFlushed = false
|
|
209
208
|
|
|
@@ -681,15 +680,15 @@ module.exports = class Core {
|
|
|
681
680
|
}
|
|
682
681
|
}
|
|
683
682
|
|
|
684
|
-
const verifier = this.verifier || new Verifier(
|
|
683
|
+
const verifier = this.verifier || new Verifier(this.header.key, manifest, { crypto: this.crypto, legacy: this._legacy })
|
|
685
684
|
|
|
686
685
|
if (!verifier.verify(batch, batch.signature)) {
|
|
687
686
|
throw INVALID_SIGNATURE('Proof contains an invalid signature')
|
|
688
687
|
}
|
|
689
688
|
|
|
690
689
|
if (!this.header.manifest) {
|
|
691
|
-
this.compat = Verifier.isCompat(this.header.key, manifest)
|
|
692
690
|
this.header.manifest = manifest
|
|
691
|
+
this.compat = verifier.compat
|
|
693
692
|
this.verifier = verifier
|
|
694
693
|
this.onupdate(0b10000, null, null, null)
|
|
695
694
|
}
|
package/lib/merkle-tree.js
CHANGED
|
@@ -79,8 +79,8 @@ class MerkleTreeBatch {
|
|
|
79
79
|
return this.hashCached
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
signable (
|
|
83
|
-
return caps.treeSignable(
|
|
82
|
+
signable (manifestHash) {
|
|
83
|
+
return caps.treeSignable(manifestHash, this.hash(), this.length, this.fork)
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
signableCompat (noHeader) {
|
package/lib/verifier.js
CHANGED
|
@@ -9,29 +9,35 @@ const multisig = require('./multisig')
|
|
|
9
9
|
const caps = require('./caps')
|
|
10
10
|
|
|
11
11
|
class Signer {
|
|
12
|
-
constructor (crypto, index, { signature = 'ed25519', publicKey, namespace = caps.DEFAULT_NAMESPACE } = {}) {
|
|
12
|
+
constructor (crypto, manifestHash, version, index, { signature = 'ed25519', publicKey, namespace = caps.DEFAULT_NAMESPACE } = {}) {
|
|
13
13
|
if (!publicKey) throw BAD_ARGUMENT('public key is required for a signer')
|
|
14
14
|
if (signature !== 'ed25519') throw BAD_ARGUMENT('Only Ed25519 signatures are supported')
|
|
15
15
|
|
|
16
16
|
this.crypto = crypto
|
|
17
|
+
this.manifestHash = manifestHash
|
|
18
|
+
this.version = version
|
|
17
19
|
this.signer = index
|
|
18
20
|
this.signature = signature
|
|
19
21
|
this.publicKey = publicKey
|
|
20
22
|
this.namespace = namespace
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
_ctx () {
|
|
26
|
+
return this.version === 0 ? this.namespace : this.manifestHash
|
|
27
|
+
}
|
|
28
|
+
|
|
23
29
|
verify (batch, signature) {
|
|
24
|
-
return this.crypto.verify(batch.signable(this.
|
|
30
|
+
return this.crypto.verify(batch.signable(this._ctx()), signature, this.publicKey)
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
sign (batch, keyPair) {
|
|
28
|
-
return this.crypto.sign(batch.signable(this.
|
|
34
|
+
return this.crypto.sign(batch.signable(this._ctx()), keyPair.secretKey)
|
|
29
35
|
}
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
class CompatSigner extends Signer {
|
|
33
39
|
constructor (crypto, index, signer, legacy) {
|
|
34
|
-
super(crypto, index, signer)
|
|
40
|
+
super(crypto, null, 0, index, signer)
|
|
35
41
|
this.legacy = legacy
|
|
36
42
|
}
|
|
37
43
|
|
|
@@ -45,16 +51,24 @@ class CompatSigner extends Signer {
|
|
|
45
51
|
}
|
|
46
52
|
|
|
47
53
|
module.exports = class Verifier {
|
|
48
|
-
constructor (manifest, { compat =
|
|
54
|
+
constructor (manifestHash, manifest, { compat = isCompat(manifestHash, manifest), crypto = defaultCrypto, legacy = false } = {}) {
|
|
55
|
+
const self = this
|
|
56
|
+
|
|
57
|
+
this.manifestHash = manifestHash
|
|
49
58
|
this.compat = compat || manifest === null
|
|
50
59
|
this.version = this.compat ? 0 : typeof manifest.version === 'number' ? manifest.version : 1
|
|
51
60
|
this.hash = manifest.hash || 'blake2b'
|
|
52
61
|
this.allowPatch = !this.compat && !!manifest.allowPatch
|
|
53
62
|
this.quorum = this.compat ? 1 : defaultQuorum(manifest)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
: []
|
|
63
|
+
|
|
64
|
+
this.signers = manifest.signers ? manifest.signers.map(createSigner) : []
|
|
57
65
|
this.prologue = this.compat ? null : (manifest.prologue || null)
|
|
66
|
+
|
|
67
|
+
function createSigner (signer, index) {
|
|
68
|
+
return self.compat
|
|
69
|
+
? new CompatSigner(crypto, index, signer, legacy)
|
|
70
|
+
: new Signer(crypto, manifestHash, self.version, index, signer)
|
|
71
|
+
}
|
|
58
72
|
}
|
|
59
73
|
|
|
60
74
|
_verifyCompat (batch, signature) {
|
|
@@ -129,21 +143,22 @@ module.exports = class Verifier {
|
|
|
129
143
|
// TODO: better api for this that is more ... multisig-ey
|
|
130
144
|
sign (batch, keyPair) {
|
|
131
145
|
if (!keyPair || !keyPair.secretKey) throw BAD_ARGUMENT('No key pair was passed')
|
|
132
|
-
if (this.signers.length > 1 || this.allowPatch) throw BAD_ARGUMENT('Can only sign directly for single signers')
|
|
133
146
|
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
147
|
+
for (const s of this.signers) {
|
|
148
|
+
if (b4a.equals(s.publicKey, keyPair.publicKey)) {
|
|
149
|
+
const signature = s.sign(batch, keyPair)
|
|
150
|
+
if (this.signers.length !== 1 || this.version === 0) return signature
|
|
151
|
+
return this.assemble([{ signer: 0, signature, patch: 0, nodes: null }])
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
throw new BAD_ARGUMENT('Public key is not a declared signer')
|
|
137
156
|
}
|
|
138
157
|
|
|
139
158
|
assemble (inputs) {
|
|
140
159
|
return this.version === 0 ? multisig.assemblev0(inputs) : multisig.assemble(inputs)
|
|
141
160
|
}
|
|
142
161
|
|
|
143
|
-
manifestHash () {
|
|
144
|
-
return manifestHash(this)
|
|
145
|
-
}
|
|
146
|
-
|
|
147
162
|
static manifestHash (manifest) {
|
|
148
163
|
return manifestHash(manifest)
|
|
149
164
|
}
|
|
@@ -163,6 +178,11 @@ module.exports = class Verifier {
|
|
|
163
178
|
}
|
|
164
179
|
}
|
|
165
180
|
|
|
181
|
+
static fromManifest (manifest, opts) {
|
|
182
|
+
const m = this.createManifest(manifest)
|
|
183
|
+
return new this(manifestHash(m), m, opts)
|
|
184
|
+
}
|
|
185
|
+
|
|
166
186
|
static createManifest (inp) {
|
|
167
187
|
if (!inp) return null
|
|
168
188
|
|
|
@@ -192,12 +212,11 @@ module.exports = class Verifier {
|
|
|
192
212
|
}
|
|
193
213
|
|
|
194
214
|
static isCompat (key, manifest) {
|
|
195
|
-
return
|
|
215
|
+
return isCompat(key, manifest)
|
|
196
216
|
}
|
|
197
217
|
|
|
198
218
|
static sign (manifest, batch, keyPair, opts) {
|
|
199
|
-
|
|
200
|
-
return v.sign(batch, keyPair)
|
|
219
|
+
return Verifier.fromManifest(manifest, opts).sign(batch, keyPair)
|
|
201
220
|
}
|
|
202
221
|
}
|
|
203
222
|
|
|
@@ -207,6 +226,10 @@ function toMap (nodes) {
|
|
|
207
226
|
return m
|
|
208
227
|
}
|
|
209
228
|
|
|
229
|
+
function isCompat (key, manifest) {
|
|
230
|
+
return !!(manifest && manifest.signers.length === 1 && b4a.equals(key, manifest.signers[0].publicKey))
|
|
231
|
+
}
|
|
232
|
+
|
|
210
233
|
function defaultQuorum (man) {
|
|
211
234
|
if (typeof man.quorum === 'number') return man.quorum
|
|
212
235
|
if (!man.signers || !man.signers.length) return 0
|