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.

365 lines
11 KiB

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