-
Notifications
You must be signed in to change notification settings - Fork 1
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
SM-781: extracted common Ecrecover func #73
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package utils | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/crypto" | ||
) | ||
|
||
const sigLen = 65 | ||
|
||
var zeroAddr common.Address | ||
|
||
// Ecrecover mimics the ecrecover opcode, returning the address that signed | ||
// hash with signature. sig must have length 65 and the last byte, the recovery | ||
// byte usually denoted v, must be 27 or 28. | ||
func Ecrecover(hash, sig []byte) (common.Address, error) { | ||
if len(sig) != sigLen { | ||
return zeroAddr, fmt.Errorf("signature has invalid length %d", len(sig)) | ||
} | ||
|
||
// Defensive copy: the caller shouldn't have to worry about us modifying | ||
// the signature. We adjust because crypto.Ecrecover demands 0 <= v <= 4. | ||
fixedSig := make([]byte, sigLen) | ||
copy(fixedSig, sig) | ||
fixedSig[64] -= 27 | ||
|
||
rawPk, err := crypto.Ecrecover(hash, fixedSig) | ||
if err != nil { | ||
return zeroAddr, err | ||
} | ||
|
||
pk, err := crypto.UnmarshalPubkey(rawPk) | ||
if err != nil { | ||
return zeroAddr, err | ||
} | ||
|
||
return crypto.PubkeyToAddress(*pk), nil | ||
} | ||
|
||
// VerifySignature godoc | ||
// checks if the provided signature corresponds to the given message and Ethereum address. | ||
// payload []byte The original message that was signed. | ||
// signature string The signature that needs to be verified. | ||
// ethAddr string The Ethereum address of the signer. | ||
// @return bool Indicates whether the signature is valid or not. | ||
// @return error If there was an issue during the verification process. | ||
zakharenkodmytro marked this conversation as resolved.
Show resolved
Hide resolved
|
||
func VerifySignature(payload []byte, signature string, ethAddr string) (bool, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do like using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated signature, make sense to me |
||
addr := common.HexToAddress(ethAddr) | ||
sig := common.FromHex(signature) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we are going to take in strings, and we do have an error return, maybe we could check that these are valid? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we will delegate validation to the client code |
||
hash := crypto.Keccak256Hash(payload) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you just want bytes, you could use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. updated |
||
|
||
recAddr, err := Ecrecover(hash.Bytes(), sig) | ||
if err != nil { | ||
return false, err | ||
} | ||
|
||
return recAddr == addr, nil | ||
} |
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.
Why not take in a
Hash
?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 is was an exact copy of https://github.com/DIMO-Network/devices-api/blob/a26b001b1680292ad42ce59e52af7e63970d8cf2/internal/controllers/helpers/handlers.go#L161, but we definitely can improve it