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.

341 lines
11 KiB

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