zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit cc708b4a880e0077c3fb0a077a8a39104701dc9c (tree)
parent 137b115681c1ca205df27c70422c42460b5aa6ec
Author: Frank Denis <124872+jedisct1@users.noreply.github.com>
Date:   Tue, 13 Jun 2023 20:20:24 +0200

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
Diffstat:
Mlib/std/crypto/pcurves/p256.zig | 8++++++--
Mlib/std/crypto/pcurves/p384.zig | 8++++++--
Mlib/std/crypto/pcurves/secp256k1.zig | 8++++++--
3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/lib/std/crypto/pcurves/p256.zig b/lib/std/crypto/pcurves/p256.zig @@ -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; } diff --git a/lib/std/crypto/pcurves/p384.zig b/lib/std/crypto/pcurves/p384.zig @@ -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; } diff --git a/lib/std/crypto/pcurves/secp256k1.zig b/lib/std/crypto/pcurves/secp256k1.zig @@ -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; }