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: P256, s1_: [32]u8, p2: P256, s2_: [32]u8, endian: std.builtin.Endian) IdentityElementError!P256
Parameters
p1: P256
s1_: [32]u8
p2: P256
s2_: [32]u8
endian: std.builtin.Endian
Possible Errors
Source
pub fn mulDoubleBasePublic(p1: P256, s1_: [32]u8, p2: P256, s2_: [32]u8, endian: std.builtin.Endian) IdentityElementError!P256 {
const s1 = if (endian == .little) s1_ else Fe.orderSwap(s1_);
const s2 = if (endian == .little) s2_ else Fe.orderSwap(s2_);
try p1.rejectIdentity();
var pc1_array: [9]P256 = undefined;
const pc1 = if (p1.is_base) basePointPc[0..9] else pc: {
pc1_array = precompute(p1, 8);
break :pc &pc1_array;
};
try p2.rejectIdentity();
var pc2_array: [9]P256 = undefined;
const pc2 = if (p2.is_base) basePointPc[0..9] else pc: {
pc2_array = precompute(p2, 8);
break :pc &pc2_array;
};
const e1 = slide(s1);
const e2 = slide(s2);
var q = P256.identityElement;
var pos: usize = 2 * 32;
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;
}