package signature
|
|
|
|
import (
|
|
"fmt"
|
|
sign "golang.org/x/crypto/nacl/sign"
|
|
rand "crypto/rand"
|
|
hex "encoding/hex"
|
|
"errors"
|
|
)
|
|
|
|
const signatureSize = 128
|
|
|
|
type SignKeys struct {
|
|
Public *[32]byte
|
|
Private *[64]byte
|
|
}
|
|
|
|
func (k *SignKeys) Generate() error {
|
|
var err error
|
|
k.Public = new([32]byte)
|
|
k.Private = new([64]byte)
|
|
k.Public, k.Private, err = sign.GenerateKey(rand.Reader)
|
|
return err
|
|
}
|
|
|
|
func (k *SignKeys) AddHexKeys(pubHex string, privHex string) error {
|
|
if len(pubHex) < 32 || len(privHex) < 64 {
|
|
return errors.New("Wrong key size, must be pub:32 priv:64 (bytes)")
|
|
}
|
|
pubKey, err := hex.DecodeString(pubHex)
|
|
if err != nil { return err }
|
|
privKey, err := hex.DecodeString(privHex)
|
|
if err != nil { return err }
|
|
k.Public = new([32]byte)
|
|
k.Private = new([64]byte)
|
|
copy(k.Public[:],pubKey[:32])
|
|
copy(k.Private[:],privKey[:64])
|
|
return nil
|
|
}
|
|
|
|
func (k *SignKeys) HexString() (string, string) {
|
|
pubHex := hex.EncodeToString(k.Public[:])
|
|
privHex := hex.EncodeToString(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")
|
|
}
|
|
signature := sign.Sign(nil, []byte(message), k.Private)
|
|
signHexFull := hex.EncodeToString(signature)
|
|
return signHexFull[:signatureSize], nil
|
|
}
|
|
|
|
// message is a normal string, signature and pubHex are HexStrings
|
|
func (k *SignKeys) Verify(message, signature, pubHex string) (bool, error) {
|
|
msgHex := hex.EncodeToString([]byte(message))
|
|
signatureAndText := fmt.Sprintf("%s%s", signature, msgHex)
|
|
signatureToVerify, err := hex.DecodeString(signatureAndText)
|
|
if err != nil { return false, err }
|
|
pubKeyToVerify, err := hex.DecodeString(pubHex)
|
|
if err != nil { return false, err }
|
|
pubKey := new([32]byte)
|
|
copy(pubKey[:],pubKeyToVerify[:32])
|
|
_, result := sign.Open(nil, signatureToVerify, pubKey)
|
|
return result, nil
|
|
}
|