Cross-posted from question
I've been working on writing a signer service for an Ethereum transaction manager and I need to sign Ethereum transactions using Google KMS Golang APIs. I'll try and summarise the problems I'm facing below.
Ethereum requires compact RLP encoded 65-byte ECDSA signatures in R || S || V format. ECDSA signatures by Google KMS on the other hand have extra header components (R length, S length, etc) along with variable length R and S components. This makes these signatures incompatible for use with Ethereum transaction signing.
A way to get around this is parsing the R and S bytes from the ecdsa signature obtained from Google KMS, compute and add the V byte to the end and use this signature to get a signed Ethereum transaction. Something like this:
var parsedSig struct{ R, S *big.Int }
_, err = asn1.Unmarshal(body, &parsedSig)
if err != nil {
logger.WithError(err).Error("failed to parse signature bytes")
return err
}
However this would possibly fail due to one or more of the following reasons:
- Creating compact ECDSA signatures of 65-byte length by parsing out the R and S components and adding the V component is possibly as distrustful as it sounds. R and S components as mentioned above are not always of 32 byte length for standard ECDSA signatures, which means that the ECDSA signature created by concatenating the components might not always result in 64 bytes.
- Currently signed transactions in Ethereum are created from Keccak-256 digest hashes after RLP encoding transactions as shown below:
Asymmetric ECDSA key signing in Google KMS doesn’t have support for Keccak-256 SHA3 message digests. Would using a SHA-256 digest for ethereum transactions work? IMO this would fail since all transaction signature verification happens on RLP encoded Keccak hashes.// from go-ethereum func rlpHash(x interface{}) (h common.Hash) { hw := sha3.NewLegacyKeccak256() rlp.Encode(hw, x) hw.Sum(h[:0]) return h }
- At this point I am not very sure how to compute the V component of the ECDSA signature after having checked the secp256k1 implementation of the
secp256k1_ecdsa_sign_recoverable()
function.
How do I go about solving these above issues to be able to create verifiable signed Ethereum transactions using asymmetric elliptic curve signing algorithm by Google KMS?