-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(WIP) Add pre-compile: verification for ed25519 sig made via GPG #2
base: optimism
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great. Definitely seems clear that this is the better path than using EIP665 and implementing the GPG stuff in Solidity.
I left a few comments on areas that will require some tweaks.
Before testing in Foundry, I would recommend adding a test to contracts_test.go
. You can hardcode 1 correct signature and one incorrect signature into a JSON file, and should be able to plug that in to verify the signature verification is working as expected.
params/protocol_params.go
Outdated
@@ -170,6 +170,7 @@ const ( | |||
Bls12381MapG2Gas uint64 = 75000 // Gas price for BLS12-381 mapping field element to G2 operation | |||
|
|||
P256VerifyGas uint64 = 3450 // secp256r1 elliptic curve signature verifier gas price | |||
GpgEd25519VerifyGas uint64 = 2000 // GPG Ed25519 signature verification gas price |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should do some benchmarking to make sure this price is still appropriate, given the extra computation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Plan for this:
- run other precompile benchmarks to get MGas/s on local machine
- run our precompile to get a sense of runs/s with varying inputs
- create pricing formula that leads to MGas/s equal or greater than compared precompiles for all inputs
- if the resulting gas price is very low, round up to be safe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd also like to get a sense of whether there are codepaths in the Go libs that are very time intensive that could be abused as a DOS vector. We can poke around a bit, but also will leave a note for auditors to explore this.
core/vm/contracts.go
Outdated
if len(input) < int(offset+32+pubKeyLen) { | ||
return nil, errPubKeyTooShort | ||
} | ||
pubKey := input[offset+32 : offset+32+pubKeyLen] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a specific length the pubKey is supposed to be that we should verify?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the comment on signature length. The armored public key length is non-deterministic (exported via gpg --export --armor <your-key-id>
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, no way to do this. I'm going to leave this comment open as a reminder that I need to talk to the Tea team to figure out a reasonable upper bound to make sure that (a) there is sufficient gas to handle it, and (b) that there is no DOS risk based on whatever gas params we choose.
I've added tests and benchmarks in Overall, enshrining GPG specific code in a precompile like this means using it with public keys and signatures in the GPG specific armored format, instead of raw 32 bytes public keys and 64 bytes signatures. So far, I haven't landed on a solution to go back and forth from armored format (pKey or signature) to hex and back. |
@@ -170,7 +170,7 @@ const ( | |||
Bls12381MapG2Gas uint64 = 75000 // Gas price for BLS12-381 mapping field element to G2 operation | |||
|
|||
P256VerifyGas uint64 = 3450 // secp256r1 elliptic curve signature verifier gas price | |||
GpgEd25519VerifyGas uint64 = 2000 // GPG Ed25519 signature verification gas price | |||
GpgEd25519VerifyGas uint64 = 7900 // GPG Ed25519 signature verification gas price |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming Ecrecover is fairly priced (as per EIP-152 Blake2 precompile) at 3000 gas/op
for ~50,100 ns/op
.
GpgEd25519Verify should be priced proportionately 7900 gas/op
for ~134,000 ns/op
as a good first estimate for gas cost.
A pre-compile contract at
0xed
that uses gopengpg to verify signatures produced on signing a bytes message with an ed25519 key via GPG.Usage