From b2e4dda0018b83819c9539609eff7e420eca3202 Mon Sep 17 00:00:00 2001 From: Frank Denis <124872+jedisct1@users.noreply.github.com> Date: Wed, 29 Jun 2022 07:43:49 +0200 Subject: [PATCH] std.crypto.{p256,p384}: process the top nibble in mulDoubleBasePublic (#11956) Unlike curve25519 where the scalar size is not large enough to fill the top nibble, this can definitely be the case for p256 and p384. --- lib/std/crypto/pcurves/p256.zig | 2 +- lib/std/crypto/pcurves/p384.zig | 2 +- lib/std/crypto/pcurves/tests/p256.zig | 10 ++++++++++ lib/std/crypto/pcurves/tests/p384.zig | 10 ++++++++++ 4 files changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/std/crypto/pcurves/p256.zig b/lib/std/crypto/pcurves/p256.zig index c7dac55b24..5898f83c10 100644 --- a/lib/std/crypto/pcurves/p256.zig +++ b/lib/std/crypto/pcurves/p256.zig @@ -437,7 +437,7 @@ pub const P256 = struct { const e1 = slide(s1); const e2 = slide(s2); var q = P256.identityElement; - var pos: usize = 2 * 32 - 1; + var pos: usize = 2 * 32; while (true) : (pos -= 1) { const slot1 = e1[pos]; if (slot1 > 0) { diff --git a/lib/std/crypto/pcurves/p384.zig b/lib/std/crypto/pcurves/p384.zig index 854343c1e4..0694d4f259 100644 --- a/lib/std/crypto/pcurves/p384.zig +++ b/lib/std/crypto/pcurves/p384.zig @@ -437,7 +437,7 @@ pub const P384 = struct { const e1 = slide(s1); const e2 = slide(s2); var q = P384.identityElement; - var pos: usize = 2 * 48 - 1; + var pos: usize = 2 * 48; while (true) : (pos -= 1) { const slot1 = e1[pos]; if (slot1 > 0) { diff --git a/lib/std/crypto/pcurves/tests/p256.zig b/lib/std/crypto/pcurves/tests/p256.zig index ce21ac8ba0..eab69d351e 100644 --- a/lib/std/crypto/pcurves/tests/p256.zig +++ b/lib/std/crypto/pcurves/tests/p256.zig @@ -112,6 +112,16 @@ test "p256 double base multiplication" { try testing.expect(pr1.equivalent(pr2)); } +test "p256 double base multiplication with large scalars" { + const p1 = P256.basePoint; + const p2 = P256.basePoint.dbl(); + const s1 = [_]u8{0xee} ** 32; + const s2 = [_]u8{0xdd} ** 32; + const pr1 = try P256.mulDoubleBasePublic(p1, s1, p2, s2, .Little); + const pr2 = (try p1.mul(s1, .Little)).add(try p2.mul(s2, .Little)); + try testing.expect(pr1.equivalent(pr2)); +} + test "p256 scalar inverse" { const expected = "3b549196a13c898a6f6e84dfb3a22c40a8b9b17fb88e408ea674e451cd01d0a6"; var out: [32]u8 = undefined; diff --git a/lib/std/crypto/pcurves/tests/p384.zig b/lib/std/crypto/pcurves/tests/p384.zig index 54c5148ae0..cba1d91a81 100644 --- a/lib/std/crypto/pcurves/tests/p384.zig +++ b/lib/std/crypto/pcurves/tests/p384.zig @@ -115,6 +115,16 @@ test "p384 double base multiplication" { try testing.expect(pr1.equivalent(pr2)); } +test "p384 double base multiplication with large scalars" { + const p1 = P384.basePoint; + const p2 = P384.basePoint.dbl(); + const s1 = [_]u8{0xee} ** 48; + const s2 = [_]u8{0xdd} ** 48; + const pr1 = try P384.mulDoubleBasePublic(p1, s1, p2, s2, .Little); + const pr2 = (try p1.mul(s1, .Little)).add(try p2.mul(s2, .Little)); + try testing.expect(pr1.equivalent(pr2)); +} + test "p384 scalar inverse" { const expected = "a3cc705f33b5679a66e76ce66e68055c927c5dba531b2837b18fe86119511091b54d733f26b2e7a0f6fa2e7ea21ca806"; var out: [48]u8 = undefined;