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.

281 lines
7.8 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 TestVerifyTxSignatureEthAddrWith0(t *testing.T) {
  179. chainID := uint16(5)
  180. var sk babyjub.PrivateKey
  181. _, err := hex.Decode(sk[:],
  182. []byte("02f0b4f87065af3797aaaf934e8b5c31563c17f2272fa71bd0146535bfbb4184"))
  183. assert.NoError(t, err)
  184. tx := PoolL2Tx{
  185. FromIdx: 10659,
  186. ToIdx: 0,
  187. ToEthAddr: ethCommon.HexToAddress("0x0004308BD15Ead4F1173624dC289DBdcC806a309"),
  188. Amount: big.NewInt(5000),
  189. TokenID: 0,
  190. Nonce: 946,
  191. Fee: 231,
  192. }
  193. toSign, err := tx.HashToSign(chainID)
  194. assert.NoError(t, err)
  195. sig := sk.SignPoseidon(toSign)
  196. assert.Equal(t,
  197. "93ce988ecac87908513648d0d021d8ad56d3b504eb38204200f07a8f6c20551de9951397d3051143d4c71203205f8849cd7382d2bcf4bd10092c1e052bb40d01",
  198. sig.Compress().String(),
  199. )
  200. tx.Signature = sig.Compress()
  201. assert.True(t, tx.VerifySignature(chainID, sk.Public().Compress()))
  202. }
  203. func TestDecompressEmptyBJJComp(t *testing.T) {
  204. pkComp := EmptyBJJComp
  205. pk, err := pkComp.Decompress()
  206. require.NoError(t, err)
  207. assert.Equal(t,
  208. "2957874849018779266517920829765869116077630550401372566248359756137677864698",
  209. pk.X.String())
  210. assert.Equal(t, "0", pk.Y.String())
  211. }
  212. func TestPoolL2TxID(t *testing.T) {
  213. tx0 := PoolL2Tx{
  214. FromIdx: 5,
  215. ToIdx: 5,
  216. Amount: big.NewInt(5),
  217. Fee: 126,
  218. TokenID: 5,
  219. Nonce: 5,
  220. }
  221. err := tx0.SetID()
  222. require.NoError(t, err)
  223. // differ TokenID
  224. tx1 := PoolL2Tx{
  225. FromIdx: 5,
  226. ToIdx: 5,
  227. Amount: big.NewInt(5),
  228. Fee: 126,
  229. TokenID: 4,
  230. Nonce: 5,
  231. }
  232. err = tx1.SetID()
  233. require.NoError(t, err)
  234. assert.NotEqual(t, tx0.TxID, tx1.TxID)
  235. // differ Nonce
  236. tx1 = PoolL2Tx{
  237. FromIdx: 5,
  238. ToIdx: 5,
  239. Amount: big.NewInt(5),
  240. Fee: 126,
  241. TokenID: 5,
  242. Nonce: 4,
  243. }
  244. err = tx1.SetID()
  245. require.NoError(t, err)
  246. assert.NotEqual(t, tx0.TxID, tx1.TxID)
  247. // differ Fee
  248. tx1 = PoolL2Tx{
  249. FromIdx: 5,
  250. ToIdx: 5,
  251. Amount: big.NewInt(5),
  252. Fee: 124,
  253. TokenID: 5,
  254. Nonce: 5,
  255. }
  256. err = tx1.SetID()
  257. require.NoError(t, err)
  258. assert.NotEqual(t, tx0.TxID, tx1.TxID)
  259. }