| author | |
| committer | |
| log | e7bc7efda73eb68e5d599feb18e2538cc16df85e |
| tree | 94dc9e845504aa6a2c2ccd10667ac6669dd7198e |
| parent | d593a596185c3442afa2e1955e1157a31bd4b554 |
According to SEC1, the point at infinity has a unique
representation (encoded as single 00 byte); it's not supposed to be
representable in affine coordinates.
So we can simplify the function to just check the equation.
The point at infinity can still be decoded by the regular fromSec1()
function.6 files changed, 21 insertions(+), 24 deletions(-)
lib/std/crypto/pcurves/p256.zig+2-6| ... | ... | @@ -49,14 +49,10 @@ pub const P256 = struct { |
| 49 | 49 | const y = p.y; |
| 50 | 50 | const x3AxB = x.sq().mul(x).sub(x).sub(x).sub(x).add(B); |
| 51 | 51 | const yy = y.sq(); |
| 52 | const on_curve = @intFromBool(x3AxB.equivalent(yy)); | |
| 53 | const is_identity = @intFromBool(x.equivalent(AffineCoordinates.identityElement.x)) & @intFromBool(y.equivalent(AffineCoordinates.identityElement.y)); | |
| 54 | if ((on_curve | is_identity) == 0) { | |
| 52 | if (!x3AxB.equivalent(yy)) { | |
| 55 | 53 | return error.InvalidEncoding; |
| 56 | 54 | } |
| 57 | var ret = P256{ .x = x, .y = y, .z = Fe.one }; | |
| 58 | ret.z.cMov(P256.identityElement.z, is_identity); | |
| 59 | return ret; | |
| 55 | return .{ .x = x, .y = y, .z = Fe.one }; | |
| 60 | 56 | } |
| 61 | 57 | |
| 62 | 58 | /// Create a point from serialized affine coordinates. |
lib/std/crypto/pcurves/p384.zig+2-6| ... | ... | @@ -49,14 +49,10 @@ pub const P384 = struct { |
| 49 | 49 | const y = p.y; |
| 50 | 50 | const x3AxB = x.sq().mul(x).sub(x).sub(x).sub(x).add(B); |
| 51 | 51 | const yy = y.sq(); |
| 52 | const on_curve = @intFromBool(x3AxB.equivalent(yy)); | |
| 53 | const is_identity = @intFromBool(x.equivalent(AffineCoordinates.identityElement.x)) & @intFromBool(y.equivalent(AffineCoordinates.identityElement.y)); | |
| 54 | if ((on_curve | is_identity) == 0) { | |
| 52 | if (!x3AxB.equivalent(yy)) { | |
| 55 | 53 | return error.InvalidEncoding; |
| 56 | 54 | } |
| 57 | var ret = P384{ .x = x, .y = y, .z = Fe.one }; | |
| 58 | ret.z.cMov(P384.identityElement.z, is_identity); | |
| 59 | return ret; | |
| 55 | return .{ .x = x, .y = y, .z = Fe.one }; | |
| 60 | 56 | } |
| 61 | 57 | |
| 62 | 58 | /// Create a point from serialized affine coordinates. |
lib/std/crypto/pcurves/secp256k1.zig+2-6| ... | ... | @@ -102,14 +102,10 @@ pub const Secp256k1 = struct { |
| 102 | 102 | const y = p.y; |
| 103 | 103 | const x3B = x.sq().mul(x).add(B); |
| 104 | 104 | const yy = y.sq(); |
| 105 | const on_curve = @intFromBool(x3B.equivalent(yy)); | |
| 106 | const is_identity = @intFromBool(x.equivalent(AffineCoordinates.identityElement.x)) & @intFromBool(y.equivalent(AffineCoordinates.identityElement.y)); | |
| 107 | if ((on_curve | is_identity) == 0) { | |
| 105 | if (!x3B.equivalent(yy)) { | |
| 108 | 106 | return error.InvalidEncoding; |
| 109 | 107 | } |
| 110 | var ret = Secp256k1{ .x = x, .y = y, .z = Fe.one }; | |
| 111 | ret.z.cMov(Secp256k1.identityElement.z, is_identity); | |
| 112 | return ret; | |
| 108 | return .{ .x = x, .y = y, .z = Fe.one }; | |
| 113 | 109 | } |
| 114 | 110 | |
| 115 | 111 | /// Create a point from serialized affine coordinates. |
lib/std/crypto/pcurves/tests/p256.zig+2-2| ... | ... | @@ -103,8 +103,8 @@ test "p256 field element non-canonical encoding" { |
| 103 | 103 | |
| 104 | 104 | test "p256 neutral element decoding" { |
| 105 | 105 | try testing.expectError(error.InvalidEncoding, P256.fromAffineCoordinates(.{ .x = P256.Fe.zero, .y = P256.Fe.zero })); |
| 106 | const p = try P256.fromAffineCoordinates(.{ .x = P256.Fe.zero, .y = P256.Fe.one }); | |
| 107 | try testing.expectError(error.IdentityElement, p.rejectIdentity()); | |
| 106 | try testing.expectError(error.InvalidEncoding, P256.fromAffineCoordinates(.{ .x = P256.Fe.zero, .y = P256.Fe.one })); | |
| 107 | try testing.expectError(error.IdentityElement, P256.identityElement.rejectIdentity()); | |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | 110 | test "p256 double base multiplication" { |
lib/std/crypto/pcurves/tests/p384.zig+2-2| ... | ... | @@ -106,8 +106,8 @@ test "p384 field element non-canonical encoding" { |
| 106 | 106 | |
| 107 | 107 | test "p384 neutral element decoding" { |
| 108 | 108 | try testing.expectError(error.InvalidEncoding, P384.fromAffineCoordinates(.{ .x = P384.Fe.zero, .y = P384.Fe.zero })); |
| 109 | const p = try P384.fromAffineCoordinates(.{ .x = P384.Fe.zero, .y = P384.Fe.one }); | |
| 110 | try testing.expectError(error.IdentityElement, p.rejectIdentity()); | |
| 109 | try testing.expectError(error.InvalidEncoding, P384.fromAffineCoordinates(.{ .x = P384.Fe.zero, .y = P384.Fe.one })); | |
| 110 | try testing.expectError(error.IdentityElement, P384.identityElement.rejectIdentity()); | |
| 111 | 111 | } |
| 112 | 112 | |
| 113 | 113 | test "p384 double base multiplication" { |
lib/std/crypto/pcurves/tests/secp256k1.zig+11-2| ... | ... | @@ -115,8 +115,17 @@ test "secp256k1 field element non-canonical encoding" { |
| 115 | 115 | |
| 116 | 116 | test "secp256k1 neutral element decoding" { |
| 117 | 117 | try testing.expectError(error.InvalidEncoding, Secp256k1.fromAffineCoordinates(.{ .x = Secp256k1.Fe.zero, .y = Secp256k1.Fe.zero })); |
| 118 | const p = try Secp256k1.fromAffineCoordinates(.{ .x = Secp256k1.Fe.zero, .y = Secp256k1.Fe.one }); | |
| 119 | try testing.expectError(error.IdentityElement, p.rejectIdentity()); | |
| 118 | try testing.expectError(error.InvalidEncoding, Secp256k1.fromAffineCoordinates(.{ .x = Secp256k1.Fe.zero, .y = Secp256k1.Fe.one })); | |
| 119 | try testing.expectError(error.IdentityElement, Secp256k1.identityElement.rejectIdentity()); | |
| 120 | } | |
| 121 | ||
| 122 | test "secp256k1 uncompressed SEC1 must not accept infinity" { | |
| 123 | var buf: [65]u8 = @splat(0); | |
| 124 | buf[0] = 0x04; | |
| 125 | buf[64] = 0x01; | |
| 126 | try testing.expectError(error.InvalidEncoding, Secp256k1.fromSec1(&buf)); | |
| 127 | buf[64] = 0x00; | |
| 128 | try testing.expectError(error.InvalidEncoding, Secp256k1.fromSec1(&buf)); | |
| 120 | 129 | } |
| 121 | 130 | |
| 122 | 131 | test "secp256k1 double base multiplication" { |