Skip to content

Instantly share code, notes, and snippets.

@chanioxaris
Created May 28, 2022 10:41
Show Gist options
  • Save chanioxaris/051034918aa4cf18d7e047cab9b15ce6 to your computer and use it in GitHub Desktop.
Save chanioxaris/051034918aa4cf18d7e047cab9b15ce6 to your computer and use it in GitHub Desktop.
Sign and verify a message using go-ethereum
package main
import (
"crypto/ecdsa"
"fmt"
"log"
"golang.org/x/crypto/sha3"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
)
const message = "Hello Ethereum world"
func main() {
privateKey, address, err := generateAddressAndPrivateKey()
if err != nil {
log.Fatalf("failed to generate address and private key: %v", err)
}
signature, err := signMessage(privateKey, message)
if err != nil {
log.Fatalf("failed to sign message: %v", err)
}
err = verifySignature(address, signature, message)
if err != nil {
log.Fatalf("failed to verify signature: %v", err)
}
fmt.Printf("Successfully signed and verified message '%s' with Ethereum address %s\n", message, address)
}
func signMessage(privateKey *ecdsa.PrivateKey, message string) (string, error) {
messageHash := accounts.TextHash([]byte(message))
signature, err := crypto.Sign(messageHash, privateKey)
if err != nil {
return "", err
}
signature[crypto.RecoveryIDOffset] += 27
return hexutil.Encode(signature), nil
}
func verifySignature(fromAddress, signatureHex, message string) error {
signature, err := hexutil.Decode(signatureHex)
if err != nil {
return err
}
signature[crypto.RecoveryIDOffset] -= 27 // Transform yellow paper V from 27/28 to 0/1
messageHash := accounts.TextHash([]byte(message))
pubKey, err := crypto.SigToPub(messageHash, signature)
if err != nil {
return err
}
if common.HexToAddress(fromAddress) != crypto.PubkeyToAddress(*pubKey) {
return fmt.Errorf("failed to verify signature")
}
return nil
}
func generateAddressAndPrivateKey() (*ecdsa.PrivateKey, string, error) {
privateKey, err := crypto.GenerateKey()
if err != nil {
return nil, "", err
}
publicKey := privateKey.Public().(*ecdsa.PublicKey)
publicKeyBytes := crypto.FromECDSAPub(publicKey)
hash := sha3.NewLegacyKeccak256()
hash.Write(publicKeyBytes[1:])
address := hexutil.Encode(hash.Sum(nil)[12:])
return privateKey, address, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment