From 030fa5e7ebc21339728c79f33bf5d5d22e0a760e Mon Sep 17 00:00:00 2001 From: Frank Denis <124872+jedisct1@users.noreply.github.com> Date: Mon, 26 Apr 2021 22:25:48 +0200 Subject: [PATCH] 25519: remove unused const, safeguard against unreduced scalars (#8624) * 25519: remove unused const, safeguard against unreduced scalars No behavior change, but it makes the existing code better match the forthcoming code for other curves. Rename nonAdjacentForm() to slide(), remove an unneeded and confusing constant, and do a reduction in slide() if 257 bits would be required. Note that in all the high-level functions, the top bit is always cleared, so the reduction is never necessary. But since the low-level functions are public, the check is a safe thing to have. * 25519: make identityElement public, deprecate neutralElement Also fix a few comments by the way. --- lib/std/crypto/25519/edwards25519.zig | 25 +++++++++---------------- lib/std/crypto/25519/field.zig | 2 +- lib/std/crypto/25519/scalar.zig | 2 +- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/lib/std/crypto/25519/edwards25519.zig b/lib/std/crypto/25519/edwards25519.zig index e8163a3960..4e3d156007 100644 --- a/lib/std/crypto/25519/edwards25519.zig +++ b/lib/std/crypto/25519/edwards25519.zig @@ -75,16 +75,8 @@ pub const Edwards25519 = struct { .is_base = true, }; - /// The edwards25519 neutral element. - pub const neutralElement = Edwards25519{ - .x = Fe{ .limbs = .{ 2251799813685229, 2251799813685247, 2251799813685247, 2251799813685247, 2251799813685247 } }, - .y = Fe{ .limbs = .{ 1507481815385608, 2223447444246085, 1083941587175919, 2059929906842505, 1581435440146976 } }, - .z = Fe{ .limbs = .{ 1507481815385608, 2223447444246085, 1083941587175919, 2059929906842505, 1581435440146976 } }, - .t = Fe{ .limbs = .{ 2251799813685229, 2251799813685247, 2251799813685247, 2251799813685247, 2251799813685247 } }, - .is_base = false, - }; - - const identityElement = Edwards25519{ .x = Fe.zero, .y = Fe.one, .z = Fe.one, .t = Fe.zero }; + pub const neutralElement = @compileError("deprecated: use identityElement instead"); + pub const identityElement = Edwards25519{ .x = Fe.zero, .y = Fe.one, .z = Fe.one, .t = Fe.zero }; /// Reject the neutral element. pub fn rejectIdentity(p: Edwards25519) IdentityElementError!void { @@ -160,9 +152,10 @@ pub const Edwards25519 = struct { return t; } - fn nonAdjacentForm(s: [32]u8) [2 * 32]i8 { + fn slide(s: [32]u8) [2 * 32]i8 { + const reduced = if ((s[s.len - 1] & 0x80) != 0) s else scalar.reduce(s); var e: [2 * 32]i8 = undefined; - for (s) |x, i| { + for (reduced) |x, i| { e[i * 2 + 0] = @as(i8, @truncate(u4, x)); e[i * 2 + 1] = @as(i8, @truncate(u4, x >> 4)); } @@ -185,7 +178,7 @@ pub const Edwards25519 = struct { // avoid these to keep the standard library lightweight. fn pcMul(pc: [9]Edwards25519, s: [32]u8, comptime vartime: bool) IdentityElementError!Edwards25519 { std.debug.assert(vartime); - const e = nonAdjacentForm(s); + const e = slide(s); var q = Edwards25519.identityElement; var pos: usize = 2 * 32 - 1; while (true) : (pos -= 1) { @@ -280,8 +273,8 @@ pub const Edwards25519 = struct { xpc[4].rejectIdentity() catch return error.WeakPublicKey; break :pc xpc; }; - const e1 = nonAdjacentForm(s1); - const e2 = nonAdjacentForm(s2); + const e1 = slide(s1); + const e2 = slide(s2); var q = Edwards25519.identityElement; var pos: usize = 2 * 32 - 1; while (true) : (pos -= 1) { @@ -318,7 +311,7 @@ pub const Edwards25519 = struct { } var es: [count][2 * 32]i8 = undefined; for (ss) |s, i| { - es[i] = nonAdjacentForm(s); + es[i] = slide(s); } var q = Edwards25519.identityElement; var pos: usize = 2 * 32 - 1; diff --git a/lib/std/crypto/25519/field.zig b/lib/std/crypto/25519/field.zig index 5ac184080c..aae53e9081 100644 --- a/lib/std/crypto/25519/field.zig +++ b/lib/std/crypto/25519/field.zig @@ -355,7 +355,7 @@ pub const Fe = struct { return fe; } - /// Compute the inverse of a field element + /// Return the inverse of a field element, or 0 if a=0. pub fn invert(a: Fe) Fe { var t0 = a.sq(); var t1 = t0.sqn(2).mul(a); diff --git a/lib/std/crypto/25519/scalar.zig b/lib/std/crypto/25519/scalar.zig index 21578486e8..e8564ff577 100644 --- a/lib/std/crypto/25519/scalar.zig +++ b/lib/std/crypto/25519/scalar.zig @@ -98,7 +98,7 @@ pub fn sub(a: [32]u8, b: [32]u8) [32]u8 { return add(a, neg(b)); } -/// A scalar in unpacked reprentation +/// A scalar in unpacked representation pub const Scalar = struct { const Limbs = [5]u64; limbs: Limbs = undefined,