Skip to content

Instantly share code, notes, and snippets.

@raddy
Created August 25, 2021 17:03
Show Gist options
  • Select an option

  • Save raddy/cef9d965550b42057ce5ba7734622132 to your computer and use it in GitHub Desktop.

Select an option

Save raddy/cef9d965550b42057ce5ba7734622132 to your computer and use it in GitHub Desktop.
Decode personal_sign in Go
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