bip322-js
Version:
A Javascript library that provides utility functions related to the BIP-322 signature scheme
101 lines • 5.33 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const elliptic_1 = require("elliptic");
/**
* Class that implement key-related utility functions.
*/
class Key {
/**
* Converts a 33-byte Bitcoin public key to a 32-byte x-only public key as used in Taproot.
* This function checks if the provided public key buffer is already 32 bytes long,
* in which case it returns the buffer unchanged. If the buffer is 33 bytes long, it
* assumes that the first byte is the parity byte used for indicating the y-coordinate
* in traditional SEC1 encoding and removes this byte, thereby converting the public key
* to an x-only format suitable for use with Bitcoin's Taproot.
*
* Adopted from https://github.com/ACken2/bip322-js/pull/6 by Czino
*
* @param publicKey The buffer containing the 33-byte or 32-byte public key to be converted.
* @returns A 32-byte buffer of the x-only public key.
* @throws If the public key is neither 32-byte nor 33-byte long
*/
static toXOnly(publicKey) {
// Throw if the input key length is invalid
if (publicKey.length !== 32 && publicKey.length !== 33) {
throw new Error("Invalid public key length");
}
// Otherwise, return the key (with the first byte removed if it is 33-byte long)
return Buffer.from(publicKey.length === 32 ? publicKey : publicKey.subarray(1, 33));
}
/**
* Compresses an uncompressed public key using the elliptic curve secp256k1.
* This method takes a public key in its uncompressed form and returns a compressed
* representation of the public key. Elliptic curve public keys can be represented in
* a shorter form known as compressed format which saves space and still retains the
* full public key's capabilities. The method uses the elliptic library to convert the
* uncompressed public key into its compressed form.
*
* The steps involved in the process are:
* 1. Initialize a new elliptic curve instance for the secp256k1 curve.
* 2. Create a key pair object from the uncompressed public key buffer.
* 3. Extract the compressed public key from the key pair object.
* 4. Return the compressed public key as a Buffer object.
*
* @param uncompressedPublicKey A Buffer containing the uncompressed public key.
* @return Buffer Returns a Buffer containing the compressed public key.
* @throws Error Throws an error if the provided public key cannot be compressed,
* typically indicating that the key is not valid.
*/
static compressPublicKey(uncompressedPublicKey) {
// Initialize elliptic curve
const ec = new elliptic_1.ec('secp256k1');
// Try to compress the provided public key
try {
// Create a key pair from the uncompressed public key buffer
const keyPair = ec.keyFromPublic(Buffer.from(uncompressedPublicKey));
// Get the compressed public key as a Buffer
const compressedPublicKey = Buffer.from(keyPair.getPublic(true, 'array'));
return compressedPublicKey;
}
catch (err) {
throw new Error('Fails to compress the provided public key. Please check if the provided key is a valid uncompressed public key.');
}
}
/**
* Uncompresses a given public key using the elliptic curve secp256k1.
* This method accepts a compressed public key and attempts to convert it into its
* uncompressed form. Public keys are often compressed to save space, but certain
* operations require the full uncompressed key. This method uses the elliptic
* library to perform the conversion.
*
* The function operates as follows:
* 1. Initialize a new elliptic curve instance using secp256k1.
* 2. Attempt to create a key pair from the compressed public key buffer.
* 3. Extract the uncompressed public key from the key pair object.
* 4. Return the uncompressed public key as a Buffer object.
* If the compressed public key provided is invalid and cannot be uncompressed,
* the method will throw an error with a descriptive message.
*
* @param compressedPublicKey A Buffer containing the compressed public key.
* @return Buffer The uncompressed public key as a Buffer.
* @throws Error Throws an error if the provided public key cannot be uncompressed,
* typically indicating that the key is not valid.
*/
static uncompressPublicKey(compressedPublicKey) {
// Initialize elliptic curve
const ec = new elliptic_1.ec('secp256k1');
// Try to uncompress the provided public key
try {
// Create a key pair from the compressed public key buffer
const keyPair = ec.keyFromPublic(Buffer.from(compressedPublicKey));
// Get the compressed public key as a Buffer
const uncompressedPublicKey = Buffer.from(keyPair.getPublic(false, 'array'));
return uncompressedPublicKey;
}
catch (err) {
throw new Error('Fails to uncompress the provided public key. Please check if the provided key is a valid compressed public key.');
}
}
}
exports.default = Key;
//# sourceMappingURL=Key.js.map
;