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.

188 lines
4.4 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/rand"
  13. "math/big"
  14. "github.com/btcsuite/btcd/btcec"
  15. )
  16. var (
  17. // G represents the base point of secp256k1
  18. G *Point = &Point{
  19. X: btcec.S256().Gx,
  20. Y: btcec.S256().Gy,
  21. }
  22. // N represents the order of G of secp256k1
  23. N *big.Int = btcec.S256().N
  24. )
  25. // Point represents a point on the secp256k1 curve
  26. type Point struct {
  27. X *big.Int
  28. Y *big.Int
  29. }
  30. // Add performs the Point addition
  31. func (p *Point) Add(q *Point) *Point {
  32. x, y := btcec.S256().Add(p.X, p.Y, q.X, q.Y)
  33. return &Point{
  34. X: x,
  35. Y: y,
  36. }
  37. }
  38. // Mul performs the Point scalar multiplication
  39. func (p *Point) Mul(scalar *big.Int) *Point {
  40. x, y := btcec.S256().ScalarMult(p.X, p.Y, scalar.Bytes())
  41. return &Point{
  42. X: x,
  43. Y: y,
  44. }
  45. }
  46. // WIP
  47. func newRand() *big.Int {
  48. var b [32]byte
  49. _, err := rand.Read(b[:])
  50. if err != nil {
  51. panic(err)
  52. }
  53. bi := new(big.Int).SetBytes(b[:])
  54. return new(big.Int).Mod(bi, N)
  55. }
  56. // PrivateKey represents the signer's private key
  57. type PrivateKey big.Int
  58. // PublicKey represents the signer's public key
  59. type PublicKey Point
  60. // NewPrivateKey returns a new random private key
  61. func NewPrivateKey() *PrivateKey {
  62. k := newRand()
  63. sk := PrivateKey(*k)
  64. return &sk
  65. }
  66. // BigInt returns a *big.Int representation of the PrivateKey
  67. func (sk *PrivateKey) BigInt() *big.Int {
  68. return (*big.Int)(sk)
  69. }
  70. // Public returns the PublicKey from the PrivateKey
  71. func (sk *PrivateKey) Public() *PublicKey {
  72. Q := G.Mul(sk.BigInt())
  73. pk := PublicKey(*Q)
  74. return &pk
  75. }
  76. // Point returns a *Point representation of the PublicKey
  77. func (pk *PublicKey) Point() *Point {
  78. return (*Point)(pk)
  79. }
  80. // NewRequestParameters returns a new random k (secret) & R (public) parameters
  81. func NewRequestParameters() (*big.Int, *Point) {
  82. k := newRand()
  83. return k, G.Mul(k) // R = kG
  84. }
  85. // BlindSign performs the blind signature on the given mBlinded using
  86. // SignerPrivateData values
  87. func (sk *PrivateKey) BlindSign(mBlinded *big.Int, k *big.Int) *big.Int {
  88. // TODO add pending checks
  89. // s' = d(m') + k
  90. sBlind := new(big.Int).Add(
  91. new(big.Int).Mul(sk.BigInt(), mBlinded),
  92. k)
  93. return sBlind
  94. }
  95. // UserSecretData contains the secret values from the User (a, b, c) and the
  96. // public F
  97. type UserSecretData struct {
  98. A *big.Int
  99. B *big.Int
  100. C *big.Int
  101. F *Point // public
  102. }
  103. // Blind performs the blinding operation on m using SignerPublicData parameters
  104. func Blind(m *big.Int, signerPubK *PublicKey, signerR *Point) (*big.Int, *UserSecretData) {
  105. u := &UserSecretData{}
  106. u.A = newRand()
  107. u.B = newRand()
  108. u.C = newRand()
  109. binv := new(big.Int).ModInverse(u.B, N)
  110. // F = b^-1 R + a b^-1 Q + c G
  111. bR := signerR.Mul(binv)
  112. abinv := new(big.Int).Mul(u.A, binv)
  113. abinv = new(big.Int).Mod(abinv, N)
  114. abQ := signerPubK.Point().Mul(abinv)
  115. cG := G.Mul(u.C)
  116. u.F = bR.Add(abQ).Add(cG)
  117. // TODO check F==O
  118. r := new(big.Int).Mod(u.F.X, N)
  119. // m' = br(m)+a
  120. br := new(big.Int).Mul(u.B, r)
  121. brm := new(big.Int).Mul(br, m)
  122. mBlinded := new(big.Int).Add(brm, u.A)
  123. mBlinded = new(big.Int).Mod(mBlinded, N)
  124. return mBlinded, u
  125. }
  126. // Signature contains the signature values S & F
  127. type Signature struct {
  128. S *big.Int
  129. F *Point
  130. }
  131. // Unblind performs the unblinding operation of the blinded signature for the
  132. // given message m and the UserSecretData
  133. func Unblind(sBlind, m *big.Int, u *UserSecretData) *Signature {
  134. // s = b^-1 s' + c
  135. binv := new(big.Int).ModInverse(u.B, N)
  136. bs := new(big.Int).Mul(binv, sBlind)
  137. s := new(big.Int).Add(bs, u.C)
  138. s = new(big.Int).Mod(s, N)
  139. return &Signature{
  140. S: s,
  141. F: u.F,
  142. }
  143. }
  144. // Verify checks the signature of the message m for the given PublicKey
  145. func Verify(m *big.Int, signature *Signature, q *PublicKey) bool {
  146. // TODO add pending checks
  147. sG := G.Mul(signature.S) // sG
  148. r := new(big.Int).Mod(signature.F.X, N) // r = Fx mod N
  149. rm := new(big.Int).Mul(r, m)
  150. rm = new(big.Int).Mod(rm, N)
  151. rmQ := q.Point().Mul(rm)
  152. rmQF := rmQ.Add(signature.F) // rmQ + F
  153. // check sG == rmQ + F
  154. if bytes.Equal(sG.X.Bytes(), rmQF.X.Bytes()) &&
  155. bytes.Equal(sG.Y.Bytes(), rmQF.Y.Bytes()) {
  156. return true
  157. }
  158. return false
  159. }