You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 lines
1.9 KiB

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