authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2021-04-26 22:25:48+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-04-26 22:25:48+02:00
log030fa5e7ebc21339728c79f33bf5d5d22e0a760e
treea0793e131036a29abc740888cfeea97fa85ce987
parent95b42f9e6b901435b6ff7841a6b180553761070b
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

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.

3 files changed, 11 insertions(+), 18 deletions(-)

lib/std/crypto/25519/edwards25519.zig+9-16
...@@ -75,16 +75,8 @@ pub const Edwards25519 = struct {...@@ -75,16 +75,8 @@ pub const Edwards25519 = struct {
75 .is_base = true,75 .is_base = true,
76 };76 };
7777
78 /// The edwards25519 neutral element.78 pub const neutralElement = @compileError("deprecated: use identityElement instead");
79 pub const neutralElement = Edwards25519{79 pub const identityElement = Edwards25519{ .x = Fe.zero, .y = Fe.one, .z = Fe.one, .t = Fe.zero };
80 .x = Fe{ .limbs = .{ 2251799813685229, 2251799813685247, 2251799813685247, 2251799813685247, 2251799813685247 } },
81 .y = Fe{ .limbs = .{ 1507481815385608, 2223447444246085, 1083941587175919, 2059929906842505, 1581435440146976 } },
82 .z = Fe{ .limbs = .{ 1507481815385608, 2223447444246085, 1083941587175919, 2059929906842505, 1581435440146976 } },
83 .t = Fe{ .limbs = .{ 2251799813685229, 2251799813685247, 2251799813685247, 2251799813685247, 2251799813685247 } },
84 .is_base = false,
85 };
86
87 const identityElement = Edwards25519{ .x = Fe.zero, .y = Fe.one, .z = Fe.one, .t = Fe.zero };
8880
89 /// Reject the neutral element.81 /// Reject the neutral element.
90 pub fn rejectIdentity(p: Edwards25519) IdentityElementError!void {82 pub fn rejectIdentity(p: Edwards25519) IdentityElementError!void {
...@@ -160,9 +152,10 @@ pub const Edwards25519 = struct {...@@ -160,9 +152,10 @@ pub const Edwards25519 = struct {
160 return t;152 return t;
161 }153 }
162154
163 fn nonAdjacentForm(s: [32]u8) [2 * 32]i8 {155 fn slide(s: [32]u8) [2 * 32]i8 {
156 const reduced = if ((s[s.len - 1] & 0x80) != 0) s else scalar.reduce(s);
164 var e: [2 * 32]i8 = undefined;157 var e: [2 * 32]i8 = undefined;
165 for (s) |x, i| {158 for (reduced) |x, i| {
166 e[i * 2 + 0] = @as(i8, @truncate(u4, x));159 e[i * 2 + 0] = @as(i8, @truncate(u4, x));
167 e[i * 2 + 1] = @as(i8, @truncate(u4, x >> 4));160 e[i * 2 + 1] = @as(i8, @truncate(u4, x >> 4));
168 }161 }
...@@ -185,7 +178,7 @@ pub const Edwards25519 = struct {...@@ -185,7 +178,7 @@ pub const Edwards25519 = struct {
185 // avoid these to keep the standard library lightweight.178 // avoid these to keep the standard library lightweight.
186 fn pcMul(pc: [9]Edwards25519, s: [32]u8, comptime vartime: bool) IdentityElementError!Edwards25519 {179 fn pcMul(pc: [9]Edwards25519, s: [32]u8, comptime vartime: bool) IdentityElementError!Edwards25519 {
187 std.debug.assert(vartime);180 std.debug.assert(vartime);
188 const e = nonAdjacentForm(s);181 const e = slide(s);
189 var q = Edwards25519.identityElement;182 var q = Edwards25519.identityElement;
190 var pos: usize = 2 * 32 - 1;183 var pos: usize = 2 * 32 - 1;
191 while (true) : (pos -= 1) {184 while (true) : (pos -= 1) {
...@@ -280,8 +273,8 @@ pub const Edwards25519 = struct {...@@ -280,8 +273,8 @@ pub const Edwards25519 = struct {
280 xpc[4].rejectIdentity() catch return error.WeakPublicKey;273 xpc[4].rejectIdentity() catch return error.WeakPublicKey;
281 break :pc xpc;274 break :pc xpc;
282 };275 };
283 const e1 = nonAdjacentForm(s1);276 const e1 = slide(s1);
284 const e2 = nonAdjacentForm(s2);277 const e2 = slide(s2);
285 var q = Edwards25519.identityElement;278 var q = Edwards25519.identityElement;
286 var pos: usize = 2 * 32 - 1;279 var pos: usize = 2 * 32 - 1;
287 while (true) : (pos -= 1) {280 while (true) : (pos -= 1) {
...@@ -318,7 +311,7 @@ pub const Edwards25519 = struct {...@@ -318,7 +311,7 @@ pub const Edwards25519 = struct {
318 }311 }
319 var es: [count][2 * 32]i8 = undefined;312 var es: [count][2 * 32]i8 = undefined;
320 for (ss) |s, i| {313 for (ss) |s, i| {
321 es[i] = nonAdjacentForm(s);314 es[i] = slide(s);
322 }315 }
323 var q = Edwards25519.identityElement;316 var q = Edwards25519.identityElement;
324 var pos: usize = 2 * 32 - 1;317 var pos: usize = 2 * 32 - 1;
lib/std/crypto/25519/field.zig+1-1
...@@ -355,7 +355,7 @@ pub const Fe = struct {...@@ -355,7 +355,7 @@ pub const Fe = struct {
355 return fe;355 return fe;
356 }356 }
357357
358 /// Compute the inverse of a field element358 /// Return the inverse of a field element, or 0 if a=0.
359 pub fn invert(a: Fe) Fe {359 pub fn invert(a: Fe) Fe {
360 var t0 = a.sq();360 var t0 = a.sq();
361 var t1 = t0.sqn(2).mul(a);361 var t1 = t0.sqn(2).mul(a);
lib/std/crypto/25519/scalar.zig+1-1
...@@ -98,7 +98,7 @@ pub fn sub(a: [32]u8, b: [32]u8) [32]u8 {...@@ -98,7 +98,7 @@ pub fn sub(a: [32]u8, b: [32]u8) [32]u8 {
98 return add(a, neg(b));98 return add(a, neg(b));
99}99}
100100
101/// A scalar in unpacked reprentation101/// A scalar in unpacked representation
102pub const Scalar = struct {102pub const Scalar = struct {
103 const Limbs = [5]u64;103 const Limbs = [5]u64;
104 limbs: Limbs = undefined,104 limbs: Limbs = undefined,