zza.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /*
  2. * Copyright (c) 2000-2018, 达梦数据库有限公司.
  3. * All rights reserved.
  4. */
  5. package security
  6. import (
  7. "crypto/rand"
  8. "errors"
  9. "io"
  10. "math/big"
  11. )
  12. type dhGroup struct {
  13. p *big.Int
  14. g *big.Int
  15. }
  16. func newDhGroup(prime, generator *big.Int) *dhGroup {
  17. return &dhGroup{
  18. p: prime,
  19. g: generator,
  20. }
  21. }
  22. func (dg *dhGroup) P() *big.Int {
  23. p := new(big.Int)
  24. p.Set(dg.p)
  25. return p
  26. }
  27. func (dg *dhGroup) G() *big.Int {
  28. g := new(big.Int)
  29. g.Set(dg.g)
  30. return g
  31. }
  32. // 生成本地公私钥
  33. func (dg *dhGroup) GeneratePrivateKey(randReader io.Reader) (key *DhKey, err error) {
  34. if randReader == nil {
  35. randReader = rand.Reader
  36. }
  37. // 0 < x < p
  38. x, err := rand.Int(randReader, dg.p)
  39. if err != nil {
  40. return
  41. }
  42. zero := big.NewInt(0)
  43. for x.Cmp(zero) == 0 {
  44. x, err = rand.Int(randReader, dg.p)
  45. if err != nil {
  46. return
  47. }
  48. }
  49. key = new(DhKey)
  50. key.x = x
  51. // y = g ^ x mod p
  52. key.y = new(big.Int).Exp(dg.g, x, dg.p)
  53. key.group = dg
  54. return
  55. }
  56. func (dg *dhGroup) ComputeKey(pubkey *DhKey, privkey *DhKey) (kye *DhKey, err error) {
  57. if dg.p == nil {
  58. err = errors.New("DH: invalid group")
  59. return
  60. }
  61. if pubkey.y == nil {
  62. err = errors.New("DH: invalid public key")
  63. return
  64. }
  65. if pubkey.y.Sign() <= 0 || pubkey.y.Cmp(dg.p) >= 0 {
  66. err = errors.New("DH parameter out of bounds")
  67. return
  68. }
  69. if privkey.x == nil {
  70. err = errors.New("DH: invalid private key")
  71. return
  72. }
  73. k := new(big.Int).Exp(pubkey.y, privkey.x, dg.p)
  74. key := new(DhKey)
  75. key.y = k
  76. key.group = dg
  77. return
  78. }