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.

118 lines
2.6 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. package bls
  2. import (
  3. "crypto/rand"
  4. "crypto/sha256"
  5. "math/big"
  6. "github.com/arnaucube/go-snark/bn128"
  7. )
  8. // this BLS implementation uses the Go implementation of the BN128 pairing github.com/arnaucube/go-snark/bn128
  9. const bits = 2048
  10. // BLS is the data structure of the BLS signature scheme, including the BN128 pairing curve
  11. type BLS struct {
  12. Bn bn128.Bn128
  13. }
  14. type BLSKeys struct {
  15. PrivK *big.Int
  16. PubK [3]*big.Int
  17. }
  18. // NewBLS generates a new BLS scheme
  19. func NewBLS() (BLS, error) {
  20. bn, err := bn128.NewBn128()
  21. if err != nil {
  22. return BLS{}, err
  23. }
  24. bls := BLS{}
  25. bls.Bn = bn
  26. return bls, nil
  27. }
  28. // NewKeys generate new Private Key and Public Key
  29. func (bls BLS) NewKeys() (BLSKeys, error) {
  30. var err error
  31. k := BLSKeys{}
  32. k.PrivK, err = rand.Prime(rand.Reader, bits)
  33. if err != nil {
  34. return BLSKeys{}, err
  35. }
  36. // pubK = pk * G
  37. k.PubK = bls.Bn.G1.MulScalar(bls.Bn.G1.G, k.PrivK)
  38. return k, nil
  39. }
  40. // Hash hashes a message m
  41. func (bls BLS) Hash(m []byte) [3][2]*big.Int {
  42. h := sha256.New()
  43. h.Write(m)
  44. hash := h.Sum(nil)
  45. r := new(big.Int).SetBytes(hash)
  46. // get point over the curve
  47. point := bls.Bn.G2.MulScalar(bls.Bn.G2.G, r)
  48. return point
  49. }
  50. // Sign performs the BLS signature of a message m
  51. func (bls BLS) Sign(privK *big.Int, m []byte) [3][2]*big.Int {
  52. // s = pk * H(m)
  53. h := bls.Hash(m)
  54. sig := bls.Bn.G2.MulScalar(h, privK)
  55. return sig
  56. }
  57. // Verify checks the signature of a message m with the given Public Key
  58. func (bls BLS) Verify(m []byte, sig [3][2]*big.Int, pubK [3]*big.Int) bool {
  59. // checks e(P, G) == e(G, s)
  60. p1, err := bls.Bn.Pairing(pubK, bls.Hash(m))
  61. if err != nil {
  62. return false
  63. }
  64. p2, err := bls.Bn.Pairing(bls.Bn.G1.G, sig)
  65. if err != nil {
  66. return false
  67. }
  68. return bls.Bn.Fq12.Equal(p1, p2)
  69. }
  70. // AggregateSignatures
  71. // s = s0 + s1 + s2 ...
  72. func (bls BLS) AggregateSignatures(signatures ...[3][2]*big.Int) [3][2]*big.Int {
  73. aggr := signatures[0]
  74. for i := 1; i < len(signatures); i++ {
  75. aggr = bls.Bn.G2.Add(aggr, signatures[i])
  76. }
  77. return aggr
  78. }
  79. // VerifyAggregatedSignatures
  80. // ê(G,S) == ê(P, H(m))
  81. // ê(G, s0+s1+s2...) == ê(p0, H(m)) x ê(p1, H(m)) x ê(p2, H(m)) ...
  82. func (bls BLS) VerifyAggregatedSignatures(aggrsig [3][2]*big.Int, pubKArray [][3]*big.Int, m []byte) bool {
  83. pairingGS, err := bls.Bn.Pairing(bls.Bn.G1.G, aggrsig)
  84. if err != nil {
  85. return false
  86. }
  87. pairingsMul, err := bls.Bn.Pairing(pubKArray[0], bls.Hash(m))
  88. if err != nil {
  89. return false
  90. }
  91. for i := 1; i < len(pubKArray); i++ {
  92. e, err := bls.Bn.Pairing(pubKArray[i], bls.Hash(m))
  93. if err != nil {
  94. return false
  95. }
  96. pairingsMul = bls.Bn.Fq12.Mul(pairingsMul, e)
  97. }
  98. if !bls.Bn.Fq12.Equal(pairingGS, pairingsMul) {
  99. return false
  100. }
  101. return true
  102. }