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.

254 lines
7.0 KiB

  1. package common
  2. import (
  3. "encoding/hex"
  4. "math/big"
  5. "testing"
  6. ethCommon "github.com/ethereum/go-ethereum/common"
  7. "github.com/iden3/go-iden3-crypto/babyjub"
  8. "github.com/stretchr/testify/assert"
  9. "github.com/stretchr/testify/require"
  10. )
  11. func TestNewPoolL2Tx(t *testing.T) {
  12. poolL2Tx := &PoolL2Tx{
  13. FromIdx: 87654,
  14. ToIdx: 300,
  15. Amount: big.NewInt(4),
  16. TokenID: 5,
  17. Nonce: 144,
  18. }
  19. poolL2Tx, err := NewPoolL2Tx(poolL2Tx)
  20. assert.NoError(t, err)
  21. assert.Equal(t, "0x022669acda59b827d20ef5354a3eebd1dffb3972b0a6bf89d18bfd2efa0ab9f41e",
  22. poolL2Tx.TxID.String())
  23. }
  24. func TestTxCompressedDataAndTxCompressedDataV2JSVectors(t *testing.T) {
  25. // test vectors values generated from javascript implementation
  26. var skPositive babyjub.PrivateKey // 'Positive' refers to the sign
  27. _, err := hex.Decode(skPositive[:],
  28. []byte("0001020304050607080900010203040506070809000102030405060708090001"))
  29. assert.NoError(t, err)
  30. var skNegative babyjub.PrivateKey // 'Negative' refers to the sign
  31. _, err = hex.Decode(skNegative[:],
  32. []byte("0001020304050607080900010203040506070809000102030405060708090002"))
  33. assert.NoError(t, err)
  34. amount, ok := new(big.Int).SetString("343597383670000000000000000000000000000000", 10)
  35. require.True(t, ok)
  36. tx := PoolL2Tx{
  37. FromIdx: (1 << 48) - 1,
  38. ToIdx: (1 << 48) - 1,
  39. Amount: amount,
  40. TokenID: (1 << 32) - 1,
  41. Nonce: (1 << 40) - 1,
  42. Fee: (1 << 3) - 1,
  43. ToBJJ: skPositive.Public().Compress(),
  44. }
  45. txCompressedData, err := tx.TxCompressedData(uint16((1 << 16) - 1))
  46. require.NoError(t, err)
  47. expectedStr := "0107ffffffffffffffffffffffffffffffffffffffffffffffc60be60f"
  48. assert.Equal(t, expectedStr, hex.EncodeToString(txCompressedData.Bytes()))
  49. txCompressedDataV2, err := tx.TxCompressedDataV2()
  50. require.NoError(t, err)
  51. expectedStr = "0107ffffffffffffffffffffffffffffffffffffffffffffffffffff"
  52. assert.Equal(t, expectedStr, hex.EncodeToString(txCompressedDataV2.Bytes()))
  53. tx = PoolL2Tx{
  54. FromIdx: 0,
  55. ToIdx: 0,
  56. Amount: big.NewInt(0),
  57. TokenID: 0,
  58. Nonce: 0,
  59. Fee: 0,
  60. ToBJJ: skNegative.Public().Compress(),
  61. }
  62. txCompressedData, err = tx.TxCompressedData(uint16(0))
  63. require.NoError(t, err)
  64. expectedStr = "c60be60f"
  65. assert.Equal(t, expectedStr, hex.EncodeToString(txCompressedData.Bytes()))
  66. txCompressedDataV2, err = tx.TxCompressedDataV2()
  67. require.NoError(t, err)
  68. assert.Equal(t, "0", txCompressedDataV2.String())
  69. amount, ok = new(big.Int).SetString("63000000000000000", 10)
  70. require.True(t, ok)
  71. tx = PoolL2Tx{
  72. FromIdx: 324,
  73. ToIdx: 256,
  74. Amount: amount,
  75. TokenID: 123,
  76. Nonce: 76,
  77. Fee: 214,
  78. ToBJJ: skNegative.Public().Compress(),
  79. }
  80. txCompressedData, err = tx.TxCompressedData(uint16(1))
  81. require.NoError(t, err)
  82. expectedStr = "d6000000004c0000007b0000000001000000000001440001c60be60f"
  83. assert.Equal(t, expectedStr, hex.EncodeToString(txCompressedData.Bytes()))
  84. txCompressedDataV2, err = tx.TxCompressedDataV2()
  85. require.NoError(t, err)
  86. expectedStr = "d6000000004c0000007b3977825f00000000000100000000000144"
  87. assert.Equal(t, expectedStr, hex.EncodeToString(txCompressedDataV2.Bytes()))
  88. tx = PoolL2Tx{
  89. FromIdx: 1,
  90. ToIdx: 2,
  91. TokenID: 3,
  92. Nonce: 4,
  93. Fee: 5,
  94. ToBJJ: skNegative.Public().Compress(),
  95. }
  96. txCompressedData, err = tx.TxCompressedData(uint16(0))
  97. require.NoError(t, err)
  98. expectedStr = "050000000004000000030000000000020000000000010000c60be60f"
  99. assert.Equal(t, expectedStr, hex.EncodeToString(txCompressedData.Bytes()))
  100. tx = PoolL2Tx{
  101. FromIdx: 2,
  102. ToIdx: 3,
  103. TokenID: 4,
  104. Nonce: 5,
  105. Fee: 6,
  106. ToBJJ: skPositive.Public().Compress(),
  107. }
  108. txCompressedData, err = tx.TxCompressedData(uint16(0))
  109. require.NoError(t, err)
  110. expectedStr = "01060000000005000000040000000000030000000000020000c60be60f"
  111. assert.Equal(t, expectedStr, hex.EncodeToString(txCompressedData.Bytes()))
  112. }
  113. func TestRqTxCompressedDataV2(t *testing.T) {
  114. var sk babyjub.PrivateKey
  115. _, err := hex.Decode(sk[:],
  116. []byte("0001020304050607080900010203040506070809000102030405060708090001"))
  117. assert.NoError(t, err)
  118. tx := PoolL2Tx{
  119. RqFromIdx: 7,
  120. RqToIdx: 8,
  121. RqAmount: big.NewInt(9),
  122. RqTokenID: 10,
  123. RqNonce: 11,
  124. RqFee: 12,
  125. RqToBJJ: sk.Public().Compress(),
  126. }
  127. txCompressedData, err := tx.RqTxCompressedDataV2()
  128. assert.NoError(t, err)
  129. // test vector value generated from javascript implementation
  130. expectedStr := "110248805340524920412994530176819463725852160917809517418728390663"
  131. assert.Equal(t, expectedStr, txCompressedData.String())
  132. expected, ok := new(big.Int).SetString(expectedStr, 10)
  133. assert.True(t, ok)
  134. assert.Equal(t, expected.Bytes(), txCompressedData.Bytes())
  135. assert.Equal(t, "010c000000000b0000000a0000000009000000000008000000000007",
  136. hex.EncodeToString(txCompressedData.Bytes()))
  137. }
  138. func TestHashToSign(t *testing.T) {
  139. chainID := uint16(0)
  140. tx := PoolL2Tx{
  141. FromIdx: 2,
  142. ToIdx: 3,
  143. Amount: big.NewInt(4),
  144. TokenID: 5,
  145. Nonce: 6,
  146. ToEthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
  147. }
  148. toSign, err := tx.HashToSign(chainID)
  149. assert.NoError(t, err)
  150. assert.Equal(t, "2d49ce1d4136e06f64e3eb1f79a346e6ee3e93ceeac909a57806a8d87005c263",
  151. hex.EncodeToString(toSign.Bytes()))
  152. }
  153. func TestVerifyTxSignature(t *testing.T) {
  154. chainID := uint16(0)
  155. var sk babyjub.PrivateKey
  156. _, err := hex.Decode(sk[:],
  157. []byte("0001020304050607080900010203040506070809000102030405060708090001"))
  158. assert.NoError(t, err)
  159. tx := PoolL2Tx{
  160. FromIdx: 2,
  161. ToIdx: 3,
  162. Amount: big.NewInt(4),
  163. TokenID: 5,
  164. Nonce: 6,
  165. ToBJJ: sk.Public().Compress(),
  166. RqToEthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
  167. RqToBJJ: sk.Public().Compress(),
  168. }
  169. toSign, err := tx.HashToSign(chainID)
  170. assert.NoError(t, err)
  171. assert.Equal(t,
  172. "1571327027383224465388301747239444557034990637650927918405777653988509342917",
  173. toSign.String())
  174. sig := sk.SignPoseidon(toSign)
  175. tx.Signature = sig.Compress()
  176. assert.True(t, tx.VerifySignature(chainID, sk.Public().Compress()))
  177. }
  178. func TestDecompressEmptyBJJComp(t *testing.T) {
  179. pkComp := EmptyBJJComp
  180. pk, err := pkComp.Decompress()
  181. require.NoError(t, err)
  182. assert.Equal(t,
  183. "2957874849018779266517920829765869116077630550401372566248359756137677864698",
  184. pk.X.String())
  185. assert.Equal(t, "0", pk.Y.String())
  186. }
  187. func TestPoolL2TxID(t *testing.T) {
  188. tx0 := PoolL2Tx{
  189. FromIdx: 5,
  190. ToIdx: 5,
  191. Amount: big.NewInt(5),
  192. Fee: 126,
  193. TokenID: 5,
  194. Nonce: 5,
  195. }
  196. err := tx0.SetID()
  197. require.NoError(t, err)
  198. // differ TokenID
  199. tx1 := PoolL2Tx{
  200. FromIdx: 5,
  201. ToIdx: 5,
  202. Amount: big.NewInt(5),
  203. Fee: 126,
  204. TokenID: 4,
  205. Nonce: 5,
  206. }
  207. err = tx1.SetID()
  208. require.NoError(t, err)
  209. assert.NotEqual(t, tx0.TxID, tx1.TxID)
  210. // differ Nonce
  211. tx1 = PoolL2Tx{
  212. FromIdx: 5,
  213. ToIdx: 5,
  214. Amount: big.NewInt(5),
  215. Fee: 126,
  216. TokenID: 5,
  217. Nonce: 4,
  218. }
  219. err = tx1.SetID()
  220. require.NoError(t, err)
  221. assert.NotEqual(t, tx0.TxID, tx1.TxID)
  222. // differ Fee
  223. tx1 = PoolL2Tx{
  224. FromIdx: 5,
  225. ToIdx: 5,
  226. Amount: big.NewInt(5),
  227. Fee: 124,
  228. TokenID: 5,
  229. Nonce: 5,
  230. }
  231. err = tx1.SetID()
  232. require.NoError(t, err)
  233. assert.NotEqual(t, tx0.TxID, tx1.TxID)
  234. }