You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

49 lines
1.4 KiB

  1. /**
  2. * @cond internal
  3. * @file f_arithmetic.c
  4. * @copyright
  5. * Copyright (c) 2014 Cryptography Research, Inc. \n
  6. * Released under the MIT License. See LICENSE.txt for license information.
  7. * @author Mike Hamburg
  8. * @brief Field-specific arithmetic.
  9. */
  10. #include "field.h"
  11. #include "constant_time.h"
  12. const gf_25519_t P25519_SQRT_MINUS_ONE = {FIELD_LITERAL(
  13. 0x61b274a0ea0b0,
  14. 0x0d5a5fc8f189d,
  15. 0x7ef5e9cbd0c60,
  16. 0x78595a6804c9e,
  17. 0x2b8324804fc1d
  18. )};
  19. /* TODO put in header */
  20. extern const gf_25519_t decaf_255_ONE;
  21. extern mask_t decaf_255_gf_eq(const gf_25519_t a, const gf_25519_t b);
  22. /* Guarantee: a^2 x = 0 if x = 0; else a^2 x = 1 or SQRT_MINUS_ONE; */
  23. void
  24. gf_isr (
  25. gf_25519_t a,
  26. const gf_25519_t x
  27. ) {
  28. gf_25519_t st[3], tmp1, tmp2;
  29. const struct { unsigned char sh, idx; } ops[] = {
  30. {1,2},{1,2},{3,1},{6,0},{1,2},{12,1},{25,1},{25,1},{50,0},{125,0},{2,2},{1,2}
  31. };
  32. st[0][0] = st[1][0] = st[2][0] = x[0];
  33. unsigned int i;
  34. for (i=0; i<sizeof(ops)/sizeof(ops[0]); i++) {
  35. gf_sqrn(tmp1, st[1^(i&1)], ops[i].sh);
  36. gf_mul(tmp2, tmp1, st[ops[i].idx]);
  37. st[i&1][0] = tmp2[0];
  38. }
  39. mask_t mask = decaf_255_gf_eq(st[1],decaf_255_ONE) | decaf_255_gf_eq(st[1],SQRT_MINUS_ONE);
  40. constant_time_select(tmp1, decaf_255_ONE, SQRT_MINUS_ONE, sizeof(tmp1), mask, 0);
  41. gf_mul(a,tmp1,st[0]);
  42. }