go-dvote/crypto/signature/signature.go
crypto/signature/signature.goRaw
1package signature
2
3import (
4 "fmt"
5 sign "golang.org/x/crypto/nacl/sign"
6 rand "crypto/rand"
7 hex "encoding/hex"
8 "errors"
9)
10
11const signatureSize = 128
12
13type SignKeys struct {
14 Public *[32]byte
15 Private *[64]byte
16}
17
18func (k *SignKeys) Generate() error {
19 var err error
20 k.Public = new([32]byte)
21 k.Private = new([64]byte)
22 k.Public, k.Private, err = sign.GenerateKey(rand.Reader)
23 return err
24}
25
26func (k *SignKeys) AddHexKeys(pubHex string, privHex string) error {
27 if len(pubHex) < 32 || len(privHex) < 64 {
28 return errors.New("Wrong key size, must be pub:32 priv:64 (bytes)")
29 }
30 pubKey, err := hex.DecodeString(pubHex)
31 if err != nil { return err }
32 privKey, err := hex.DecodeString(privHex)
33 if err != nil { return err }
34 k.Public = new([32]byte)
35 k.Private = new([64]byte)
36 copy(k.Public[:],pubKey[:32])
37 copy(k.Private[:],privKey[:64])
38 return nil
39}
40
41func (k *SignKeys) HexString() (string, string) {
42 pubHex := hex.EncodeToString(k.Public[:])
43 privHex := hex.EncodeToString(k.Private[:])
44 return pubHex, privHex
45}
46
47// message is a normal string (no HexString)
48func (k *SignKeys) Sign(message string) (string, error) {
49 if k.Private == nil {
50 return "", errors.New("No private key available")
51 }
52 signature := sign.Sign(nil, []byte(message), k.Private)
53 signHexFull := hex.EncodeToString(signature)
54 return signHexFull[:signatureSize], nil
55}
56
57// message is a normal string, signature and pubHex are HexStrings
58func (k *SignKeys) Verify(message, signature, pubHex string) (bool, error) {
59 msgHex := hex.EncodeToString([]byte(message))
60 signatureAndText := fmt.Sprintf("%s%s", signature, msgHex)
61 signatureToVerify, err := hex.DecodeString(signatureAndText)
62 if err != nil { return false, err }
63 pubKeyToVerify, err := hex.DecodeString(pubHex)
64 if err != nil { return false, err }
65 pubKey := new([32]byte)
66 copy(pubKey[:],pubKeyToVerify[:32])
67 _, result := sign.Open(nil, signatureToVerify, pubKey)
68 return result, nil
69}