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.
 
 
 
 
 

173 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 __P448_H__
  5. #define __P448_H__ 1
  6. #include "word.h"
  7. #include <stdint.h>
  8. #include <assert.h>
  9. typedef struct gf_448_s {
  10. uint32_t limb[16];
  11. } __attribute__((aligned(32))) gf_448_s, gf_448_t[1];
  12. #define LIMBPERM(x) (((x)<<1 | (x)>>3) & 15)
  13. #define USE_NEON_PERM 1
  14. #define LBITS 28
  15. #define LIMBHI(x) ((x##ull)>>LBITS)
  16. #define LIMBLO(x) ((x##ull)&((1ull<<LBITS)-1))
  17. # define FIELD_LITERAL(a,b,c,d,e,f,g,h) \
  18. {{LIMBLO(a),LIMBLO(e), LIMBHI(a),LIMBHI(e), \
  19. LIMBLO(b),LIMBLO(f), LIMBHI(b),LIMBHI(f), \
  20. LIMBLO(c),LIMBLO(g), LIMBHI(c),LIMBHI(g), \
  21. LIMBLO(d),LIMBLO(h), LIMBHI(d),LIMBHI(h)}}
  22. #ifdef __cplusplus
  23. extern "C" {
  24. #endif
  25. static __inline__ void
  26. p448_add_RAW (
  27. gf_448_t out,
  28. const gf_448_t a,
  29. const gf_448_t b
  30. ) __attribute__((unused,always_inline));
  31. static __inline__ void
  32. p448_sub_RAW (
  33. gf_448_t out,
  34. const gf_448_t a,
  35. const gf_448_t b
  36. ) __attribute__((unused,always_inline));
  37. static __inline__ void
  38. p448_copy (
  39. gf_448_t out,
  40. const gf_448_t a
  41. ) __attribute__((unused,always_inline));
  42. static __inline__ void
  43. p448_weak_reduce (
  44. gf_448_t inout
  45. ) __attribute__((unused,always_inline));
  46. void
  47. p448_strong_reduce (
  48. gf_448_t inout
  49. );
  50. static __inline__ void
  51. p448_bias (
  52. gf_448_t inout,
  53. int amount
  54. ) __attribute__((unused,always_inline));
  55. void
  56. p448_mul (
  57. gf_448_s *__restrict__ out,
  58. const gf_448_t a,
  59. const gf_448_t b
  60. );
  61. void
  62. p448_mulw (
  63. gf_448_s *__restrict__ out,
  64. const gf_448_t a,
  65. uint64_t b
  66. );
  67. void
  68. p448_sqr (
  69. gf_448_s *__restrict__ out,
  70. const gf_448_t a
  71. );
  72. void
  73. p448_serialize (
  74. uint8_t *serial,
  75. const gf_448_t x
  76. );
  77. mask_t
  78. p448_deserialize (
  79. gf_448_t x,
  80. const uint8_t serial[56]
  81. );
  82. /* -------------- Inline functions begin here -------------- */
  83. void
  84. p448_add_RAW (
  85. gf_448_t out,
  86. const gf_448_t a,
  87. const gf_448_t b
  88. ) {
  89. unsigned int i;
  90. for (i=0; i<sizeof(*out)/sizeof(uint32xn_t); i++) {
  91. ((uint32xn_t*)out)[i] = ((const uint32xn_t*)a)[i] + ((const uint32xn_t*)b)[i];
  92. }
  93. }
  94. void
  95. p448_sub_RAW (
  96. gf_448_t out,
  97. const gf_448_t a,
  98. const gf_448_t b
  99. ) {
  100. unsigned int i;
  101. for (i=0; i<sizeof(*out)/sizeof(uint32xn_t); i++) {
  102. ((uint32xn_t*)out)[i] = ((const uint32xn_t*)a)[i] - ((const uint32xn_t*)b)[i];
  103. }
  104. /*
  105. unsigned int i;
  106. for (i=0; i<sizeof(*out)/sizeof(out->limb[0]); i++) {
  107. out->limb[i] = a->limb[i] - b->limb[i];
  108. }
  109. */
  110. }
  111. void
  112. p448_copy (
  113. gf_448_t out,
  114. const gf_448_t a
  115. ) {
  116. *out = *a;
  117. }
  118. void
  119. p448_bias (
  120. gf_448_t a,
  121. int amt
  122. ) {
  123. uint32_t co1 = ((1ull<<28)-1)*amt, co2 = co1-amt;
  124. uint32x4_t lo = {co1,co2,co1,co1}, hi = {co1,co1,co1,co1};
  125. uint32x4_t *aa = (uint32x4_t*) a;
  126. aa[0] += lo;
  127. aa[1] += hi;
  128. aa[2] += hi;
  129. aa[3] += hi;
  130. }
  131. void
  132. p448_weak_reduce (
  133. gf_448_t a
  134. ) {
  135. uint32x2_t *aa = (uint32x2_t*) a, vmask = {(1ull<<28)-1, (1ull<<28)-1}, vm2 = {0,-1},
  136. tmp = vshr_n_u32(aa[7],28);
  137. int i;
  138. for (i=7; i>=1; i--) {
  139. aa[i] = vsra_n_u32(aa[i] & vmask, aa[i-1], 28);
  140. }
  141. aa[0] = (aa[0] & vmask) + vrev64_u32(tmp) + (tmp&vm2);
  142. }
  143. #ifdef __cplusplus
  144. }; /* extern "C" */
  145. #endif
  146. #endif /* __P448_H__ */