UNPKG

@node-dlc/core

Version:
79 lines 3.24 kB
"use strict"; 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