in FourQ_ARM/crypto_util.c [46:127]
ECCRYPTO_STATUS decode(const unsigned char* Pencoded, point_t P)
{ // Decode point P
// SECURITY NOTE: this function does not run in constant time.
felm_t r, t, t0, t1, t2, t3, t4;
f2elm_t u, v, one = {0};
digit_t sign_dec;
point_extproj_t R;
unsigned int i, sign;
one[0][0] = 1;
memmove((unsigned char*)P->y, Pencoded, 32); // Decoding y-coordinate and sign
sign = (unsigned int)(Pencoded[31] >> 7);
P->y[1][NWORDS_FIELD-1] &= mask7fff;
fp2sqr1271(P->y, u);
fp2mul1271(u, (felm_t*)&PARAMETER_d, v);
fp2sub1271(u, one, u);
fp2add1271(v, one, v);
fpsqr1271(v[0], t0); // t0 = v0^2
fpsqr1271(v[1], t1); // t1 = v1^2
fpadd1271(t0, t1, t0); // t0 = t0+t1
fpmul1271(u[0], v[0], t1); // t1 = u0*v0
fpmul1271(u[1], v[1], t2); // t2 = u1*v1
fpadd1271(t1, t2, t1); // t1 = t1+t2
fpmul1271(u[1], v[0], t2); // t2 = u1*v0
fpmul1271(u[0], v[1], t3); // t3 = u0*v1
fpsub1271(t2, t3, t2); // t2 = t2-t3
fpsqr1271(t1, t3); // t3 = t1^2
fpsqr1271(t2, t4); // t4 = t2^2
fpadd1271(t3, t4, t3); // t3 = t3+t4
for (i = 0; i < 125; i++) { // t3 = t3^(2^125)
fpsqr1271(t3, t3);
}
fpadd1271(t1, t3, t); // t = t1+t3
mod1271(t);
if (is_zero_ct(t, NWORDS_FIELD) == true) {
fpsub1271(t1, t3, t); // t = t1-t3
}
fpadd1271(t, t, t); // t = 2*t
fpsqr1271(t0, t3); // t3 = t0^2
fpmul1271(t0, t3, t3); // t3 = t3*t0
fpmul1271(t, t3, t3); // t3 = t3*t
fpexp1251(t3, r); // r = t3^(2^125-1)
fpmul1271(t0, r, t3); // t3 = t0*r
fpmul1271(t, t3, P->x[0]); // x0 = t*t3
fpsqr1271(P->x[0], t1);
fpmul1271(t0, t1, t1); // t1 = t0*x0^2
fpdiv1271(P->x[0]); // x0 = x0/2
fpmul1271(t2, t3, P->x[1]); // x1 = t3*t2
fpsub1271(t, t1, t);
mod1271(t);
if (is_zero_ct(t, NWORDS_FIELD) == false) { // If t != t1 then swap x0 and x1
fpcopy1271(P->x[0], t0);
fpcopy1271(P->x[1], P->x[0]);
fpcopy1271(t0, P->x[1]);
}
mod1271(P->x[0]);
if (is_zero_ct((digit_t*)P->x, NWORDS_FIELD) == true) {
sign_dec = ((digit_t*)&P->x[1])[NWORDS_FIELD-1] >> (sizeof(digit_t)*8 - 2);
} else {
sign_dec = ((digit_t*)&P->x[0])[NWORDS_FIELD-1] >> (sizeof(digit_t)*8 - 2);
}
if (sign != (unsigned int)sign_dec) { // If sign of x-coordinate decoded != input sign bit, then negate x-coordinate
fp2neg1271(P->x);
}
point_setup(P, R);
if (ecc_point_validate(R) == false) {
fpneg1271(R->x[1]);
fpcopy1271(R->x[1], P->x[1]);
if (ecc_point_validate(R) == false) { // Final point validation
return ECCRYPTO_ERROR;
}
}
return ECCRYPTO_SUCCESS;
}