diff --git a/crypto/bn256/cloudflare/twist.go b/crypto/bn256/cloudflare/twist.go index 2c7a69a4d7..c2e39c57ca 100644 --- a/crypto/bn256/cloudflare/twist.go +++ b/crypto/bn256/cloudflare/twist.go @@ -43,7 +43,7 @@ func (c *twistPoint) Set(a *twistPoint) { c.t.Set(&a.t) } -// IsOnCurve returns true iff c is on the curve. +// IsOnCurve returns true iff c is on the curve and is in the correct subgroup. func (c *twistPoint) IsOnCurve() bool { c.MakeAffine() if c.IsInfinity() { @@ -57,6 +57,8 @@ func (c *twistPoint) IsOnCurve() bool { if *y2 != *x3 { return false } + // Subgroup check: multiply the point by the group order and + // verify that it becomes the point at infinity. cneg := &twistPoint{} cneg.Mul(c, Order) return cneg.z.IsZero() diff --git a/crypto/bn256/google/twist.go b/crypto/bn256/google/twist.go index 43364ff5b7..631d1ca8df 100644 --- a/crypto/bn256/google/twist.go +++ b/crypto/bn256/google/twist.go @@ -67,7 +67,7 @@ func (c *twistPoint) Set(a *twistPoint) { c.t.Set(a.t) } -// IsOnCurve returns true iff c is on the curve where c must be in affine form. +// IsOnCurve returns true iff c is on the curve and is in the correct subgroup, where c must be in affine form. func (c *twistPoint) IsOnCurve() bool { pool := new(bnPool) yy := newGFp2(pool).Square(c.y, pool) @@ -80,6 +80,8 @@ func (c *twistPoint) IsOnCurve() bool { if yy.x.Sign() != 0 || yy.y.Sign() != 0 { return false } + // Subgroup check: multiply the point by the group order and + // verify that it becomes the point at infinity. cneg := newTwistPoint(pool) cneg.Mul(c, Order, pool) return cneg.z.IsZero()