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.

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