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.

80 lines
2.0 KiB

  1. package ecdsa
  2. import (
  3. "bytes"
  4. "math/big"
  5. // ecc "../ecc"
  6. "github.com/arnaucube/cryptofun/ecc"
  7. )
  8. // DSA is the ECDSA data structure
  9. type DSA struct {
  10. EC ecc.EC
  11. G ecc.Point
  12. N *big.Int
  13. }
  14. // NewDSA defines a new DSA data structure
  15. func NewDSA(ec ecc.EC, g ecc.Point) (DSA, error) {
  16. var dsa DSA
  17. var err error
  18. dsa.EC = ec
  19. dsa.G = g
  20. dsa.N, err = ec.Order(g)
  21. return dsa, err
  22. }
  23. // PubK returns the public key Point calculated from the private key over the elliptic curve
  24. func (dsa DSA) PubK(privK *big.Int) (ecc.Point, error) {
  25. // privK: rand < ec.Q
  26. privKCopy := new(big.Int).SetBytes(privK.Bytes())
  27. pubK, err := dsa.EC.Mul(dsa.G, privKCopy)
  28. return pubK, err
  29. }
  30. // Sign performs the ECDSA signature
  31. func (dsa DSA) Sign(hashval *big.Int, privK *big.Int, r *big.Int) ([2]*big.Int, error) {
  32. rCopy := new(big.Int).SetBytes(r.Bytes())
  33. m, err := dsa.EC.Mul(dsa.G, rCopy)
  34. if err != nil {
  35. return [2]*big.Int{}, err
  36. }
  37. // inv(r) mod dsa.N
  38. inv := new(big.Int).ModInverse(r, dsa.N)
  39. // m.X * privK
  40. privKCopy := new(big.Int).SetBytes(privK.Bytes())
  41. xPrivK := new(big.Int).Mul(m.X, privKCopy)
  42. // (hashval + m.X * privK)
  43. hashvalXPrivK := new(big.Int).Add(hashval, xPrivK)
  44. // inv * (hashval + m.X * privK) mod dsa.N
  45. a := new(big.Int).Mul(inv, hashvalXPrivK)
  46. r2 := new(big.Int).Mod(a, dsa.N)
  47. return [2]*big.Int{m.X, r2}, err
  48. }
  49. // Verify validates the ECDSA signature
  50. func (dsa DSA) Verify(hashval *big.Int, sig [2]*big.Int, pubK ecc.Point) (bool, error) {
  51. w := new(big.Int).ModInverse(sig[1], dsa.N)
  52. wCopy := new(big.Int).SetBytes(w.Bytes())
  53. u1raw := new(big.Int).Mul(hashval, wCopy)
  54. u1 := new(big.Int).Mod(u1raw, dsa.N)
  55. wCopy = new(big.Int).SetBytes(w.Bytes())
  56. u2raw := new(big.Int).Mul(sig[0], wCopy)
  57. u2 := new(big.Int).Mod(u2raw, dsa.N)
  58. gU1, err := dsa.EC.Mul(dsa.G, u1)
  59. if err != nil {
  60. return false, err
  61. }
  62. pubKU2, err := dsa.EC.Mul(pubK, u2)
  63. if err != nil {
  64. return false, err
  65. }
  66. p, err := dsa.EC.Add(gU1, pubKU2)
  67. if err != nil {
  68. return false, err
  69. }
  70. pXmodN := new(big.Int).Mod(p.X, dsa.N)
  71. return bytes.Equal(pXmodN.Bytes(), sig[0].Bytes()), nil
  72. }