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.

66 lines
1.6 KiB

  1. package elgamal
  2. import (
  3. "math/big"
  4. "github.com/arnaucube/cryptofun/ecc"
  5. )
  6. // EG is the ElGamal data structure
  7. type EG struct {
  8. EC ecc.EC
  9. G ecc.Point
  10. N *big.Int
  11. }
  12. // NewEG defines a new EG data structure
  13. func NewEG(ec ecc.EC, g ecc.Point) (EG, error) {
  14. var eg EG
  15. var err error
  16. eg.EC = ec
  17. eg.G = g
  18. eg.N, err = ec.Order(g)
  19. return eg, err
  20. }
  21. // PubK returns the public key Point calculated from the private key over the elliptic curve
  22. func (eg EG) PubK(privK *big.Int) (ecc.Point, error) {
  23. // privK: rand < ec.Q
  24. privKCopy := new(big.Int).SetBytes(privK.Bytes())
  25. pubK, err := eg.EC.Mul(eg.G, privKCopy)
  26. return pubK, err
  27. }
  28. // Encrypt encrypts a point m with the public key point, returns two points
  29. func (eg EG) Encrypt(m ecc.Point, pubK ecc.Point, r *big.Int) ([2]ecc.Point, error) {
  30. rCopy := new(big.Int).SetBytes(r.Bytes())
  31. p1, err := eg.EC.Mul(eg.G, rCopy)
  32. if err != nil {
  33. return [2]ecc.Point{}, err
  34. }
  35. rCopy = new(big.Int).SetBytes(r.Bytes())
  36. p2, err := eg.EC.Mul(pubK, rCopy)
  37. if err != nil {
  38. return [2]ecc.Point{}, err
  39. }
  40. p3, err := eg.EC.Add(m, p2)
  41. if err != nil {
  42. return [2]ecc.Point{}, err
  43. }
  44. c := [2]ecc.Point{p1, p3}
  45. return c, err
  46. }
  47. // Decrypt decrypts c (two points) with the private key, returns the point decrypted
  48. func (eg EG) Decrypt(c [2]ecc.Point, privK *big.Int) (ecc.Point, error) {
  49. c1 := c[0]
  50. c2 := c[1]
  51. privKCopy := new(big.Int).SetBytes(privK.Bytes())
  52. c1PrivK, err := eg.EC.Mul(c1, privKCopy)
  53. if err != nil {
  54. return ecc.Point{}, err
  55. }
  56. c1PrivKNeg := eg.EC.Neg(c1PrivK)
  57. d, err := eg.EC.Add(c2, c1PrivKNeg)
  58. return d, err
  59. }