try-anything.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * try-anything.c version 20090215
  3. * D. J. Bernstein
  4. * Public domain.
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <time.h>
  10. #include <unistd.h>
  11. #include <sys/time.h>
  12. #include <sys/types.h>
  13. #include <sys/resource.h>
  14. #include "cpucycles.h"
  15. typedef int uint32;
  16. static uint32 seed[32] = { 3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6,4,3,3,8,3,2,7,9,5 } ;
  17. static uint32 in[12];
  18. static uint32 out[8];
  19. static int outleft = 0;
  20. #define ROTATE(x,b) (((x) << (b)) | ((x) >> (32 - (b))))
  21. #define MUSH(i,b) x = t[i] += (((x ^ seed[i]) + sum) ^ ROTATE(x,b));
  22. static void surf(void)
  23. {
  24. uint32 t[12]; uint32 x; uint32 sum = 0;
  25. int r; int i; int loop;
  26. for (i = 0;i < 12;++i) t[i] = in[i] ^ seed[12 + i];
  27. for (i = 0;i < 8;++i) out[i] = seed[24 + i];
  28. x = t[11];
  29. for (loop = 0;loop < 2;++loop) {
  30. for (r = 0;r < 16;++r) {
  31. sum += 0x9e3779b9;
  32. MUSH(0,5) MUSH(1,7) MUSH(2,9) MUSH(3,13)
  33. MUSH(4,5) MUSH(5,7) MUSH(6,9) MUSH(7,13)
  34. MUSH(8,5) MUSH(9,7) MUSH(10,9) MUSH(11,13)
  35. }
  36. for (i = 0;i < 8;++i) out[i] ^= t[i + 4];
  37. }
  38. }
  39. void randombytes(unsigned char *x,unsigned long long xlen)
  40. {
  41. while (xlen > 0) {
  42. if (!outleft) {
  43. if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
  44. surf();
  45. outleft = 8;
  46. }
  47. *x = out[--outleft];
  48. ++x;
  49. --xlen;
  50. }
  51. }
  52. extern void preallocate(void);
  53. extern void allocate(void);
  54. extern void predoit(void);
  55. extern void doit(void);
  56. extern char checksum[];
  57. extern const char *checksum_compute(void);
  58. extern const char *primitiveimplementation;
  59. static void printword(const char *s)
  60. {
  61. if (!*s) putchar('-');
  62. while (*s) {
  63. if (*s == ' ') putchar('_');
  64. else if (*s == '\t') putchar('_');
  65. else if (*s == '\r') putchar('_');
  66. else if (*s == '\n') putchar('_');
  67. else putchar(*s);
  68. ++s;
  69. }
  70. putchar(' ');
  71. }
  72. static void printnum(long long x)
  73. {
  74. printf("%lld ",x);
  75. }
  76. static void fail(const char *why)
  77. {
  78. printf("%s\n",why);
  79. exit(111);
  80. }
  81. unsigned char *alignedcalloc(unsigned long long len)
  82. {
  83. unsigned char *x = (unsigned char *) calloc(1,len + 256);
  84. long long i;
  85. if (!x) fail("out of memory");
  86. /* will never deallocate so shifting is ok */
  87. for (i = 0;i < len + 256;++i) x[i] = random();
  88. x += 64;
  89. x += 63 & (-(unsigned long) x);
  90. for (i = 0;i < len;++i) x[i] = 0;
  91. return x;
  92. }
  93. #define TIMINGS 63
  94. static long long cycles[TIMINGS + 1];
  95. void limits()
  96. {
  97. #ifdef RLIM_INFINITY
  98. struct rlimit r;
  99. r.rlim_cur = 0;
  100. r.rlim_max = 0;
  101. #ifdef RLIMIT_NOFILE
  102. setrlimit(RLIMIT_NOFILE,&r);
  103. #endif
  104. #ifdef RLIMIT_NPROC
  105. setrlimit(RLIMIT_NPROC,&r);
  106. #endif
  107. #ifdef RLIMIT_CORE
  108. setrlimit(RLIMIT_CORE,&r);
  109. #endif
  110. #endif
  111. }
  112. int main()
  113. {
  114. long long i;
  115. long long j;
  116. long long abovej;
  117. long long belowj;
  118. long long checksumcycles;
  119. long long cyclespersecond;
  120. const char *problem;
  121. cyclespersecond = cpucycles_persecond();
  122. preallocate();
  123. limits();
  124. allocate();
  125. srandom(getpid());
  126. cycles[0] = cpucycles();
  127. problem = checksum_compute(); if (problem) fail(problem);
  128. cycles[1] = cpucycles();
  129. checksumcycles = cycles[1] - cycles[0];
  130. predoit();
  131. for (i = 0;i <= TIMINGS;++i) {
  132. cycles[i] = cpucycles();
  133. }
  134. for (i = 0;i <= TIMINGS;++i) {
  135. cycles[i] = cpucycles();
  136. doit();
  137. }
  138. for (i = 0;i < TIMINGS;++i) cycles[i] = cycles[i + 1] - cycles[i];
  139. for (j = 0;j < TIMINGS;++j) {
  140. belowj = 0;
  141. for (i = 0;i < TIMINGS;++i) if (cycles[i] < cycles[j]) ++belowj;
  142. abovej = 0;
  143. for (i = 0;i < TIMINGS;++i) if (cycles[i] > cycles[j]) ++abovej;
  144. if (belowj * 2 < TIMINGS && abovej * 2 < TIMINGS) break;
  145. }
  146. printword(checksum);
  147. printnum(cycles[j]);
  148. printnum(checksumcycles);
  149. printnum(cyclespersecond);
  150. printword(primitiveimplementation);
  151. printf("\n");
  152. return 0;
  153. }