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.

211 lines
5.2 KiB

  1. package blindsecp256k1
  2. import (
  3. "encoding/hex"
  4. "math/big"
  5. "testing"
  6. "github.com/btcsuite/btcd/btcec"
  7. "github.com/ethereum/go-ethereum/crypto"
  8. "github.com/stretchr/testify/assert"
  9. "github.com/stretchr/testify/require"
  10. )
  11. // TODO abstract the test to work with any curve, and be
  12. // called from a test that testes all the tests with the
  13. // main curves
  14. func TestFlow(t *testing.T) {
  15. curv := btcec.S256()
  16. // signer: create new signer key pair
  17. sk := NewPrivateKey(curv)
  18. signerPubK := sk.Public(curv)
  19. // signer: when user requests new R parameter to blind a new msg,
  20. // create new signerR (public) with its secret k
  21. k, signerR := NewRequestParameters(curv)
  22. // user: blinds the msg using signer's R
  23. msg := new(big.Int).SetBytes([]byte("test"))
  24. msgBlinded, userSecretData, err := Blind(curv, msg, signerR)
  25. require.Nil(t, err)
  26. // signer: signs the blinded message using its private key & secret k
  27. sBlind, err := sk.BlindSign(curv, msgBlinded, k)
  28. require.Nil(t, err)
  29. // user: unblinds the blinded signature
  30. sig := Unblind(curv, sBlind, userSecretData)
  31. sigB := sig.Bytes()
  32. sig2, err := NewSignatureFromBytes(sigB)
  33. assert.Nil(t, err)
  34. assert.Equal(t, sig, sig2)
  35. // signature can be verified with signer PublicKey
  36. verified := Verify(curv, msg, sig, signerPubK)
  37. assert.True(t, verified)
  38. }
  39. func TestHashMOddBytes(t *testing.T) {
  40. // This test is made with same values than
  41. // https://github.com/arnaucube/blindsecp256k1-js to ensure
  42. // compatibility
  43. mStr := "3024162961766929396601888431330224482373544644288322432261208139289299439809"
  44. m, ok := new(big.Int).SetString(mStr, 10)
  45. require.True(t, ok)
  46. mBytes := m.Bytes()
  47. hBytes := crypto.Keccak256(mBytes[3:])
  48. h := new(big.Int).SetBytes(hBytes)
  49. assert.Equal(t,
  50. "57523339312508913023232057765773019244858443678197951618720342803494056599369",
  51. h.String())
  52. hBytes = crypto.Keccak256(append(mBytes, []byte{0x12, 0x34}...))
  53. h = new(big.Int).SetBytes(hBytes)
  54. assert.Equal(t,
  55. "9697834584560956691445940439424778243200861871421750951058436814122640359156",
  56. h.String())
  57. }
  58. // func newBigIntWithBitLen(n int) *big.Int {
  59. // b := make([]byte, n/8)
  60. // for i := 0; i < len(b); i++ {
  61. // b[i] = 255
  62. // }
  63. // bi := new(big.Int).SetBytes(b[:])
  64. // return bi
  65. // }
  66. //
  67. // func TestMinBigIntBytesLen(t *testing.T) {
  68. // k := big.NewInt(1)
  69. // sk := PrivateKey(*k)
  70. //
  71. // mBlinded := newBigIntWithBitLen(MinBigIntBytesLen)
  72. // require.Equal(t, MinBigIntBytesLen, mBlinded.BitLen())
  73. // _, err := sk.BlindSign(mBlinded, k)
  74. // assert.Nil(t, err)
  75. //
  76. // mBlinded = new(big.Int).Div(mBlinded, big.NewInt(2))
  77. // require.Equal(t, MinBigIntBytesLen-1, mBlinded.BitLen())
  78. // _, err = sk.BlindSign(mBlinded, k)
  79. // assert.Equal(t, "mBlinded too small", err.Error())
  80. // }
  81. func TestPointCompressDecompress(t *testing.T) {
  82. curv := btcec.S256()
  83. c := Curve{curv}
  84. G := &Point{
  85. X: curv.Gx,
  86. Y: curv.Gy,
  87. }
  88. p := &Point{
  89. X: curv.Gx,
  90. Y: curv.Gy,
  91. }
  92. b := p.Compress()
  93. assert.Equal(t,
  94. "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800",
  95. hex.EncodeToString(b[:]))
  96. p2, err := DecompressPoint(curv, b)
  97. require.Nil(t, err)
  98. assert.Equal(t, p, p2)
  99. for i := 2; i < 1000; i++ {
  100. p := c.Mul(G, big.NewInt(int64(i)))
  101. b := p.Compress()
  102. assert.Equal(t, 33, len(b))
  103. p2, err := DecompressPoint(curv, b)
  104. require.Nil(t, err)
  105. assert.Equal(t, p, p2)
  106. }
  107. }
  108. func TestSignatureCompressDecompress(t *testing.T) {
  109. curv := btcec.S256()
  110. c := Curve{curv}
  111. G := &Point{
  112. X: curv.Gx,
  113. Y: curv.Gy,
  114. }
  115. f := G
  116. sig := &Signature{
  117. S: big.NewInt(1),
  118. F: f,
  119. }
  120. b := sig.Compress()
  121. assert.Equal(t,
  122. "01000000000000000000000000000000000000000000000000000000000000007"+
  123. "9be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800",
  124. hex.EncodeToString(b[:]))
  125. sig2, err := DecompressSignature(curv, b)
  126. require.Nil(t, err)
  127. assert.Equal(t, sig, sig2)
  128. f = G
  129. P := curv.Params().P
  130. // Q = (P+1)/4
  131. Q := new(big.Int).Div(new(big.Int).Add(P,
  132. big.NewInt(1)), big.NewInt(4)) // nolint:gomnd
  133. sig = &Signature{
  134. S: Q,
  135. F: f,
  136. }
  137. b = sig.Compress()
  138. assert.Equal(t,
  139. "0cffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffff3f7"+
  140. "9be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f8179800",
  141. hex.EncodeToString(b[:]))
  142. sig2, err = DecompressSignature(curv, b)
  143. require.Nil(t, err)
  144. require.Equal(t, sig, sig2)
  145. for i := 2; i < 10; i++ {
  146. s := new(big.Int).Mod(new(big.Int).Mul(Q, big.NewInt(int64(i))), P)
  147. f := c.Mul(G, big.NewInt(int64(i)))
  148. sig := &Signature{
  149. S: s,
  150. F: f,
  151. }
  152. b := sig.Compress()
  153. assert.Equal(t, 65, len(b))
  154. sig2, err := DecompressSignature(curv, b)
  155. require.Nil(t, err)
  156. assert.Equal(t, sig, sig2)
  157. }
  158. }
  159. func BenchmarkCompressDecompress(b *testing.B) {
  160. curv := btcec.S256()
  161. c := Curve{curv}
  162. const n = 256
  163. var points [n]*Point
  164. var compPoints [n][33]byte
  165. G := &Point{
  166. X: curv.Gx,
  167. Y: curv.Gy,
  168. }
  169. for i := 0; i < n; i++ {
  170. points[i] = c.Mul(G, big.NewInt(int64(i)))
  171. }
  172. for i := 0; i < n; i++ {
  173. compPoints[i] = points[i].Compress()
  174. }
  175. b.Run("Compress", func(b *testing.B) {
  176. for i := 0; i < b.N; i++ {
  177. _ = points[i%n].Compress()
  178. }
  179. })
  180. b.Run("DecompressPoint", func(b *testing.B) {
  181. for i := 0; i < b.N; i++ {
  182. _, _ = DecompressPoint(curv, compPoints[i%n])
  183. }
  184. })
  185. }