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.

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