bitcoinpqc
Version:
NodeJS TypeScript bindings for Bitcoin PQC library
125 lines (124 loc) • 4.92 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getLibrary = getLibrary;
exports.setLibraryForTesting = setLibraryForTesting;
const types_1 = require("./types");
// Try to load the native addon
let nativeAddon = null;
try {
nativeAddon = require("../build/Release/bitcoinpqc");
console.log("Loaded native addon successfully");
}
catch (error) {
console.warn("Failed to load native addon:", error);
}
// Mock library implementation as fallback
class MockBitcoinPqcNative {
constructor() {
// These values are from the actual implementation
this.keySizes = {
[types_1.Algorithm.SECP256K1_SCHNORR]: {
publicKey: 32,
secretKey: 32,
signature: 64,
},
[types_1.Algorithm.FN_DSA_512]: { publicKey: 897, secretKey: 1281, signature: 666 }, // Average size
[types_1.Algorithm.ML_DSA_44]: {
publicKey: 1312,
secretKey: 2528,
signature: 2420,
},
[types_1.Algorithm.SLH_DSA_SHAKE_128S]: {
publicKey: 32,
secretKey: 64,
signature: 7856,
},
};
}
bitcoin_pqc_public_key_size(algorithm) {
return this.keySizes[algorithm]?.publicKey || 0;
}
bitcoin_pqc_secret_key_size(algorithm) {
return this.keySizes[algorithm]?.secretKey || 0;
}
bitcoin_pqc_signature_size(algorithm) {
return this.keySizes[algorithm]?.signature || 0;
}
bitcoin_pqc_keygen(algorithm, randomData) {
if (randomData.length < 128) {
return {
publicKey: new Uint8Array(0),
secretKey: new Uint8Array(0),
resultCode: types_1.ErrorCode.BAD_ARGUMENT,
};
}
if (algorithm < 0 || algorithm > 3) {
return {
publicKey: new Uint8Array(0),
secretKey: new Uint8Array(0),
resultCode: types_1.ErrorCode.BAD_ARGUMENT,
};
}
const pkSize = this.bitcoin_pqc_public_key_size(algorithm);
const skSize = this.bitcoin_pqc_secret_key_size(algorithm);
// In a real implementation, this would call the native library
// Here we're just creating dummy keys based on the random data
const publicKey = new Uint8Array(pkSize);
const secretKey = new Uint8Array(skSize);
// Use random data to populate the key
for (let i = 0; i < pkSize && i < randomData.length; i++) {
publicKey[i] = randomData[i];
}
for (let i = 0; i < skSize && i < randomData.length; i++) {
secretKey[i] = randomData[i + Math.floor(randomData.length / 2)];
}
return { publicKey, secretKey, resultCode: types_1.ErrorCode.OK };
}
bitcoin_pqc_sign(algorithm, secretKey, message) {
if (algorithm < 0 || algorithm > 3) {
return {
signature: new Uint8Array(0),
resultCode: types_1.ErrorCode.BAD_ARGUMENT,
};
}
const expectedSize = this.bitcoin_pqc_secret_key_size(algorithm);
if (secretKey.length !== expectedSize) {
return { signature: new Uint8Array(0), resultCode: types_1.ErrorCode.BAD_KEY };
}
const sigSize = this.bitcoin_pqc_signature_size(algorithm);
const signature = new Uint8Array(sigSize);
// In a real implementation, this would call the native library
// Here we're just creating a dummy signature
// In reality, this would be a deterministic signature based on the message and secret key
for (let i = 0; i < sigSize; i++) {
signature[i] = i < message.length ? message[i] : 0;
}
return { signature, resultCode: types_1.ErrorCode.OK };
}
bitcoin_pqc_verify(algorithm, publicKey, message, signature) {
if (algorithm < 0 || algorithm > 3) {
return types_1.ErrorCode.BAD_ARGUMENT;
}
const expectedPkSize = this.bitcoin_pqc_public_key_size(algorithm);
if (publicKey.length !== expectedPkSize) {
return types_1.ErrorCode.BAD_KEY;
}
const expectedSigSize = this.bitcoin_pqc_signature_size(algorithm);
if (signature.length !== expectedSigSize) {
return types_1.ErrorCode.BAD_SIGNATURE;
}
// In a real implementation, this would verify the signature
// Here we're just pretending it's valid
return types_1.ErrorCode.OK;
}
}
// Fall back to mock implementation if native addon is not available
const addonOrMock = nativeAddon || new MockBitcoinPqcNative();
// Get the library instance
function getLibrary() {
return addonOrMock;
}
// For testing - allow library to be replaced
function setLibraryForTesting(mockLib) {
nativeAddon = mockLib;
}