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.

189 lines
4.3 KiB

3 years ago
  1. // Package blindsecp256k1 implements the Blind signature scheme explained at
  2. // "New Blind Signature Schemes Based on the (Elliptic Curve) Discrete
  3. // Logarithm Problem", by Hamid Mala & Nafiseh Nezhadansari
  4. // https://sci-hub.do/10.1109/ICCKE.2013.6682844
  5. //
  6. // LICENSE can be found at https://github.com/arnaucube/go-blindsecp256k1/blob/master/LICENSE
  7. //
  8. package blindsecp256k1
  9. // WARNING: WIP code
  10. import (
  11. "bytes"
  12. "crypto/rand"
  13. "math/big"
  14. "github.com/btcsuite/btcd/btcec"
  15. "github.com/ethereum/go-ethereum/crypto"
  16. )
  17. var (
  18. // G represents the base point of secp256k1
  19. G *Point = &Point{
  20. X: btcec.S256().Gx,
  21. Y: btcec.S256().Gy,
  22. }
  23. // N represents the order of G of secp256k1
  24. N *big.Int = btcec.S256().N
  25. )
  26. // Point represents a point on the secp256k1 curve
  27. type Point struct {
  28. X *big.Int
  29. Y *big.Int
  30. }
  31. // Add performs the Point addition
  32. func (p *Point) Add(q *Point) *Point {
  33. x, y := btcec.S256().Add(p.X, p.Y, q.X, q.Y)
  34. return &Point{
  35. X: x,
  36. Y: y,
  37. }
  38. }
  39. // Mul performs the Point scalar multiplication
  40. func (p *Point) Mul(scalar *big.Int) *Point {
  41. x, y := btcec.S256().ScalarMult(p.X, p.Y, scalar.Bytes())
  42. return &Point{
  43. X: x,
  44. Y: y,
  45. }
  46. }
  47. // WIP
  48. func newRand() *big.Int {
  49. var b [32]byte
  50. _, err := rand.Read(b[:])
  51. if err != nil {
  52. panic(err)
  53. }
  54. bi := new(big.Int).SetBytes(b[:])
  55. return new(big.Int).Mod(bi, N)
  56. }
  57. // PrivateKey represents the signer's private key
  58. type PrivateKey big.Int
  59. // PublicKey represents the signer's public key
  60. type PublicKey Point
  61. // NewPrivateKey returns a new random private key
  62. func NewPrivateKey() *PrivateKey {
  63. k := newRand()
  64. sk := PrivateKey(*k)
  65. return &sk
  66. }
  67. // BigInt returns a *big.Int representation of the PrivateKey
  68. func (sk *PrivateKey) BigInt() *big.Int {
  69. return (*big.Int)(sk)
  70. }
  71. // Public returns the PublicKey from the PrivateKey
  72. func (sk *PrivateKey) Public() *PublicKey {
  73. Q := G.Mul(sk.BigInt())
  74. pk := PublicKey(*Q)
  75. return &pk
  76. }
  77. // Point returns a *Point representation of the PublicKey
  78. func (pk *PublicKey) Point() *Point {
  79. return (*Point)(pk)
  80. }
  81. // NewRequestParameters returns a new random k (secret) & R (public) parameters
  82. func NewRequestParameters() (*big.Int, *Point) {
  83. k := newRand()
  84. return k, G.Mul(k) // R = kG
  85. }
  86. // BlindSign performs the blind signature on the given mBlinded using the
  87. // PrivateKey and the secret k values
  88. func (sk *PrivateKey) BlindSign(mBlinded *big.Int, k *big.Int) *big.Int {
  89. // TODO add pending checks
  90. // s' = dm' + k
  91. sBlind := new(big.Int).Add(
  92. new(big.Int).Mul(sk.BigInt(), mBlinded),
  93. k)
  94. return sBlind
  95. }
  96. // UserSecretData contains the secret values from the User (a, b, c) and the
  97. // public F
  98. type UserSecretData struct {
  99. A *big.Int
  100. B *big.Int
  101. F *Point // public (in the paper is R)
  102. }
  103. // Blind performs the blinding operation on m using signerR parameter
  104. func Blind(m *big.Int, signerR *Point) (*big.Int, *UserSecretData) {
  105. u := &UserSecretData{}
  106. u.A = newRand()
  107. u.B = newRand()
  108. // (R) F = aR' + bG
  109. aR := signerR.Mul(u.A)
  110. bG := G.Mul(u.B)
  111. u.F = aR.Add(bG)
  112. // TODO check that F != O (point at infinity)
  113. rx := new(big.Int).Mod(u.F.X, N)
  114. // m' = a^-1 rx h(m)
  115. ainv := new(big.Int).ModInverse(u.A, N)
  116. ainvrx := new(big.Int).Mul(ainv, rx)
  117. hBytes := crypto.Keccak256(m.Bytes())
  118. h := new(big.Int).SetBytes(hBytes)
  119. mBlinded := new(big.Int).Mul(ainvrx, h)
  120. return mBlinded, u
  121. }
  122. // Signature contains the signature values S & F
  123. type Signature struct {
  124. S *big.Int
  125. F *Point
  126. }
  127. // Unblind performs the unblinding operation of the blinded signature for the
  128. // given message m and the UserSecretData
  129. func Unblind(sBlind, m *big.Int, u *UserSecretData) *Signature {
  130. // s = a s' + b
  131. as := new(big.Int).Mul(u.A, sBlind)
  132. s := new(big.Int).Add(as, u.B)
  133. return &Signature{
  134. S: s,
  135. F: u.F,
  136. }
  137. }
  138. // Verify checks the signature of the message m for the given PublicKey
  139. func Verify(m *big.Int, s *Signature, q *PublicKey) bool {
  140. // TODO add pending checks
  141. sG := G.Mul(s.S) // sG
  142. hBytes := crypto.Keccak256(m.Bytes())
  143. h := new(big.Int).SetBytes(hBytes)
  144. rx := new(big.Int).Mod(s.F.X, N)
  145. rxh := new(big.Int).Mul(rx, h)
  146. // rxhG := G.Mul(rxh) // originally the paper uses G
  147. rxhG := q.Point().Mul(rxh)
  148. right := s.F.Add(rxhG)
  149. // check sG == R + rx h(m) G (where R in this code is F)
  150. if bytes.Equal(sG.X.Bytes(), right.X.Bytes()) &&
  151. bytes.Equal(sG.Y.Bytes(), right.Y.Bytes()) {
  152. return true
  153. }
  154. return false
  155. }