Function mulMulti [src]
Multiscalar multiplication IN VARIABLE TIME for public data
Computes ps0ss0 + ps1ss1 + ps2*ss2... faster than doing many of these operations individually
Prototype
pub fn mulMulti(comptime count: usize, ps: [count]Edwards25519, ss: [count][32]u8) (IdentityElementError || WeakPublicKeyError)!Edwards25519
Parameters
count: usize
ps: [count]Edwards25519
ss: [count][32]u8
Source
pub fn mulMulti(comptime count: usize, ps: [count]Edwards25519, ss: [count][32]u8) (IdentityElementError || WeakPublicKeyError)!Edwards25519 {
var pcs: [count][9]Edwards25519 = undefined;
var bpc: [9]Edwards25519 = undefined;
@memcpy(&bpc, basePointPc[0..bpc.len]);
for (ps, 0..) |p, i| {
if (p.is_base) {
pcs[i] = bpc;
} else {
pcs[i] = precompute(p, 8);
pcs[i][4].rejectIdentity() catch return error.WeakPublicKey;
}
}
var es: [count][2 * 32]i8 = undefined;
for (ss, 0..) |s, i| {
es[i] = slide(s);
}
var q = Edwards25519.identityElement;
var pos: usize = 2 * 32 - 1;
while (true) : (pos -= 1) {
for (es, 0..) |e, i| {
const slot = e[pos];
if (slot > 0) {
q = q.add(pcs[i][@as(usize, @intCast(slot))]);
} else if (slot < 0) {
q = q.sub(pcs[i][@as(usize, @intCast(-slot))]);
}
}
if (pos == 0) break;
q = q.dbl().dbl().dbl().dbl();
}
try q.rejectIdentity();
return q;
}