| Crates.io | bitcoinpqc |
| lib.rs | bitcoinpqc |
| version | 0.2.0 |
| created_at | 2025-03-21 12:48:20.596438+00 |
| updated_at | 2025-09-16 16:18:35.936168+00 |
| description | Post-Quantum Cryptographic signature algorithms for Bitcoin (BIP-360) |
| homepage | |
| repository | https://github.com/bitcoin/libbitcoinpqc |
| max_upload_size | |
| id | 1600448 |
| size | 1,787,661 |
A C library, with Rust bindings, for Post-Quantum Cryptographic (PQC) signature algorithms. This library implements two NIST PQC standard signature algorithms for use with BIP-360 and the Bitcoin QuBit soft fork:
Notice that all PQC signature algorithms used are certified according to the Federal Information Processing Standards, or FIPS. This should help in the future with native hardware support.
This library serves as the cryptographic foundation for the Bitcoin QuBit soft fork, which aims to make Bitcoin's signature verification quantum-resistant through the implementation of BIP-360. QuBit introduces new post-quantum secure transaction types that can protect Bitcoin from potential threats posed by quantum computers.
| Algorithm | Public Key Size | Secret Key Size | Signature Size | Security Level |
|---|---|---|---|---|
| secp256k1 | 32 bytes | 32 bytes | 64 bytes | Classical |
| ML-DSA-44 | 1,312 bytes | 2,528 bytes | 2,420 bytes | NIST Level 2 |
| SLH-DSA-SHAKE-128s | 32 bytes | 64 bytes | 7,856 bytes | NIST Level 1 |
See REPORT.md for performance and size comparison to secp256k1.
This library implements the cryptographic primitives required by BIP-360, which defines the standard for post-quantum resistant signatures in Bitcoin. It supports all three recommended algorithms with the specified parameter sets.
This project is licensed under the MIT License - see the LICENSE file for details.
Cryptographic dependencies included in this project:
7ec789ace6874d875f4bb84cb61b81155398167e444cdcc84eb36b66fe27b3a2529ee48f6d8150c2# Clone the repository
git clone https://github.com/bitcoin/libbitcoinpqc.git
cd libbitcoinpqc
# Build the C library using CMake
mkdir build
cd build
cmake ..
make
# Build the Rust library and bindings
cd ..
cargo build --release
This library includes fuzz testing targets using cargo-fuzz.
# Install cargo-fuzz
cargo install cargo-fuzz
# Run a specific fuzz target
cargo fuzz run keypair_generation
cargo fuzz run sign_verify
cargo fuzz run cross_algorithm
# Run a fuzz target for a specific amount of time (in seconds)
cargo fuzz run keypair_generation -- -max_total_time=60
# Run a fuzz target with a specific number of iterations
cargo fuzz run sign_verify -- -runs=1000000
See fuzz/README.md for more details on fuzz testing.
#include <libbitcoinpqc/bitcoinpqc.h>
// Generate random data (from a secure source in production)
uint8_t random_data[256];
// Fill random_data with entropy...
// Generate a key pair
bitcoin_pqc_keypair_t keypair;
bitcoin_pqc_keygen(BITCOIN_PQC_MLDSA44, &keypair, random_data, sizeof(random_data));
// Sign a message
const uint8_t message[] = "Message to sign";
bitcoin_pqc_signature_t signature;
bitcoin_pqc_sign(BITCOIN_PQC_MLDSA44, keypair.secret_key, keypair.secret_key_size,
message, sizeof(message) - 1, &signature);
// Verify the signature
bitcoin_pqc_error_t result = bitcoin_pqc_verify(BITCOIN_PQC_MLDSA44,
keypair.public_key, keypair.public_key_size,
message, sizeof(message) - 1,
signature.signature, signature.signature_size);
// Clean up resources
bitcoin_pqc_signature_free(&signature);
bitcoin_pqc_keypair_free(&keypair);
Rust docs can be found on docs.rs.
use bitcoinpqc::{Algorithm, generate_keypair, sign, verify};
use rand::{RngCore, rngs::OsRng};
// Generate random data for key generation
let mut random_data = vec![0u8; 128];
OsRng.fill_bytes(&mut random_data);
// Generate a key pair
let keypair = generate_keypair(Algorithm::MLDSA44, &random_data).unwrap();
// Create a message to sign
let message = b"Message to sign";
// Sign the message deterministically
let signature = sign(&keypair.secret_key, message).unwrap();
// Verify the signature
verify(&keypair.public_key, message, &signature).unwrap();
Python bindings are also available for libbitcoinpqc, allowing you to use the post-quantum cryptographic algorithms from Python code.
# Install the Python package
cd python
pip install -e .
import secrets
from bitcoinpqc import Algorithm, keygen, sign, verify
# Generate random data for key generation
random_data = secrets.token_bytes(128)
# Generate a key pair
algorithm = Algorithm.ML_DSA_44 # CRYSTALS-Dilithium
keypair = keygen(algorithm, random_data)
# Create a message to sign
message = b"Hello, Bitcoin PQC!"
# Sign the message
signature = sign(algorithm, keypair.secret_key, message)
# Verify the signature
is_valid = verify(algorithm, keypair.public_key, message, signature)
print(f"Signature valid: {is_valid}") # Should print True
# Verification with incorrect message will fail
bad_message = b"Tampered message!"
is_valid = verify(algorithm, keypair.public_key, bad_message, signature)
print(f"Signature valid: {is_valid}") # Should print False
The Python API mirrors the C API closely, with some Pythonic improvements:
Algorithm - Enum class for algorithm selection
SECP256K1_SCHNORRML_DSA_44 (CRYSTALS-Dilithium)SLH_DSA_SHAKE_128S (SPHINCS+)KeyPair - Class to hold a public/secret key pair
algorithm - The algorithm usedpublic_key - The public key as bytessecret_key - The secret key as bytesSignature - Class to hold a signature
algorithm - The algorithm usedsignature - The signature as bytesFunctions
public_key_size(algorithm) - Get the public key size for an algorithmsecret_key_size(algorithm) - Get the secret key size for an algorithmsignature_size(algorithm) - Get the signature size for an algorithmkeygen(algorithm, random_data) - Generate a key pairsign(algorithm, secret_key, message) - Sign a messageverify(algorithm, public_key, message, signature) - Verify a signatureNodeJS TypeScript bindings allow you to use post-quantum cryptographic algorithms in JavaScript/TypeScript projects.
# Install the Node.js package
npm install bitcoinpqc
import { Algorithm, generateKeyPair, sign, verify } from 'bitcoinpqc';
import crypto from 'crypto';
// Generate random data for key generation
const randomData = crypto.randomBytes(128);
// Generate a key pair using ML-DSA-44 (CRYSTALS-Dilithium)
const keypair = generateKeyPair(Algorithm.ML_DSA_44, randomData);
// Create a message to sign
const message = Buffer.from('Message to sign');
// Sign the message deterministically
const signature = sign(keypair.secretKey, message);
// Verify the signature
verify(keypair.publicKey, message, signature);
// If verification fails, it will throw a PqcError
// You can also verify using the raw signature bytes
verify(keypair.publicKey, message, signature.bytes);
The TypeScript API provides a clean, modern interface:
Algorithm - Enum for algorithm selection
SECP256K1_SCHNORRML_DSA_44 (CRYSTALS-Dilithium)SLH_DSA_SHAKE_128S (SPHINCS+)Classes
PublicKey - Public key wrapperSecretKey - Secret key wrapper with secure handlingKeyPair - Container for public/secret key pairsSignature - Signature wrapperFunctions
publicKeySize(algorithm) - Get the public key size for an algorithmsecretKeySize(algorithm) - Get the secret key size for an algorithmsignatureSize(algorithm) - Get the signature size for an algorithmgenerateKeyPair(algorithm, randomData) - Generate a key pairsign(secretKey, message) - Sign a messageverify(publicKey, message, signature) - Verify a signatureFor more details, see the NodeJS TypeScript bindings README.