@node-dlc/core
Version:
95 lines (89 loc) • 3.05 kB
text/typescript
import { LockTime, Sequence } from '@node-dlc/bitcoin';
import { bigFromBufBE } from '@node-dlc/bufio';
import { sha256 } from '@node-dlc/crypto';
export class CommitmentNumber {
/**
* Using the obscured commitment number, creates a Sequence with
* the upper byte set to 0x80 and the lower three bytes set to the
* upper 3 bytes of the 48-bit commitment number.
*
* The upper most byte is set to 0x80 so that the relative lock time
* is disabled.
*
* @param commitment commitment number to obscure
*/
public static getSequence(obscurred: bigint): Sequence {
return new Sequence(
Number((BigInt(0x80) << BigInt(24)) | (obscurred >> BigInt(24))),
);
}
/**
* Using the obscured commitment number, creates a LockTime with
* the upper byte set to 0x20 and the lower three bytes set to the
* lower 3 bytes of the 48-bit commitment number.
*
* The uppermost byte is set to 0x20 so the LockTime uses a time
* based absolute locktime that has already expired.
*
* @param obscurred obscurred commitment number
*/
public static getLockTime(obscurred: bigint): LockTime {
return new LockTime(
Number((BigInt(0x20) << BigInt(24)) | (obscurred & BigInt(0xffffff))),
);
}
/**
* Reveals the commitment number provided by the nSequence and
* nLockTime values. This function reverses the obscurring using the
* known payment base points.
*
* @param locktime
* @param sequence
*/
public static reveal(
locktime: LockTime,
sequence: Sequence,
openBasePoint: Buffer,
acceptBasePoint: Buffer,
): number {
const hash = CommitmentNumber.getHash(openBasePoint, acceptBasePoint);
const upper = BigInt(sequence.value & 0xffffff) << BigInt(24);
const lower = BigInt(locktime.value & 0xffffff);
return Number(hash ^ (upper | lower));
}
/**
* Defined in BOLT3, the obscurred commitment number is attached to the
* commitment transaction. The 48-bit commitment number is broken into
* two pieces, the lower 3-bytes are obscured in nLocketime and the
* upper 3-bytes are obscured in the funding input's nSequence.
*
* The obscurred commitment number is calculated as the:
* sha256(open_channel payment_basepoint || accept_channel payment_basepoint) ^ commitment_number
* @param commitment
* @param openBasePoint
* @param acceptBasePoint
*/
public static obscure(
commitment: number,
openBasePoint: Buffer,
acceptBasePoint: Buffer,
): bigint {
return (
CommitmentNumber.getHash(openBasePoint, acceptBasePoint) ^
BigInt(commitment)
);
}
/**
* Obtains the lower 6-bytes from the sha256 of the open_channel
* basepoint and the accept_channel basepoint.
* @param openBasePoint
* @param acceptBasePoint
*/
private static getHash(
openBasePoint: Buffer,
acceptBasePoint: Buffer,
): bigint {
const hash = sha256(Buffer.concat([openBasePoint, acceptBasePoint]));
return bigFromBufBE(hash.slice(hash.length - 6));
}
}