authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2020-11-15 22:33:01+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-18 21:45:42-08:00
log3f134cfe5e3837aadd5b197bb0aa28dd191b8a08
treee6a1cd77806038cdc4df08e995a163b4e059696a
parente814f7105214c588f5df4c173ecf84dd3a11b01d

edwards25519 - skip useless operations and duplicate lookup table

Just some trivial changes; no functional changes. Skip useless nul additions and multiplications and comptime the basepoint multiples only once.

1 files changed, 23 insertions(+), 26 deletions(-)

lib/std/crypto/25519/edwards25519.zig+23-26
...@@ -144,7 +144,7 @@ pub const Edwards25519 = struct {...@@ -144,7 +144,7 @@ pub const Edwards25519 = struct {
144144
145 inline fn pcSelect(pc: [16]Edwards25519, b: u8) Edwards25519 {145 inline fn pcSelect(pc: [16]Edwards25519, b: u8) Edwards25519 {
146 var t = Edwards25519.identityElement;146 var t = Edwards25519.identityElement;
147 comptime var i: u8 = 0;147 comptime var i: u8 = 1;
148 inline while (i < 16) : (i += 1) {148 inline while (i < 16) : (i += 1) {
149 t.cMov(pc[i], ((@as(usize, b ^ i) -% 1) >> 8) & 1);149 t.cMov(pc[i], ((@as(usize, b ^ i) -% 1) >> 8) & 1);
150 }150 }
...@@ -155,7 +155,6 @@ pub const Edwards25519 = struct {...@@ -155,7 +155,6 @@ pub const Edwards25519 = struct {
155 var q = Edwards25519.identityElement;155 var q = Edwards25519.identityElement;
156 var pos: usize = 252;156 var pos: usize = 252;
157 while (true) : (pos -= 4) {157 while (true) : (pos -= 4) {
158 q = q.dbl().dbl().dbl().dbl();
159 const bit = (s[pos >> 3] >> @truncate(u3, pos)) & 0xf;158 const bit = (s[pos >> 3] >> @truncate(u3, pos)) & 0xf;
160 if (vartime) {159 if (vartime) {
161 if (bit != 0) {160 if (bit != 0) {
...@@ -165,6 +164,7 @@ pub const Edwards25519 = struct {...@@ -165,6 +164,7 @@ pub const Edwards25519 = struct {
165 q = q.add(pcSelect(pc, bit));164 q = q.add(pcSelect(pc, bit));
166 }165 }
167 if (pos == 0) break;166 if (pos == 0) break;
167 q = q.dbl().dbl().dbl().dbl();
168 }168 }
169 try q.rejectIdentity();169 try q.rejectIdentity();
170 return q;170 return q;
...@@ -181,32 +181,31 @@ pub const Edwards25519 = struct {...@@ -181,32 +181,31 @@ pub const Edwards25519 = struct {
181 return pc;181 return pc;
182 }182 }
183183
184 const basePointPc = comptime pc: {
185 @setEvalBranchQuota(10000);
186 break :pc precompute(Edwards25519.basePoint);
187 };
188
184 /// Multiply an Edwards25519 point by a scalar without clamping it.189 /// Multiply an Edwards25519 point by a scalar without clamping it.
185 /// Return error.WeakPublicKey if the resulting point is190 /// Return error.WeakPublicKey if the resulting point is
186 /// the identity element.191 /// the identity element.
187 pub fn mul(p: Edwards25519, s: [32]u8) !Edwards25519 {192 pub fn mul(p: Edwards25519, s: [32]u8) !Edwards25519 {
188 var pc: [16]Edwards25519 = undefined;193 const pc = if (p.is_base) basePointPc else pc: {
189 if (p.is_base) {194 const xpc = precompute(p);
190 @setEvalBranchQuota(10000);195 xpc[4].rejectIdentity() catch |_| return error.WeakPublicKey;
191 pc = comptime precompute(Edwards25519.basePoint);196 break :pc xpc;
192 } else {197 };
193 pc = precompute(p);
194 pc[4].rejectIdentity() catch |_| return error.WeakPublicKey;
195 }
196 return pcMul(pc, s, false);198 return pcMul(pc, s, false);
197 }199 }
198200
199 /// Multiply an Edwards25519 point by a *PUBLIC* scalar *IN VARIABLE TIME*201 /// Multiply an Edwards25519 point by a *PUBLIC* scalar *IN VARIABLE TIME*
200 /// This can be used for signature verification.202 /// This can be used for signature verification.
201 pub fn mulPublic(p: Edwards25519, s: [32]u8) !Edwards25519 {203 pub fn mulPublic(p: Edwards25519, s: [32]u8) !Edwards25519 {
202 var pc: [16]Edwards25519 = undefined;204 const pc = if (p.is_base) basePointPc else pc: {
203 if (p.is_base) {205 const xpc = precompute(p);
204 @setEvalBranchQuota(10000);206 xpc[4].rejectIdentity() catch |_| return error.WeakPublicKey;
205 pc = comptime precompute(Edwards25519.basePoint);207 break :pc xpc;
206 } else {208 };
207 pc = precompute(p);
208 pc[4].rejectIdentity() catch |_| return error.WeakPublicKey;
209 }
210 return pcMul(pc, s, true);209 return pcMul(pc, s, true);
211 }210 }
212211
...@@ -215,18 +214,15 @@ pub const Edwards25519 = struct {...@@ -215,18 +214,15 @@ pub const Edwards25519 = struct {
215 pub fn mulMulti(comptime count: usize, ps: [count]Edwards25519, ss: [count][32]u8) !Edwards25519 {214 pub fn mulMulti(comptime count: usize, ps: [count]Edwards25519, ss: [count][32]u8) !Edwards25519 {
216 var pcs: [count][16]Edwards25519 = undefined;215 var pcs: [count][16]Edwards25519 = undefined;
217 for (ps) |p, i| {216 for (ps) |p, i| {
218 if (p.is_base) {217 pcs[i] = if (p.is_base) basePointPc else pc: {
219 @setEvalBranchQuota(10000);218 const xpc = precompute(p);
220 pcs[i] = comptime precompute(Edwards25519.basePoint);219 xpc[4].rejectIdentity() catch |_| return error.WeakPublicKey;
221 } else {220 break :pc xpc;
222 pcs[i] = precompute(p);221 };
223 pcs[i][4].rejectIdentity() catch |_| return error.WeakPublicKey;
224 }
225 }222 }
226 var q = Edwards25519.identityElement;223 var q = Edwards25519.identityElement;
227 var pos: usize = 252;224 var pos: usize = 252;
228 while (true) : (pos -= 4) {225 while (true) : (pos -= 4) {
229 q = q.dbl().dbl().dbl().dbl();
230 for (ss) |s, i| {226 for (ss) |s, i| {
231 const bit = (s[pos >> 3] >> @truncate(u3, pos)) & 0xf;227 const bit = (s[pos >> 3] >> @truncate(u3, pos)) & 0xf;
232 if (bit != 0) {228 if (bit != 0) {
...@@ -234,6 +230,7 @@ pub const Edwards25519 = struct {...@@ -234,6 +230,7 @@ pub const Edwards25519 = struct {
234 }230 }
235 }231 }
236 if (pos == 0) break;232 if (pos == 0) break;
233 q = q.dbl().dbl().dbl().dbl();
237 }234 }
238 try q.rejectIdentity();235 try q.rejectIdentity();
239 return q;236 return q;