diff --git a/sm9/bn256/twist.go b/sm9/bn256/twist.go index 1b53ce5..e56575a 100644 --- a/sm9/bn256/twist.go +++ b/sm9/bn256/twist.go @@ -208,6 +208,29 @@ func (c *twistPoint) MakeAffine() { c.t.SetOne() } +// MakeAffine reverses the Jacobian transform. +// the Jacobian coordinates are (x1, y1, z1) +// where x = x1/z1² and y = y1/z1³. +func (c *twistPoint) AffineFromJacobian() { + if c.z.IsOne() { + return + } else if c.z.IsZero() { + c.x.SetZero() + c.y.SetOne() + c.t.SetZero() + return + } + + zInv := (&gfP2{}).Invert(&c.z) + t := (&gfP2{}).Mul(&c.y, zInv) + zInv2 := (&gfP2{}).Square(zInv) + c.y.Mul(t, zInv2) + t.Mul(&c.x, zInv2) + c.x.Set(t) + c.z.SetOne() + c.t.SetOne() +} + func (c *twistPoint) Neg(a *twistPoint) { c.x.Set(&a.x) c.y.Neg(&a.y) diff --git a/sm9/bn256/twist_test.go b/sm9/bn256/twist_test.go index bf34e7a..6ea1a0b 100644 --- a/sm9/bn256/twist_test.go +++ b/sm9/bn256/twist_test.go @@ -28,7 +28,7 @@ func TestAddNeg(t *testing.T) { func Test_TwistFrobeniusP(t *testing.T) { ret1, ret2 := &twistPoint{}, &twistPoint{} ret1.Frobenius(twistGen) - ret1.MakeAffine() + ret1.AffineFromJacobian() ret2.x.Conjugate(&twistGen.x) ret2.x.MulScalar(&ret2.x, betaToNegPPlus1Over3) @@ -49,12 +49,15 @@ func Test_TwistFrobeniusP(t *testing.T) { func Test_TwistFrobeniusP2(t *testing.T) { ret1, ret2 := &twistPoint{}, &twistPoint{} ret1.Frobenius(twistGen) + ret1.AffineFromJacobian() ret1.Frobenius(ret1) + ret1.AffineFromJacobian() if !ret1.IsOnCurve() { t.Errorf("point should be on curve") } ret2.FrobeniusP2(twistGen) + ret2.AffineFromJacobian() if !ret2.IsOnCurve() { t.Errorf("point should be on curve") } @@ -77,7 +80,7 @@ func Test_TwistFrobeniusP2_Case2(t *testing.T) { } ret2.FrobeniusP2(twistGen) - ret2.MakeAffine() + ret2.AffineFromJacobian() if !ret2.IsOnCurve() { t.Errorf("point should be on curve") } @@ -100,7 +103,7 @@ func Test_TwistNegFrobeniusP2_Case2(t *testing.T) { } ret2.NegFrobeniusP2(twistGen) - ret2.MakeAffine() + ret2.AffineFromJacobian() if !ret2.IsOnCurve() { t.Errorf("point should be on curve") }