ge25519_unpackneg.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. #include "fe25519.h"
  2. #include "ge25519.h"
  3. /* d */
  4. static const fe25519 ecd = {{0x75EB4DCA135978A3, 0x00700A4D4141D8AB, 0x8CC740797779E898, 0x52036CEE2B6FFE73}};
  5. /* sqrt(-1) */
  6. static const fe25519 sqrtm1 = {{0xC4EE1B274A0EA0B0, 0x2F431806AD2FE478, 0x2B4D00993DFBD7A7, 0x2B8324804FC1DF0B}};
  7. /* return 0 on success, -1 otherwise */
  8. int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32])
  9. {
  10. fe25519 t, chk, num, den, den2, den4, den6;
  11. unsigned char par = p[31] >> 7;
  12. fe25519_setint(&r->z,1);
  13. fe25519_unpack(&r->y, p);
  14. fe25519_square(&num, &r->y); /* x = y^2 */
  15. fe25519_mul(&den, &num, &ecd); /* den = dy^2 */
  16. fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */
  17. fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */
  18. /* Computation of sqrt(num/den)
  19. 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8)
  20. */
  21. fe25519_square(&den2, &den);
  22. fe25519_square(&den4, &den2);
  23. fe25519_mul(&den6, &den4, &den2);
  24. fe25519_mul(&t, &den6, &num);
  25. fe25519_mul(&t, &t, &den);
  26. fe25519_pow2523(&t, &t);
  27. /* 2. computation of r->x = t * num * den^3
  28. */
  29. fe25519_mul(&t, &t, &num);
  30. fe25519_mul(&t, &t, &den);
  31. fe25519_mul(&t, &t, &den);
  32. fe25519_mul(&r->x, &t, &den);
  33. /* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not:
  34. */
  35. fe25519_square(&chk, &r->x);
  36. fe25519_mul(&chk, &chk, &den);
  37. if (!fe25519_iseq_vartime(&chk, &num))
  38. fe25519_mul(&r->x, &r->x, &sqrtm1);
  39. /* 4. Now we have one of the two square roots, except if input was not a square
  40. */
  41. fe25519_square(&chk, &r->x);
  42. fe25519_mul(&chk, &chk, &den);
  43. if (!fe25519_iseq_vartime(&chk, &num))
  44. return -1;
  45. /* 5. Choose the desired square root according to parity:
  46. */
  47. if(fe25519_getparity(&r->x) != (1-par))
  48. fe25519_neg(&r->x, &r->x);
  49. fe25519_mul(&r->t, &r->x, &r->y);
  50. return 0;
  51. }