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.

120 lines
2.9 KiB

  1. package paillier
  2. import (
  3. "crypto/rand"
  4. "errors"
  5. "math/big"
  6. prime "../prime"
  7. )
  8. const (
  9. bits = 16
  10. )
  11. // PublicKey stores the public key data
  12. type PublicKey struct {
  13. N *big.Int `json:"n"`
  14. G *big.Int `json:"g"`
  15. }
  16. // PrivateKey stores the private key data
  17. type PrivateKey struct {
  18. Lambda *big.Int `json:"lambda"`
  19. Mu *big.Int `json:"mu"`
  20. }
  21. // Key stores the public and private key data
  22. type Key struct {
  23. PubK PublicKey
  24. PrivK PrivateKey
  25. }
  26. // GenerateKeyPair generates a random private and public key
  27. func GenerateKeyPair() (key Key, err error) {
  28. p, err := rand.Prime(rand.Reader, bits/2)
  29. if err != nil {
  30. return key, err
  31. }
  32. q, err := rand.Prime(rand.Reader, bits/2)
  33. if err != nil {
  34. return key, err
  35. }
  36. pq := new(big.Int).Mul(p, q)
  37. p1q1 := big.NewInt((p.Int64() - 1) * (q.Int64() - 1))
  38. gcd := new(big.Int).GCD(nil, nil, pq, p1q1)
  39. if gcd.Int64() != int64(1) {
  40. return key, errors.New("gcd comprovation failed")
  41. }
  42. n := new(big.Int).Mul(p, q)
  43. lambda := big.NewInt(int64(lcm(float64(p.Int64())-1, float64(q.Int64())-1)))
  44. //g generation
  45. alpha := big.NewInt(int64(prime.RandInt(0, int(n.Int64()))))
  46. beta := big.NewInt(int64(prime.RandInt(0, int(n.Int64()))))
  47. alphan := new(big.Int).Mul(alpha, n)
  48. alphan1 := new(big.Int).Add(alphan, big.NewInt(1))
  49. betaN := new(big.Int).Exp(beta, n, nil)
  50. ab := new(big.Int).Mul(alphan1, betaN)
  51. n2 := new(big.Int).Mul(n, n)
  52. g := new(big.Int).Mod(ab, n2)
  53. //in some Paillier implementations use this:
  54. // g = new(big.Int).Add(n, big.NewInt(1))
  55. key.PubK.N = n
  56. key.PubK.G = g
  57. //mu generation
  58. Glambda := new(big.Int).Exp(g, lambda, nil)
  59. u := new(big.Int).Mod(Glambda, n2)
  60. L := l(u, n)
  61. mu := new(big.Int).ModInverse(L, n)
  62. key.PrivK.Lambda = lambda
  63. key.PrivK.Mu = mu
  64. return key, nil
  65. }
  66. func lcm(a, b float64) float64 {
  67. r := (a * b) / float64(prime.Gcd(int(a), int(b)))
  68. return r
  69. }
  70. func l(u *big.Int, n *big.Int) *big.Int {
  71. u1 := new(big.Int).Sub(u, big.NewInt(1))
  72. L := new(big.Int).Div(u1, n)
  73. return L
  74. }
  75. // Encrypt encrypts a message m with given PublicKey
  76. func Encrypt(m *big.Int, pubK PublicKey) *big.Int {
  77. gM := new(big.Int).Exp(pubK.G, m, nil)
  78. r := big.NewInt(int64(prime.RandInt(0, int(pubK.N.Int64()))))
  79. rN := new(big.Int).Exp(r, pubK.N, nil)
  80. gMrN := new(big.Int).Mul(gM, rN)
  81. n2 := new(big.Int).Mul(pubK.N, pubK.N)
  82. c := new(big.Int).Mod(gMrN, n2)
  83. return c
  84. }
  85. // Decrypt deencrypts a ciphertext c with given PublicKey and PrivateKey
  86. func Decrypt(c *big.Int, pubK PublicKey, privK PrivateKey) *big.Int {
  87. cLambda := new(big.Int).Exp(c, privK.Lambda, nil)
  88. n2 := new(big.Int).Mul(pubK.N, pubK.N)
  89. u := new(big.Int).Mod(cLambda, n2)
  90. L := l(u, pubK.N)
  91. LMu := new(big.Int).Mul(L, privK.Mu)
  92. m := new(big.Int).Mod(LMu, pubK.N)
  93. return m
  94. }
  95. // HomomorphicAddition calculates the addition of tow encrypted values given a PublicKey
  96. func HomomorphicAddition(c1 *big.Int, c2 *big.Int, pubK PublicKey) *big.Int {
  97. c1c2 := new(big.Int).Mul(c1, c2)
  98. n2 := new(big.Int).Mul(pubK.N, pubK.N)
  99. d := new(big.Int).Mod(c1c2, n2)
  100. return d
  101. }