Signed-off-by: p4u <p4u@dabax.net>testnet
@ -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 |
||||
|
} |
@ -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) |
||||
|
} |