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.

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