Created
August 25, 2021 17:03
-
-
Save raddy/cef9d965550b42057ce5ba7734622132 to your computer and use it in GitHub Desktop.
Decode personal_sign in Go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "fmt" | |
| "os" | |
| "strings" | |
| "github.com/ethereum/go-ethereum/common" | |
| "github.com/ethereum/go-ethereum/common/hexutil" | |
| "github.com/ethereum/go-ethereum/crypto" | |
| ) | |
| type EIP191 struct { | |
| msg string | |
| signature string | |
| address string | |
| } | |
| func check(e error) { | |
| if e != nil { | |
| panic(e) | |
| } | |
| } | |
| func hasValidLastByte(sig []byte) bool { | |
| return sig[64] == 0 || sig[64] == 1 | |
| } | |
| func hasMatchingAddress(knownAddress string, recoveredAddress string) bool { | |
| return strings.ToLower(knownAddress) == strings.ToLower(recoveredAddress) | |
| } | |
| func signEIP191(message string) common.Hash { | |
| msg := []byte(message) | |
| formattedMsg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(msg), msg) | |
| return crypto.Keccak256Hash([]byte(formattedMsg)) | |
| } | |
| func decodePersonal(eipChallenge EIP191) { | |
| decodedSig, err := hexutil.Decode(eipChallenge.signature) | |
| check(err) | |
| if decodedSig[64] < 27 { | |
| if !hasValidLastByte(decodedSig) { | |
| panic("Invalid last byte") | |
| } | |
| } else { | |
| decodedSig[64] -= 27 // shift byte? | |
| } | |
| hash := signEIP191(eipChallenge.msg) | |
| recoveredPublicKey, err := crypto.Ecrecover(hash.Bytes(), decodedSig) | |
| check(err) | |
| secp256k1RecoveredPublicKey, err := crypto.UnmarshalPubkey(recoveredPublicKey) | |
| check(err) | |
| recoveredAddress := crypto.PubkeyToAddress(*secp256k1RecoveredPublicKey).Hex() | |
| if hasMatchingAddress(eipChallenge.address, recoveredAddress) { | |
| fmt.Println("Signature matches known address!") | |
| } else { | |
| fmt.Printf("Recovered address %s does not match %s\n", recoveredAddress, eipChallenge.address) | |
| } | |
| } | |
| func main() { | |
| eipChallenge := EIP191{os.Args[1], os.Args[2], os.Args[3]} | |
| decodePersonal(eipChallenge) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment