Function mulDoubleBasePublic [src]
Double-base multiplication of public parameters - Compute (p1s1)+(p2s2) IN VARIABLE TIME
This can be used for signature verification.
Prototype
pub fn mulDoubleBasePublic(p1: Edwards25519, s1: [32]u8, p2: Edwards25519, s2: [32]u8) (IdentityElementError || WeakPublicKeyError)!Edwards25519
Parameters
p1: Edwards25519
s1: [32]u8
p2: Edwards25519
s2: [32]u8
Source
pub fn mulDoubleBasePublic(p1: Edwards25519, s1: [32]u8, p2: Edwards25519, s2: [32]u8) (IdentityElementError || WeakPublicKeyError)!Edwards25519 {
var pc1_array: [9]Edwards25519 = undefined;
const pc1 = if (p1.is_base) basePointPc[0..9] else pc: {
pc1_array = precompute(p1, 8);
pc1_array[4].rejectIdentity() catch return error.WeakPublicKey;
break :pc &pc1_array;
};
var pc2_array: [9]Edwards25519 = undefined;
const pc2 = if (p2.is_base) basePointPc[0..9] else pc: {
pc2_array = precompute(p2, 8);
pc2_array[4].rejectIdentity() catch return error.WeakPublicKey;
break :pc &pc2_array;
};
const e1 = slide(s1);
const e2 = slide(s2);
var q = Edwards25519.identityElement;
var pos: usize = 2 * 32 - 1;
while (true) : (pos -= 1) {
const slot1 = e1[pos];
if (slot1 > 0) {
q = q.add(pc1[@as(usize, @intCast(slot1))]);
} else if (slot1 < 0) {
q = q.sub(pc1[@as(usize, @intCast(-slot1))]);
}
const slot2 = e2[pos];
if (slot2 > 0) {
q = q.add(pc2[@as(usize, @intCast(slot2))]);
} else if (slot2 < 0) {
q = q.sub(pc2[@as(usize, @intCast(-slot2))]);
}
if (pos == 0) break;
q = q.dbl().dbl().dbl().dbl();
}
try q.rejectIdentity();
return q;
}