Commit 030fa5e7eb

Frank Denis <124872+jedisct1@users.noreply.github.com>
2021-04-26 22:25:48
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.
1 parent 95b42f9
Changed files (3)
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;
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);
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,