fuzz-curve25519.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. #if defined(_WIN32)
  2. #include <windows.h>
  3. #include <wincrypt.h>
  4. typedef unsigned int uint32_t;
  5. typedef unsigned __int64 uint64_t;
  6. #else
  7. #include <stdint.h>
  8. #endif
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include "ed25519-donna.h"
  12. #include "curve25519-ref10.h"
  13. static void
  14. print_diff(const char *desc, const unsigned char *a, const unsigned char *b, size_t len) {
  15. size_t p = 0;
  16. unsigned char diff;
  17. printf("%s diff:\n", desc);
  18. while (len--) {
  19. diff = *a++ ^ *b++;
  20. if (!diff)
  21. printf("____,");
  22. else
  23. printf("0x%02x,", diff);
  24. if ((++p & 15) == 0)
  25. printf("\n");
  26. }
  27. printf("\n\n");
  28. }
  29. static void
  30. print_bytes(const char *desc, const unsigned char *bytes, size_t len) {
  31. size_t p = 0;
  32. printf("%s:\n", desc);
  33. while (len--) {
  34. printf("0x%02x,", *bytes++);
  35. if ((++p & 15) == 0)
  36. printf("\n");
  37. }
  38. printf("\n\n");
  39. }
  40. /* chacha20/12 prng */
  41. void
  42. prng(unsigned char *out, size_t bytes) {
  43. static uint32_t state[16];
  44. static int init = 0;
  45. uint32_t x[16], t;
  46. size_t i;
  47. if (!init) {
  48. #if defined(_WIN32)
  49. HCRYPTPROV csp;
  50. if (!CryptAcquireContext(&csp, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
  51. printf("CryptAcquireContext failed\n");
  52. exit(1);
  53. }
  54. if (!CryptGenRandom(csp, (DWORD)sizeof(state), (BYTE*)state)) {
  55. printf("CryptGenRandom failed\n");
  56. exit(1);
  57. }
  58. CryptReleaseContext(csp, 0);
  59. #else
  60. FILE *f = NULL;
  61. f = fopen("/dev/urandom", "rb");
  62. if (!f) {
  63. printf("failed to open /dev/urandom\n");
  64. exit(1);
  65. }
  66. if (fread(state, sizeof(state), 1, f) != 1) {
  67. printf("read error on /dev/urandom\n");
  68. exit(1);
  69. }
  70. #endif
  71. init = 1;
  72. }
  73. while (bytes) {
  74. for (i = 0; i < 16; i++) x[i] = state[i];
  75. #define rotl32(x,k) ((x << k) | (x >> (32 - k)))
  76. #define quarter(a,b,c,d) \
  77. x[a] += x[b]; t = x[d]^x[a]; x[d] = rotl32(t,16); \
  78. x[c] += x[d]; t = x[b]^x[c]; x[b] = rotl32(t,12); \
  79. x[a] += x[b]; t = x[d]^x[a]; x[d] = rotl32(t, 8); \
  80. x[c] += x[d]; t = x[b]^x[c]; x[b] = rotl32(t, 7);
  81. for (i = 0; i < 12; i += 2) {
  82. quarter( 0, 4, 8,12)
  83. quarter( 1, 5, 9,13)
  84. quarter( 2, 6,10,14)
  85. quarter( 3, 7,11,15)
  86. quarter( 0, 5,10,15)
  87. quarter( 1, 6,11,12)
  88. quarter( 2, 7, 8,13)
  89. quarter( 3, 4, 9,14)
  90. };
  91. if (bytes <= 64) {
  92. memcpy(out, x, bytes);
  93. bytes = 0;
  94. } else {
  95. memcpy(out, x, 64);
  96. bytes -= 64;
  97. out += 64;
  98. }
  99. /* don't need a nonce, so last 4 words are the counter. 2^136 bytes can be generated */
  100. if (!++state[12]) if (!++state[13]) if (!++state[14]) ++state[15];
  101. }
  102. }
  103. int main() {
  104. const size_t skmax = 1024;
  105. static unsigned char sk[1024][32];
  106. unsigned char pk[3][32];
  107. unsigned char *skp;
  108. size_t ski, pki, i;
  109. uint64_t ctr;
  110. printf("fuzzing: ");
  111. printf(" ref10");
  112. printf(" curved25519");
  113. #if defined(ED25519_SSE2)
  114. printf(" curved25519-sse2");
  115. #endif
  116. printf("\n\n");
  117. for (ctr = 0, ski = skmax;;ctr++) {
  118. if (ski == skmax) {
  119. prng((unsigned char *)sk, sizeof(sk));
  120. ski = 0;
  121. }
  122. skp = sk[ski++];
  123. pki = 0;
  124. crypto_scalarmult_base_ref10(pk[pki++], skp);
  125. curved25519_scalarmult_basepoint(pk[pki++], skp);
  126. #if defined(ED25519_SSE2)
  127. curved25519_scalarmult_basepoint_sse2(pk[pki++], skp);
  128. #endif
  129. for (i = 1; i < pki; i++) {
  130. if (memcmp(pk[0], pk[i], 32) != 0) {
  131. printf("\n\n");
  132. print_bytes("sk", skp, 32);
  133. print_bytes("ref10", pk[0], 32);
  134. print_diff("curved25519", pk[0], pk[1], 32);
  135. #if defined(ED25519_SSE2)
  136. print_diff("curved25519-sse2", pk[0], pk[2], 32);
  137. #endif
  138. exit(1);
  139. }
  140. }
  141. if (ctr && (ctr % 0x1000 == 0)) {
  142. printf(".");
  143. if ((ctr % 0x20000) == 0) {
  144. printf(" [");
  145. for (i = 0; i < 8; i++)
  146. printf("%02x", (unsigned char)(ctr >> ((7 - i) * 8)));
  147. printf("]\n");
  148. }
  149. }
  150. }
  151. }