in src/compression/sidh_compressed.c [53:126]
static void FullIsogeny_A_dual(unsigned char* PrivateKeyA, f2elm_t As[][5], f2elm_t a24, unsigned int sike)
{
// Input: a private key PrivateKeyA in the range [0, 2^eA - 1].
// Output: the public key PublicKeyA consisting of 3 elements in GF(p^2) which are encoded by removing leading 0 bytes.
point_proj_t R, pts[MAX_INT_POINTS_ALICE];
f2elm_t XPA, XQA, XRA, coeff[5], A24 = {0}, C24 = {0}, A = {0};
unsigned int i, row, m, index = 0, pts_index[MAX_INT_POINTS_ALICE], npts = 0, ii = 0;
digit_t SecretKeyA[NWORDS_ORDER] = {0};
// Initialize basis points
init_basis((digit_t*)A_gen, XPA, XQA, XRA);
// Initialize constants: A24 = A+2C, C24 = 4C, where A=6, C=1
fpcopy((digit_t*)&Montgomery_one, A24[0]);
fp2add(A24, A24, A24);
fp2add(A24, A24, C24);
fp2add(A24, C24, A);
fp2add(C24, C24, A24);
// Retrieve kernel point
decode_to_digits(PrivateKeyA, SecretKeyA, SECRETKEY_A_BYTES, NWORDS_ORDER);
LADDER3PT(XPA, XQA, XRA, SecretKeyA, ALICE, R, A);
fp2inv_mont(R->Z);
fp2mul_mont(R->X,R->Z,R->X);
fpcopy((digit_t*)&Montgomery_one, R->Z[0]);
fpzero(R->Z[1]);
if (sike == 1)
fp2_encode(R->X, &PrivateKeyA[SECRETKEY_A_BYTES + CRYPTO_PUBLICKEYBYTES]); // privA ||= x(KA) = x(PA + sk_A*QA)
#if (OALICE_BITS % 2 == 1)
point_proj_t S;
xDBLe(R, S, A24, C24, (int)(OALICE_BITS-1));
get_2_isog(S, A24, C24);
eval_2_isog(R, S);
fp2copy(S->X, As[MAX_Alice][2]);
fp2copy(S->Z, As[MAX_Alice][3]);
#endif
// Traverse tree
index = 0;
for (row = 1; row < MAX_Alice; row++) {
while (index < MAX_Alice-row) {
fp2copy(R->X, pts[npts]->X);
fp2copy(R->Z, pts[npts]->Z);
pts_index[npts++] = index;
m = strat_Alice[ii++];
xDBLe(R, R, A24, C24, (int)(2*m));
index += m;
}
fp2copy(A24, As[row-1][0]);
fp2copy(C24, As[row-1][1]);
get_4_isog_dual(R, A24, C24, coeff);
for (i = 0; i < npts; i++) {
eval_4_isog(pts[i], coeff);
}
eval_dual_4_isog_shared(coeff[2], coeff[3], coeff[4], *(As+row-1)+2);
fp2copy(pts[npts-1]->X, R->X);
fp2copy(pts[npts-1]->Z, R->Z);
index = pts_index[npts-1];
npts -= 1;
}
fp2copy(A24, As[MAX_Alice-1][0]);
fp2copy(C24, As[MAX_Alice-1][1]);
get_4_isog_dual(R, A24, C24, coeff);
eval_dual_4_isog_shared(coeff[2], coeff[3], coeff[4], *(As+MAX_Alice-1)+2);
fp2copy(A24, As[MAX_Alice][0]);
fp2copy(C24, As[MAX_Alice][1]);
fp2inv_mont_bingcd(C24);
fp2mul_mont(A24, C24, a24);
}