authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2020-10-19 22:24:09+02:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2020-10-22 09:58:26+02:00
log2d9befe9bfbd333d411c1d38062e5d117da4e508
treeb4d1f7bcc301eef352863ab938333e2f25fd4da4
parent0fb6fdd7eb8c9ec7057e2ecb2d0d4506cddc6dd1

Implement multiscalar edwards25519 point multiplication


2 files changed, 33 insertions(+), 9 deletions(-)

lib/std/crypto/25519/ed25519.zig+4-9
...@@ -168,18 +168,13 @@ pub const Ed25519 = struct {...@@ -168,18 +168,13 @@ pub const Ed25519 = struct {
168 }168 }
169 zs_sum = Curve.scalar.mul8(zs_sum);169 zs_sum = Curve.scalar.mul8(zs_sum);
170170
171 var zr = Curve.neutralElement;171 var zhs: [count]Curve.scalar.CompressedScalar = undefined;
172 for (z_batch) |z, i| {172 for (z_batch) |z, i| {
173 zr = zr.add(try expected_r_batch[i].mulPublic(z));173 zhs[i] = Curve.scalar.mul(z, hram_batch[i]);
174 }174 }
175 zr = zr.clearCofactor();
176175
177 var zah = Curve.neutralElement;176 const zr = (try Curve.mulMulti(count, expected_r_batch, z_batch)).clearCofactor();
178 for (z_batch) |z, i| {177 const zah = (try Curve.mulMulti(count, a_batch, zhs)).clearCofactor();
179 const zh = Curve.scalar.mul(z, hram_batch[i]);
180 zah = zah.add(try a_batch[i].mulPublic(zh));
181 }
182 zah = zah.clearCofactor();
183178
184 const zsb = try Curve.basePoint.mulPublic(zs_sum);179 const zsb = try Curve.basePoint.mulPublic(zs_sum);
185 if (zr.add(zah).sub(zsb).rejectIdentity()) |_| {180 if (zr.add(zah).sub(zsb).rejectIdentity()) |_| {
lib/std/crypto/25519/edwards25519.zig+29
...@@ -208,6 +208,35 @@ pub const Edwards25519 = struct {...@@ -208,6 +208,35 @@ pub const Edwards25519 = struct {
208 return pcMul(pc, s, true);208 return pcMul(pc, s, true);
209 }209 }
210210
211 /// Multiscalar multiplication *IN VARIABLE TIME* for public data
212 /// Computes ps0*ss0 + ps1*ss1 + ps2*ss2... faster than doing many of these operations individually
213 pub fn mulMulti(comptime count: usize, ps: [count]Edwards25519, ss: [count][32]u8) !Edwards25519 {
214 var pcs: [count][16]Edwards25519 = undefined;
215 for (ps) |p, i| {
216 if (p.is_base) {
217 @setEvalBranchQuota(10000);
218 pcs[i] = comptime precompute(Edwards25519.basePoint);
219 } else {
220 pcs[i] = precompute(p);
221 pcs[i][4].rejectIdentity() catch |_| return error.WeakPublicKey;
222 }
223 }
224 var q = Edwards25519.identityElement;
225 var pos: usize = 252;
226 while (true) : (pos -= 4) {
227 q = q.dbl().dbl().dbl().dbl();
228 for (ss) |s, i| {
229 const bit = (s[pos >> 3] >> @truncate(u3, pos)) & 0xf;
230 if (bit != 0) {
231 q = q.add(pcs[i][bit]);
232 }
233 }
234 if (pos == 0) break;
235 }
236 try q.rejectIdentity();
237 return q;
238 }
239
211 /// Multiply an Edwards25519 point by a scalar after "clamping" it.240 /// Multiply an Edwards25519 point by a scalar after "clamping" it.
212 /// Clamping forces the scalar to be a multiple of the cofactor in241 /// Clamping forces the scalar to be a multiple of the cofactor in
213 /// order to prevent small subgroups attacks.242 /// order to prevent small subgroups attacks.