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.
 
 
 

99 lines
2.4 KiB

  1. #include "sort.h"
  2. /*
  3. Constant-time uint32_t sorting by Daniel J. Bernstein
  4. Source: https://sorting.cr.yp.to
  5. */
  6. #define int32_MINMAX(a,b) \
  7. do { \
  8. int32 ab = (b) ^ (a); \
  9. int32 c = (b) - (a); \
  10. c ^= ab & (c ^ (b)); \
  11. c >>= 31; \
  12. c &= ab; \
  13. (a) ^= c; \
  14. (b) ^= c; \
  15. } while(0)
  16. static void int32_sort(int32 *x, size_t n) {
  17. size_t top, p, q, r, i, j;
  18. if (n < 2) {
  19. return;
  20. }
  21. top = 1;
  22. while (top < n - top) {
  23. top += top;
  24. }
  25. for (p = top; p >= 1; p >>= 1) {
  26. i = 0;
  27. while (i + 2 * p <= n) {
  28. for (j = i; j < i + p; ++j) {
  29. int32_MINMAX(x[j], x[j + p]);
  30. }
  31. i += 2 * p;
  32. }
  33. for (j = i; j < n - p; ++j) {
  34. int32_MINMAX(x[j], x[j + p]);
  35. }
  36. i = 0;
  37. j = 0;
  38. for (q = top; q > p; q >>= 1) {
  39. if (j != i) {
  40. for (;;) {
  41. if (j == n - q) {
  42. goto done;
  43. }
  44. int32 a = x[j + p];
  45. for (r = q; r > p; r >>= 1) {
  46. int32_MINMAX(a, x[j + r]);
  47. }
  48. x[j + p] = a;
  49. ++j;
  50. if (j == i + p) {
  51. i += 2 * p;
  52. break;
  53. }
  54. }
  55. }
  56. while (i + p <= n - q) {
  57. for (j = i; j < i + p; ++j) {
  58. int32 a = x[j + p];
  59. for (r = q; r > p; r >>= 1) {
  60. int32_MINMAX(a, x[j + r]);
  61. }
  62. x[j + p] = a;
  63. }
  64. i += 2 * p;
  65. }
  66. /* now i + p > n - q */
  67. j = i;
  68. while (j < n - q) {
  69. int32 a = x[j + p];
  70. for (r = q; r > p; r >>= 1) {
  71. int32_MINMAX(a, x[j + r]);
  72. }
  73. x[j + p] = a;
  74. ++j;
  75. }
  76. done:
  77. ;
  78. }
  79. }
  80. }
  81. /* can save time by integrating xor loops with int32_sort */
  82. void PQCLEAN_LEDAKEMLT12_LEAKTIME_uint32_sort(uint32_t *x, size_t n) {
  83. size_t j;
  84. for (j = 0; j < n; ++j) {
  85. x[j] ^= 0x80000000;
  86. }
  87. int32_sort((int32_t *) x, n);
  88. for (j = 0; j < n; ++j) {
  89. x[j] ^= 0x80000000;
  90. }
  91. }