Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core/vm: add subgroup checks for mul/mulexp for G1/G2 #29637

Merged
merged 2 commits into from Apr 30, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 24 additions & 0 deletions core/vm/contracts.go
Expand Up @@ -705,6 +705,8 @@ func (c *bls12381G1Add) Run(input []byte) ([]byte, error) {
return nil, err
}

// No need to check the subgroup here, as specified by EIP-2537

// Compute r = p_0 + p_1
p0.Add(p0, p1)

Expand Down Expand Up @@ -734,6 +736,11 @@ func (c *bls12381G1Mul) Run(input []byte) ([]byte, error) {
if p0, err = decodePointG1(input[:128]); err != nil {
return nil, err
}
// 'point is on curve' check already done,
// Here we need to apply subgroup checks.
MariusVanDerWijden marked this conversation as resolved.
Show resolved Hide resolved
if !p0.IsInSubGroup() {
return nil, errBLS12381G1PointSubgroup
}
// Decode scalar value
e := new(big.Int).SetBytes(input[128:])

Expand Down Expand Up @@ -787,6 +794,11 @@ func (c *bls12381G1MultiExp) Run(input []byte) ([]byte, error) {
if err != nil {
return nil, err
}
// 'point is on curve' check already done,
// Here we need to apply subgroup checks.
if !p.IsInSubGroup() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally, this seems un-optimal to me (all these cases). We perform both these calls, with IsOnCurve done from inside decodePointGX.

// IsOnCurve returns true if p in on the curve
func (p *G1Affine) IsOnCurve() bool {
	var point G1Jac
	point.FromAffine(p)
	return point.IsOnCurve() // call this function to handle infinity point
}

// IsInSubGroup returns true if p is in the correct subgroup, false otherwise
func (p *G1Affine) IsInSubGroup() bool {
	var _p G1Jac
	_p.FromAffine(p)
	return _p.IsInSubGroup()
}

Seems like it should be faster to do

func (p *G1Affine) IsOnCurveAndInSubGroup() bool {
	var point G1Jac
	point.FromAffine(p)
	point.IsOnCurve() && point.IsInSubGroup()
}

?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe (probably?) it doesn't make any difference

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes very little difference I think. The subgroup check is the heaviest, moving from affine to jac is very quick and the curve checks are very quick as well

return nil, errBLS12381G1PointSubgroup
}
points[i] = *p
// Decode scalar value
scalars[i] = *new(fr.Element).SetBytes(input[t1:t2])
Expand Down Expand Up @@ -827,6 +839,8 @@ func (c *bls12381G2Add) Run(input []byte) ([]byte, error) {
return nil, err
}

// No need to check the subgroup here, as specified by EIP-2537

// Compute r = p_0 + p_1
r := new(bls12381.G2Affine)
r.Add(p0, p1)
Expand Down Expand Up @@ -857,6 +871,11 @@ func (c *bls12381G2Mul) Run(input []byte) ([]byte, error) {
if p0, err = decodePointG2(input[:256]); err != nil {
return nil, err
}
// 'point is on curve' check already done,
// Here we need to apply subgroup checks.
if !p0.IsInSubGroup() {
return nil, errBLS12381G2PointSubgroup
}
// Decode scalar value
e := new(big.Int).SetBytes(input[256:])

Expand Down Expand Up @@ -910,6 +929,11 @@ func (c *bls12381G2MultiExp) Run(input []byte) ([]byte, error) {
if err != nil {
return nil, err
}
// 'point is on curve' check already done,
// Here we need to apply subgroup checks.
if !p.IsInSubGroup() {
return nil, errBLS12381G2PointSubgroup
}
points[i] = *p
// Decode scalar value
scalars[i] = *new(fr.Element).SetBytes(input[t1:t2])
Expand Down