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.
 
 
 
 
 

248 lines
3.9 KiB

  1. /* Copyright (c) 2014 Cryptography Research, Inc.
  2. * Released under the MIT License. See LICENSE.txt for license information.
  3. */
  4. #ifndef __P521_H__
  5. #define __P521_H__ 1
  6. #include <stdint.h>
  7. #include <assert.h>
  8. #include <string.h>
  9. #include "word.h"
  10. #define LIMBPERM(x) (((x)%3)*3 + (x)/3)
  11. #define USE_P521_3x3_TRANSPOSE
  12. typedef struct p521_t {
  13. uint64_t limb[9];
  14. } p521_t;
  15. #ifdef __cplusplus
  16. extern "C" {
  17. #endif
  18. static __inline__ void
  19. p521_set_ui (
  20. p521_t *out,
  21. uint64_t x
  22. ) __attribute__((unused));
  23. static __inline__ void
  24. p521_add (
  25. p521_t *out,
  26. const p521_t *a,
  27. const p521_t *b
  28. ) __attribute__((unused));
  29. static __inline__ void
  30. p521_sub (
  31. p521_t *out,
  32. const p521_t *a,
  33. const p521_t *b
  34. ) __attribute__((unused));
  35. static __inline__ void
  36. p521_neg (
  37. p521_t *out,
  38. const p521_t *a
  39. ) __attribute__((unused));
  40. static __inline__ void
  41. p521_addw (
  42. p521_t *a,
  43. uint64_t x
  44. ) __attribute__((unused));
  45. static __inline__ void
  46. p521_subw (
  47. p521_t *a,
  48. uint64_t x
  49. ) __attribute__((unused));
  50. static __inline__ void
  51. p521_copy (
  52. p521_t *out,
  53. const p521_t *a
  54. ) __attribute__((unused));
  55. static __inline__ void
  56. p521_weak_reduce (
  57. p521_t *inout
  58. ) __attribute__((unused));
  59. void
  60. p521_strong_reduce (
  61. p521_t *inout
  62. );
  63. mask_t
  64. p521_is_zero (
  65. const p521_t *in
  66. );
  67. static __inline__ void
  68. p521_bias (
  69. p521_t *inout,
  70. int amount
  71. ) __attribute__((unused));
  72. static __inline__ void
  73. p521_really_bias (
  74. p521_t *inout,
  75. int amount
  76. ) __attribute__((unused));
  77. void
  78. p521_mul (
  79. p521_t *__restrict__ out,
  80. const p521_t *a,
  81. const p521_t *b
  82. );
  83. void
  84. p521_mulw (
  85. p521_t *__restrict__ out,
  86. const p521_t *a,
  87. uint64_t b
  88. );
  89. void
  90. p521_sqr (
  91. p521_t *__restrict__ out,
  92. const p521_t *a
  93. );
  94. void
  95. p521_serialize (
  96. uint8_t *serial,
  97. const struct p521_t *x
  98. );
  99. mask_t
  100. p521_deserialize (
  101. p521_t *x,
  102. const uint8_t serial[66]
  103. );
  104. /* -------------- Inline functions begin here -------------- */
  105. void
  106. p521_set_ui (
  107. p521_t *out,
  108. uint64_t x
  109. ) {
  110. int i;
  111. out->limb[0] = x;
  112. for (i=1; i<9; i++) {
  113. out->limb[i] = 0;
  114. }
  115. }
  116. void
  117. p521_add (
  118. p521_t *out,
  119. const p521_t *a,
  120. const p521_t *b
  121. ) {
  122. unsigned int i;
  123. for (i=0; i<9; i++) {
  124. out->limb[i] = a->limb[i] + b->limb[i];
  125. }
  126. p521_weak_reduce(out);
  127. }
  128. void
  129. p521_sub (
  130. p521_t *out,
  131. const p521_t *a,
  132. const p521_t *b
  133. ) {
  134. unsigned int i;
  135. uint64_t co1 = ((1ull<<58)-1)*4, co2 = ((1ull<<57)-1)*4;
  136. for (i=0; i<9; i++) {
  137. out->limb[i] = a->limb[i] - b->limb[i] + ((i==8) ? co2 : co1);
  138. }
  139. p521_weak_reduce(out);
  140. }
  141. void
  142. p521_neg (
  143. struct p521_t *out,
  144. const p521_t *a
  145. ) {
  146. unsigned int i;
  147. uint64_t co1 = ((1ull<<58)-1)*4, co2 = ((1ull<<57)-1)*4;
  148. for (i=0; i<9; i++) {
  149. out->limb[i] = ((i==8) ? co2 : co1) - a->limb[i];
  150. }
  151. p521_weak_reduce(out);
  152. }
  153. void
  154. p521_addw (
  155. p521_t *a,
  156. uint64_t x
  157. ) {
  158. a->limb[0] += x;
  159. a->limb[LIMBPERM(1)] += a->limb[0]>>58;
  160. a->limb[0] &= (1ull<<58)-1;
  161. }
  162. void
  163. p521_subw (
  164. p521_t *a,
  165. uint64_t x
  166. ) {
  167. a->limb[0] -= x;
  168. p521_really_bias(a, 1);
  169. p521_weak_reduce(a);
  170. }
  171. void
  172. p521_copy (
  173. p521_t *out,
  174. const p521_t *a
  175. ) {
  176. memcpy(out,a,sizeof(*a));
  177. }
  178. void
  179. p521_really_bias (
  180. p521_t *a,
  181. int amt
  182. ) {
  183. uint64_t co1 = ((1ull<<58)-1)*2*amt, co2 = ((1ull<<57)-1)*2*amt;
  184. int i;
  185. for (i=0; i<9; i++) {
  186. a->limb[i] += (i==8) ? co2 : co1;
  187. }
  188. }
  189. void
  190. p521_bias (
  191. p521_t *a,
  192. int amt
  193. ) {
  194. (void) a;
  195. (void) amt;
  196. }
  197. void
  198. p521_weak_reduce (
  199. p521_t *a
  200. ) {
  201. uint64_t mask = (1ull<<58) - 1;
  202. uint64_t tmp = a->limb[8] >> 57;
  203. int i;
  204. for (i=8; i>0; i--) {
  205. a->limb[LIMBPERM(i)] = (a->limb[LIMBPERM(i)] & ((i==8) ? mask>>1 : mask)) + (a->limb[LIMBPERM(i-1)]>>58);
  206. }
  207. a->limb[0] = (a->limb[0] & mask) + tmp;
  208. }
  209. #ifdef __cplusplus
  210. }; /* extern "C" */
  211. #endif
  212. #endif /* __P521_H__ */