crypto.pcurves: don't assume that points with X=0 are at infinity (#16017)

There's also a valid point with X=0 on each curves.

Fixes #16015
This commit is contained in:
Frank Denis 2023-06-13 20:20:24 +02:00 committed by GitHub
parent 137b115681
commit cc708b4a88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 18 additions and 6 deletions

View File

@ -36,7 +36,9 @@ pub const P256 = struct {
/// Reject the neutral element.
pub fn rejectIdentity(p: P256) IdentityElementError!void {
if (p.x.isZero()) {
const affine_0 = @boolToInt(p.x.equivalent(AffineCoordinates.identityElement.x)) & (@boolToInt(p.y.isZero()) | @boolToInt(p.y.equivalent(AffineCoordinates.identityElement.y)));
const is_identity = @boolToInt(p.z.isZero()) | affine_0;
if (is_identity != 0) {
return error.IdentityElement;
}
}
@ -286,12 +288,14 @@ pub const P256 = struct {
/// Return affine coordinates.
pub fn affineCoordinates(p: P256) AffineCoordinates {
const affine_0 = @boolToInt(p.x.equivalent(AffineCoordinates.identityElement.x)) & (@boolToInt(p.y.isZero()) | @boolToInt(p.y.equivalent(AffineCoordinates.identityElement.y)));
const is_identity = @boolToInt(p.z.isZero()) | affine_0;
const zinv = p.z.invert();
var ret = AffineCoordinates{
.x = p.x.mul(zinv),
.y = p.y.mul(zinv),
};
ret.cMov(AffineCoordinates.identityElement, @boolToInt(p.x.isZero()));
ret.cMov(AffineCoordinates.identityElement, is_identity);
return ret;
}

View File

@ -36,7 +36,9 @@ pub const P384 = struct {
/// Reject the neutral element.
pub fn rejectIdentity(p: P384) IdentityElementError!void {
if (p.x.isZero()) {
const affine_0 = @boolToInt(p.x.equivalent(AffineCoordinates.identityElement.x)) & (@boolToInt(p.y.isZero()) | @boolToInt(p.y.equivalent(AffineCoordinates.identityElement.y)));
const is_identity = @boolToInt(p.z.isZero()) | affine_0;
if (is_identity != 0) {
return error.IdentityElement;
}
}
@ -286,12 +288,14 @@ pub const P384 = struct {
/// Return affine coordinates.
pub fn affineCoordinates(p: P384) AffineCoordinates {
const affine_0 = @boolToInt(p.x.equivalent(AffineCoordinates.identityElement.x)) & (@boolToInt(p.y.isZero()) | @boolToInt(p.y.equivalent(AffineCoordinates.identityElement.y)));
const is_identity = @boolToInt(p.z.isZero()) | affine_0;
const zinv = p.z.invert();
var ret = AffineCoordinates{
.x = p.x.mul(zinv),
.y = p.y.mul(zinv),
};
ret.cMov(AffineCoordinates.identityElement, @boolToInt(p.x.isZero()));
ret.cMov(AffineCoordinates.identityElement, is_identity);
return ret;
}

View File

@ -89,7 +89,9 @@ pub const Secp256k1 = struct {
/// Reject the neutral element.
pub fn rejectIdentity(p: Secp256k1) IdentityElementError!void {
if (p.x.isZero()) {
const affine_0 = @boolToInt(p.x.equivalent(AffineCoordinates.identityElement.x)) & (@boolToInt(p.y.isZero()) | @boolToInt(p.y.equivalent(AffineCoordinates.identityElement.y)));
const is_identity = @boolToInt(p.z.isZero()) | affine_0;
if (is_identity != 0) {
return error.IdentityElement;
}
}
@ -314,12 +316,14 @@ pub const Secp256k1 = struct {
/// Return affine coordinates.
pub fn affineCoordinates(p: Secp256k1) AffineCoordinates {
const affine_0 = @boolToInt(p.x.equivalent(AffineCoordinates.identityElement.x)) & (@boolToInt(p.y.isZero()) | @boolToInt(p.y.equivalent(AffineCoordinates.identityElement.y)));
const is_identity = @boolToInt(p.z.isZero()) | affine_0;
const zinv = p.z.invert();
var ret = AffineCoordinates{
.x = p.x.mul(zinv),
.y = p.y.mul(zinv),
};
ret.cMov(AffineCoordinates.identityElement, @boolToInt(p.x.isZero()));
ret.cMov(AffineCoordinates.identityElement, is_identity);
return ret;
}