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.

361 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 TestPackAndUnpackSignY(t *testing.T) {
  193. x := utils.NewIntFromString(
  194. "17777552123799933955779906779655732241715742912184938656739573121738514868268")
  195. y := utils.NewIntFromString(
  196. "2626589144620713026669568689430873010625803728049924121243784502389097019475")
  197. p := &Point{X: x, Y: y}
  198. pComp := p.Compress()
  199. s, y := UnpackSignY(pComp)
  200. pComp2 := PackSignY(s, y)
  201. assert.Equal(t, pComp, pComp2)
  202. emptyPointComp := [32]byte{}
  203. s, y = UnpackSignY(emptyPointComp)
  204. pComp2 = PackSignY(s, y)
  205. assert.Equal(t, emptyPointComp, pComp2)
  206. }
  207. func TestCompressDecompress1(t *testing.T) {
  208. x := utils.NewIntFromString(
  209. "17777552123799933955779906779655732241715742912184938656739573121738514868268")
  210. y := utils.NewIntFromString(
  211. "2626589144620713026669568689430873010625803728049924121243784502389097019475")
  212. p := &Point{X: x, Y: y}
  213. buf := p.Compress()
  214. assert.Equal(t,
  215. "53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85",
  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 TestCompressDecompress2(t *testing.T) {
  223. x := utils.NewIntFromString(
  224. "6890855772600357754907169075114257697580319025794532037257385534741338397365")
  225. y := utils.NewIntFromString(
  226. "4338620300185947561074059802482547481416142213883829469920100239455078257889")
  227. p := &Point{X: x, Y: y}
  228. buf := p.Compress()
  229. assert.Equal(t,
  230. "e114eb17eddf794f063a68fecac515e3620e131976108555735c8b0773929709",
  231. hex.EncodeToString(buf[:]))
  232. p2, err := NewPoint().Decompress(buf)
  233. assert.Equal(t, nil, err)
  234. assert.Equal(t, p.X.String(), p2.X.String())
  235. assert.Equal(t, p.Y.String(), p2.Y.String())
  236. }
  237. func TestCompressDecompressRnd(t *testing.T) {
  238. for i := 0; i < 64; i++ {
  239. p1 := NewPoint().Mul(big.NewInt(int64(i)), B8)
  240. buf := p1.Compress()
  241. p2, err := NewPoint().Decompress(buf)
  242. assert.Equal(t, nil, err)
  243. assert.Equal(t, p1.X.Bytes(), p2.X.Bytes())
  244. assert.Equal(t, p1.Y.Bytes(), p2.Y.Bytes())
  245. }
  246. }
  247. func BenchmarkBabyjub(b *testing.B) {
  248. const n = 256
  249. rnd := rand.New(rand.NewSource(42)) //nolint:gosec
  250. var badpoints [n]*Point
  251. for i := 0; i < n; i++ {
  252. x := new(big.Int).Rand(rnd, constants.Q)
  253. y := new(big.Int).Rand(rnd, constants.Q)
  254. badpoints[i] = &Point{X: x, Y: y}
  255. }
  256. var points [n]*Point
  257. var pointsProj [n]*PointProjective
  258. baseX := utils.NewIntFromString(
  259. "17777552123799933955779906779655732241715742912184938656739573121738514868268")
  260. baseY := utils.NewIntFromString(
  261. "2626589144620713026669568689430873010625803728049924121243784502389097019475")
  262. base := &Point{X: baseX, Y: baseY}
  263. for i := 0; i < n; i++ {
  264. s := new(big.Int).Rand(rnd, constants.Q)
  265. points[i] = NewPoint().Mul(s, base)
  266. pointsProj[i] = NewPoint().Mul(s, base).Projective()
  267. }
  268. var scalars [n]*big.Int
  269. for i := 0; i < n; i++ {
  270. scalars[i] = new(big.Int).Rand(rnd, constants.Q)
  271. }
  272. b.Run("AddConst", func(b *testing.B) {
  273. p0 := &Point{X: big.NewInt(0), Y: big.NewInt(1)}
  274. p1 := &Point{X: big.NewInt(0), Y: big.NewInt(1)}
  275. p0Proj := p0.Projective()
  276. p1Proj := p1.Projective()
  277. p2 := NewPoint().Projective()
  278. for i := 0; i < b.N; i++ {
  279. p2.Add(p0Proj, p1Proj)
  280. }
  281. })
  282. b.Run("AddRnd", func(b *testing.B) {
  283. res := NewPoint().Projective()
  284. for i := 0; i < b.N; i++ {
  285. res.Add(pointsProj[i%(n/2)], pointsProj[i%(n/2)+1])
  286. }
  287. })
  288. b.Run("MulRnd", func(b *testing.B) {
  289. res := NewPoint()
  290. for i := 0; i < b.N; i++ {
  291. res.Mul(scalars[i%n], points[i%n])
  292. }
  293. })
  294. b.Run("Compress", func(b *testing.B) {
  295. for i := 0; i < b.N; i++ {
  296. points[i%n].Compress()
  297. }
  298. })
  299. b.Run("InCurve", func(b *testing.B) {
  300. for i := 0; i < b.N; i++ {
  301. badpoints[i%n].InCurve()
  302. }
  303. })
  304. b.Run("InSubGroup", func(b *testing.B) {
  305. for i := 0; i < b.N; i++ {
  306. points[i%n].InCurve()
  307. }
  308. })
  309. }