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.

100 lines
1.8 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 (sig *Signature) Bytes() []byte {
  40. b := sig.R.Bytes()
  41. b = append(b, sig.S.Bytes()...)
  42. return b
  43. }
  44. func SignatureFromBytes(b []byte) (*Signature, error) {
  45. if len(b) != 64 {
  46. return nil, errors.New("Invalid signature")
  47. }
  48. rBytes := b[:32]
  49. sBytes := b[32:]
  50. r := new(big.Int).SetBytes(rBytes)
  51. s := new(big.Int).SetBytes(sBytes)
  52. sig := &Signature{
  53. R: r,
  54. S: s,
  55. }
  56. return sig, nil
  57. }
  58. type Signature struct {
  59. R *big.Int
  60. S *big.Int
  61. }
  62. func Sign(privK *ecdsa.PrivateKey, m []byte) (*Signature, error) {
  63. r := big.NewInt(0)
  64. s := big.NewInt(0)
  65. hashMsg := HashBytes(m)
  66. r, s, err := ecdsa.Sign(rand.Reader, privK, hashMsg[:])
  67. if err != nil {
  68. return nil, err
  69. }
  70. sig := &Signature{
  71. R: r,
  72. S: s,
  73. }
  74. return sig, nil
  75. }
  76. func VerifySignature(pubK *ecdsa.PublicKey, m []byte, sig Signature) bool {
  77. hashMsg := HashBytes(m)
  78. verified := ecdsa.Verify(pubK, hashMsg[:], sig.R, sig.S)
  79. return verified
  80. }