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.
 
 
 
 
 

45 lines
1.3 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 SQRT_MINUS_ONE = {FIELD_LITERAL(
  13. 0x61b274a0ea0b0,
  14. 0x0d5a5fc8f189d,
  15. 0x7ef5e9cbd0c60,
  16. 0x78595a6804c9e,
  17. 0x2b8324804fc1d
  18. )};
  19. const gf MODULUS = {FIELD_LITERAL(
  20. 0x7ffffffffffed, 0x7ffffffffffff, 0x7ffffffffffff, 0x7ffffffffffff, 0x7ffffffffffff
  21. )};
  22. /* Guarantee: a^2 x = 0 if x = 0; else a^2 x = 1 or SQRT_MINUS_ONE; */
  23. void gf_isr (gf a, const gf x) {
  24. gf st[3], tmp1, tmp2;
  25. const struct { unsigned char sh, idx; } ops[] = {
  26. {1,2},{1,2},{3,1},{6,0},{1,2},{12,1},{25,1},{25,1},{50,0},{125,0},{2,2},{1,2}
  27. };
  28. st[0][0] = st[1][0] = st[2][0] = x[0];
  29. unsigned int i;
  30. for (i=0; i<sizeof(ops)/sizeof(ops[0]); i++) {
  31. gf_sqrn(tmp1, st[1^(i&1)], ops[i].sh);
  32. gf_mul(tmp2, tmp1, st[ops[i].idx]);
  33. st[i&1][0] = tmp2[0];
  34. }
  35. mask_t mask = gf_eq(st[1],ONE) | gf_eq(st[1],SQRT_MINUS_ONE);
  36. constant_time_select(tmp1, SQRT_MINUS_ONE, ONE, sizeof(tmp1), mask, 0);
  37. gf_mul(a,tmp1,st[0]);
  38. }