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.

94 lines
1.7 KiB

  1. package core
  2. import (
  3. "crypto/ecdsa"
  4. "crypto/elliptic"
  5. "crypto/rand"
  6. "encoding/hex"
  7. "errors"
  8. "math/big"
  9. )
  10. // Address is the type data for addresses
  11. type Address [32]byte
  12. func (addr Address) String() string {
  13. return hex.EncodeToString(addr[:])
  14. }
  15. func NewKey() (*ecdsa.PrivateKey, error) {
  16. curve := elliptic.P256()
  17. privatekey := new(ecdsa.PrivateKey)
  18. privatekey, err := ecdsa.GenerateKey(curve, rand.Reader)
  19. if err != nil {
  20. return nil, err
  21. }
  22. return privatekey, err
  23. }
  24. func PackPubK(pubK *ecdsa.PublicKey) []byte {
  25. return elliptic.Marshal(pubK.Curve, pubK.X, pubK.Y)
  26. }
  27. func UnpackPubK(b []byte) *ecdsa.PublicKey {
  28. x, y := elliptic.Unmarshal(elliptic.P256(), b)
  29. return &ecdsa.PublicKey{
  30. Curve: elliptic.P256(),
  31. X: x,
  32. Y: y,
  33. }
  34. }
  35. func AddressFromPrivK(privK *ecdsa.PrivateKey) Address {
  36. h := HashBytes(PackPubK(&privK.PublicKey))
  37. return Address(h)
  38. }
  39. func PackSignature(r, s *big.Int) []byte {
  40. sig := r.Bytes()
  41. sig = append(sig, s.Bytes()...)
  42. return sig
  43. }
  44. func UnpackSignature(sig []byte) (*big.Int, *big.Int, error) {
  45. if len(sig) != 64 {
  46. return nil, nil, errors.New("Invalid signature")
  47. }
  48. rBytes := sig[:32]
  49. sBytes := sig[32:]
  50. r := new(big.Int).SetBytes(rBytes)
  51. s := new(big.Int).SetBytes(sBytes)
  52. return r, s, nil
  53. }
  54. func Sign(privK *ecdsa.PrivateKey, m []byte) ([]byte, error) {
  55. r := big.NewInt(0)
  56. s := big.NewInt(0)
  57. hashMsg := HashBytes(m)
  58. r, s, err := ecdsa.Sign(rand.Reader, privK, hashMsg[:])
  59. if err != nil {
  60. return []byte{}, err
  61. }
  62. sig := PackSignature(r, s)
  63. return sig, nil
  64. }
  65. func VerifySignature(pubK *ecdsa.PublicKey, m []byte, sig []byte) bool {
  66. hashMsg := HashBytes(m)
  67. r, s, err := UnpackSignature(sig)
  68. if err != nil {
  69. return false
  70. }
  71. verified := ecdsa.Verify(pubK, hashMsg[:], r, s)
  72. return verified
  73. }