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.
 
 
 
 
 

183 lines
3.3 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. #include "constant_time.h"
  11. #define LIMBPERM(x) (((x)%3)*4 + (x)/3)
  12. #define USE_P521_3x3_TRANSPOSE
  13. typedef struct p521_t {
  14. uint64_t limb[12];
  15. } __attribute__((aligned(32))) p521_t;
  16. #ifdef __cplusplus
  17. extern "C" {
  18. #endif
  19. static __inline__ void
  20. p521_add_RAW (
  21. p521_t *out,
  22. const p521_t *a,
  23. const p521_t *b
  24. ) __attribute__((unused));
  25. static __inline__ void
  26. p521_sub_RAW (
  27. p521_t *out,
  28. const p521_t *a,
  29. const p521_t *b
  30. ) __attribute__((unused));
  31. static __inline__ void
  32. p521_copy (
  33. p521_t *out,
  34. const p521_t *a
  35. ) __attribute__((unused));
  36. static __inline__ void
  37. p521_weak_reduce (
  38. p521_t *inout
  39. ) __attribute__((unused));
  40. void
  41. p521_strong_reduce (
  42. p521_t *inout
  43. );
  44. static __inline__ void
  45. p521_bias (
  46. p521_t *inout,
  47. int amount
  48. ) __attribute__((unused));
  49. void
  50. p521_mul (
  51. p521_t *__restrict__ out,
  52. const p521_t *a,
  53. const p521_t *b
  54. );
  55. void
  56. p521_mulw (
  57. p521_t *__restrict__ out,
  58. const p521_t *a,
  59. uint64_t b
  60. );
  61. void
  62. p521_sqr (
  63. p521_t *__restrict__ out,
  64. const p521_t *a
  65. );
  66. void
  67. p521_serialize (
  68. uint8_t *serial,
  69. const struct p521_t *x
  70. );
  71. mask_t
  72. p521_deserialize (
  73. p521_t *x,
  74. const uint8_t serial[66]
  75. );
  76. /* -------------- Inline functions begin here -------------- */
  77. typedef uint64x4_t uint64x3_t; /* fit it in a vector register */
  78. static const uint64x3_t mask58 = { (1ull<<58) - 1, (1ull<<58) - 1, (1ull<<58) - 1, 0 };
  79. /* Currently requires CLANG. Sorry. */
  80. static inline uint64x3_t
  81. __attribute__((unused))
  82. timesW (
  83. uint64x3_t u
  84. ) {
  85. return u.zxyw + u.zwww;
  86. }
  87. void
  88. p521_add_RAW (
  89. p521_t *out,
  90. const p521_t *a,
  91. const p521_t *b
  92. ) {
  93. unsigned int i;
  94. for (i=0; i<sizeof(*out)/sizeof(uint64xn_t); i++) {
  95. ((uint64xn_t*)out)[i] = ((const uint64xn_t*)a)[i] + ((const uint64xn_t*)b)[i];
  96. }
  97. }
  98. void
  99. p521_sub_RAW (
  100. p521_t *out,
  101. const p521_t *a,
  102. const p521_t *b
  103. ) {
  104. unsigned int i;
  105. for (i=0; i<sizeof(*out)/sizeof(uint64xn_t); i++) {
  106. ((uint64xn_t*)out)[i] = ((const uint64xn_t*)a)[i] - ((const uint64xn_t*)b)[i];
  107. }
  108. }
  109. void
  110. p521_copy (
  111. p521_t *out,
  112. const p521_t *a
  113. ) {
  114. memcpy(out,a,sizeof(*a));
  115. }
  116. void
  117. p521_bias (
  118. p521_t *a,
  119. int amt
  120. ) {
  121. uint64_t co0 = ((1ull<<58)-2)*amt, co1 = ((1ull<<58)-1)*amt;
  122. uint64x4_t vlo = { co0, co1, co1, 0 }, vhi = { co1, co1, co1, 0 };
  123. ((uint64x4_t*)a)[0] += vlo;
  124. ((uint64x4_t*)a)[1] += vhi;
  125. ((uint64x4_t*)a)[2] += vhi;
  126. }
  127. void
  128. p521_weak_reduce (
  129. p521_t *a
  130. ) {
  131. #if 0
  132. int i;
  133. assert(a->limb[3] == 0 && a->limb[7] == 0 && a->limb[11] == 0);
  134. for (i=0; i<12; i++) {
  135. assert(a->limb[i] < 3ull<<61);
  136. }
  137. #endif
  138. uint64x3_t
  139. ot0 = ((uint64x4_t*)a)[0],
  140. ot1 = ((uint64x4_t*)a)[1],
  141. ot2 = ((uint64x4_t*)a)[2];
  142. uint64x3_t out0 = (ot0 & mask58) + timesW(ot2>>58);
  143. uint64x3_t out1 = (ot1 & mask58) + (ot0>>58);
  144. uint64x3_t out2 = (ot2 & mask58) + (ot1>>58);
  145. ((uint64x4_t*)a)[0] = out0;
  146. ((uint64x4_t*)a)[1] = out1;
  147. ((uint64x4_t*)a)[2] = out2;
  148. }
  149. #ifdef __cplusplus
  150. }; /* extern "C" */
  151. #endif
  152. #endif /* __P521_H__ */