Skip to content

Commit 26aea8c

Browse files
authored
crypto: add support for the NIST P-384 curve (#11735)
After P-256, here comes P-384, also known as secp384r1. Like P-256, it is required for TLS, and is the current NIST recommendation for key exchange and signatures, for better or for worse. Like P-256, all the finite field arithmetic has been computed and verified to be correct by fiat-crypto.
1 parent 83beed0 commit 26aea8c

File tree

12 files changed

+8067
-4
lines changed

12 files changed

+8067
-4
lines changed

lib/std/crypto.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ pub const ecc = struct {
6262
pub const Curve25519 = @import("crypto/25519/curve25519.zig").Curve25519;
6363
pub const Edwards25519 = @import("crypto/25519/edwards25519.zig").Edwards25519;
6464
pub const P256 = @import("crypto/pcurves/p256.zig").P256;
65+
pub const P384 = @import("crypto/pcurves/p384.zig").P384;
6566
pub const Ristretto255 = @import("crypto/25519/ristretto255.zig").Ristretto255;
6667
};
6768

@@ -201,6 +202,7 @@ test {
201202
_ = ecc.Curve25519;
202203
_ = ecc.Edwards25519;
203204
_ = ecc.P256;
205+
_ = ecc.P384;
204206
_ = ecc.Ristretto255;
205207

206208
_ = hash.blake2;

lib/std/crypto/pcurves/common.zig

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,18 @@ pub fn Field(comptime params: FieldParams) type {
253253
const x47 = x15.mul(x53);
254254
const ls = x47.mul(((x53.sqn(17).mul(x2)).sqn(143).mul(x47)).sqn(47)).sq().mul(x2);
255255
return ls.equivalent(Fe.one);
256+
} else if (field_order == 39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319) {
257+
const t111 = x2.mul(x2.mul(x2.sq()).sq());
258+
const t111111 = t111.mul(t111.sqn(3));
259+
const t1111110 = t111111.sq();
260+
const t1111111 = x2.mul(t1111110);
261+
const x12 = t1111110.sqn(5).mul(t111111);
262+
const x31 = x12.sqn(12).mul(x12).sqn(7).mul(t1111111);
263+
const x32 = x31.sq().mul(x2);
264+
const x63 = x32.sqn(31).mul(x31);
265+
const x126 = x63.sqn(63).mul(x63);
266+
const ls = x126.sqn(126).mul(x126).sqn(3).mul(t111).sqn(33).mul(x32).sqn(95).mul(x31);
267+
return ls.equivalent(Fe.one);
256268
} else {
257269
const ls = x2.pow(std.meta.Int(.unsigned, field_bits), (field_order - 1) / 2); // Legendre symbol
258270
return ls.equivalent(Fe.one);
@@ -268,6 +280,17 @@ pub fn Field(comptime params: FieldParams) type {
268280
const t11111111 = t1111.mul(t1111.sqn(4));
269281
const x16 = t11111111.sqn(8).mul(t11111111);
270282
return x16.sqn(16).mul(x16).sqn(32).mul(x2).sqn(96).mul(x2).sqn(94);
283+
} else if (field_order == 39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319) {
284+
const t111 = x2.mul(x2.mul(x2.sq()).sq());
285+
const t111111 = t111.mul(t111.sqn(3));
286+
const t1111110 = t111111.sq();
287+
const t1111111 = x2.mul(t1111110);
288+
const x12 = t1111110.sqn(5).mul(t111111);
289+
const x31 = x12.sqn(12).mul(x12).sqn(7).mul(t1111111);
290+
const x32 = x31.sq().mul(x2);
291+
const x63 = x32.sqn(31).mul(x31);
292+
const x126 = x63.sqn(63).mul(x63);
293+
return x126.sqn(126).mul(x126).sqn(3).mul(t111).sqn(33).mul(x32).sqn(64).mul(x2).sqn(30);
271294
} else {
272295
return x2.pow(std.meta.Int(.unsigned, field_bits), (field_order + 1) / 4);
273296
}

lib/std/crypto/pcurves/p256.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,5 +474,5 @@ pub const AffineCoordinates = struct {
474474
};
475475

476476
test "p256" {
477-
_ = @import("tests.zig");
477+
_ = @import("tests/p256.zig");
478478
}

lib/std/crypto/pcurves/p256/field.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ pub const Fe = Field(.{
77
.fiat = @import("p256_64.zig"),
88
.field_order = 115792089210356248762697446949407573530086143415290314195533631308867097853951,
99
.field_bits = 256,
10-
.saturated_bits = 255,
10+
.saturated_bits = 256,
1111
.encoded_length = 32,
1212
});

lib/std/crypto/pcurves/p256/scalar.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const Fe = Field(.{
2020
.fiat = @import("p256_scalar_64.zig"),
2121
.field_order = 115792089210356248762697446949407573529996955224135760342422259061068512044369,
2222
.field_bits = 256,
23-
.saturated_bits = 255,
23+
.saturated_bits = 256,
2424
.encoded_length = encoded_length,
2525
});
2626

0 commit comments

Comments
 (0)