@node-dlc/core
Version:
79 lines • 3.24 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CommitmentSecretStore = void 0;
const CommitmentSecret_1 = require("./CommitmentSecret");
/**
* Defined in BOLT3, this class compactly stored received commitment
* secrets from our counterparty. Without this mechanism we are required
* to store every commitment secret that we receive (2^48) which can be
* a huge amount of data at 32-bytes per secret.
*
* Instead we can use the fact that later commitment secrets act as
* prefixes for prior commitment secrets. We can then compactly store
* only the secrets we need to derive older commitment secrets.
*/
class CommitmentSecretStore {
/**
* Returns the index of the least-significant bit. This is used to
* determine what the value at I is a prefix for.
* @param I commitment
*/
static calcIndex(I) {
for (let i = BigInt(0); i < BigInt(48); i++) {
if (I & (BigInt(1) << i))
return Number(i);
}
return 48; // seed
}
constructor() {
this.secrets = new Array(49);
for (let i = 0; i < this.secrets.length; i++) {
this.secrets[i] = { index: BigInt(0), secret: undefined };
}
}
/**
* Insert the commitment secret into the store and verify that the
* secret is able to derive all prior commitment secrets that we
* already know about.
*
* @param secret 32-byte secp256k1 secret
* @param i commitment number
*/
insert(secret, i) {
const B = CommitmentSecretStore.calcIndex(i);
// validate that the new secret allows derivation of known keys
// up to the new key
for (let b = 0; b < B; b++) {
const existing = this.secrets[b].secret;
const derived = CommitmentSecret_1.CommitmentSecret.derive(secret, this.secrets[b].index, B);
if (!derived.equals(existing)) {
throw new Error('The secret for I is incorrect');
}
}
// update the position
this.secrets[Number(B)].index = i;
this.secrets[Number(B)].secret = secret;
}
/**
* Derives old commitment secrets from the from the compact store.
* Throws if we do not have the commitment secret for the specified
* commitment nmber.
* @param i derivation number starting at 2^48-1 down to zero.
*/
derive(i) {
for (let b = 0; b < this.secrets.length; b++) {
// construct a mask of the upper bits. Basically we lop off
// the lower b bits and then right-shift back into place
const mask = (BigInt(0xffffffffffff) >> BigInt(b)) << BigInt(b);
// Check if the prefix found using I & mask is one that we
// can use to derive our value. If not, we need to try
// another bit.
if ((i & mask) === this.secrets[b].index && this.secrets[b].secret) {
return CommitmentSecret_1.CommitmentSecret.derive(this.secrets[b].secret, i, b);
}
}
throw new Error("Index I hasn't been received yet");
}
}
exports.CommitmentSecretStore = CommitmentSecretStore;
//# sourceMappingURL=CommitmentSecretStore.js.map