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.

192 lines
4.4 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. sBlind = new(big.Int).Mod(sBlind, N)
  95. return sBlind
  96. }
  97. // UserSecretData contains the secret values from the User (a, b, c) and the
  98. // public F
  99. type UserSecretData struct {
  100. A *big.Int
  101. B *big.Int
  102. F *Point // public (in the paper is R)
  103. }
  104. // Blind performs the blinding operation on m using signerR parameter
  105. func Blind(m *big.Int, signerR *Point) (*big.Int, *UserSecretData) {
  106. u := &UserSecretData{}
  107. u.A = newRand()
  108. u.B = newRand()
  109. // (R) F = aR' + bG
  110. aR := signerR.Mul(u.A)
  111. bG := G.Mul(u.B)
  112. u.F = aR.Add(bG)
  113. // TODO check that F != O (point at infinity)
  114. rx := new(big.Int).Mod(u.F.X, N)
  115. // m' = a^-1 rx h(m)
  116. ainv := new(big.Int).ModInverse(u.A, N)
  117. ainvrx := new(big.Int).Mul(ainv, rx)
  118. hBytes := crypto.Keccak256(m.Bytes())
  119. h := new(big.Int).SetBytes(hBytes)
  120. mBlinded := new(big.Int).Mul(ainvrx, h)
  121. mBlinded = new(big.Int).Mod(mBlinded, N)
  122. return mBlinded, u
  123. }
  124. // Signature contains the signature values S & F
  125. type Signature struct {
  126. S *big.Int
  127. F *Point
  128. }
  129. // Unblind performs the unblinding operation of the blinded signature for the
  130. // given the UserSecretData
  131. func Unblind(sBlind *big.Int, u *UserSecretData) *Signature {
  132. // s = a s' + b
  133. as := new(big.Int).Mul(u.A, sBlind)
  134. s := new(big.Int).Add(as, u.B)
  135. s = new(big.Int).Mod(s, N)
  136. return &Signature{
  137. S: s,
  138. F: u.F,
  139. }
  140. }
  141. // Verify checks the signature of the message m for the given PublicKey
  142. func Verify(m *big.Int, s *Signature, q *PublicKey) bool {
  143. // TODO add pending checks
  144. sG := G.Mul(s.S) // sG
  145. hBytes := crypto.Keccak256(m.Bytes())
  146. h := new(big.Int).SetBytes(hBytes)
  147. rx := new(big.Int).Mod(s.F.X, N)
  148. rxh := new(big.Int).Mul(rx, h)
  149. // rxhG := G.Mul(rxh) // originally the paper uses G
  150. rxhG := q.Point().Mul(rxh)
  151. right := s.F.Add(rxhG)
  152. // check sG == R + rx h(m) Q (where R in this code is F)
  153. if bytes.Equal(sG.X.Bytes(), right.X.Bytes()) &&
  154. bytes.Equal(sG.Y.Bytes(), right.Y.Bytes()) {
  155. return true
  156. }
  157. return false
  158. }