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.
 
 
 
 
 

254 lines
5.3 KiB

  1. /**
  2. * @file field.h
  3. * @brief Generic field header.
  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. */
  9. #ifndef __FIELD_H__
  10. #define __FIELD_H__
  11. #include "constant_time.h"
  12. #include "f_field.h"
  13. #include <string.h>
  14. #define is32 (GOLDI_BITS == 32 || FIELD_BITS != 448)
  15. #if (is32)
  16. #define IF32(s) (s)
  17. #else
  18. #define IF32(s)
  19. #endif
  20. /** @brief Bytes in a field element */
  21. #define FIELD_BYTES (1+(FIELD_BITS-1)/8)
  22. /** @brief Words in a field element */
  23. #define FIELD_WORDS (1+(FIELD_BITS-1)/sizeof(word_t))
  24. /* TODO: standardize notation */
  25. /** @brief The number of words in the Goldilocks field. */
  26. #define GOLDI_FIELD_WORDS DIV_CEIL(FIELD_BITS,WORD_BITS)
  27. /** @brief The number of bits in the Goldilocks curve's cofactor (cofactor=4). */
  28. #define COFACTOR_BITS 2
  29. /** @brief The number of bits in a Goldilocks scalar. */
  30. #define SCALAR_BITS (FIELD_BITS - COFACTOR_BITS)
  31. /** @brief The number of bytes in a Goldilocks scalar. */
  32. #define SCALAR_BYTES (1+(SCALAR_BITS)/8)
  33. /** @brief The number of words in the Goldilocks field. */
  34. #define SCALAR_WORDS WORDS_FOR_BITS(SCALAR_BITS)
  35. /**
  36. * @brief For GMP tests: little-endian representation of the field modulus.
  37. */
  38. extern const uint8_t FIELD_MODULUS[FIELD_BYTES];
  39. /**
  40. * Copy one field element to another.
  41. */
  42. static inline void
  43. __attribute__((unused,always_inline))
  44. field_copy (
  45. struct field_t *__restrict__ a,
  46. const struct field_t *__restrict__ b
  47. ) {
  48. memcpy(a,b,sizeof(*a));
  49. }
  50. /**
  51. * Returns 1/sqrt(+- x).
  52. *
  53. * The Legendre symbol of the result is the same as that of the
  54. * input.
  55. *
  56. * If x=0, returns 0.
  57. */
  58. void
  59. field_isr (
  60. struct field_t* a,
  61. const struct field_t* x
  62. );
  63. /**
  64. * Batch inverts out[i] = 1/in[i]
  65. *
  66. * If any input is zero, all the outputs will be zero.
  67. */
  68. void
  69. field_simultaneous_invert (
  70. struct field_t *__restrict__ out,
  71. const struct field_t *in,
  72. unsigned int n
  73. );
  74. /**
  75. * Returns 1/x.
  76. *
  77. * If x=0, returns 0.
  78. */
  79. void
  80. field_inverse (
  81. struct field_t* a,
  82. const struct field_t* x
  83. );
  84. /**
  85. * Returns -1 if a==b, 0 otherwise.
  86. */
  87. mask_t
  88. field_eq (
  89. const struct field_t *a,
  90. const struct field_t *b
  91. );
  92. /**
  93. * Square x, n times.
  94. */
  95. static __inline__ void
  96. __attribute__((unused,always_inline))
  97. field_sqrn (
  98. field_t *__restrict__ y,
  99. const field_t *x,
  100. int n
  101. ) {
  102. field_t tmp;
  103. assert(n>0);
  104. if (n&1) {
  105. field_sqr(y,x);
  106. n--;
  107. } else {
  108. field_sqr(&tmp,x);
  109. field_sqr(y,&tmp);
  110. n-=2;
  111. }
  112. for (; n; n-=2) {
  113. field_sqr(&tmp,y);
  114. field_sqr(y,&tmp);
  115. }
  116. }
  117. static __inline__ mask_t
  118. __attribute__((unused,always_inline))
  119. field_low_bit (const struct field_t *f) {
  120. struct field_t red;
  121. field_copy(&red,f);
  122. field_strong_reduce(&red);
  123. return -(1&red.limb[0]);
  124. }
  125. static __inline__ mask_t
  126. __attribute__((unused,always_inline))
  127. field_make_nonzero (struct field_t *f) {
  128. mask_t z = field_is_zero(f);
  129. field_addw( f, -z );
  130. return z;
  131. }
  132. /* Multiply by signed curve constant */
  133. static __inline__ void
  134. field_mulw_scc (
  135. struct field_t* __restrict__ out,
  136. const struct field_t *a,
  137. int64_t scc
  138. ) {
  139. if (scc >= 0) {
  140. field_mulw(out, a, scc);
  141. } else {
  142. field_mulw(out, a, -scc);
  143. field_neg_RAW(out,out);
  144. field_bias(out,2);
  145. }
  146. }
  147. /* Multiply by signed curve constant and weak reduce if biased */
  148. static __inline__ void
  149. field_mulw_scc_wr (
  150. struct field_t* __restrict__ out,
  151. const struct field_t *a,
  152. int64_t scc
  153. ) {
  154. field_mulw_scc(out, a, scc);
  155. if (scc < 0)
  156. field_weak_reduce(out);
  157. }
  158. static __inline__ void
  159. field_subx_RAW (
  160. struct field_t *d,
  161. const struct field_t *a,
  162. const struct field_t *b
  163. ) {
  164. field_sub_RAW ( d, a, b );
  165. field_bias( d, 2 );
  166. IF32( field_weak_reduce ( d ) );
  167. }
  168. static __inline__ void
  169. field_sub (
  170. struct field_t *d,
  171. const struct field_t *a,
  172. const struct field_t *b
  173. ) {
  174. field_sub_RAW ( d, a, b );
  175. field_bias( d, 2 );
  176. field_weak_reduce ( d );
  177. }
  178. static __inline__ void
  179. field_add (
  180. struct field_t *d,
  181. const struct field_t *a,
  182. const struct field_t *b
  183. ) {
  184. field_add_RAW ( d, a, b );
  185. field_weak_reduce ( d );
  186. }
  187. static __inline__ void
  188. field_subw (
  189. struct field_t *d,
  190. word_t c
  191. ) {
  192. field_subw_RAW ( d, c );
  193. field_bias( d, 1 );
  194. field_weak_reduce ( d );
  195. }
  196. static __inline__ void
  197. field_negx (
  198. struct field_t *d,
  199. const struct field_t *a
  200. ) {
  201. field_neg_RAW ( d, a );
  202. field_bias( d, 2 );
  203. field_weak_reduce ( d );
  204. }
  205. /**
  206. * Negate a in place if doNegate.
  207. */
  208. static inline void
  209. __attribute__((unused,always_inline))
  210. field_cond_neg (
  211. field_t *a,
  212. mask_t doNegate
  213. ) {
  214. struct field_t negated;
  215. field_negx(&negated, a);
  216. constant_time_select(a, &negated, a, sizeof(negated), doNegate);
  217. }
  218. /** Require the warning annotation on raw routines */
  219. #define ANALYZE_THIS_ROUTINE_CAREFULLY const int ANNOTATE___ANALYZE_THIS_ROUTINE_CAREFULLY = 0;
  220. #define MUST_BE_CAREFUL (void) ANNOTATE___ANALYZE_THIS_ROUTINE_CAREFULLY
  221. #define field_add_nr(a,b,c) { MUST_BE_CAREFUL; field_add_RAW(a,b,c); }
  222. #define field_sub_nr(a,b,c) { MUST_BE_CAREFUL; field_sub_RAW(a,b,c); }
  223. #define field_subx_nr(a,b,c) { MUST_BE_CAREFUL; field_subx_RAW(a,b,c); }
  224. #endif // __FIELD_H__