diff --git a/crypto/signature_ecdsa/signature.go b/crypto/signature_ecdsa/signature.go new file mode 100644 index 0000000..907a0a9 --- /dev/null +++ b/crypto/signature_ecdsa/signature.go @@ -0,0 +1,69 @@ +package signature + +import ( + "crypto/ecdsa" + hex "encoding/hex" + "errors" + + crypto "github.com/ethereum/go-ethereum/crypto" +) + +type SignKeys struct { + Public *ecdsa.PublicKey + Private *ecdsa.PrivateKey +} + +// generate new keys +func (k *SignKeys) Generate() error { + var err error + key, err := crypto.GenerateKey() + if err != nil { + return err + } + k.Public = &key.PublicKey + k.Private = key + return nil +} + +// imports a private hex key +func (k *SignKeys) AddHexKey(privHex string) error { + var err error + k.Private, err = crypto.HexToECDSA(privHex) + if err == nil { + k.Public = &k.Private.PublicKey + } + return err +} + +// returns the public and private keys as hex strings +func (k *SignKeys) HexString() (string, string) { + pubHex := hex.EncodeToString(crypto.CompressPubkey(k.Public)) + privHex := hex.EncodeToString(crypto.FromECDSA(k.Private)) + return pubHex, privHex +} + +// message is a normal string (no HexString) +func (k *SignKeys) Sign(message string) (string, error) { + if k.Private == nil { + return "", errors.New("No private key available") + } + hash := crypto.Keccak256([]byte(message)) + signature, err := crypto.Sign(hash, k.Private) + signHex := hex.EncodeToString(signature) + return signHex, err +} + +// message is a normal string, signature and pubHex are HexStrings +func (k *SignKeys) Verify(message, signHex, pubHex string) (bool, error) { + signature, err := hex.DecodeString(signHex) + if err != nil { + return false, err + } + pub, err := hex.DecodeString(pubHex) + if err != nil { + return false, err + } + hash := crypto.Keccak256([]byte(message)) + result := crypto.VerifySignature(pub, hash, signature[:64]) + return result, nil +} diff --git a/crypto/signature_ecdsa/signature_test.go b/crypto/signature_ecdsa/signature_test.go new file mode 100644 index 0000000..ac90670 --- /dev/null +++ b/crypto/signature_ecdsa/signature_test.go @@ -0,0 +1,34 @@ +package signature + +import "testing" + +func TestSignature(t *testing.T) { + t.Log("Testing signature creation and verification") + var s SignKeys + s.Generate() + pub, priv := s.HexString() + t.Logf("Generated pub:%s priv:%s\n", pub, priv) + message := "Hello, this is gonna be signed!" + t.Logf("Message to sign: %s\n", message) + msgSign, err := s.Sign(message) + if err != nil { + t.Errorf("Error while signing %s\n", err) + } + t.Logf("Signature is %s\n", msgSign) + + var s2 SignKeys + err = s2.AddHexKey(priv) + if err != nil { + t.Errorf("Error importing hex privKey: %s\n", err) + } + pub, priv = s2.HexString() + t.Logf("Imported pub:%s priv:%s\n", pub, priv) + v, err := s.Verify(message, msgSign, pub) + if err != nil { + t.Errorf("Verification error: %s\n", err) + } + if !v { + t.Error("Verification failed!") + } + t.Logf("Testing verification... %t\n", v) +}