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.
 
 
 
 
 

288 lines
5.1 KiB

  1. /* Copyright (c) 2014 Cryptography Research, Inc.
  2. * Released under the MIT License. See LICENSE.txt for license information.
  3. */
  4. #ifndef __P448_H__
  5. #define __P448_H__ 1
  6. #include "word.h"
  7. #include <stdint.h>
  8. #include <assert.h>
  9. typedef struct p448_t {
  10. uint32_t limb[16];
  11. } __attribute__((aligned(32))) p448_t;
  12. #ifdef __cplusplus
  13. extern "C" {
  14. #endif
  15. static __inline__ void
  16. p448_set_ui (
  17. p448_t *out,
  18. uint64_t x
  19. ) __attribute__((unused,always_inline));
  20. static __inline__ void
  21. p448_add (
  22. p448_t *out,
  23. const p448_t *a,
  24. const p448_t *b
  25. ) __attribute__((unused,always_inline));
  26. static __inline__ void
  27. p448_sub (
  28. p448_t *out,
  29. const p448_t *a,
  30. const p448_t *b
  31. ) __attribute__((unused,always_inline));
  32. static __inline__ void
  33. p448_neg (
  34. p448_t *out,
  35. const p448_t *a
  36. ) __attribute__((unused,always_inline));
  37. static __inline__ void
  38. p448_cond_neg (
  39. p448_t *a,
  40. mask_t doNegate
  41. ) __attribute__((unused,always_inline));
  42. static __inline__ void
  43. p448_addw (
  44. p448_t *a,
  45. uint32_t x
  46. ) __attribute__((unused,always_inline));
  47. static __inline__ void
  48. p448_subw (
  49. p448_t *a,
  50. uint32_t x
  51. ) __attribute__((unused,always_inline));
  52. static __inline__ void
  53. p448_copy (
  54. p448_t *out,
  55. const p448_t *a
  56. ) __attribute__((unused,always_inline));
  57. static __inline__ void
  58. p448_weak_reduce (
  59. p448_t *inout
  60. ) __attribute__((unused,always_inline));
  61. void
  62. p448_strong_reduce (
  63. p448_t *inout
  64. );
  65. mask_t
  66. p448_is_zero (
  67. const p448_t *in
  68. );
  69. static __inline__ void
  70. p448_bias (
  71. p448_t *inout,
  72. int amount
  73. ) __attribute__((unused,always_inline));
  74. void
  75. p448_mul (
  76. p448_t *__restrict__ out,
  77. const p448_t *a,
  78. const p448_t *b
  79. );
  80. void
  81. p448_mulw (
  82. p448_t *__restrict__ out,
  83. const p448_t *a,
  84. uint64_t b
  85. );
  86. void
  87. p448_sqr (
  88. p448_t *__restrict__ out,
  89. const p448_t *a
  90. );
  91. void
  92. p448_serialize (
  93. uint8_t *serial,
  94. const struct p448_t *x
  95. );
  96. mask_t
  97. p448_deserialize (
  98. p448_t *x,
  99. const uint8_t serial[56]
  100. );
  101. static inline mask_t
  102. p448_eq (
  103. const struct p448_t *a,
  104. const struct p448_t *b
  105. ) __attribute__((always_inline,unused));
  106. /* -------------- Inline functions begin here -------------- */
  107. void
  108. p448_set_ui (
  109. p448_t *out,
  110. uint64_t x
  111. ) {
  112. int i;
  113. out->limb[0] = x & ((1<<28)-1);
  114. out->limb[1] = x>>28;
  115. for (i=2; i<16; i++) {
  116. out->limb[i] = 0;
  117. }
  118. }
  119. void
  120. p448_add (
  121. p448_t *out,
  122. const p448_t *a,
  123. const p448_t *b
  124. ) {
  125. unsigned int i;
  126. for (i=0; i<sizeof(*out)/sizeof(uint32xn_t); i++) {
  127. ((uint32xn_t*)out)[i] = ((const uint32xn_t*)a)[i] + ((const uint32xn_t*)b)[i];
  128. }
  129. /*
  130. unsigned int i;
  131. for (i=0; i<sizeof(*out)/sizeof(out->limb[0]); i++) {
  132. out->limb[i] = a->limb[i] + b->limb[i];
  133. }
  134. */
  135. }
  136. void
  137. p448_sub (
  138. p448_t *out,
  139. const p448_t *a,
  140. const p448_t *b
  141. ) {
  142. unsigned int i;
  143. for (i=0; i<sizeof(*out)/sizeof(uint32xn_t); i++) {
  144. ((uint32xn_t*)out)[i] = ((const uint32xn_t*)a)[i] - ((const uint32xn_t*)b)[i];
  145. }
  146. /*
  147. unsigned int i;
  148. for (i=0; i<sizeof(*out)/sizeof(out->limb[0]); i++) {
  149. out->limb[i] = a->limb[i] - b->limb[i];
  150. }
  151. */
  152. }
  153. void
  154. p448_neg (
  155. p448_t *out,
  156. const p448_t *a
  157. ) {
  158. unsigned int i;
  159. for (i=0; i<sizeof(*out)/sizeof(uint32xn_t); i++) {
  160. ((uint32xn_t*)out)[i] = -((const uint32xn_t*)a)[i];
  161. }
  162. /*
  163. unsigned int i;
  164. for (i=0; i<sizeof(*out)/sizeof(out->limb[0]); i++) {
  165. out->limb[i] = -a->limb[i];
  166. }
  167. */
  168. }
  169. void
  170. p448_cond_neg(
  171. p448_t *a,
  172. mask_t doNegate
  173. ) {
  174. unsigned int i;
  175. struct p448_t negated;
  176. big_register_t *aa = (big_register_t *)a;
  177. big_register_t *nn = (big_register_t*)&negated;
  178. big_register_t m = br_set_to_mask(doNegate);
  179. p448_neg(&negated, a);
  180. p448_bias(&negated, 2);
  181. for (i=0; i<sizeof(*a)/sizeof(*aa); i++) {
  182. aa[i] = (aa[i] & ~m) | (nn[i] & m);
  183. }
  184. }
  185. void
  186. p448_addw (
  187. p448_t *a,
  188. uint32_t x
  189. ) {
  190. a->limb[0] += x;
  191. }
  192. void
  193. p448_subw (
  194. p448_t *a,
  195. uint32_t x
  196. ) {
  197. a->limb[0] -= x;
  198. }
  199. void
  200. p448_copy (
  201. p448_t *out,
  202. const p448_t *a
  203. ) {
  204. *out = *a;
  205. }
  206. void
  207. p448_bias (
  208. p448_t *a,
  209. int amt
  210. ) {
  211. uint32_t co1 = ((1ull<<28)-1)*amt, co2 = co1-amt;
  212. uint32x4_t lo = {co1,co1,co1,co1}, hi = {co2,co1,co1,co1};
  213. uint32x4_t *aa = (uint32x4_t*) a;
  214. aa[0] += lo;
  215. aa[1] += lo;
  216. aa[2] += hi;
  217. aa[3] += lo;
  218. }
  219. void
  220. p448_weak_reduce (
  221. p448_t *a
  222. ) {
  223. uint64_t mask = (1ull<<28) - 1;
  224. uint64_t tmp = a->limb[15] >> 28;
  225. int i;
  226. a->limb[8] += tmp;
  227. for (i=15; i>0; i--) {
  228. a->limb[i] = (a->limb[i] & mask) + (a->limb[i-1]>>28);
  229. }
  230. a->limb[0] = (a->limb[0] & mask) + tmp;
  231. }
  232. mask_t
  233. p448_eq (
  234. const struct p448_t *a,
  235. const struct p448_t *b
  236. ) {
  237. struct p448_t ra, rb;
  238. p448_copy(&ra, a);
  239. p448_copy(&rb, b);
  240. p448_weak_reduce(&ra);
  241. p448_weak_reduce(&rb);
  242. p448_sub(&ra, &ra, &rb);
  243. p448_bias(&ra, 2);
  244. return p448_is_zero(&ra);
  245. }
  246. #ifdef __cplusplus
  247. }; /* extern "C" */
  248. #endif
  249. #endif /* __P448_H__ */