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.

370 lines
11 KiB

  1. package common
  2. import (
  3. "encoding/hex"
  4. "fmt"
  5. "math"
  6. "math/big"
  7. "strings"
  8. "testing"
  9. ethCommon "github.com/ethereum/go-ethereum/common"
  10. ethCrypto "github.com/ethereum/go-ethereum/crypto"
  11. "github.com/hermeznetwork/tracerr"
  12. "github.com/iden3/go-iden3-crypto/babyjub"
  13. cryptoConstants "github.com/iden3/go-iden3-crypto/constants"
  14. "github.com/iden3/go-iden3-crypto/poseidon"
  15. cryptoUtils "github.com/iden3/go-iden3-crypto/utils"
  16. "github.com/stretchr/testify/assert"
  17. "github.com/stretchr/testify/require"
  18. )
  19. func TestIdxParser(t *testing.T) {
  20. i := Idx(1)
  21. iBytes, err := i.Bytes()
  22. assert.Nil(t, err)
  23. assert.Equal(t, 6, len(iBytes))
  24. assert.Equal(t, "000000000001", hex.EncodeToString(iBytes[:]))
  25. i2, err := IdxFromBytes(iBytes[:])
  26. assert.Nil(t, err)
  27. assert.Equal(t, i, i2)
  28. i = Idx(100)
  29. assert.Equal(t, big.NewInt(100), i.BigInt())
  30. // value before overflow
  31. i = Idx(281474976710655)
  32. iBytes, err = i.Bytes()
  33. assert.Nil(t, err)
  34. assert.Equal(t, 6, len(iBytes))
  35. assert.Equal(t, "ffffffffffff", hex.EncodeToString(iBytes[:]))
  36. i2, err = IdxFromBytes(iBytes[:])
  37. assert.Nil(t, err)
  38. assert.Equal(t, i, i2)
  39. // expect value overflow
  40. i = Idx(281474976710656)
  41. iBytes, err = i.Bytes()
  42. assert.NotNil(t, err)
  43. assert.Equal(t, ErrIdxOverflow, tracerr.Unwrap(err))
  44. }
  45. func TestNonceParser(t *testing.T) {
  46. n := Nonce(1)
  47. nBytes, err := n.Bytes()
  48. assert.Nil(t, err)
  49. assert.Equal(t, 5, len(nBytes))
  50. assert.Equal(t, "0000000001", hex.EncodeToString(nBytes[:]))
  51. n2 := NonceFromBytes(nBytes)
  52. assert.Equal(t, n, n2)
  53. // value before overflow
  54. n = Nonce(1099511627775)
  55. nBytes, err = n.Bytes()
  56. assert.Nil(t, err)
  57. assert.Equal(t, 5, len(nBytes))
  58. assert.Equal(t, "ffffffffff", hex.EncodeToString(nBytes[:]))
  59. n2 = NonceFromBytes(nBytes)
  60. assert.Equal(t, n, n2)
  61. // expect value overflow
  62. n = Nonce(1099511627776)
  63. nBytes, err = n.Bytes()
  64. assert.NotNil(t, err)
  65. assert.Equal(t, ErrNonceOverflow, tracerr.Unwrap(err))
  66. }
  67. func TestAccount(t *testing.T) {
  68. var sk babyjub.PrivateKey
  69. _, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
  70. assert.Nil(t, err)
  71. pk := sk.Public()
  72. account := &Account{
  73. TokenID: TokenID(1),
  74. Nonce: Nonce(1234),
  75. Balance: big.NewInt(1000),
  76. PublicKey: pk,
  77. EthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
  78. }
  79. b, err := account.Bytes()
  80. assert.Nil(t, err)
  81. assert.Equal(t, byte(1), b[22])
  82. a1, err := AccountFromBytes(b)
  83. assert.Nil(t, err)
  84. assert.Equal(t, account, a1)
  85. e, err := account.BigInts()
  86. assert.Nil(t, err)
  87. assert.True(t, cryptoUtils.CheckBigIntInField(e[0]))
  88. assert.True(t, cryptoUtils.CheckBigIntInField(e[1]))
  89. assert.True(t, cryptoUtils.CheckBigIntInField(e[2]))
  90. assert.True(t, cryptoUtils.CheckBigIntInField(e[3]))
  91. assert.Equal(t, "1000", e[1].String())
  92. assert.Equal(t, pk.Y.String(), e[2].String())
  93. assert.Equal(t, new(big.Int).SetBytes(account.EthAddr.Bytes()).String(), e[3].String())
  94. a2, err := AccountFromBigInts(e)
  95. assert.Nil(t, err)
  96. assert.Equal(t, account, a2)
  97. assert.Equal(t, a1, a2)
  98. }
  99. func TestAccountLoop(t *testing.T) {
  100. // check that for different deterministic BabyJubJub keys & random Address there is no problem
  101. for i := 0; i < 256; i++ {
  102. var sk babyjub.PrivateKey
  103. _, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
  104. assert.Nil(t, err)
  105. pk := sk.Public()
  106. key, err := ethCrypto.GenerateKey()
  107. assert.Nil(t, err)
  108. address := ethCrypto.PubkeyToAddress(key.PublicKey)
  109. account := &Account{
  110. TokenID: TokenID(i),
  111. Nonce: Nonce(i),
  112. Balance: big.NewInt(1000),
  113. PublicKey: pk,
  114. EthAddr: address,
  115. }
  116. b, err := account.Bytes()
  117. assert.Nil(t, err)
  118. a1, err := AccountFromBytes(b)
  119. assert.Nil(t, err)
  120. assert.Equal(t, account, a1)
  121. e, err := account.BigInts()
  122. assert.Nil(t, err)
  123. assert.True(t, cryptoUtils.CheckBigIntInField(e[0]))
  124. assert.True(t, cryptoUtils.CheckBigIntInField(e[1]))
  125. assert.True(t, cryptoUtils.CheckBigIntInField(e[2]))
  126. assert.True(t, cryptoUtils.CheckBigIntInField(e[3]))
  127. a2, err := AccountFromBigInts(e)
  128. assert.Nil(t, err)
  129. assert.Equal(t, account, a2)
  130. }
  131. }
  132. func TestAccountLoopRandom(t *testing.T) {
  133. // check that for different random Address & BabyJubJub keys there is
  134. // no problem
  135. for i := 0; i < 256; i++ {
  136. sk := babyjub.NewRandPrivKey()
  137. pk := sk.Public()
  138. key, err := ethCrypto.GenerateKey()
  139. assert.Nil(t, err)
  140. address := ethCrypto.PubkeyToAddress(key.PublicKey)
  141. account := &Account{
  142. TokenID: TokenID(i),
  143. Nonce: Nonce(i),
  144. Balance: big.NewInt(1000),
  145. PublicKey: pk,
  146. EthAddr: address,
  147. }
  148. b, err := account.Bytes()
  149. assert.Nil(t, err)
  150. a1, err := AccountFromBytes(b)
  151. assert.Nil(t, err)
  152. assert.Equal(t, account, a1)
  153. e, err := account.BigInts()
  154. assert.Nil(t, err)
  155. assert.True(t, cryptoUtils.CheckBigIntInField(e[0]))
  156. assert.True(t, cryptoUtils.CheckBigIntInField(e[1]))
  157. assert.True(t, cryptoUtils.CheckBigIntInField(e[2]))
  158. assert.True(t, cryptoUtils.CheckBigIntInField(e[3]))
  159. a2, err := AccountFromBigInts(e)
  160. assert.Nil(t, err)
  161. assert.Equal(t, account, a2)
  162. }
  163. }
  164. func bigFromStr(h string, u int) *big.Int {
  165. if u == 16 {
  166. h = strings.TrimPrefix(h, "0x")
  167. }
  168. b, ok := new(big.Int).SetString(h, u)
  169. if !ok {
  170. panic("bigFromStr err")
  171. }
  172. return b
  173. }
  174. func TestAccountHashValue(t *testing.T) {
  175. var sk babyjub.PrivateKey
  176. _, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
  177. assert.Nil(t, err)
  178. pk := sk.Public()
  179. account := &Account{
  180. TokenID: TokenID(1),
  181. Nonce: Nonce(1234),
  182. Balance: big.NewInt(1000),
  183. PublicKey: pk,
  184. EthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
  185. }
  186. v, err := account.HashValue()
  187. assert.Nil(t, err)
  188. assert.Equal(t, "16297758255249203915951182296472515138555043617458222397753168518282206850764", v.String())
  189. }
  190. func TestAccountHashValueTestVectors(t *testing.T) {
  191. // values from js test vectors
  192. ay := new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(253), nil), big.NewInt(1))
  193. assert.Equal(t, "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", (hex.EncodeToString(ay.Bytes())))
  194. bjj, err := babyjub.PointFromSignAndY(true, ay)
  195. require.Nil(t, err)
  196. account := &Account{
  197. Idx: 1,
  198. TokenID: 0xFFFFFFFF,
  199. PublicKey: (*babyjub.PublicKey)(bjj),
  200. EthAddr: ethCommon.HexToAddress("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
  201. Nonce: Nonce(0xFFFFFFFFFF),
  202. Balance: bigFromStr("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16),
  203. }
  204. e, err := account.BigInts()
  205. assert.Nil(t, err)
  206. assert.Equal(t, "9444732965739290427391", e[0].String())
  207. assert.Equal(t, "6277101735386680763835789423207666416102355444464034512895", e[1].String())
  208. assert.Equal(t, "14474011154664524427946373126085988481658748083205070504932198000989141204991", e[2].String())
  209. assert.Equal(t, "1461501637330902918203684832716283019655932542975", e[3].String())
  210. h, err := poseidon.Hash(e[:])
  211. assert.Nil(t, err)
  212. assert.Equal(t, "4550823210217540218403400309533329186487982452461145263910122718498735057257", h.String())
  213. v, err := account.HashValue()
  214. assert.Nil(t, err)
  215. assert.Equal(t, "4550823210217540218403400309533329186487982452461145263910122718498735057257", v.String())
  216. // second account
  217. ay = big.NewInt(0)
  218. bjj, err = babyjub.PointFromSignAndY(false, ay)
  219. require.Nil(t, err)
  220. account = &Account{
  221. TokenID: 0,
  222. PublicKey: (*babyjub.PublicKey)(bjj),
  223. EthAddr: ethCommon.HexToAddress("0x00"),
  224. Nonce: Nonce(0),
  225. Balance: big.NewInt(0),
  226. }
  227. v, err = account.HashValue()
  228. assert.Nil(t, err)
  229. assert.Equal(t, "7750253361301235345986002241352365187241910378619330147114280396816709365657", v.String())
  230. // third account
  231. ay = bigFromStr("21b0a1688b37f77b1d1d5539ec3b826db5ac78b2513f574a04c50a7d4f8246d7", 16)
  232. bjj, err = babyjub.PointFromSignAndY(false, ay)
  233. require.Nil(t, err)
  234. account = &Account{
  235. TokenID: 3,
  236. PublicKey: (*babyjub.PublicKey)(bjj),
  237. EthAddr: ethCommon.HexToAddress("0xA3C88ac39A76789437AED31B9608da72e1bbfBF9"),
  238. Nonce: Nonce(129),
  239. Balance: bigFromStr("42000000000000000000", 10),
  240. }
  241. e, err = account.BigInts()
  242. assert.Nil(t, err)
  243. assert.Equal(t, "554050781187", e[0].String())
  244. assert.Equal(t, "42000000000000000000", e[1].String())
  245. assert.Equal(t, "15238403086306505038849621710779816852318505119327426213168494964113886299863", e[2].String())
  246. assert.Equal(t, "935037732739828347587684875151694054123613453305", e[3].String())
  247. v, err = account.HashValue()
  248. assert.Nil(t, err)
  249. assert.Equal(t, "10565754214047872850889045989683221123564392137456000481397520902594455245517", v.String())
  250. }
  251. func TestAccountErrNotInFF(t *testing.T) {
  252. z := big.NewInt(0)
  253. // Q-1 should not give error
  254. r := new(big.Int).Sub(cryptoConstants.Q, big.NewInt(1))
  255. e := [NLeafElems]*big.Int{z, z, r, r}
  256. _, err := AccountFromBigInts(e)
  257. assert.Nil(t, err)
  258. // Q should give error
  259. r = cryptoConstants.Q
  260. e = [NLeafElems]*big.Int{z, z, r, r}
  261. _, err = AccountFromBigInts(e)
  262. assert.NotNil(t, err)
  263. assert.Equal(t, ErrNotInFF, tracerr.Unwrap(err))
  264. // Q+1 should give error
  265. r = new(big.Int).Add(cryptoConstants.Q, big.NewInt(1))
  266. e = [NLeafElems]*big.Int{z, z, r, r}
  267. _, err = AccountFromBigInts(e)
  268. assert.NotNil(t, err)
  269. assert.Equal(t, ErrNotInFF, tracerr.Unwrap(err))
  270. }
  271. func TestAccountErrNumOverflowNonce(t *testing.T) {
  272. var sk babyjub.PrivateKey
  273. _, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
  274. assert.Nil(t, err)
  275. pk := sk.Public()
  276. // check limit
  277. account := &Account{
  278. TokenID: TokenID(1),
  279. Nonce: Nonce(math.Pow(2, 40) - 1),
  280. Balance: big.NewInt(1000),
  281. PublicKey: pk,
  282. EthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
  283. }
  284. _, err = account.Bytes()
  285. assert.Nil(t, err)
  286. // force value overflow
  287. account.Nonce = Nonce(math.Pow(2, 40))
  288. b, err := account.Bytes()
  289. assert.NotNil(t, err)
  290. assert.Equal(t, fmt.Errorf("%s Nonce", ErrNumOverflow), tracerr.Unwrap(err))
  291. _, err = AccountFromBytes(b)
  292. assert.Nil(t, err)
  293. }
  294. func TestAccountErrNumOverflowBalance(t *testing.T) {
  295. var sk babyjub.PrivateKey
  296. _, err := hex.Decode(sk[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
  297. assert.Nil(t, err)
  298. pk := sk.Public()
  299. // check limit
  300. account := &Account{
  301. TokenID: TokenID(1),
  302. Nonce: Nonce(math.Pow(2, 40) - 1),
  303. Balance: new(big.Int).Sub(new(big.Int).Exp(big.NewInt(2), big.NewInt(192), nil), big.NewInt(1)),
  304. PublicKey: pk,
  305. EthAddr: ethCommon.HexToAddress("0xc58d29fA6e86E4FAe04DDcEd660d45BCf3Cb2370"),
  306. }
  307. assert.Equal(t, "6277101735386680763835789423207666416102355444464034512895", account.Balance.String())
  308. _, err = account.Bytes()
  309. assert.Nil(t, err)
  310. // force value overflow
  311. account.Balance = new(big.Int).Exp(big.NewInt(2), big.NewInt(192), nil)
  312. assert.Equal(t, "6277101735386680763835789423207666416102355444464034512896", account.Balance.String())
  313. b, err := account.Bytes()
  314. assert.NotNil(t, err)
  315. assert.Equal(t, fmt.Errorf("%s Balance", ErrNumOverflow), tracerr.Unwrap(err))
  316. _, err = AccountFromBytes(b)
  317. assert.Nil(t, err)
  318. b[39] = 1
  319. _, err = AccountFromBytes(b)
  320. assert.NotNil(t, err)
  321. assert.Equal(t, fmt.Errorf("%s Balance", ErrNumOverflow), tracerr.Unwrap(err))
  322. }