This repository is a proof of concept implementation of QCAP, a distributed protocol to create a Bitcoin canary address that is less secure in comparison to Bitcoin's native address' by design. The canary trap serves as a public alert: if its funds are ever spent, it signals that a sufficiently powerful computer, and probably a quantum computer has broken the ECDLP on secp192r1 (and is approaching to break the security of Bitcoin's secp256k1). The protocol is implemented in Python and leverages several cryptographic libraries.
The Quantum Canary Address Generation Protocol (QCAP) is a multi-phase, distributed protocol involving n participants and a coordinator. The diagram of the steps carried out by each participant/coordinator in the protocol can be seen below:
- Each participant generates a random Bitcoin private key and derives their corresponding public keys on both
secp192r1andsecp256k1curves. - Outputs are saved in
../outputs/participant/participant_id/keys. - Each participant generates the proofs for the DLEQ, DELQAG, and rangeproofs for the generated keys and stores them in
../outputs/participant/participant_id/proofs.
- The coordinator verifies the proofs provided by the participants.
- The coordinator aggregates the public keys proved valid (from both
secp192r1andsecp256k1) via elliptic curve point addition.
- The coordinator generates the file containing all public information of the protocol to be uploaded to the IPFS and saves it as
../outputs/IPFS.json.
- The coordinator creates the tweaked public key for the taproot address from the aggregated public key on
secp256k1. - It then creates the
OP-RETURNfor the funding transaction being the CID of the IPFS file. - It initiates the crowdfunding process by publishing the transaction sending some initial funds to the created taproot address from the aggregated public key.
- Languages/Libraries:
- Python:
bitcoinutils,coincurve,cryptography,tinyec,secrets,hashlib,py-cid. - Javascript:
secp256k1,bulletproof-js.
- Python:
- Directory Structure:
outputs/participant/participant_#id/keys: Participant key pairs.outputs/participant/participant_#id/proofs/proof_#publickey.json: DLEQ and DLEQAG proofs for the key pairs onsecp192r1andsecp256k1.outputs/participant/participant_#id/proofs/range_proof_#chunk.json: Range proofs for each chunk of the commitments.outputs/IPFS.json: This file contains all the protocol’s public information, including proofs and public key pairs.
The instructions here are just aiming to run the code locally to see the proofs and the format of the commitment transaction. In case you'd like to publish the commitment transaction to testnet or mainnet please have your WIF, and the outpoint info from your UTXO in the corresponding network ready.
- To install the python dependencies run the following command in the root directory of the project:
pip3 install -r requirements.txt - To install the javascript dependencies run the following command in the root directory of the project:
npm install Note that this repository requires Node.js version 16 or higher (preferably version 24).
-
To run the protocol locally you first need to set the protocol parameters in the
/setup.jsonfile. Note that the automatic script only works for when the network is set toregtest. Below you can find the description regarding each parameter in the setup:max_num_participants: This is the maximum number of participants allowed in the protocol. Exceeding this value would cause overflow in the aggregation of the public keys insecp192r1.number_of_bits_of_secret_chunks: This is the size of the secret value for each chunk in bits ( in the paper it's referred to asb_x).failure_rate: This is the failure rate for which the prover has to repeat the proof generation process to create a validz. ( in the paper it's referred to asb_f).number_of_bits_of_challenge: This is the size of the challenge for the proof in bits ( in the paper it's referred to asb_c).number_of_chunks: The number of chunks that the secret is devided into.network: The network for which the values are going to be created.number_of_participants: The actual number of participants you would like to run the tests for.
-
To run the phases of the protocol according to their order run the following command ( only in case of
regtestfortestnetormainnetrun the scripts in the order in cagp.sh manually)
./cagp.shNote: Depending on your responses, you may need to provide additional information to create the transaction. Please have this information ready beforehand. The script does not upload the IPFS file to any public service, so it is your responsibility to do so using a IPFS Pinning Service or your own IPFS Node. Some examples of free IPFS Pinning Services (require login):
