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.

165 lines
4.3 KiB

  1. // Package blindsecp256k1v0 implements the Blind signature scheme explained at
  2. // "An Efficient Blind Signature Scheme Based on the Elliptic Curve Discrete
  3. // Logarithm Problem", by Morteza Nikooghadama & Ali Zakerolhosseini
  4. // http://www.isecure-journal.com/article_39171_47f9ec605dd3918c2793565ec21fcd7a.pdf
  5. //
  6. // LICENSE can be found at https://github.com/arnaucube/go-blindsecp256k1/blob/master/LICENSE
  7. //
  8. package blindsecp256k1v0
  9. // WARNING: WIP code
  10. import (
  11. "bytes"
  12. "crypto/ecdsa"
  13. "crypto/rand"
  14. "math/big"
  15. "github.com/arnaucube/go-blindsecp256k1"
  16. "github.com/ethereum/go-ethereum/crypto/secp256k1"
  17. )
  18. // WIP
  19. func newRand() (*big.Int, error) {
  20. pk, err := ecdsa.GenerateKey(secp256k1.S256(), rand.Reader)
  21. if err != nil {
  22. return nil, err
  23. }
  24. return pk.D, nil
  25. }
  26. // PrivateKey represents the signer's private key
  27. type PrivateKey big.Int
  28. // NewPrivateKey returns a new random private key
  29. func NewPrivateKey() (*PrivateKey, error) {
  30. k, err := newRand()
  31. if err != nil {
  32. return nil, err
  33. }
  34. sk := PrivateKey(*k)
  35. return &sk, nil
  36. }
  37. // BigInt returns a *big.Int representation of the PrivateKey
  38. func (sk *PrivateKey) BigInt() *big.Int {
  39. return (*big.Int)(sk)
  40. }
  41. // Public returns the PublicKey from the PrivateKey
  42. func (sk *PrivateKey) Public() *blindsecp256k1.PublicKey {
  43. Q := blindsecp256k1.G.Mul(sk.BigInt())
  44. pk := blindsecp256k1.PublicKey(*Q)
  45. return &pk
  46. }
  47. // NewRequestParameters returns a new random k (secret) & R (public) parameters
  48. func NewRequestParameters() (*big.Int, *blindsecp256k1.Point, error) {
  49. k, err := newRand()
  50. if err != nil {
  51. return nil, nil, err
  52. }
  53. // k, R = kG
  54. return k, blindsecp256k1.G.Mul(k), nil
  55. }
  56. // BlindSign performs the blind signature on the given mBlinded using
  57. // SignerPrivateData values
  58. func (sk *PrivateKey) BlindSign(mBlinded *big.Int, k *big.Int) *big.Int {
  59. // WARNING missing checks, this package is not updated, use
  60. // blindsecp256k1 instead
  61. // TODO add pending checks
  62. // s' = d(m') + k
  63. sBlind := new(big.Int).Add(
  64. new(big.Int).Mul(sk.BigInt(), mBlinded),
  65. k)
  66. return sBlind
  67. }
  68. // UserSecretData contains the secret values from the User (a, b, c) and the
  69. // public F
  70. type UserSecretData struct {
  71. A *big.Int
  72. B *big.Int
  73. C *big.Int
  74. F *blindsecp256k1.Point // public
  75. }
  76. // Blind performs the blinding operation on m using SignerPublicData parameters
  77. func Blind(m *big.Int, signerPubK *blindsecp256k1.PublicKey,
  78. signerR *blindsecp256k1.Point) (*big.Int, *UserSecretData, error) {
  79. var err error
  80. u := &UserSecretData{}
  81. u.A, err = newRand()
  82. if err != nil {
  83. return nil, nil, err
  84. }
  85. u.B, err = newRand()
  86. if err != nil {
  87. return nil, nil, err
  88. }
  89. u.C, err = newRand()
  90. if err != nil {
  91. return nil, nil, err
  92. }
  93. binv := new(big.Int).ModInverse(u.B, blindsecp256k1.N)
  94. // F = b^-1 R + a b^-1 Q + c G
  95. bR := signerR.Mul(binv)
  96. abinv := new(big.Int).Mul(u.A, binv)
  97. abinv = new(big.Int).Mod(abinv, blindsecp256k1.N)
  98. abQ := signerPubK.Point().Mul(abinv)
  99. cG := blindsecp256k1.G.Mul(u.C)
  100. u.F = bR.Add(abQ).Add(cG)
  101. // TODO check F==O
  102. r := new(big.Int).Mod(u.F.X, blindsecp256k1.N)
  103. // m' = br(m)+a
  104. br := new(big.Int).Mul(u.B, r)
  105. brm := new(big.Int).Mul(br, m)
  106. mBlinded := new(big.Int).Add(brm, u.A)
  107. mBlinded = new(big.Int).Mod(mBlinded, blindsecp256k1.N)
  108. return mBlinded, u, nil
  109. }
  110. // Signature contains the signature values S & F
  111. type Signature struct {
  112. S *big.Int
  113. F *blindsecp256k1.Point
  114. }
  115. // Unblind performs the unblinding operation of the blinded signature for the
  116. // given and the UserSecretData
  117. func Unblind(sBlind *big.Int, u *UserSecretData) *Signature {
  118. // s = b^-1 s' + c
  119. binv := new(big.Int).ModInverse(u.B, blindsecp256k1.N)
  120. bs := new(big.Int).Mul(binv, sBlind)
  121. s := new(big.Int).Add(bs, u.C)
  122. s = new(big.Int).Mod(s, blindsecp256k1.N)
  123. return &Signature{
  124. S: s,
  125. F: u.F,
  126. }
  127. }
  128. // Verify checks the signature of the message m for the given PublicKey
  129. func Verify(m *big.Int, signature *Signature, q *blindsecp256k1.PublicKey) bool {
  130. // TODO add pending checks
  131. sG := blindsecp256k1.G.Mul(signature.S) // sG
  132. r := new(big.Int).Mod(signature.F.X, blindsecp256k1.N) // r = Fx mod N
  133. rm := new(big.Int).Mul(r, m)
  134. rm = new(big.Int).Mod(rm, blindsecp256k1.N)
  135. rmQ := q.Point().Mul(rm)
  136. rmQF := rmQ.Add(signature.F) // rmQ + F
  137. // check sG == rmQ + F
  138. if bytes.Equal(sG.X.Bytes(), rmQF.X.Bytes()) &&
  139. bytes.Equal(sG.Y.Bytes(), rmQF.Y.Bytes()) {
  140. return true
  141. }
  142. return false
  143. }