Skip to content

Commit

Permalink
update scheme and fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mafintosh committed Feb 12, 2024
1 parent bbfdf53 commit 33c3c0f
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 149 deletions.
15 changes: 2 additions & 13 deletions lib/caps.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,10 @@ exports.replicate = function (isInitiator, key, handshakeHash) {
return out
}

exports.treeSignable = function (namespace, manifestHash, treeHash, length, fork) {
const state = { start: 0, end: 144, buffer: b4a.allocUnsafe(144) }
c.raw.encode(state, TREE)
c.raw.encode(state, namespace)
c.raw.encode(state, manifestHash)
c.raw.encode(state, treeHash)
c.uint64.encode(state, length)
c.uint64.encode(state, fork)
return state.buffer
}

exports.treeSignableV0 = function (namespace, treeHash, length, fork) {
exports.treeSignable = function (manifestHash, treeHash, length, fork) {
const state = { start: 0, end: 112, buffer: b4a.allocUnsafe(112) }
c.raw.encode(state, TREE)
c.raw.encode(state, namespace)
c.raw.encode(state, manifestHash)
c.raw.encode(state, treeHash)
c.uint64.encode(state, length)
c.uint64.encode(state, fork)
Expand Down
8 changes: 2 additions & 6 deletions lib/merkle-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,8 @@ class MerkleTreeBatch {
return this.hashCached
}

signable (namespace, manifestHash) {
return caps.treeSignable(namespace, manifestHash, this.hash(), this.length, this.fork)
}

signableV0 (namespace) {
return caps.treeSignableV0(namespace, this.hash(), this.length, this.fork)
signable (manifestHash) {
return caps.treeSignable(manifestHash, this.hash(), this.length, this.fork)
}

signableCompat (noHeader) {
Expand Down
30 changes: 12 additions & 18 deletions lib/verifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,35 @@ const multisig = require('./multisig')
const caps = require('./caps')

class Signer {
constructor (crypto, index, { signature = 'ed25519', publicKey, namespace = caps.DEFAULT_NAMESPACE } = {}) {
constructor (crypto, version, index, { signature = 'ed25519', publicKey, namespace = caps.DEFAULT_NAMESPACE } = {}) {
if (!publicKey) throw BAD_ARGUMENT('public key is required for a signer')
if (signature !== 'ed25519') throw BAD_ARGUMENT('Only Ed25519 signatures are supported')

this.crypto = crypto
this.version = version
this.signer = index
this.manifestHash = null // set after construction
this.signature = signature
this.publicKey = publicKey
this.namespace = namespace
}

verify (batch, signature) {
return this.crypto.verify(batch.signable(this.namespace, this.manifestHash), signature, this.publicKey)
_ctx () {
return this.version === 0 ? this.namespace : this.manifestHash
}

sign (batch, keyPair) {
return this.crypto.sign(batch.signable(this.namespace, this.manifestHash), keyPair.secretKey)
}
}

class SignerV0 extends Signer {
verify (batch, signature) {
return this.crypto.verify(batch.signableV0(this.namespace), signature, this.publicKey)
return this.crypto.verify(batch.signable(this._ctx()), signature, this.publicKey)
}

sign (batch, keyPair) {
return this.crypto.sign(batch.signableV0(this.namespace), keyPair.secretKey)
return this.crypto.sign(batch.signable(this._ctx()), keyPair.secretKey)
}
}

class CompatSigner extends Signer {
constructor (crypto, index, signer, legacy) {
super(crypto, index, signer)
super(crypto, 0, index, signer)
this.legacy = legacy
}

Expand Down Expand Up @@ -75,9 +70,9 @@ module.exports = class Verifier {
}

function createSigner (signer, index) {
if (self.compat) return new CompatSigner(crypto, index, signer, legacy)
if (self.version === 0) return new SignerV0(crypto, index, signer)
return new Signer(crypto, index, signer)
return self.compat
? new CompatSigner(crypto, index, signer, legacy)
: new Signer(crypto, self.version, index, signer)
}
}

Expand Down Expand Up @@ -153,17 +148,16 @@ module.exports = class Verifier {
// TODO: better api for this that is more ... multisig-ey
sign (batch, keyPair) {
if (!keyPair || !keyPair.secretKey) throw BAD_ARGUMENT('No key pair was passed')
// if (this.signers.length > 1 || this.allowPatch) throw BAD_ARGUMENT('Can only sign directly for single signers')

for (const s of this.signers) {
if (s.publicKey.equals(keyPair.publicKey)) {
if (b4a.equals(s.publicKey, keyPair.publicKey)) {
const signature = s.sign(batch, keyPair)
if (this.signers.length !== 1 || this.version === 0) return signature
return this.assemble([{ signer: 0, signature, patch: 0, nodes: null }])
}
}

throw new Error('Public key is not a declared signer')
throw new BAD_ARGUMENT('Public key is not a declared signer')
}

assemble (inputs) {
Expand Down
Loading

0 comments on commit 33c3c0f

Please sign in to comment.