BIP-340 provides greater (provable) security than ECDSA/secp256k1-based schemes and offers signature non-malleability and linearity. Signing also makes use of "tagged hashes" to mitigate things like related-key attacks, which accordingly "...increases robustness in multi-user settings."
Once approved and released, implement the following in rosetta-sdk-go including any relevant tests:
./keys/keys.go - Key Import & Generation
./keys/signer_bip340.go - Sign & Verify
It should be mentioned that the new CurveType is necessary due to BIP-340's requirement of 32-byte/x-only keys while the existing rosetta-sdk-go key interface extends no such ability under the existing Secp256k1 curve.
CurveType
rosetta-specifications
# CurveType.yaml
description: |
CurveType is the type of cryptographic curve associated with a PublicKey.
* secp256k1: SEC compressed - `33 bytes` (https://secg.org/sec1-v2.pdf#subsubsection.2.3.3)
+ * secp256k1_bip340: x-only - `32 bytes` (implicitly even `Y` coord. Secp256k1 compressed keys may be repurposed by dropping the first byte. (https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#Public_Key_Generation))
* secp256r1: SEC compressed - `33 bytes` (https://secg.org/sec1-v2.pdf#subsubsection.2.3.3)
* edwards25519: `y (255-bits) || x-sign-bit (1-bit)` - `32 bytes` (https://ed25519.cr.yp.to/ed25519-20110926.pdf)
* tweedle: 1st pk : Fq.t (32 bytes) || 2nd pk : Fq.t (32 bytes) (https://github.com/CodaProtocol/coda/blob/develop/rfcs/0038-rosetta-construction-api.md#marshal-keys)
* pallas: `x (255 bits) || y-parity-bit (1-bit) - 32 bytes` (https://github.com/zcash/pasta)
type: string
enum:
- secp256k1
+ - secp256k1_bip340
- secp256r1
- edwards25519
- tweedle
- pallas
rosetta-sdk-go Key Import
Accept the import of any standard secp256k1 privateKey and drop the first byte (compression odd/even flag) of its associated publicKey per BIP-340 spec to extend backward compatibility.
This results in a 32-byte publicKey vs. secp256k1's 33-byte compressed publicKey.
No further tweaks need to be performed to an imported keyPair as the Sign/Verify scheme implicitly chooses the 'Y' coordinates that are a quadratic residue.
The above would be implemented in rosetta-sdk-go in the file ./keys/keys.go and add the import of the following package:
"github.com/btcsuite/btcd/btcec/v2"
*note that github.com/btcsuite/btcd packages are already used by rosetta-sdk-go.
rosetta-sdk-go Key Generation
Explicitly choose the keyPair whose public key has a Y value that is a quadratic residue by negating the newly-generated privateKey when its associated public key is found to be 'odd' in its compressed form.
The above would be implemented in rosetta-sdk-go in the file ./keys/keys.go and add the import of the following package:
"github.com/btcsuite/btcd/btcec/v2"
*note that github.com/btcsuite/btcd packages are already used by rosetta-sdk-go.
# SignatureType.yaml
description: |
SignatureType is the type of a cryptographic signature.
* ecdsa: `r (32-bytes) || s (32-bytes)` - `64 bytes`
* ecdsa_recovery: `r (32-bytes) || s (32-bytes) || v (1-byte)` - `65 bytes`
* ed25519: `R (32-byte) || s (32-bytes)` - `64 bytes`
* schnorr_1: `r (32-bytes) || s (32-bytes)` - `64 bytes` (schnorr signature implemented by Zilliqa where both `r` and `s` are scalars encoded as `32-bytes` values, most significant byte first.)
+ * schnorr_bip340: `r (32-bytes) || s (32-bytes)` - `64 bytes` (sig = (bytes(R) || bytes((k + ed) mod n) where `r` is the `X` coordinate of a point `R` whose `Y` coordinate is even, most significant bytes first.)
* schnorr_poseidon: `r (32-bytes) || s (32-bytes)` where s = Hash(1st pk || 2nd pk || r) - `64 bytes` (schnorr signature w/ Poseidon hash function implemented by O(1) Labs where both `r` and `s` are scalars encoded as `32-bytes` values, least significant byte first. https://github.com/CodaProtocol/signer-reference/blob/master/schnorr.ml )
type: string
enum:
- ecdsa
- ecdsa_recovery
- ed25519
- schnorr_1
+ - schnorr_bip340
- schnorr_poseidon
Bitcoin's BIP-340 Schnorr signature scheme is a
secp256k1
curve variant not directly supported by Rosetta.The primary outward distinction between the Ecdsa/Secp256k1 scheme and BIP-340 is the use of x-only 32-byte publicKeys and 64-byte (
[R,s]
) signatures.BIP-340's underlying Sign/Verify scheme also internally encodes the signing keyPairs' signature and public point as its variants whose
'Y'
coordinates are a quadratic residue ('even'). (see more here: https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki#design)Benefits
BIP-340 provides greater (provable) security than ECDSA/secp256k1-based schemes and offers signature non-malleability and linearity. Signing also makes use of "tagged hashes" to mitigate things like related-key attacks, which accordingly "...increases robustness in multi-user settings."
While this proposal to introduce BIP-340 does not include multisignature support, this would be a likely precondition to doing so. (e.g., https://github.com/coinbase/rosetta-specifications/issues/50)
Solution
Add the following to
rosetta-specifications
:./models/CurveType.yaml
-Secp256k1Bip340
./models/SignatureType.yaml
-SchnorrBip340
Once approved and released, implement the following in
rosetta-sdk-go
including any relevant tests:./keys/keys.go
- Key Import & Generation./keys/signer_bip340.go
- Sign & VerifyIt should be mentioned that the new CurveType is necessary due to BIP-340's requirement of 32-byte/x-only keys while the existing
rosetta-sdk-go
key interface extends no such ability under the existingSecp256k1
curve.CurveType
rosetta-specifications
rosetta-sdk-go
Key Importimport
of any standardsecp256k1
privateKey and drop the first byte (compression odd/even flag) of its associated publicKey per BIP-340 spec to extend backward compatibility.secp256k1
's 33-byte compressed publicKey.'Y'
coordinates that are a quadratic residue.rosetta-sdk-go
Key GenerationY
value that is a quadratic residue by negating the newly-generated privateKey when its associated public key is found to be 'odd' in its compressed form.References
SignatureType
rosetta-specifications
rosetta-sdk-go
Sign & VerifyBackwards Compatible
Key Imports: Yes
Everything Else: n/a