pt.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * Copyright (c) 1994, 1995 Colin Plumb. All rights reserved.
  3. * For licensing and other legal details, see the file legal.c.
  4. *
  5. * primetest.c - Test driver for prime generation.
  6. */
  7. #include "first.h"
  8. #include <stdio.h>
  9. #include <stdlib.h> /* For strtoul() */
  10. #include "bn.h"
  11. #include "bnprint.h"
  12. #include "cputime.h"
  13. #include "prime.h"
  14. #include "noise.h"
  15. #include "kludge.h"
  16. #define bnPut(prompt, bn) bnPrint(stdout, prompt, bn, "\n")
  17. /*
  18. * Generate a new RSA key, with the specified number of bits and
  19. * public exponent. The high two bits of each prime are always
  20. * set to make the number more difficult to factor by forcing the
  21. * number into the high end of the range.
  22. */
  23. struct Progress {
  24. FILE *f;
  25. unsigned column;
  26. unsigned wrap;
  27. };
  28. static int
  29. primeProgress(void *arg, int c)
  30. {
  31. struct Progress *p = arg;
  32. if (++p->column > p->wrap) {
  33. putc('\n', p->f);
  34. p->column = 1;
  35. }
  36. putc(c, p->f);
  37. fflush(p->f);
  38. return 0;
  39. }
  40. static int
  41. hextoval(char c)
  42. {
  43. if (c < '0')
  44. return -1;
  45. c -= '0';
  46. if (c < 10)
  47. return c;
  48. c -= 'A'-'0';
  49. c &= ~('a'-'A');
  50. if (c >= 0 && c < 6)
  51. return c+10;
  52. return -1;
  53. }
  54. static int
  55. stringToBn(struct BigNum *bn, char const *string)
  56. {
  57. size_t len = strlen(string);
  58. char buf;
  59. int i, j;
  60. (void)bnSetQ(bn, 0);
  61. if (len & 1) {
  62. i = hextoval(*string++);
  63. if (i < 0)
  64. return 0;
  65. buf = i;
  66. if (bnInsertBigBytes(bn, &buf, len/2, 1) < 0)
  67. return -1;
  68. }
  69. len /= 2;
  70. while (len--) {
  71. i = hextoval(*string++);
  72. if (i < 0)
  73. return 0;
  74. j = hextoval(*string++);
  75. if (j < 0)
  76. return 0;
  77. buf = i*16 + j;
  78. if (bnInsertBigBytes(bn, &buf, len, 1) < 0)
  79. return -1;
  80. }
  81. return 1; /* Success */
  82. }
  83. static int
  84. primeTest(char const *string)
  85. {
  86. int modexps = 0;
  87. struct BigNum bn; /* Temporary */
  88. int i, j;
  89. struct Progress progress;
  90. #if CLOCK_AVAIL
  91. timetype start, stop;
  92. unsigned long curs, tots = 0;
  93. unsigned curms, totms = 0;
  94. #endif
  95. progress.f = stdout;
  96. progress.wrap = 78;
  97. bnBegin(&bn);
  98. /* Find p - choose a starting place */
  99. i = stringToBn(&bn, string);
  100. if (i < 1) {
  101. if (i < 0)
  102. goto error;
  103. printf("Malformed string: \"%s\"\n", string);
  104. bnEnd(&bn);
  105. return 0;
  106. }
  107. /* And search for primes */
  108. for (j = 0; j < 40; j++) {
  109. progress.column = 0;
  110. #if CLOCK_AVAIL
  111. gettime(&start);
  112. #endif
  113. i = primeGen(&bn, 0, primeProgress, &progress, 0);
  114. if (i < 0)
  115. goto error;
  116. #if CLOCK_AVAIL
  117. gettime(&stop);
  118. subtime(stop, start);
  119. tots += curs = sec(stop);
  120. totms += curms = msec(stop);
  121. #endif
  122. modexps += i;
  123. putchar('\n'); /* Signal done */
  124. printf("%d modular exponentiations performed", i);
  125. #if CLOCK_AVAIL
  126. printf(" in %lu.%03u s", curs, curms);
  127. #endif
  128. putchar('\n');
  129. bnPut("n = ", &bn);
  130. if (bnAddQ(&bn, 2) < 0)
  131. goto error;
  132. }
  133. bnEnd(&bn);
  134. printf("Total %d modular exponentiations performed", modexps);
  135. #if CLOCK_AVAIL
  136. tots += totms/1000;
  137. totms %= 1000;
  138. printf(" in %lu.%03u s\n", tots, totms);
  139. totms += 1000 * (tots % j);
  140. tots /= j;
  141. totms /= j;
  142. tots += totms / 1000;
  143. totms %= 1000;
  144. printf("Average time: %lu.%03u s", tots, totms);
  145. #endif
  146. putchar('\n');
  147. /* And that's it... success! */
  148. return 1;
  149. error:
  150. puts("\nError!");
  151. bnEnd(&bn);
  152. return -1;
  153. }
  154. int
  155. main(int argc, char **argv)
  156. {
  157. if (argc < 2) {
  158. fprintf(stderr, "Usage: %s <hex>...\n", argv[0]);
  159. fputs("\
  160. This finds the next primes after the given hex strings.\n", stderr);
  161. return 1;
  162. }
  163. bnInit();
  164. while (--argc)
  165. primeTest(*++argv);
  166. return 0;
  167. }