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.

315 lines
9.4 KiB

  1. package babyjub
  2. import (
  3. "encoding/hex"
  4. "math/big"
  5. "math/rand"
  6. "testing"
  7. "github.com/iden3/go-iden3-crypto/constants"
  8. "github.com/iden3/go-iden3-crypto/ff"
  9. "github.com/iden3/go-iden3-crypto/utils"
  10. "github.com/stretchr/testify/assert"
  11. )
  12. func zero() *ff.Element {
  13. return ff.NewElement().SetZero()
  14. }
  15. func one() *ff.Element {
  16. return ff.NewElement().SetOne()
  17. }
  18. func TestAdd1(t *testing.T) {
  19. a := &Point{X: zero(), Y: one()}
  20. b := &Point{X: zero(), Y: one()}
  21. c := NewPoint().Add(a, b)
  22. // fmt.Printf("%v = 2 * %v", *c, *a)
  23. assert.Equal(t, "0", c.X.String())
  24. assert.Equal(t, "1", c.Y.String())
  25. }
  26. func TestAdd2(t *testing.T) {
  27. aX := ff.NewElement().SetString(
  28. "17777552123799933955779906779655732241715742912184938656739573121738514868268")
  29. aY := ff.NewElement().SetString(
  30. "2626589144620713026669568689430873010625803728049924121243784502389097019475")
  31. a := &Point{X: aX, Y: aY}
  32. bX := ff.NewElement().SetString(
  33. "17777552123799933955779906779655732241715742912184938656739573121738514868268")
  34. bY := ff.NewElement().SetString(
  35. "2626589144620713026669568689430873010625803728049924121243784502389097019475")
  36. b := &Point{X: bX, Y: bY}
  37. c := NewPoint().Add(a, b)
  38. // fmt.Printf("%v = 2 * %v", *c, *a)
  39. assert.Equal(t,
  40. "6890855772600357754907169075114257697580319025794532037257385534741338397365",
  41. c.X.String())
  42. assert.Equal(t,
  43. "4338620300185947561074059802482547481416142213883829469920100239455078257889",
  44. c.Y.String())
  45. }
  46. func TestAdd3(t *testing.T) {
  47. aX := ff.NewElement().SetString(
  48. "17777552123799933955779906779655732241715742912184938656739573121738514868268")
  49. aY := ff.NewElement().SetString(
  50. "2626589144620713026669568689430873010625803728049924121243784502389097019475")
  51. a := &Point{X: aX, Y: aY}
  52. bX := ff.NewElement().SetString(
  53. "16540640123574156134436876038791482806971768689494387082833631921987005038935")
  54. bY := ff.NewElement().SetString(
  55. "20819045374670962167435360035096875258406992893633759881276124905556507972311")
  56. b := &Point{X: bX, Y: bY}
  57. c := NewPoint().Add(a, b)
  58. // fmt.Printf("%v = 2 * %v", *c, *a)
  59. assert.Equal(t,
  60. "7916061937171219682591368294088513039687205273691143098332585753343424131937",
  61. c.X.String())
  62. assert.Equal(t,
  63. "14035240266687799601661095864649209771790948434046947201833777492504781204499",
  64. c.Y.String())
  65. }
  66. func TestAdd4(t *testing.T) {
  67. aX := ff.NewElement().SetString(
  68. "0")
  69. aY := ff.NewElement().SetString(
  70. "1")
  71. a := &Point{X: aX, Y: aY}
  72. bX := ff.NewElement().SetString(
  73. "16540640123574156134436876038791482806971768689494387082833631921987005038935")
  74. bY := ff.NewElement().SetString(
  75. "20819045374670962167435360035096875258406992893633759881276124905556507972311")
  76. b := &Point{X: bX, Y: bY}
  77. c := NewPoint().Add(a, b)
  78. // fmt.Printf("%v = 2 * %v", *c, *a)
  79. assert.Equal(t,
  80. "16540640123574156134436876038791482806971768689494387082833631921987005038935",
  81. c.X.String())
  82. assert.Equal(t,
  83. "20819045374670962167435360035096875258406992893633759881276124905556507972311",
  84. c.Y.String())
  85. }
  86. func TestInCurve1(t *testing.T) {
  87. p := &Point{X: zero(), Y: one()}
  88. assert.Equal(t, true, p.InCurve())
  89. }
  90. func TestInCurve2(t *testing.T) {
  91. p := &Point{X: one(), Y: zero()}
  92. assert.Equal(t, false, p.InCurve())
  93. }
  94. func TestMul0(t *testing.T) {
  95. x := ff.NewElement().SetString(
  96. "17777552123799933955779906779655732241715742912184938656739573121738514868268")
  97. y := ff.NewElement().SetString(
  98. "2626589144620713026669568689430873010625803728049924121243784502389097019475")
  99. p := &Point{X: x, Y: y}
  100. s := utils.NewIntFromString("3")
  101. r2 := NewPoint().Add(p, p)
  102. r2 = NewPoint().Add(r2, p)
  103. r := NewPoint().Mul(s, p)
  104. assert.Equal(t, r2.X.String(), r.X.String())
  105. assert.Equal(t, r2.Y.String(), r.Y.String())
  106. assert.Equal(t,
  107. "19372461775513343691590086534037741906533799473648040012278229434133483800898",
  108. r.X.String())
  109. assert.Equal(t,
  110. "9458658722007214007257525444427903161243386465067105737478306991484593958249",
  111. r.Y.String())
  112. }
  113. func TestMul1(t *testing.T) {
  114. x := ff.NewElement().SetString(
  115. "17777552123799933955779906779655732241715742912184938656739573121738514868268")
  116. y := ff.NewElement().SetString(
  117. "2626589144620713026669568689430873010625803728049924121243784502389097019475")
  118. p := &Point{X: x, Y: y}
  119. s := utils.NewIntFromString(
  120. "14035240266687799601661095864649209771790948434046947201833777492504781204499")
  121. r := NewPoint().Mul(s, p)
  122. assert.Equal(t,
  123. "17070357974431721403481313912716834497662307308519659060910483826664480189605",
  124. r.X.String())
  125. assert.Equal(t,
  126. "4014745322800118607127020275658861516666525056516280575712425373174125159339",
  127. r.Y.String())
  128. }
  129. func TestMul2(t *testing.T) {
  130. x := ff.NewElement().SetString(
  131. "6890855772600357754907169075114257697580319025794532037257385534741338397365")
  132. y := ff.NewElement().SetString(
  133. "4338620300185947561074059802482547481416142213883829469920100239455078257889")
  134. p := &Point{X: x, Y: y}
  135. s := utils.NewIntFromString(
  136. "20819045374670962167435360035096875258406992893633759881276124905556507972311")
  137. r := NewPoint().Mul(s, p)
  138. assert.Equal(t,
  139. "13563888653650925984868671744672725781658357821216877865297235725727006259983",
  140. r.X.String())
  141. assert.Equal(t,
  142. "8442587202676550862664528699803615547505326611544120184665036919364004251662",
  143. r.Y.String())
  144. }
  145. func TestInCurve3(t *testing.T) {
  146. x := ff.NewElement().SetString(
  147. "17777552123799933955779906779655732241715742912184938656739573121738514868268")
  148. y := ff.NewElement().SetString(
  149. "2626589144620713026669568689430873010625803728049924121243784502389097019475")
  150. p := &Point{X: x, Y: y}
  151. assert.Equal(t, true, p.InCurve())
  152. }
  153. func TestInCurve4(t *testing.T) {
  154. x := ff.NewElement().SetString(
  155. "6890855772600357754907169075114257697580319025794532037257385534741338397365")
  156. y := ff.NewElement().SetString(
  157. "4338620300185947561074059802482547481416142213883829469920100239455078257889")
  158. p := &Point{X: x, Y: y}
  159. assert.Equal(t, true, p.InCurve())
  160. }
  161. func TestInSubGroup1(t *testing.T) {
  162. x := ff.NewElement().SetString(
  163. "17777552123799933955779906779655732241715742912184938656739573121738514868268")
  164. y := ff.NewElement().SetString(
  165. "2626589144620713026669568689430873010625803728049924121243784502389097019475")
  166. p := &Point{X: x, Y: y}
  167. assert.Equal(t, true, p.InSubGroup())
  168. }
  169. func TestInSubGroup2(t *testing.T) {
  170. x := ff.NewElement().SetString(
  171. "6890855772600357754907169075114257697580319025794532037257385534741338397365")
  172. y := ff.NewElement().SetString(
  173. "4338620300185947561074059802482547481416142213883829469920100239455078257889")
  174. p := &Point{X: x, Y: y}
  175. assert.Equal(t, true, p.InSubGroup())
  176. }
  177. func TestCompressDecompress1(t *testing.T) {
  178. x := ff.NewElement().SetString(
  179. "17777552123799933955779906779655732241715742912184938656739573121738514868268")
  180. y := ff.NewElement().SetString(
  181. "2626589144620713026669568689430873010625803728049924121243784502389097019475")
  182. p := &Point{X: x, Y: y}
  183. buf := p.Compress()
  184. assert.Equal(t, "53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85", hex.EncodeToString(buf[:]))
  185. p2, err := NewPoint().Decompress(buf)
  186. assert.Equal(t, nil, err)
  187. assert.Equal(t, p.X.String(), p2.X.String())
  188. assert.Equal(t, p.Y.String(), p2.Y.String())
  189. }
  190. func TestCompressDecompress2(t *testing.T) {
  191. x := ff.NewElement().SetString(
  192. "6890855772600357754907169075114257697580319025794532037257385534741338397365")
  193. y := ff.NewElement().SetString(
  194. "4338620300185947561074059802482547481416142213883829469920100239455078257889")
  195. p := &Point{X: x, Y: y}
  196. buf := p.Compress()
  197. assert.Equal(t, "e114eb17eddf794f063a68fecac515e3620e131976108555735c8b0773929709", hex.EncodeToString(buf[:]))
  198. p2, err := NewPoint().Decompress(buf)
  199. assert.Equal(t, nil, err)
  200. assert.Equal(t, p.X.String(), p2.X.String())
  201. assert.Equal(t, p.Y.String(), p2.Y.String())
  202. }
  203. func TestCompressDecompressRnd(t *testing.T) {
  204. for i := 0; i < 64; i++ {
  205. p1 := NewPoint().Mul(big.NewInt(int64(i)), B8)
  206. buf := p1.Compress()
  207. p2, err := NewPoint().Decompress(buf)
  208. assert.Equal(t, nil, err)
  209. // assert.Equal(t, p1, p2)
  210. assert.True(t, p1.Equal(p2))
  211. }
  212. }
  213. func BenchmarkBabyjub(b *testing.B) {
  214. const n = 256
  215. rnd := rand.New(rand.NewSource(42))
  216. var badpoints [n]*Point
  217. for i := 0; i < n; i++ {
  218. x := ff.NewElement().SetRandom()
  219. y := ff.NewElement().SetRandom()
  220. badpoints[i] = &Point{X: x, Y: y}
  221. }
  222. var points [n]*Point
  223. baseX := ff.NewElement().SetString(
  224. "17777552123799933955779906779655732241715742912184938656739573121738514868268")
  225. baseY := ff.NewElement().SetString(
  226. "2626589144620713026669568689430873010625803728049924121243784502389097019475")
  227. base := &Point{X: baseX, Y: baseY}
  228. for i := 0; i < n; i++ {
  229. s := new(big.Int).Rand(rnd, constants.Q)
  230. points[i] = NewPoint().Mul(s, base)
  231. }
  232. var scalars [n]*big.Int
  233. for i := 0; i < n; i++ {
  234. scalars[i] = new(big.Int).Rand(rnd, constants.Q)
  235. }
  236. b.Run("AddConst", func(b *testing.B) {
  237. p0 := &Point{X: zero(), Y: one()}
  238. p1 := &Point{X: zero(), Y: one()}
  239. p2 := NewPoint()
  240. for i := 0; i < b.N; i++ {
  241. p2.Add(p0, p1)
  242. }
  243. })
  244. b.Run("AddRnd", func(b *testing.B) {
  245. res := NewPoint()
  246. for i := 0; i < b.N; i++ {
  247. res.Add(points[i%(n/2)], points[i%(n/2)+1])
  248. }
  249. })
  250. b.Run("MulRnd", func(b *testing.B) {
  251. res := NewPoint()
  252. for i := 0; i < b.N; i++ {
  253. res.Mul(scalars[i%n], points[i%n])
  254. }
  255. })
  256. b.Run("Compress", func(b *testing.B) {
  257. for i := 0; i < b.N; i++ {
  258. points[i%n].Compress()
  259. }
  260. })
  261. b.Run("InCurve", func(b *testing.B) {
  262. for i := 0; i < b.N; i++ {
  263. badpoints[i%n].InCurve()
  264. }
  265. })
  266. b.Run("InSubGroup", func(b *testing.B) {
  267. for i := 0; i < b.N; i++ {
  268. points[i%n].InCurve()
  269. }
  270. })
  271. }