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.

212 lines
4.9 KiB

3 years ago
  1. // Package blindsecp256k1 implements the Blind signature scheme explained at
  2. // http://www.isecure-journal.com/article_39171_47f9ec605dd3918c2793565ec21fcd7a.pdf
  3. //
  4. // LICENSE can be found at https://github.com/arnaucube/go-blindsecp256k1/blob/master/LICENSE
  5. //
  6. package blindsecp256k1
  7. // WARNING: WIP code
  8. import (
  9. "bytes"
  10. "crypto/rand"
  11. "math/big"
  12. "github.com/ethereum/go-ethereum/crypto/secp256k1"
  13. )
  14. var (
  15. // G represents the base point of secp256k1
  16. G *Point = &Point{
  17. X: secp256k1.S256().Gx,
  18. Y: secp256k1.S256().Gy,
  19. }
  20. // N represents the order of G of secp256k1
  21. N *big.Int = secp256k1.S256().N
  22. )
  23. // Point represents a point on the secp256k1 curve
  24. type Point struct {
  25. X *big.Int
  26. Y *big.Int
  27. }
  28. // Add performs the Point addition
  29. func (p *Point) Add(q *Point) *Point {
  30. x, y := secp256k1.S256().Add(p.X, p.Y, q.X, q.Y)
  31. return &Point{
  32. X: x,
  33. Y: y,
  34. }
  35. }
  36. // Mul performs the Point scalar multiplication
  37. func (p *Point) Mul(scalar *big.Int) *Point {
  38. x, y := secp256k1.S256().ScalarMult(p.X, p.Y, scalar.Bytes())
  39. return &Point{
  40. X: x,
  41. Y: y,
  42. }
  43. }
  44. // WIP
  45. func newRand() *big.Int {
  46. var b [32]byte
  47. _, err := rand.Read(b[:])
  48. if err != nil {
  49. panic(err)
  50. }
  51. bi := new(big.Int).SetBytes(b[:])
  52. return new(big.Int).Mod(bi, N)
  53. }
  54. // PrivateKey represents the signer's private key
  55. type PrivateKey big.Int
  56. // PublicKey represents the signer's public key
  57. type PublicKey Point
  58. // NewPrivateKey returns a new random private key
  59. func NewPrivateKey() *PrivateKey {
  60. k := newRand()
  61. sk := PrivateKey(*k)
  62. return &sk
  63. }
  64. // BigInt returns a *big.Int representation of the PrivateKey
  65. func (sk *PrivateKey) BigInt() *big.Int {
  66. return (*big.Int)(sk)
  67. }
  68. // Public returns the PublicKey from the PrivateKey
  69. func (sk *PrivateKey) Public() *PublicKey {
  70. Q := G.Mul(sk.BigInt())
  71. pk := PublicKey(*Q)
  72. return &pk
  73. }
  74. // Point returns a *Point representation of the PublicKey
  75. func (pk *PublicKey) Point() *Point {
  76. return (*Point)(pk)
  77. }
  78. // SignerPrivateData contains the secret values from the Signer
  79. type SignerPrivateData struct {
  80. D *PrivateKey
  81. K *big.Int
  82. }
  83. // SignerPublicData contains the public values from the Signer (generated from
  84. // its SignerPrivateData)
  85. type SignerPublicData struct {
  86. // Q is the Signer Public Key
  87. Q *PublicKey // = skG
  88. R *Point // = kG
  89. }
  90. // NewSigner returns a new SignerPrivateData with random D & K
  91. func NewSigner() *SignerPrivateData {
  92. sk := NewPrivateKey()
  93. k := newRand()
  94. return &SignerPrivateData{
  95. D: sk,
  96. K: k,
  97. }
  98. }
  99. // PublicData returns the SignerPublicData from the SignerPrivateData
  100. func (signer *SignerPrivateData) PublicData() *SignerPublicData {
  101. return &SignerPublicData{
  102. Q: signer.D.Public(), // Q = dG
  103. R: G.Mul(signer.K), // R = kG
  104. }
  105. }
  106. // BlindSign performs the blind signature on the given mBlinded using
  107. // SignerPrivateData values
  108. func (signer *SignerPrivateData) BlindSign(mBlinded *big.Int) *big.Int {
  109. // TODO add pending checks
  110. // s' = d(m') + k
  111. sBlind := new(big.Int).Add(
  112. new(big.Int).Mul(signer.D.BigInt(), mBlinded),
  113. signer.K)
  114. return sBlind
  115. }
  116. // UserSecretData contains the secret values from the User (a, b, c) and the
  117. // public F
  118. type UserSecretData struct {
  119. A *big.Int
  120. B *big.Int
  121. C *big.Int
  122. F *Point // public
  123. }
  124. // Blind performs the blinding operation on m using SignerPublicData parameters
  125. func Blind(m *big.Int, signer *SignerPublicData) (*big.Int, *UserSecretData) {
  126. u := &UserSecretData{}
  127. u.A = newRand()
  128. u.B = newRand()
  129. u.C = newRand()
  130. binv := new(big.Int).ModInverse(u.B, N)
  131. // F = b^-1 R + a b^-1 Q + c G
  132. bR := signer.R.Mul(binv)
  133. abinv := new(big.Int).Mul(u.A, binv)
  134. abinv = new(big.Int).Mod(abinv, N)
  135. abQ := signer.Q.Point().Mul(abinv)
  136. cG := G.Mul(u.C)
  137. u.F = bR.Add(abQ).Add(cG)
  138. // TODO check F==O
  139. r := new(big.Int).Mod(u.F.X, N)
  140. // m' = br(m)+a
  141. br := new(big.Int).Mul(u.B, r)
  142. brm := new(big.Int).Mul(br, m)
  143. mBlinded := new(big.Int).Add(brm, u.A)
  144. mBlinded = new(big.Int).Mod(mBlinded, N)
  145. return mBlinded, u
  146. }
  147. // Signature contains the signature values S & F
  148. type Signature struct {
  149. S *big.Int
  150. F *Point
  151. }
  152. // Unblind performs the unblinding operation of the blinded signature for the
  153. // given message m and the UserSecretData
  154. func Unblind(sBlind, m *big.Int, u *UserSecretData) *Signature {
  155. // s = b^-1 s' + c
  156. binv := new(big.Int).ModInverse(u.B, N)
  157. bs := new(big.Int).Mul(binv, sBlind)
  158. s := new(big.Int).Add(bs, u.C)
  159. s = new(big.Int).Mod(s, N)
  160. return &Signature{
  161. S: s,
  162. F: u.F,
  163. }
  164. }
  165. // Verify checks the signature of the message m for the given PublicKey
  166. func Verify(m *big.Int, signature *Signature, q *PublicKey) bool {
  167. // TODO add pending checks
  168. sG := G.Mul(signature.S) // sG
  169. r := new(big.Int).Mod(signature.F.X, N) // r = Fx mod N
  170. rm := new(big.Int).Mul(r, m)
  171. rm = new(big.Int).Mod(rm, N)
  172. rmQ := q.Point().Mul(rm)
  173. rmQF := rmQ.Add(signature.F) // rmQ + F
  174. // check sG == rmQ + F
  175. if bytes.Equal(sG.X.Bytes(), rmQF.X.Bytes()) &&
  176. bytes.Equal(sG.Y.Bytes(), rmQF.Y.Bytes()) {
  177. return true
  178. }
  179. return false
  180. }