crypton-2.2.3: cbits/crypton_mont_sqr.h
/* Generated by cbits/crypton_mont_sqr.py; do not edit.
*
* Montgomery squaring for AArch64 at 16, 24 and 32 limbs, the halves of
* RSA-2048, -3072 and -4096. Each answers what mont_sqr answers. */
#ifndef CRYPTON_MONT_SQR_H
#define CRYPTON_MONT_SQR_H
#include "crypton_bignum.h"
/* (t2:t1:t0) += x * y */
#define MONT_SQR_MAC(t0, t1, t2, x, y) \
do { \
limb_t lo_, hi_; \
__asm__("mul\t%0, %5, %6\n\t" \
"umulh\t%1, %5, %6\n\t" \
"adds\t%2, %2, %0\n\t" \
"adcs\t%3, %3, %1\n\t" \
"adc\t%4, %4, xzr" \
: "=&r"(lo_), "=&r"(hi_), "+r"(t0), "+r"(t1), "+r"(t2) \
: "r"(x), "r"(y) \
: "cc"); \
} while (0)
/* (s2:s1:s0) = x * y */
#define MONT_SQR_MUL(s0, s1, s2, x, y) \
__asm__("mul\t%0, %3, %4\n\t" \
"umulh\t%1, %3, %4\n\t" \
"mov\t%2, xzr" \
: "=&r"(s0), "=&r"(s1), "=r"(s2) \
: "r"(x), "r"(y))
/* (t2:t1:t0) += 2 * (s2:s1:s0) */
#define MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2) \
do { \
s2 = (s2 << 1) | (s1 >> 63); \
s1 = (s1 << 1) | (s0 >> 63); \
s0 <<= 1; \
__asm__("adds\t%0, %0, %3\n\t" \
"adcs\t%1, %1, %4\n\t" \
"adc\t%2, %2, %5" \
: "+r"(t0), "+r"(t1), "+r"(t2) \
: "r"(s0), "r"(s1), "r"(s2) \
: "cc"); \
} while (0)
/* r = a * a * R^-1 mod m, for a under m; t is 2n limbs of scratch */
static void crypton_mont_sqr16(limb_t *r, const limb_t *a, const limb_t *m,
limb_t n0, limb_t *t)
{
limb_t *u = t, *z = t + 16;
limb_t t0 = 0, t1 = 0, t2 = 0, s0, s1, s2, borrow, take;
/* column 0 */
MONT_SQR_MAC(t0, t1, t2, a[0], a[0]);
u[0] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[0], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 1 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[1]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[1]);
u[1] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[1], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 2 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[2]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[1], a[1]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[1]);
u[2] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[2], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 3 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[3]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[2]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[1]);
u[3] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[3], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 4 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[4]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[3]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[2], a[2]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[1]);
u[4] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[4], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 5 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[5]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[4]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[3]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[1]);
u[5] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[5], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 6 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[6]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[5]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[4]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[3], a[3]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[1]);
u[6] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[6], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 7 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[6]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[5]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[4]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[1]);
u[7] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[7], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 8 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[6]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[5]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[4], a[4]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[1]);
u[8] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[8], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 9 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[6]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[5]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[1]);
u[9] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[9], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 10 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[6]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[5], a[5]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[1]);
u[10] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[10], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 11 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[6]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[1]);
u[11] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[11], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 12 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[7]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[6], a[6]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[1]);
u[12] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[12], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 13 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[7]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[1]);
u[13] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[13], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 14 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[8]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[7], a[7]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[1]);
u[14] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[14], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 15 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[8]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[1]);
u[15] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[15], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 16 */
MONT_SQR_MUL(s0, s1, s2, a[1], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[9]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[8], a[8]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[1]);
z[0] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 17 */
MONT_SQR_MUL(s0, s1, s2, a[2], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[9]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[2], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[2]);
z[1] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 18 */
MONT_SQR_MUL(s0, s1, s2, a[3], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[10]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[9], a[9]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[3]);
z[2] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 19 */
MONT_SQR_MUL(s0, s1, s2, a[4], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[10]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[4], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[4]);
z[3] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 20 */
MONT_SQR_MUL(s0, s1, s2, a[5], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[11]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[10], a[10]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[5]);
z[4] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 21 */
MONT_SQR_MUL(s0, s1, s2, a[6], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[11]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[6], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[6]);
z[5] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 22 */
MONT_SQR_MUL(s0, s1, s2, a[7], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[12]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[11], a[11]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[7]);
z[6] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 23 */
MONT_SQR_MUL(s0, s1, s2, a[8], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[12]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[8], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[8]);
z[7] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 24 */
MONT_SQR_MUL(s0, s1, s2, a[9], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[13]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[12], a[12]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[9]);
z[8] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 25 */
MONT_SQR_MUL(s0, s1, s2, a[10], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[13]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[10], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[10]);
z[9] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 26 */
MONT_SQR_MUL(s0, s1, s2, a[11], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[14]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[13], a[13]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[11]);
z[10] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 27 */
MONT_SQR_MUL(s0, s1, s2, a[12], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[14]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[12], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[12]);
z[11] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 28 */
MONT_SQR_MUL(s0, s1, s2, a[13], a[15]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[14], a[14]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[13]);
z[12] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 29 */
MONT_SQR_MUL(s0, s1, s2, a[14], a[15]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[14], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[14]);
z[13] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 30 */
MONT_SQR_MAC(t0, t1, t2, a[15], a[15]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[15]);
z[14] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
z[15] = t0;
/* under 2m, with t1 the bit above n limbs: at most one subtraction */
borrow = sub_n(r, z, m, 16);
take = t1 | (borrow ^ 1);
select_n(r, r, z, take & 1, 16);
}
/* r = a * a * R^-1 mod m, for a under m; t is 2n limbs of scratch */
static void crypton_mont_sqr24(limb_t *r, const limb_t *a, const limb_t *m,
limb_t n0, limb_t *t)
{
limb_t *u = t, *z = t + 24;
limb_t t0 = 0, t1 = 0, t2 = 0, s0, s1, s2, borrow, take;
/* column 0 */
MONT_SQR_MAC(t0, t1, t2, a[0], a[0]);
u[0] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[0], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 1 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[1]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[1]);
u[1] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[1], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 2 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[2]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[1], a[1]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[1]);
u[2] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[2], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 3 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[3]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[2]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[1]);
u[3] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[3], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 4 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[4]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[3]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[2], a[2]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[1]);
u[4] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[4], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 5 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[5]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[4]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[3]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[1]);
u[5] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[5], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 6 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[6]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[5]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[4]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[3], a[3]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[1]);
u[6] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[6], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 7 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[6]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[5]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[4]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[1]);
u[7] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[7], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 8 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[6]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[5]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[4], a[4]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[1]);
u[8] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[8], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 9 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[6]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[5]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[1]);
u[9] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[9], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 10 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[6]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[5], a[5]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[1]);
u[10] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[10], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 11 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[6]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[1]);
u[11] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[11], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 12 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[7]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[6], a[6]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[1]);
u[12] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[12], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 13 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[7]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[1]);
u[13] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[13], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 14 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[8]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[7], a[7]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[1]);
u[14] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[14], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 15 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[8]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[1]);
u[15] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[15], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 16 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[9]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[8], a[8]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[1]);
u[16] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[16], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 17 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[9]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[1]);
u[17] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[17], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 18 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[10]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[9], a[9]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[1]);
u[18] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[18], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 19 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[10]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[1]);
u[19] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[19], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 20 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[11]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[10], a[10]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[1]);
u[20] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[20], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 21 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[11]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[1]);
u[21] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[21], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 22 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[12]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[11], a[11]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[1]);
u[22] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[22], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 23 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[12]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[1]);
u[23] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[23], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 24 */
MONT_SQR_MUL(s0, s1, s2, a[1], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[13]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[12], a[12]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[1]);
z[0] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 25 */
MONT_SQR_MUL(s0, s1, s2, a[2], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[13]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[2], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[2]);
z[1] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 26 */
MONT_SQR_MUL(s0, s1, s2, a[3], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[14]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[13], a[13]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[3]);
z[2] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 27 */
MONT_SQR_MUL(s0, s1, s2, a[4], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[14]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[4], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[4]);
z[3] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 28 */
MONT_SQR_MUL(s0, s1, s2, a[5], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[15]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[14], a[14]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[5]);
z[4] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 29 */
MONT_SQR_MUL(s0, s1, s2, a[6], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[15]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[6], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[6]);
z[5] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 30 */
MONT_SQR_MUL(s0, s1, s2, a[7], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[16]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[15], a[15]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[7]);
z[6] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 31 */
MONT_SQR_MUL(s0, s1, s2, a[8], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[16]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[8], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[8]);
z[7] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 32 */
MONT_SQR_MUL(s0, s1, s2, a[9], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[17]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[16], a[16]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[9]);
z[8] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 33 */
MONT_SQR_MUL(s0, s1, s2, a[10], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[17]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[10], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[10]);
z[9] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 34 */
MONT_SQR_MUL(s0, s1, s2, a[11], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[18]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[17], a[17]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[11]);
z[10] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 35 */
MONT_SQR_MUL(s0, s1, s2, a[12], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[18]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[12], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[12]);
z[11] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 36 */
MONT_SQR_MUL(s0, s1, s2, a[13], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[19]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[18], a[18]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[13]);
z[12] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 37 */
MONT_SQR_MUL(s0, s1, s2, a[14], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[19]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[14], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[14]);
z[13] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 38 */
MONT_SQR_MUL(s0, s1, s2, a[15], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[20]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[19], a[19]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[15]);
z[14] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 39 */
MONT_SQR_MUL(s0, s1, s2, a[16], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[19], a[20]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[16], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[16]);
z[15] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 40 */
MONT_SQR_MUL(s0, s1, s2, a[17], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[19], a[21]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[20], a[20]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[17]);
z[16] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 41 */
MONT_SQR_MUL(s0, s1, s2, a[18], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[19], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[20], a[21]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[18], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[18]);
z[17] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 42 */
MONT_SQR_MUL(s0, s1, s2, a[19], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[20], a[22]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[21], a[21]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[19]);
z[18] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 43 */
MONT_SQR_MUL(s0, s1, s2, a[20], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[21], a[22]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[20], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[20]);
z[19] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 44 */
MONT_SQR_MUL(s0, s1, s2, a[21], a[23]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[22], a[22]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[21]);
z[20] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 45 */
MONT_SQR_MUL(s0, s1, s2, a[22], a[23]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[22], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[22]);
z[21] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 46 */
MONT_SQR_MAC(t0, t1, t2, a[23], a[23]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[23]);
z[22] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
z[23] = t0;
/* under 2m, with t1 the bit above n limbs: at most one subtraction */
borrow = sub_n(r, z, m, 24);
take = t1 | (borrow ^ 1);
select_n(r, r, z, take & 1, 24);
}
/* r = a * a * R^-1 mod m, for a under m; t is 2n limbs of scratch */
static void crypton_mont_sqr32(limb_t *r, const limb_t *a, const limb_t *m,
limb_t n0, limb_t *t)
{
limb_t *u = t, *z = t + 32;
limb_t t0 = 0, t1 = 0, t2 = 0, s0, s1, s2, borrow, take;
/* column 0 */
MONT_SQR_MAC(t0, t1, t2, a[0], a[0]);
u[0] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[0], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 1 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[1]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[1]);
u[1] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[1], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 2 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[2]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[1], a[1]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[1]);
u[2] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[2], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 3 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[3]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[2]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[1]);
u[3] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[3], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 4 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[4]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[3]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[2], a[2]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[1]);
u[4] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[4], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 5 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[5]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[4]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[3]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[1]);
u[5] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[5], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 6 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[6]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[5]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[4]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[3], a[3]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[1]);
u[6] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[6], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 7 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[6]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[5]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[4]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[1]);
u[7] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[7], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 8 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[6]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[5]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[4], a[4]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[1]);
u[8] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[8], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 9 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[6]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[5]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[1]);
u[9] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[9], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 10 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[6]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[5], a[5]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[1]);
u[10] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[10], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 11 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[7]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[6]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[1]);
u[11] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[11], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 12 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[7]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[6], a[6]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[1]);
u[12] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[12], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 13 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[8]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[7]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[1]);
u[13] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[13], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 14 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[8]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[7], a[7]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[1]);
u[14] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[14], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 15 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[9]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[8]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[1]);
u[15] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[15], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 16 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[9]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[8], a[8]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[1]);
u[16] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[16], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 17 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[10]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[9]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[1]);
u[17] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[17], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 18 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[10]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[9], a[9]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[1]);
u[18] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[18], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 19 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[11]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[10]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[1]);
u[19] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[19], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 20 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[11]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[10], a[10]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[1]);
u[20] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[20], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 21 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[12]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[11]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[1]);
u[21] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[21], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 22 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[12]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[11], a[11]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[1]);
u[22] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[22], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 23 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[13]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[12]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[1]);
u[23] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[23], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 24 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[13]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[12], a[12]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[1]);
u[24] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[24], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 25 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[14]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[13]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[1]);
u[25] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[25], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 26 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[14]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[13], a[13]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[1]);
u[26] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[26], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 27 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[15]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[14]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[1]);
u[27] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[27], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 28 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[15]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[14], a[14]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[1]);
u[28] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[28], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 29 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[16]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[15]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[1]);
u[29] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[29], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 30 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[16]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[15], a[15]);
MONT_SQR_MAC(t0, t1, t2, u[0], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[1]);
u[30] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[30], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 31 */
MONT_SQR_MUL(s0, s1, s2, a[0], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[1], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[17]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[16]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[0], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[1]);
u[31] = t0 * n0;
MONT_SQR_MAC(t0, t1, t2, u[31], m[0]);
t0 = t1;
t1 = t2;
t2 = 0;
/* column 32 */
MONT_SQR_MUL(s0, s1, s2, a[1], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[2], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[17]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[16], a[16]);
MONT_SQR_MAC(t0, t1, t2, u[1], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[2], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[2]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[1]);
z[0] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 33 */
MONT_SQR_MUL(s0, s1, s2, a[2], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[3], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[18]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[17]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[2], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[3]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[2]);
z[1] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 34 */
MONT_SQR_MUL(s0, s1, s2, a[3], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[4], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[18]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[17], a[17]);
MONT_SQR_MAC(t0, t1, t2, u[3], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[4], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[4]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[3]);
z[2] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 35 */
MONT_SQR_MUL(s0, s1, s2, a[4], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[5], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[19]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[18]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[4], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[5]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[4]);
z[3] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 36 */
MONT_SQR_MUL(s0, s1, s2, a[5], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[6], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[19]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[18], a[18]);
MONT_SQR_MAC(t0, t1, t2, u[5], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[6], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[6]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[5]);
z[4] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 37 */
MONT_SQR_MUL(s0, s1, s2, a[6], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[7], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[20]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[19]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[6], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[7]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[6]);
z[5] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 38 */
MONT_SQR_MUL(s0, s1, s2, a[7], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[8], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[20]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[19], a[19]);
MONT_SQR_MAC(t0, t1, t2, u[7], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[8], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[8]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[7]);
z[6] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 39 */
MONT_SQR_MUL(s0, s1, s2, a[8], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[9], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[21]);
MONT_SQR_MAC(s0, s1, s2, a[19], a[20]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[8], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[9]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[8]);
z[7] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 40 */
MONT_SQR_MUL(s0, s1, s2, a[9], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[10], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[19], a[21]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[20], a[20]);
MONT_SQR_MAC(t0, t1, t2, u[9], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[10], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[10]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[9]);
z[8] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 41 */
MONT_SQR_MUL(s0, s1, s2, a[10], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[11], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[19], a[22]);
MONT_SQR_MAC(s0, s1, s2, a[20], a[21]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[10], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[11]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[10]);
z[9] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 42 */
MONT_SQR_MUL(s0, s1, s2, a[11], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[12], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[19], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[20], a[22]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[21], a[21]);
MONT_SQR_MAC(t0, t1, t2, u[11], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[12], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[12]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[11]);
z[10] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 43 */
MONT_SQR_MUL(s0, s1, s2, a[12], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[13], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[19], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[20], a[23]);
MONT_SQR_MAC(s0, s1, s2, a[21], a[22]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[12], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[13]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[12]);
z[11] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 44 */
MONT_SQR_MUL(s0, s1, s2, a[13], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[14], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[19], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[20], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[21], a[23]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[22], a[22]);
MONT_SQR_MAC(t0, t1, t2, u[13], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[14], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[14]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[13]);
z[12] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 45 */
MONT_SQR_MUL(s0, s1, s2, a[14], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[15], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[19], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[20], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[21], a[24]);
MONT_SQR_MAC(s0, s1, s2, a[22], a[23]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[14], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[15]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[14]);
z[13] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 46 */
MONT_SQR_MUL(s0, s1, s2, a[15], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[16], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[19], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[20], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[21], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[22], a[24]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[23], a[23]);
MONT_SQR_MAC(t0, t1, t2, u[15], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[16], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[16]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[15]);
z[14] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 47 */
MONT_SQR_MUL(s0, s1, s2, a[16], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[17], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[19], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[20], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[21], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[22], a[25]);
MONT_SQR_MAC(s0, s1, s2, a[23], a[24]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[16], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[17]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[16]);
z[15] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 48 */
MONT_SQR_MUL(s0, s1, s2, a[17], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[18], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[19], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[20], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[21], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[22], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[23], a[25]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[24], a[24]);
MONT_SQR_MAC(t0, t1, t2, u[17], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[18], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[18]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[17]);
z[16] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 49 */
MONT_SQR_MUL(s0, s1, s2, a[18], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[19], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[20], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[21], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[22], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[23], a[26]);
MONT_SQR_MAC(s0, s1, s2, a[24], a[25]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[18], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[19]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[18]);
z[17] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 50 */
MONT_SQR_MUL(s0, s1, s2, a[19], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[20], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[21], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[22], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[23], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[24], a[26]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[25], a[25]);
MONT_SQR_MAC(t0, t1, t2, u[19], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[20], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[20]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[19]);
z[18] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 51 */
MONT_SQR_MUL(s0, s1, s2, a[20], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[21], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[22], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[23], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[24], a[27]);
MONT_SQR_MAC(s0, s1, s2, a[25], a[26]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[20], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[21]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[20]);
z[19] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 52 */
MONT_SQR_MUL(s0, s1, s2, a[21], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[22], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[23], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[24], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[25], a[27]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[26], a[26]);
MONT_SQR_MAC(t0, t1, t2, u[21], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[22], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[22]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[21]);
z[20] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 53 */
MONT_SQR_MUL(s0, s1, s2, a[22], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[23], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[24], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[25], a[28]);
MONT_SQR_MAC(s0, s1, s2, a[26], a[27]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[22], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[23]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[22]);
z[21] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 54 */
MONT_SQR_MUL(s0, s1, s2, a[23], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[24], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[25], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[26], a[28]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[27], a[27]);
MONT_SQR_MAC(t0, t1, t2, u[23], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[24], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[24]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[23]);
z[22] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 55 */
MONT_SQR_MUL(s0, s1, s2, a[24], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[25], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[26], a[29]);
MONT_SQR_MAC(s0, s1, s2, a[27], a[28]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[24], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[25]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[24]);
z[23] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 56 */
MONT_SQR_MUL(s0, s1, s2, a[25], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[26], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[27], a[29]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[28], a[28]);
MONT_SQR_MAC(t0, t1, t2, u[25], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[26], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[26]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[25]);
z[24] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 57 */
MONT_SQR_MUL(s0, s1, s2, a[26], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[27], a[30]);
MONT_SQR_MAC(s0, s1, s2, a[28], a[29]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[26], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[27]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[26]);
z[25] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 58 */
MONT_SQR_MUL(s0, s1, s2, a[27], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[28], a[30]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[29], a[29]);
MONT_SQR_MAC(t0, t1, t2, u[27], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[28], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[28]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[27]);
z[26] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 59 */
MONT_SQR_MUL(s0, s1, s2, a[28], a[31]);
MONT_SQR_MAC(s0, s1, s2, a[29], a[30]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[28], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[29]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[28]);
z[27] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 60 */
MONT_SQR_MUL(s0, s1, s2, a[29], a[31]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, a[30], a[30]);
MONT_SQR_MAC(t0, t1, t2, u[29], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[30], m[30]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[29]);
z[28] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 61 */
MONT_SQR_MUL(s0, s1, s2, a[30], a[31]);
MONT_SQR_ADD2(t0, t1, t2, s0, s1, s2);
MONT_SQR_MAC(t0, t1, t2, u[30], m[31]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[30]);
z[29] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
/* column 62 */
MONT_SQR_MAC(t0, t1, t2, a[31], a[31]);
MONT_SQR_MAC(t0, t1, t2, u[31], m[31]);
z[30] = t0;
t0 = t1;
t1 = t2;
t2 = 0;
z[31] = t0;
/* under 2m, with t1 the bit above n limbs: at most one subtraction */
borrow = sub_n(r, z, m, 32);
take = t1 | (borrow ^ 1);
select_n(r, r, z, take & 1, 32);
}
#endif