/* A helpful wrapper around fproduct: output = in * in2. * * output must be distinct to both inputs. The output is reduced degree and * reduced coefficient. */ void fmul(felem *output, const felem *in, const felem *in2) { felem t[19]; fproduct(t, in, in2); freduce_degree(t); freduce_coefficients(t); memcpy(output, t, sizeof(felem) * 10); }
void fsquare(felem *output, const felem *in) { felem t[19]; fsquare_inner(t, in); freduce_degree(t); freduce_coefficients(t); memcpy(output, t, sizeof(felem) * 10); }
/* Input: Q, Q', Q-Q' * Output: 2Q, Q+Q' * * x2 z3: long form * x3 z3: long form * x z: short form, destroyed * xprime zprime: short form, destroyed * qmqp: short form, preserved */ void fmonty(felem *x2, felem *z2, /* output 2Q */ felem *x3, felem *z3, /* output Q + Q' */ felem *x, felem *z, /* input Q */ felem *xprime, felem *zprime, /* input Q' */ const felem *qmqp /* input Q - Q' */) { felem origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19], zzprime[19], zzzprime[19], xxxprime[19]; memcpy(origx, x, 10 * sizeof(felem)); fsum(x, z); fdifference(z, origx); /* does x - z */ memcpy(origxprime, xprime, sizeof(felem) * 10); fsum(xprime, zprime); fdifference(zprime, origxprime); fproduct(xxprime, xprime, z); fproduct(zzprime, x, zprime); freduce_degree(xxprime); freduce_coefficients(xxprime); freduce_degree(zzprime); freduce_coefficients(zzprime); memcpy(origxprime, xxprime, sizeof(felem) * 10); fsum(xxprime, zzprime); fdifference(zzprime, origxprime); fsquare(xxxprime, xxprime); fsquare(zzzprime, zzprime); fproduct(zzprime, zzzprime, qmqp); freduce_degree(zzprime); freduce_coefficients(zzprime); memcpy(x3, xxxprime, sizeof(felem) * 10); memcpy(z3, zzprime, sizeof(felem) * 10); fsquare(xx, x); fsquare(zz, z); fproduct(x2, xx, zz); freduce_degree(x2); freduce_coefficients(x2); fdifference(zz, xx); /* does zz = xx - zz */ memset(zzz + 10, 0, sizeof(felem) * 9); fscalar_product(zzz, zz, 121665); freduce_degree(zzz); freduce_coefficients(zzz); fsum(zzz, xx); fproduct(z2, zz, zzz); freduce_degree(z2); freduce_coefficients(z2); }
fmonty(felem *x2, /* output 2Q */ felem *x3, /* output Q + Q' */ felem *x, /* input Q */ felem *xprime, /* input Q' */ const felem *qmqp /* input Q - Q' */) { felem *const z2 = &x2[5]; felem *const z3 = &x3[5]; felem *const z = &x[5]; felem *const zprime = &xprime[5]; felem origx[5], origxprime[5], zzz[5], xx[5], zz[5], xxprime[5], zzprime[5], zzzprime[5]; memcpy(origx, x, 5 * sizeof(felem)); fsum(x, z); fdifference_backwards(z, origx); // does x - z memcpy(origxprime, xprime, sizeof(felem) * 5); fsum(xprime, zprime); fdifference_backwards(zprime, origxprime); fmul(xxprime, xprime, z); fmul(zzprime, x, zprime); memcpy(origxprime, xxprime, sizeof(felem) * 5); fsum(xxprime, zzprime); fdifference_backwards(zzprime, origxprime); fsquare(x3, xxprime); fsquare(zzzprime, zzprime); fmul(z3, zzzprime, qmqp); fsquare(xx, x); fsquare(zz, z); fmul(x2, xx, zz); fdifference_backwards(zz, xx); // does zz = xx - zz fscalar(zzz, zz); // * 121665 freduce_coefficients(zzz); fsum(zzz, xx); fmul(z2, zz, zzz); }