github.com/cloudflare/circl@v1.5.0/ecc/bls12381/g1Isog.go (about) 1 package bls12381 2 3 import ( 4 "fmt" 5 6 "github.com/cloudflare/circl/ecc/bls12381/ff" 7 ) 8 9 type isogG1Point struct{ x, y, z ff.Fp } 10 11 func (p isogG1Point) String() string { return fmt.Sprintf("x: %v\ny: %v\nz: %v", p.x, p.y, p.z) } 12 13 // IsOnCurve returns true if g is a valid point on the curve. 14 func (p *isogG1Point) IsOnCurve() bool { 15 var x2, x3, z2, z3, y2 ff.Fp 16 y2.Sqr(&p.y) // y2 = y^2 17 y2.Mul(&y2, &p.z) // y2 = y^2*z 18 z2.Sqr(&p.z) // z2 = z^2 19 z3.Mul(&z2, &p.z) // z3 = z^3 20 z3.Mul(&z3, &g1Isog11.b) // z3 = B*z^3 21 x2.Sqr(&p.x) // x2 = x^2 22 x3.Mul(&z2, &g1Isog11.a) // x3 = A*z^2 23 x3.Add(&x3, &x2) // x3 = x^2 + A*z^2 24 x3.Mul(&x3, &p.x) // x3 = x^3 + A*x*z^2 25 x3.Add(&x3, &z3) // x3 = x^3 + A*x*z^2 + Bz^3 26 27 return y2.IsEqual(&x3) == 1 && *p != isogG1Point{} 28 } 29 30 // sswu implements the Simplified Shallue-van de Woestijne-Ulas method for 31 // mapping a field element to a point on the isogenous curve. 32 func (p *isogG1Point) sswu(u *ff.Fp) { 33 // Method in Appendix-G.2.1 of 34 // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11 35 tv1, tv2, tv3, tv4 := &ff.Fp{}, &ff.Fp{}, &ff.Fp{}, &ff.Fp{} 36 xd, x1n, gxd, gx1 := &ff.Fp{}, &ff.Fp{}, &ff.Fp{}, &ff.Fp{} 37 y, y1, x2n, y2, xn := &ff.Fp{}, &ff.Fp{}, &ff.Fp{}, &ff.Fp{}, &ff.Fp{} 38 39 tv1.Sqr(u) // 1. tv1 = u^2 40 tv3.Mul(&g1sswu.Z, tv1) // 2. tv3 = Z * tv1 41 tv2.Sqr(tv3) // 3. tv2 = tv3^2 42 xd.Add(tv2, tv3) // 4. xd = tv2 + tv3 43 tv4.SetOne() // 5. tv4 = 1 44 x1n.Add(xd, tv4) // x1n = xd + tv4 45 x1n.Mul(x1n, &g1Isog11.b) // 6. x1n = x1n * B 46 xd.Mul(&g1Isog11.a, xd) // 7. xd = A * xd 47 xd.Neg() // xd = -xd 48 e1 := xd.IsZero() // 8. e1 = xd == 0 49 tv4.Mul(&g1sswu.Z, &g1Isog11.a) // 9. tv4 = Z * A 50 xd.CMov(xd, tv4, e1) // xd = CMOV(xd, tv4, e1) 51 tv2.Sqr(xd) // 10. tv2 = xd^2 52 gxd.Mul(tv2, xd) // 11. gxd = tv2 * xd 53 tv2.Mul(&g1Isog11.a, tv2) // 12. tv2 = A * tv2 54 gx1.Sqr(x1n) // 13. gx1 = x1n^2 55 gx1.Add(gx1, tv2) // 14. gx1 = gx1 + tv2 56 gx1.Mul(gx1, x1n) // 15. gx1 = gx1 * x1n 57 tv2.Mul(&g1Isog11.b, gxd) // 16. tv2 = B * gxd 58 gx1.Add(gx1, tv2) // 17. gx1 = gx1 + tv2 59 tv4.Sqr(gxd) // 18. tv4 = gxd^2 60 tv2.Mul(gx1, gxd) // 19. tv2 = gx1 * gxd 61 tv4.Mul(tv4, tv2) // 20. tv4 = tv4 * tv2 62 y1.ExpVarTime(tv4, g1sswu.c1[:]) // 21. y1 = tv4^c1 63 y1.Mul(y1, tv2) // 22. y1 = y1 * tv2 64 x2n.Mul(tv3, x1n) // 23. x2n = tv3 * x1n 65 y2.Mul(y1, &g1sswu.c2) // 24. y2 = y1 * c2 66 y2.Mul(y2, tv1) // 25. y2 = y2 * tv1 67 y2.Mul(y2, u) // 26. y2 = y2 * u 68 tv2.Sqr(y1) // 27. tv2 = y1^2 69 tv2.Mul(tv2, gxd) // 28. tv2 = tv2 * gxd 70 e2 := tv2.IsEqual(gx1) // 29. e2 = tv2 == gx1 71 xn.CMov(x2n, x1n, e2) // 30. xn = CMOV(x2n, x1n, e2) 72 y.CMov(y2, y1, e2) // 31. y = CMOV(y2, y1, e2) 73 e3 := u.Sgn0() ^ y.Sgn0() // 32. e3 = sgn0(u) == sgn0(y) 74 *tv1 = *y // 33. tv1 = y 75 tv1.Neg() // tv1 = -y 76 y.CMov(tv1, y, ^e3) // y = CMOV(tv1, y, e3) 77 p.x = *xn // 34. return 78 p.y.Mul(y, xd) // (x,y) = (xn/xd, y/1) 79 p.z = *xd // (X,Y,Z) = (xn, y*xd, xd) 80 } 81 82 // evalIsogG1 calculates g = g1Isog11(p), where g1Isog11 is an isogeny of 83 // degree 11 to the curve used in G1. 84 func (g *G1) evalIsogG1(p *isogG1Point) { 85 x, y, z := &p.x, &p.y, &p.z 86 t, zi := &ff.Fp{}, &ff.Fp{} 87 xNum, xDen, yNum, yDen := &ff.Fp{}, &ff.Fp{}, &ff.Fp{}, &ff.Fp{} 88 89 ixn := len(g1Isog11.xNum) - 1 90 ixd := len(g1Isog11.xDen) - 1 91 iyn := len(g1Isog11.yNum) - 1 92 iyd := len(g1Isog11.yDen) - 1 93 94 *xNum = g1Isog11.xNum[ixn] 95 *xDen = g1Isog11.xDen[ixd] 96 *yNum = g1Isog11.yNum[iyn] 97 *yDen = g1Isog11.yDen[iyd] 98 *zi = *z 99 100 for (ixn | ixd | iyn | iyd) != 0 { 101 if ixn > 0 { 102 ixn-- 103 t.Mul(zi, &g1Isog11.xNum[ixn]) 104 xNum.Mul(xNum, x) 105 xNum.Add(xNum, t) 106 } 107 if ixd > 0 { 108 ixd-- 109 t.Mul(zi, &g1Isog11.xDen[ixd]) 110 xDen.Mul(xDen, x) 111 xDen.Add(xDen, t) 112 } 113 if iyn > 0 { 114 iyn-- 115 t.Mul(zi, &g1Isog11.yNum[iyn]) 116 yNum.Mul(yNum, x) 117 yNum.Add(yNum, t) 118 } 119 if iyd > 0 { 120 iyd-- 121 t.Mul(zi, &g1Isog11.yDen[iyd]) 122 yDen.Mul(yDen, x) 123 yDen.Add(yDen, t) 124 } 125 126 zi.Mul(zi, z) 127 } 128 129 g.x.Mul(xNum, yDen) 130 g.y.Mul(yNum, xDen) 131 g.y.Mul(&g.y, y) 132 g.z.Mul(xDen, yDen) 133 g.z.Mul(&g.z, z) 134 }