diff --git a/bip-0360.mediawiki b/bip-0360.mediawiki index 001664ffb3..789cf0cf73 100644 --- a/bip-0360.mediawiki +++ b/bip-0360.mediawiki @@ -3,6 +3,7 @@ Title: Pay to Quantum Resistant Hash Layer: Consensus (soft fork) Author: Hunter Beast + Ethan Heilman Comments-Summary: No comments yet. Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-0360 Status: Draft @@ -11,13 +12,14 @@ License: BSD-3-Clause - == Introduction == === Abstract === -This document proposes the introduction of a new output type using signatures based on Post-Quantum Cryptography (PQC). -This approach for adding a post-quantum secure output type does not require a hard fork or block size increase. +This document proposes the introduction of a new output type Pay to Quantum Resistant Hash (P2QRH). +This output type is designed to be compatible with the future addition of PQ signature algorithms to Bitcoin. +This changes would enable the use of Bitcoin transactions and tapscripts that are secure against Cryptoanalytically-Relevant Quantum Computers (CRQCs). +This approach for adding a post-quantum secure output type (and signatures) does not require a hard fork or block size increase. === Copyright === @@ -39,7 +41,7 @@ offering insufficient protection. The computational complexity of this attack is [https://pubs.aip.org/avs/aqs/article/4/1/013801/2835275/The-impact-of-hardware-specifications-on-reaching ''The impact of hardware specifications on reaching quantum advantage in the fault-tolerant regime'']. This proposal aims to mitigate these risks by introducing a Pay to Quantum Resistant Hash (P2QRH) output type that -relies on PQC signature algorithms. By adopting PQC, Bitcoin can enhance its quantum +makes tapscript quantum resistant and enables the use of PQ signature algorithms. By adopting PQC, Bitcoin can enhance its quantum resistance without requiring a hard fork or block size increase. The vulnerability of existing Bitcoin addressesA vulnerable Bitcoin address is any @@ -79,8 +81,8 @@ As the value being sent increases, so too should the fee in order to commit the possible. Once the transaction is mined, it makes useless the public key revealed by spending a UTXO, so long as it is never reused. -It is proposed to implement a Pay to Quantum Resistant Hash (P2QRH) output type that relies on a PQC signature -algorithm. This new output type protects transactions submitted to the mempool and helps preserve the free market by +It is proposed to implement a Pay to Quantum Resistant Hash (P2QRH) output type that relies on a PQ signature +algorithm. This new output type protects transactions submitted to the mempool and helps preserve the fee market by preventing the need for private, out-of-band mempool transactions. The following table is intended to inform the average Bitcoin user whether their bitcoin is vulnerable to a long-exposure @@ -170,133 +172,197 @@ using Grover's algorithm would require at least 10^24 quantum operations. As for === Rationale === This is the first in a series of BIPs under a QuBit soft fork. A qubit is a fundamental unit of quantum computing, and -the capital B refers to Bitcoin. The name QuBit also rhymes to some extent with SegWit. +the capital B refers to Bitcoin. The name QuBit also rhymes to some extent with SegWit. This BIP proposes a new output type +called P2QRH (Pay to Quantum Resistant Hash). This output type is designed to support post-quantum signature algorithms +but those algorithms will be specified in future BIPs. It is proposed to use SegWit version 3. This results in addresses that start with bc1r, which could be a useful way to remember that these are quantum (r)esistant addresses. This is referencing the lookup table under [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 BIP-173]. -P2QRH is meant to be implemented on top of P2TR, combining the security of classical Schnorr signatures along with -post-quantum cryptography. This is a form of hybrid cryptography such that no regression in security is presented -should a vulnerability exist in one of the signature algorithms used. One key distinction between P2QRH and P2TR -however is that P2QRH will encode a hash of the public key. This is a significant deviation from how Taproot works by -itself, but it is necessary to avoid exposing public keys on-chain where they are vulnerable to attack. - -P2QRH uses a 32-byte HASH256 (specifically SHA-256 twice-over) of the public key to reduce the size of new outputs and -also to increase security by not having the public key available on-chain. While HASH256 uses double SHA-256 like -Bitcoin's Proof of Work, this does not meaningfully increase quantum resistance compared to single SHA-256, as both -provide approximately 2^128 security against Grover's algorithm. The practical impact of quantum attacks on SHA-256 -remains theoretical since quantum circuits for SHA-256 are still theoretical, but using the same hash function as -Proof of Work maintains consistency with Bitcoin's existing security model. This hash serves as a minimal cryptographic -commitment to a public key in the style of a -[https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#user-content-Witness_program BIP-141 witness program]. -Because it goes into the scriptPubKey, it does not receive a witness or attestation discount. - -Post-quantum public keys are generally larger than those used by ECC, depending on the security level. -Originally BIP-360 proposed NIST Level V, 256-bit security, but this was changed to NIST Level I, 128-bit security -due to concerns over the size of the public keys, the time it would take to verify signatures, and being generally -deemed "overkill". - -Support for FALCON signatures will be introduced first, with the intention of adding other post-quantum -algorithms as they are approved. By way of comparison, FALCON signatures are roughly 20x larger than Schnorr signatures. -FALCON has recently been approved by NIST. NIST approval streamlines implementations through establishing -consensus in the scientific and developer community. This means, to maintain present transaction throughput, an -increase in the witness discount will likely be desired in a QuBit soft fork. That will be specified in a future QuBit -BIP. - -An increase in the witness discount must not be taken lightly. It must be resistant to applications that might take -advantage of this discount (e.g., storage of arbitrary data as seen with "inscriptions") without a corresponding -increase in economic activity. An increase in the witness discount would not only impact node runners but those with -inscriptions would also have the scarcity of their non-monetary assets affected. The only way to prevent these effects -while also increasing the discount is to have a completely separate witness--a "quantum witness." Because it is meant -only for public keys and signatures, we call this section of the transaction the attestation. - -Additionally, it should be noted, whether an output with a P2QRH spend script corresponds to a PQC signature is not -known until the output is spent. - -While it might be seen as a maintenance burden for Bitcoin ecosystem devs to go from a single cryptosystem -implementation to three additional distinct PQC cryptosystems--and it most certainly is--the ramifications of a chain -broken through extrinsic factors should provide sufficient motivation. An increase in software maintenance everywhere -signatures are used should be seen as an acceptable compromise for maintained integrity of Bitcoin transfers during a -regime of quantum advantage. - -The inclusion of these three cryptosystems: SPHINCS+, CRYSTALS-Dilithium, and FALCON have various advocates -within the community due to their varying security assumptions. Hash-based cryptosystems are more conservative, -time-tested, and well-reviewed. Lattice cryptography is relatively new and introduces novel security assumptions to -Bitcoin, but their signatures are smaller and might be considered by some to be an adequate alternative to hash-based -signatures. - -The reason multiple cryptosystems are included is in the interest of supporting hybrid cryptography, especially for -high value outputs, such as cold wallets used by exchanges. To improve the viability of the activation client and -adoption by wallets and libraries, a library akin to libsecp256k1 will be developed. This library, libbitcoinpqc, -will support the new PQC cryptosystems and can be used as a reference for other language-native implementations. - -In the distant future, following the implementation of the P2QRH output type in a QuBit soft fork, there will likely -be a need for Pay to Quantum Secure (P2QS) addresses. A distinction is made between cryptography that's merely resistant -to quantum attack, and cryptography that's secured by specialized quantum hardware. P2QRH is resistant to quantum -attack, while P2QS is quantum secure. These will require specialized quantum hardware for signing, while still -[https://quantum-journal.org/papers/q-2023-01-19-901/ using public keys that are verifiable via classical means]. - -While P2QRH lacks features like signature aggregation for smaller transactions, it offers a pragmatic first step -toward quantum resistance. Future BIPs can add enhancements like P2QS, signature aggregation, and possibly full +Our design to augment Bitcoin with quantum resistance is guided by the following principles: + +'''Minimize changes.''' We should reuse existing Bitcoin code and preserve +existing software behavior, workflows, user expectations and compatibility whenever possible. + +'''Gradual upgrade path.''' We should provide an upgrade path for wallets and exchanges which can be +carried out gradually and iteratively rather than all at once. This is critical as the earlier the ecosystem +begins upgrading to quantum resistance, the lower the number of coins at risk when quantum attacks become practical. + +'''Use standardized post-quantum signature algorithms.''' Standardized algorithms have gotten the most scrutiny and +are likely to be most well supported and well studied going forward. The entire Bitcoin ecosystem will benefit +from using the most popular post-quantum signature algorithms including leveraging hardware acceleration +instructions, commodity trusted hardware, software libraries and cryptography research. + +'''Provide security against unexpected cryptanalytic breakthroughs.''' Consider the risk +if Bitcoin only supported one PQ signature algorithm, and following the widespread rollout of CRQCs, a critical +weakness is unexpectedly discovered in this signature algorithm. There would be no safe algorithm available. We believe that +prudence dictates we take such risks seriously and ensure that Bitcoin always has at least two secure signature algorithms built +on orthogonal cryptographic assumptions. In the event one algorithm is broken an alternative will be available. An added benefit +is that parties seeking to securely store bitcoins over decades can secure their coins under multiple algorithms, +ensuring their coins will not be stolen even in the face of a catastrophic break in one of those signature algorithms. + +Based on these principles, we propose two independent changes that together provide Bitcoin with +full quantum resistance. First, we introduce a new output type called P2QRH (Pay to Quantum Resistant Hash) so that tapscript +can be used in a quantum resistant manner. Second, we add opcodes to tapscript for verifying two Post-Quantum (PQ) signature +algorithms, ML-DSA (CRYSTALS-Dilithium) and SLH-DSA (SPHINCS+). + +P2QRH is simply P2TR with the quantum vulnerable key-spend path removed so that it commits to the root of +the tapleaf merkle tree in the output and to remove the witness element size limit of 520 bytes, as PQ +signatures are larger than 520 bytes. This allows P2QRH to reuse the mature and battle tested P2TR, tapleaf +and tapscript code already in Bitcoin. This reduces the implementation burden on wallets, exchanges, and +libraries since they can reuse code they already have. + +By separating P2QRH from the introduction of PQ signatures relying parties can move from P2TR to P2QRH +without simultaneously having to change from Schnorr signatures to PQ signatures. Simply moving coins from +P2TR to P2QRH protects those coins from long-exposure quantum attacks. Then to gain full quantum resistance, +verification of PQ signatures can be added as an additional tapleaf alongside Schnorr signaturesInspired by Matt Corallo's discussion of this idea on the Bitcoin-dev mailing list [https://groups.google.com/g/bitcoindev/c/oQKezDOc4us/m/T1vSMkZNAAAJ Re: P2QRH / BIP-360 Update]. +When quantum attacks become practical, users would then be fully protected as the P2QRH output would allow +them to switch to sending their coins using the PQ signature algorithms. This allows the upgrade to quantum +resistance to be largely invisible to users. + +Consider the P2QRH output with three tapscripts: + +* Spend requires a Schnorr signature +* Spend requires a ML-DSA signature +* Spend requires a SLH-DSA signature + +In the event that Schnorr signatures are broken, users can spend their coins using ML-DSA. +If both Schnorr and ML-DSA are broken, the user can still rely on SLH-DSA. + +One intent in supporting Schnorr, ML-DSA, and SLH-DSA in tapscript, is to allow parties to construct outputs such that funds +are still secure even if two of the three the signature algorithms are completely broken. This is motivated by the use case +of securely storing Bitcoins in a cold wallet for very long periods of time (50 to 100 years). + +For PQ signatures we considered the NIST approved SLH-DSA (SPHINCS+), ML-DSA (CRYSTALS-Dilithium), +FN-DSA (FALCON). Of these three algorithms, SLH-DSA has the largest signature size, but is the most conservative +choice from a security perspective because SLH-DSA is based on well studied and time-tested hash-based cryptography. +Both FN-DSA and ML-DSA signatures are significantly smaller than SLH-DSA signatures but are based on newer lattice-based +cryptography. Since ML-DSA and FN-DSA are both similar lattice-based designs, we choose to only support one of them as the +additional value in diversity of cryptographic assumptions would be marginal. + +We also considered SQIsign. While it outperforms the three other PQ signature algorithms by having the smallest signatures, +it has the worst verification performance and requires a much more complex implementation. We may revisit SQIsign separately in the +future as recent research shows massive performance improvements to SQIsign in version 2.0. "[SQIsign] signing is now nearly 20× faster, at 103.0 Mcycles, and verification is more than 6× faster, at 5.1 Mcycles" [https://csrc.nist.gov/csrc/media/Projects/pqc-dig-sig/documents/round-2/spec-files/sqisign-spec-round2-web.pdf SQIsign: Algorithm specifications and supporting documentation Version 2.0 (February 5 2025)]. + +ML-DSA is intended as the main PQ signature algorithm in Bitcoin. It provides a good balance of security, performance +and signature size and is likely to the most widely supported PQ signature algorithm on the internet. SLH-DSA has a radically +different design and set of cryptographic assumptions than ML-DSA. As such SLH-DSA provides an effective +hedge against an unexpected cryptanalytic breakthrough. + +P2QRH, ML-DSA, and SLH-DSA could be activated simultaneously in a single soft fork or P2QRH could be activated first and then +ML-DSA and SLH-DSA could be independently activated by redefining OP_SUCCESSx opcodes. If at some future point another signature +algorithm was desired it could follow this pattern. + +To improve the viability of the activation client and adoption by wallets and libraries, a library akin to +libsecp256k1 will be developed. This library, [https://github.com/cryptoquick/libbitcoinpqc libbitcoinpqc], will support the new PQ signature algorithms +and can be used as a reference for other language-native implementations. + +==== PQ Signature Size ==== + +Post-quantum public keys are generally larger than those used by ECC, depending on the security level. Originally BIP-360 +proposed NIST Level V, 256-bit security, but this was changed to NIST Level I, 128-bit security due to concerns over the +size of the public keys, the time it would take to verify signatures, and being generally deemed "overkill". + +We recognize that the size of ML-DSA (CRYSTALS-Dilithium) and SLH-DSA (SPHINCS+) signatures + public key pairs is a significant concern. +By way of comparison with Schnorr public key + signature pairs, SLH-DSA is roughly 80x larger and ML-DSA is roughly 40x larger. This means to +maintain present transaction throughput, an increase in the witness discount may be desired. + +An increase in the witness discount must not be taken lightly. Parties may take advantage of this discount for purposes other than +authorizing transactions (e.g., storage of arbitrary data as seen with "inscriptions"). An increase in the witness discount would +not only impact node runners but those with inscriptions would have the scarcity of their non-monetary assets affected. + +There was some hope of designing P2QRH such that discounted public keys and signatures could not be repurposed for the storage of +arbitrary data by requiring that they successfully be verified before being written to Bitcoin's blockchain, a.k.a. "JPEG resistance". +Later research Bas Westerbaan (2025), [https://groups.google.com/g/bitcoindev/c/5Ff0jdQPofo jpeg resistance of various post-quantum signature schemes] +provided strong evidence that this was not a feasible approach for the NIST approved Post-Quantum signature algorithms. +It is an open question if Post-Quantum signature algorithms can be designed to provide JPEG resistance. + +==== Future Considerations ==== + +While P2QRH lacks features like signature aggregation, it offers a pragmatic first step +toward quantum resistance. Future BIPs can add enhancements like signature aggregation, and possibly full BIP-32 compatibility once tested and viable. Until quantum cryptography hardware and advanced schemes are widespread, -P2QRH provides meaningful protection against quantum threats without delaying deployment for a perfect solution. +P2QRH provides meaningful protection against quantum threats as early as possible. -Additional follow-on BIPs will be needed to implement P2QS, signature aggregation, and full BIP-32 compatibility +Additional follow-on BIPs will be needed to implement signature aggregation, and full BIP-32 compatibility (if possible) BIP-32 relies on elliptic curve operations to derive keys from xpubs to support watch-only wallets, which PQC schemes may not support.. However, until specialized quantum cryptography hardware -is widespread and signature aggregation schemes are thoroughly vetted, P2QRH addresses should be an adequate -intermediate solution that provides meaningful protection against quantum threats. +is widespread and signature aggregation schemes are thoroughly vetted, P2QRH addresses are an intermediate solution +to quantum threats. == Specification == We define the signature scheme and transaction structure as follows. -=== Descriptor Format === +=== Pay to Quantum Resistant Hash (P2QRH) === -To integrate P2QRH into existing wallet software and scripts, we introduce a new output descriptor function -qrh(). This function represents a P2QRH output, similar to how wpkh() and tr() -are used for P2WPKH and P2TR outputs, respectively. +A P2QRH output is simply the root of the tapleaf merkle tree defined as in [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP-341] +and used as an internal value in P2TR. -The qrh() function takes a threshold value and multiple key specifications grouped by key type. The format is: +To construct a P2QRH output we follow the same process as [https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki BIP-341] +to compute the tapscript merkle root. However, instead of the root of the Merkle tree being hashed together with the internal +key in P2QRH the root is hashed by itself using the tag "QuantumRoot". - qrh(threshold, keytype(0x01, [hash1, hash2, ...]), keytype(0x02, [hash1, hash2, ...]), ...) + +D = tagged_hash("TapLeaf", bytes([leaf_version]) + ser_script(script)) +CD = tagged_hash("TapBranch", C + D) +CDE = tagged_hash("TapBranch", E + CD) +ABCDE = tagged_hash("TapBranch", AB + CDE) +Root = tagged_hash("QuantumRoot", ABCDE) + -Where: +TODO: Add image of P2QRH output merkle tree structure. + +Validation follows the pattern of a P2TR script spend but without the P2TR public key, internal key, or key tweak. +A P2QRH input provides the following: + + +script witness stack, +tapleaf script, +control block = [version byte, m*32 byte merkle path] # m is the depth of the merkle tree + + +The script witness stack provides the same functionality as it does in P2TR. It places input values on the stack to +be evaluated by the tapscript. + +A P2QRH script witness stack differs in only one way from a P2TR script witness stack. P2QRH does not limit the size +of the witness stack elements to 520 bytes. This is needed because PQ signatures and public keys can be larger than +520 bytes. -* threshold is an integer specifying the minimum number of signatures required -* keytype is the hex value representing the key type (0x01 for secp256k1, 0x02 for FALCON-512, 0x04 for CRYSTALS-Dilithium Level I, 0x08 for SPHINCS+-128s) -* [hash1, hash2, ...] is an array of HASH256 hashes of public keys for the corresponding algorithm type +The tapleaf script is a tapscript that is executed to validate the input. The tapscript in P2QRH is unchanged from BIP-342. -For example: +The control block is a 1 + 32+m byte array, where the first byte is the version byte and the next 32+m bytes are the +Merkle path to the tapleaf script. The intent of the version byte is similar to the header byte in a P2TR control +block, but all 8 bits are used for versioning. We omit the public key from the control block as it is not needed in P2QRH. - qrh(3, keytype(0x01, hash256(secp256k1_pubkey1), hash256(secp256k1_pubkey2), hash256(secp256k1_pubkey3), secp256k1_pubkey4_hash, secp256k1_pubkey5_hash), - keytype(0x02, hash256(falcon_pubkey1), hash256(falcon_pubkey2), hash256(falcon_pubkey3), falcon_pubkey4_hash, falcon_pubkey5_hash), - keytype(0x04, hash256(dilithium_pubkey1), hash256(dilithium_pubkey2), hash256(dilithium_pubkey3), dilithium_pubkey4_hash, dilithium_pubkey5_hash), - keytype(0x08, hash256(sphincs_pubkey1), hash256(sphincs_pubkey2), hash256(sphincs_pubkey3), sphincs_pubkey4_hash, sphincs_pubkey5_hash)) +TODO: Do we want a version byte in the control block? -This represents a 3-of-5 multisig for each key type, with a total of 20 keys: 5 keys per type (3 full public keys and 2 -hashes) across 4 different key types. +A consequence of the above design, tapscript cannot pass a PQ public key to be verified with a PQ signature if the +PQ public key is larger than 520 bytes. This is because while the script stack can contain stack elements larger +than 520 bytes, the OP_PUSH opcode in tapscript cannot push stack elements larger than 520 bytes. To solve this issue the +tapscript can push the HASH256 of the PQ public key and then verify that the PQ public key from the script witness stack +hashes to the value committed in the tapscript. -Internally, the descriptor computes the HASH256 of the concatenated HASH256 of all the quantum-resistant public keys, -with the threshold and key type bitmask prepended. For each key in the descriptor: + +script witness stack = [pubkey, signature] # len(pubkey) > 520 bytes and len(signature) > 520 bytes +tapscript = [OP_DUP, OP_HASH256, OP_PUSHDATA HASH256(expected_pubkey), OP_EQUALVERIFY, OP_CHECKSIG_SLH, OP_VERIFY] + -- If it is already a hash (indicated in the descriptor), it is used directly -- If it is a public key, HASH256 is applied to it first +TODO: We should think very carefully about any issues allowing larger witness stack elements may cause because tapscript +assumes no stack element sizes greater than 520 bytes. + +==== Script Validation ==== + +To spend a P2QRH output, the following conditions must be met: + +1. The scriptPubKey must be of the form: -This approach ensures that all items in the vector are HASH256 values, whether they originated from raw public keys or -were provided as hashes. During spending, this allows for selective disclosure of public keys, where some keys can -remain hidden (represented only by their hashes) while others are fully revealed with their corresponding public keys. -This flexibility is particularly valuable in multisig schemes where not all keys need to be revealed to satisfy the -threshold requirement. At a minimum, there should be two different key types in a P2QRH output: one key that makes use -of classical cryptography, and one that makes use of a PQC algorithm chosen within the wallet. +OP_PUSHNUM_3 <32-byte hash> -Also, it's important to note that order of keys and hashes in the descriptor matters and is based on the original -public key values, in addition to the key type. Additionally, qrh() does not compile to script, but instead, describes -what's needed to compute the scriptPubKey hash commitment and also to reveal the attestation needed to spend the -output. +TODO: Very specific specification of P2QRH validation -=== Address Format === +==== Address Format ==== P2QRH uses SegWit version 3 outputs, resulting in addresses that start with bc1r, following [https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki#bech32 BIP-173]. Bech32 encoding maps version 3 to the @@ -304,9 +370,9 @@ prefix r. Example P2QRH address: -bc1r... (32-byte Bech32m-encoded HASH256 of the HASH256 of the public keys) +bc1r... (32-byte Bech32m-encoded tagged hash tapleaf merkle root) -=== ScriptPubKey === +==== ScriptPubKey ==== The scriptPubKey for a P2QRH output is: @@ -317,239 +383,26 @@ Where: * OP_PUSHNUM_3 (0x03) indicates SegWit version 3. * is the 32-byte HASH256 of the commitment, as defined in the Hash Commitment section below. -==== Key Type Bitmask ==== - -The key type bitmask is a 1-byte value that indicates the type of key used in the commitment. It is encoded as follows: - -* 0x01 - Key type 0 - secp256k1 -* 0x02 - Key type 1 - FALCON-512 -* 0x04 - Key type 2 - CRYSTALS-Dilithium Level I -* 0x08 - Key type 3 - SPHINCS+-128s -* 0x10 - Unused -* 0x20 - Unused -* 0x40 - Unused -* 0x80 - Reserved for if additional key types are added in the future - -Example key type bitmask using all supported key types: - - 0x01 | 0x02 | 0x04 | 0x08 = 0x0F - -==== Hash Commitment ==== - -If there is only a single public key, the hash is computed as the HASH256 of the public key. - -In order to support multiple keys, as in the context of multisig or singlesig hybrid cryptography, the hash is -computed as a commitment to a vector of public key hashes: - -1. Sort the public keys first by key type, then by public key value -2. For each sorted public key, compute its HASH256 -3. Concatenate all the public key hashes in sorted order -4. Prepend key type bitmask and threshold to the concatenated hashes -5. Compute the HASH256 of the result - -For example with 4 public keys: - - // First sort the public keys - sorted_pubkeys = sort_by_key_type_and_value([pubkey1, pubkey2, pubkey3, pubkey4]) - - // Then compute hashes of sorted keys - h1 = HASH256(sorted_pubkeys[0]) - h2 = HASH256(sorted_pubkeys[1]) - h3 = HASH256(sorted_pubkeys[2]) - h4 = HASH256(sorted_pubkeys[3]) - - // Concatenate all hashes - concatenated = h1 || h2 || h3 || h4 - - commitment = key_type_bitmask || threshold || concatenated - - hash = HASH256(commitment) - -With sort_by_key_type_and_value defined as: - - def sort_by_key_type_and_value(pubkeys): - return sorted(pubkeys, key=lambda x: (x.key_type, x.public_key)) - -When spending, if a public key hash is provided in the attestation with an empty signature, that hash will be used -directly in the vector computation rather than hashing the full public key. This allows unused public keys to be -excluded from the transaction while still proving they were part of the original commitment. - -The vector construction creates an efficient cryptographic commitment to multiple public keys while enabling -selective disclosure. - -A threshold is provided to indicate the number of signatures required to spend the output. This is used in the -cryptographic commitment in the hash computation and revealed in the attestation when spent. - -Only a single 32-byte X-only secp256k1 public key can be provided as key type 0. There are a few reasons for this: - -1. It maintains Taproot compatibility by removing ambiguity which key is representative of the Taptree. -2. It prevents abuse of public keys to store arbitrary data once quantum computing is ubiquitous. -3. When a secp256k1 key is specified in the key type bitmask, how many keys it commits to is unambiguous. -4. If multiple keys need to be committed to, they must be aggregated, which saves on transaction size. - -This design maintains compatibility for [https://github.com/bitcoin/bips/blob/master/bip-0114.mediawiki BIP-114] -Taproot Merkelized Alternative Script Tree (MAST) merkle root in the commitment, which makes P2QRH a -quantum-resistant version of Taproot transactions. The TapScript itself must however be provided in the witness, -as no script execution is allowed in the attestation. - -In a multisig context, aside from secp256k1 keys, the number of keys provided in the attestation is variable and -must meet the threshold as committed to in the hash computation and revealed in the attestation. - -When the address is generated, all public keys must be known in advance, and they must be sorted, first by key -type, then by public key value, so as to be deterministic. - -The key count does not need to be provided for PQC keys because the key type bitmask and threshold are sufficient -to validate a multisig transaction. - -In a singlesig context, multiple PQC keys can be provided, but the key type bitmask and threshold must still also -be provided to be consistent with the multisig semantics. The threshold will be set as 0x01, and the key type -bitmask will indicate how many keys of each type are present. - -=== Transaction Serialization === - -Following BIP-141, a new transaction serialization format is introduced to include an attestation field after the witness field: - - [nVersion][marker][flag][txins][txouts][witness][attestation][nLockTime] - -* marker: 0x00 (same as SegWit) -* flag: -** 0x02 (indicates the presence of attestation data only) -** 0x03 (indicates the presence of both witness and attestation data) -* attestation: Contains the quantum-resistant public keys and signatures. - -=== Quantum Transaction ID (qtxid) === +=== Post-Quantum Signature Algorithms === -The transaction ID is computed as the HASH256 of the serialized transaction, including the attestation and witness -(if a witness is present). When decoded, this is called the qtxid, which will differ from the txid and wtxid if an -attestation is present. +We propose adding the opcodes OP_CHECKSIG_ML (ML-DSA) and OP_CHECKSIG_SLH (SLH-DSA) to tapscript by redefining OP_SUCCESSx +opcodes. As ML-DSA and SLH-DSA are post-quantum signature algorithms this would allow the user of post-quantum signatures +in tapscript. -=== Attestation Structure === +These opcodes function similarly to the existing OP_CHECKSIG opcode. They pop the public key and signature from the stack +and then perform signature verification using the specified post-quantum signature algorithm. -The attestation field consists of: +TODO: Open questions: +TODO: 1. Should we have OP_CHECKSIG_VERIFY and OP_CHECKSIGADD variants as well? +TODO: 2. Should we provide these opcodes been in a separate BIP? -* key_type_bitmask: A [https://learnmeabitcoin.com/technical/general/compact-size/ compact size] value indicating which key types are present. -* threshold: A compact size value indicating the number of signatures required to spend the output. -* num_pubkeys: The number of public keys (compact size). +==== OP_CHECKSIG_ML ==== -For each public key: +TODO: Add full specification here -* key_type: The key type (compact size). Only one bit is used to indicate the key type. -* pubkey_length: compact size length of the public key (compact size). -* pubkey: The public key bytes. +==== OP_CHECKSIG_SLH ==== -Then: - -* num_signatures: The number of signatures (compact size). - -For each signature: - -* signature_length: compact size length of the signature. -* signature: The signature bytes. - -This structure repeats for each input, in order, for flexibility in supporting multisig schemes and various -quantum-resistant algorithms. - -For each input, a separate attestation field is used. To know how many attestation fields are present, implementations -must count the number of inputs present in the transaction. - -==== Attestation Parsing Example ==== - -Signing for a single input using both secp256k1 Schnorr and FALCON-512: - -Number of public keys: - - [key_type_bitmask]: 0x03 - [threshold]: 0x01 - [num_pubkeys]: 0x02 - -Pubkey 1: - [key_type]: 0x01 - [pubkey_length]: 0x20 (32 bytes) - [pubkey]: public_key_secp256k1 - -Pubkey 2: - [key_type]: 0x02 - [pubkey_length]: 0x0701 (1793 bytes) - [pubkey]: public_key_falcon_512 - -Number of signatures: - - [num_signatures]: 0x02 - -Signature 1: - [signature_length]: 0x40 (64 bytes) - [signature]: signature_secp256k1 - -Signature 2: - [signature_length]: 0x0500 (1280 bytes) - [signature]: signature_falcon_512 - -Note: This contrasts with multisig inputs, where the attestation structure repeats for each public key and signature. - -=== Signature Algorithms === - -The specific quantum-resistant signature algorithm used cannot be inferred from the length of the public key due to -collisions in length between algorithms. Instead, when each key is revealed in the attestation, the key type bitmask -indicates which algorithm was used. - -Supported PQC algorithms and their NIST Level I parameters: - -* '''secp256k1 - BIP-340 - Schnorr + X-Only''' -** Key Type 0 -** Public Key Length: 32 bytes -** Signature Length: 64 bytes -** Total Size: 96 bytes -** Cycles to sign: 42,000 (EdDSA) -** Cycles to verify: 130,000 (EdDSA) -* '''FN-DSA-512 - FIPS 206 - FALCON-512:''' -** Key Type 1 -** Public Key Length: 897 bytes -** Signature Length: 667 bytes -** Total Size: 1,564 bytes -** Cycles to sign: 1,009,764 -** Cycles to verify: 81,036 -* '''ML-DSA-44 - FIPS 204 - CRYSTALS-Dilithium Level I:''' -** Key Type 2 -** Public Key Length: 1,312 bytes -** Signature Length: 2,420 bytes -** Total Size: 3,732 bytes -** Cycles to sign: 333,013 -** Cycles to verify: 118,412 -* '''SLH-DSA-SHAKE-128s - FIPS 205 - SPHINCS+-128s:''' -** Key Type 3 -** Public Key Length: 32 bytes -** Signature Length: 7,856 bytes -** Total Size: 7,888 bytes -** Cycles to sign: 4,682,570,992 -** Cycles to verify: 4,764,084 - -Implementations must recognize the supported algorithms and validate accordingly. - -A bitmask is used to indicate the algorithm used for each public key and signature pair. The bitmask enumerates based on -the key type as indicated above. This is used in the cryptographic commitment in the hash computation and -revealed in the attestation for each public key when spent. - -=== Script Validation === - -To spend a P2QRH output, the following conditions must be met: - -1. The scriptPubKey must be of the form: - -OP_PUSHNUM_3 <32-byte hash> - -2. The attestation must include: - -* The quantum-resistant public key(s) whose HASH256 concatenated and hashed again matches the in -the scriptPubKey. - -* Valid signatures corresponding to the public key(s) and the transaction data. - -* The key type bitmask and threshold must match the commitment in the scriptPubKey. - -3. For multi-signature schemes, all required public keys and signatures must be provided for that input within the -attestation. Public keys that are not needed or available can be selectively disclosed by including their hash in the -attestation accompanied with an empty signature by providing a 0x00 signature length byte. This works so long as -enough keys to meet the threshold are provided. +TODO: Add full specification here ==== Sighash Calculation ==== @@ -560,6 +413,8 @@ The sighash for P2QRH outputs follows the same procedure as defined in [https:// * '''Key Data:''' In addition to transaction data, the sighash includes the spent output's scriptPubKey. * '''Extension Fields:''' Specific data is included or excluded from the sighash based on the sighash flag. +TODO: Currently BIP-360 proposes using the tag "TapSighash" in the tagged hash of the sighash for PQ signatures. I can see an argument that the sighash should be specific to the signature algorithm used to prevent signatures from one algorithm being used for an algorithm, e.g. "TapSighashML" for ML-DSA + This signature hash construction ensures transaction malleability is prevented while providing flexibility through different sighash types (DEFAULT, ALL, NONE, SINGLE, and ANYONECANPAY variants). The exact computation follows the procedure specified in BIP-341 to maintain compatibility with Taproot signatures. @@ -567,23 +422,6 @@ procedure specified in BIP-341 to maintain compatibility with Taproot signatures If a sighash flag other than DEFAULT is needed, it can be placed in the transaction witness. In this case, it will be the only field in the witness. -==== Signature Verification ==== - -Signature verification is as follows: - -1. Extract the from the scriptPubKey. - -2. For each input: - -* Compute hashed_pubkeys as specified in the Hash Computation section. - -* Compare the resulting hash to . If they do not match, the script fails. - -3. Verify each signature against the corresponding public key and the sighash. - -4. Ensure that the signature algorithm used matches the expected lengths for NIST Level I security, and is supported by -the implementation. - === Compatibility with BIP-141 === By adhering to the SegWit transaction structure and versioning, P2QRH outputs are compatible with existing transaction @@ -609,7 +447,7 @@ key generation. ==== Algorithm Selection ==== -Introducing three quantum-resistant algorithms to the Bitcoin ecosystem provides users with the option to select an +Introducing two quantum-resistant algorithms to the Bitcoin ecosystem provides users with the option to select an appropriate algorithm for their use case, generally based on the amount of value they wish to secure. Developers can choose to implement support for multiple algorithms in wallets and on nodes to offer quantum-resistant options.