Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save asanikovich/a1df652dc491ca888df3386fa9095db9 to your computer and use it in GitHub Desktop.
Save asanikovich/a1df652dc491ca888df3386fa9095db9 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