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.

196 lines
5.1 KiB

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