test.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <mp.h>
  4. #include "dat.h"
  5. int loops = 1;
  6. long randomreg;
  7. void
  8. srand(long seed)
  9. {
  10. randomreg = seed;
  11. }
  12. long
  13. lrand(void)
  14. {
  15. randomreg = randomreg*104381 + 81761;
  16. return randomreg;
  17. }
  18. void
  19. prng(uchar *p, int n)
  20. {
  21. while(n-- > 0)
  22. *p++ = lrand();
  23. }
  24. void
  25. testconv(char *str)
  26. {
  27. mpint *b;
  28. char *p;
  29. b = strtomp(str, nil, 16, nil);
  30. p = mptoa(b, 10, nil, 0);
  31. print("%s = ", p);
  32. strtomp(p, nil, 10, b);
  33. free(p);
  34. print("%B\n", b);
  35. p = mptoa(b, 16, nil, 0);
  36. print("%s = ", p);
  37. strtomp(p, nil, 16, b);
  38. free(p);
  39. print("%B\n", b);
  40. p = mptoa(b, 32, nil, 0);
  41. print("%s = ", p);
  42. strtomp(p, nil, 32, b);
  43. free(p);
  44. print("%B\n", b);
  45. p = mptoa(b, 64, nil, 0);
  46. print("%s = ", p);
  47. strtomp(p, nil, 64, b);
  48. free(p);
  49. print("%B\n", b);
  50. mpfree(b);
  51. }
  52. void
  53. testshift(char *str)
  54. {
  55. mpint *b1, *b2;
  56. int i;
  57. b1 = strtomp(str, nil, 16, nil);
  58. b2 = mpnew(0);
  59. for(i = 0; i < 64; i++){
  60. mpleft(b1, i, b2);
  61. print("%2.2d %B\n", i, b2);
  62. }
  63. for(i = 0; i < 64; i++){
  64. mpright(b2, i, b1);
  65. print("%2.2d %B\n", i, b1);
  66. }
  67. mpfree(b1);
  68. mpfree(b2);
  69. }
  70. void
  71. testaddsub(char *str)
  72. {
  73. mpint *b1, *b2;
  74. int i;
  75. b1 = strtomp(str, nil, 16, nil);
  76. b2 = mpnew(0);
  77. for(i = 0; i < 16; i++){
  78. mpadd(b1, b2, b2);
  79. print("%2.2d %B\n", i, b2);
  80. }
  81. for(i = 0; i < 16; i++){
  82. mpsub(b2, b1, b2);
  83. print("%2.2d %B\n", i, b2);
  84. }
  85. mpfree(b1);
  86. mpfree(b2);
  87. }
  88. void
  89. testvecdigmuladd(char *str, mpdigit d)
  90. {
  91. mpint *b, *b2;
  92. int i;
  93. vlong now;
  94. b = strtomp(str, nil, 16, nil);
  95. b2 = mpnew(0);
  96. mpbits(b2, (b->top+1)*Dbits);
  97. now = nsec();
  98. for(i = 0; i < loops; i++){
  99. memset(b2->p, 0, b2->top*Dbytes);
  100. mpvecdigmuladd(b->p, b->top, d, b2->p);
  101. }
  102. if(loops > 1)
  103. print("%lld ns for a %d*%d vecdigmul\n", (nsec()-now)/loops, b->top*Dbits, Dbits);
  104. mpnorm(b2);
  105. print("0 + %B * %ux = %B\n", b, d, b2);
  106. mpfree(b);
  107. mpfree(b2);
  108. }
  109. void
  110. testvecdigmulsub(char *str, mpdigit d)
  111. {
  112. mpint *b, *b2;
  113. int i;
  114. vlong now;
  115. b = strtomp(str, nil, 16, nil);
  116. b2 = mpnew(0);
  117. mpbits(b2, (b->top+1)*Dbits);
  118. now = nsec();
  119. for(i = 0; i < loops; i++){
  120. memset(b2->p, 0, b2->top*Dbytes);
  121. mpvecdigmulsub(b->p, b->top, d, b2->p);
  122. }
  123. if(loops > 1)
  124. print("%lld ns for a %d*%d vecdigmul\n", (nsec()-now)/loops, b->top*Dbits, Dbits);
  125. mpnorm(b2);
  126. print("0 - %B * %ux = %B\n", b, d, b2);
  127. mpfree(b);
  128. mpfree(b2);
  129. }
  130. void
  131. testmul(char *str)
  132. {
  133. mpint *b, *b1, *b2;
  134. vlong now;
  135. int i;
  136. b = strtomp(str, nil, 16, nil);
  137. b1 = mpcopy(b);
  138. b2 = mpnew(0);
  139. now = nsec();
  140. for(i = 0; i < loops; i++)
  141. mpmul(b, b1, b2);
  142. if(loops > 1)
  143. print("%lld µs for a %d*%d mult\n", (nsec()-now)/(loops*1000),
  144. b->top*Dbits, b1->top*Dbits);
  145. print("%B * %B = %B\n", b, b1, b2);
  146. mpfree(b);
  147. mpfree(b1);
  148. mpfree(b2);
  149. }
  150. void
  151. testmul2(mpint *b, mpint *b1)
  152. {
  153. mpint *b2;
  154. vlong now;
  155. int i;
  156. b2 = mpnew(0);
  157. now = nsec();
  158. for(i = 0; i < loops; i++)
  159. mpmul(b, b1, b2);
  160. if(loops > 1)
  161. print("%lld µs for a %d*%d mult\n", (nsec()-now)/(loops*1000), b->top*Dbits, b1->top*Dbits);
  162. print("%B * ", b);
  163. print("%B = ", b1);
  164. print("%B\n", b2);
  165. mpfree(b2);
  166. }
  167. void
  168. testdigdiv(char *str, mpdigit d)
  169. {
  170. mpint *b;
  171. mpdigit q;
  172. int i;
  173. vlong now;
  174. b = strtomp(str, nil, 16, nil);
  175. now = nsec();
  176. for(i = 0; i < loops; i++)
  177. mpdigdiv(b->p, d, &q);
  178. if(loops > 1)
  179. print("%lld ns for a %d / %d div\n", (nsec()-now)/loops, 2*Dbits, Dbits);
  180. print("%B / %ux = %ux\n", b, d, q);
  181. mpfree(b);
  182. }
  183. void
  184. testdiv(mpint *x, mpint *y)
  185. {
  186. mpint *b2, *b3;
  187. vlong now;
  188. int i;
  189. b2 = mpnew(0);
  190. b3 = mpnew(0);
  191. now = nsec();
  192. for(i = 0; i < loops; i++)
  193. mpdiv(x, y, b2, b3);
  194. if(loops > 1)
  195. print("%lld µs for a %d/%d div\n", (nsec()-now)/(1000*loops),
  196. x->top*Dbits, y->top*Dbits);
  197. print("%B / %B = %B %B\n", x, y, b2, b3);
  198. mpfree(b2);
  199. mpfree(b3);
  200. }
  201. void
  202. testmod(mpint *x, mpint *y)
  203. {
  204. mpint *r;
  205. vlong now;
  206. int i;
  207. r = mpnew(0);
  208. now = nsec();
  209. for(i = 0; i < loops; i++)
  210. mpmod(x, y, r);
  211. if(loops > 1)
  212. print("%lld µs for a %d/%d mod\n", (nsec()-now)/(1000*loops),
  213. x->top*Dbits, y->top*Dbits);
  214. print("%B mod %B = %B\n", x, y, r);
  215. mpfree(r);
  216. }
  217. void
  218. testinvert(mpint *x, mpint *y)
  219. {
  220. mpint *r, *d1, *d2;
  221. vlong now;
  222. int i;
  223. r = mpnew(0);
  224. d1 = mpnew(0);
  225. d2 = mpnew(0);
  226. now = nsec();
  227. mpextendedgcd(x, y, r, d1, d2);
  228. mpdiv(x, r, x, d1);
  229. mpdiv(y, r, y, d1);
  230. for(i = 0; i < loops; i++)
  231. mpinvert(x, y, r);
  232. if(loops > 1)
  233. print("%lld µs for a %d in %d invert\n", (nsec()-now)/(1000*loops),
  234. x->top*Dbits, y->top*Dbits);
  235. print("%B**-1 mod %B = %B\n", x, y, r);
  236. mpmul(r, x, d1);
  237. mpmod(d1, y, d2);
  238. print("%B*%B mod %B = %B\n", x, r, y, d2);
  239. mpfree(r);
  240. mpfree(d1);
  241. mpfree(d2);
  242. }
  243. void
  244. testsub1(char *a, char *b)
  245. {
  246. mpint *b1, *b2, *b3;
  247. b1 = strtomp(a, nil, 16, nil);
  248. b2 = strtomp(b, nil, 16, nil);
  249. b3 = mpnew(0);
  250. mpsub(b1, b2, b3);
  251. print("%B - %B = %B\n", b1, b2, b3);
  252. }
  253. void
  254. testmul1(char *a, char *b)
  255. {
  256. mpint *b1, *b2, *b3;
  257. b1 = strtomp(a, nil, 16, nil);
  258. b2 = strtomp(b, nil, 16, nil);
  259. b3 = mpnew(0);
  260. mpmul(b1, b2, b3);
  261. print("%B * %B = %B\n", b1, b2, b3);
  262. }
  263. void
  264. testexp(char *base, char *exp, char *mod)
  265. {
  266. mpint *b, *e, *m, *res;
  267. int i;
  268. uvlong now;
  269. b = strtomp(base, nil, 16, nil);
  270. e = strtomp(exp, nil, 16, nil);
  271. res = mpnew(0);
  272. if(mod != nil)
  273. m = strtomp(mod, nil, 16, nil);
  274. else
  275. m = nil;
  276. now = nsec();
  277. for(i = 0; i < loops; i++)
  278. mpexp(b, e, m, res);
  279. if(loops > 1)
  280. print("%ulldµs for a %d to the %d bit exp\n", (nsec()-now)/(loops*1000),
  281. b->top*Dbits, e->top*Dbits);
  282. if(m != nil)
  283. print("%B ^ %B mod %B == %B\n", b, e, m, res);
  284. else
  285. print("%B ^ %B == %B\n", b, e, res);
  286. mpfree(b);
  287. mpfree(e);
  288. mpfree(res);
  289. if(m != nil)
  290. mpfree(m);
  291. }
  292. void
  293. testgcd(void)
  294. {
  295. mpint *a, *b, *d, *x, *y, *t1, *t2;
  296. int i;
  297. uvlong now, then;
  298. uvlong etime;
  299. d = mpnew(0);
  300. x = mpnew(0);
  301. y = mpnew(0);
  302. t1 = mpnew(0);
  303. t2 = mpnew(0);
  304. etime = 0;
  305. a = strtomp("4EECAB3E04C4E6BC1F49D438731450396BF272B4D7B08F91C38E88ADCD281699889AFF872E2204C80CCAA8E460797103DE539D5DF8335A9B20C0B44886384F134C517287202FCA914D8A5096446B40CD861C641EF9C2730CB057D7B133F4C2B16BBD3D75FDDBD9151AAF0F9144AAA473AC93CF945DBFE0859FB685D5CBD0A8B3", nil, 16, nil);
  306. b = strtomp("C41CFBE4D4846F67A3DF7DE9921A49D3B42DC33728427AB159CEC8CBBDB12B5F0C244F1A734AEB9840804EA3C25036AD1B61AFF3ABBC247CD4B384224567A863A6F020E7EE9795554BCD08ABAD7321AF27E1E92E3DB1C6E7E94FAAE590AE9C48F96D93D178E809401ABE8A534A1EC44359733475A36A70C7B425125062B1142D", nil, 16, nil);
  307. mpextendedgcd(a, b, d, x, y);
  308. print("gcd %B*%B+%B*%B = %B?\n", a, x, b, y, d);
  309. mpfree(a);
  310. mpfree(b);
  311. for(i = 0; i < loops; i++){
  312. a = mprand(2048, prng, nil);
  313. b = mprand(2048, prng, nil);
  314. then = nsec();
  315. mpextendedgcd(a, b, d, x, y);
  316. now = nsec();
  317. etime += now-then;
  318. mpmul(a, x, t1);
  319. mpmul(b, y, t2);
  320. mpadd(t1, t2, t2);
  321. if(mpcmp(d, t2) != 0)
  322. print("%d gcd %B*%B+%B*%B != %B\n", i, a, x, b, y, d);
  323. // else
  324. // print("%d euclid %B*%B+%B*%B == %B\n", i, a, x, b, y, d);
  325. mpfree(a);
  326. mpfree(b);
  327. }
  328. mpfree(x);
  329. mpfree(y);
  330. mpfree(d);
  331. mpfree(t1);
  332. mpfree(t2);
  333. if(loops > 1)
  334. print("binary %llud\n", etime);
  335. }
  336. extern int _unnormalizedwarning = 1;
  337. void
  338. main(int argc, char **argv)
  339. {
  340. mpint *x, *y;
  341. ARGBEGIN{
  342. case 'n':
  343. loops = atoi(ARGF());
  344. break;
  345. }ARGEND;
  346. fmtinstall('B', mpconv);
  347. fmtinstall('Q', mpconv);
  348. srand(0);
  349. mpsetminbits(2*Dbits);
  350. testshift("1111111111111111");
  351. testaddsub("fffffffffffffffff");
  352. testdigdiv("1234567812345678", 0x76543218);
  353. testdigdiv("1ffff", 0xffff);
  354. testdigdiv("ffff", 0xffff);
  355. testdigdiv("fff", 0xffff);
  356. testdigdiv("effffffff", 0xffff);
  357. testdigdiv("ffffffff", 0x1);
  358. testdigdiv("ffffffff", 0);
  359. testdigdiv("200000000", 2);
  360. testdigdiv("ffffff00fffffff1", 0xfffffff1);
  361. testvecdigmuladd("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 2);
  362. testconv("0");
  363. testconv("-abc0123456789abcedf");
  364. testconv("abc0123456789abcedf");
  365. testvecdigmulsub("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 2);
  366. testsub1("1FFFFFFFE00000000", "FFFFFFFE00000001");
  367. testmul1("ffffffff", "f");
  368. testmul("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
  369. testmul1("100000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000004FFFFFFFFFFFFFFFE0000000200000000000000000000000000000003FFFFFFFFFFFFFFFE0000000200000000000000000000000000000002FFFFFFFFFFFFFFFE0000000200000000000000000000000000000001FFFFFFFFFFFFFFFE0000000200000000000000000000000000000000FFFFFFFFFFFFFFFE0000000200000000FFFFFFFE00000001", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
  370. testmul1("1000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001", "1000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001");
  371. testmul1("1000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001", "1000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001000000000000000000000001");
  372. testmul1("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
  373. x = mprand(256, prng, nil);
  374. y = mprand(128, prng, nil);
  375. testdiv(x, y);
  376. x = mprand(2048, prng, nil);
  377. y = mprand(1024, prng, nil);
  378. testdiv(x, y);
  379. // x = mprand(4*1024, prng, nil);
  380. // y = mprand(4*1024, prng, nil);
  381. // testmul2(x, y);
  382. testsub1("677132C9", "-A26559B6");
  383. testgcd();
  384. x = mprand(512, prng, nil);
  385. x->sign = -1;
  386. y = mprand(256, prng, nil);
  387. testdiv(x, y);
  388. testmod(x, y);
  389. x->sign = 1;
  390. testinvert(y, x);
  391. testexp("111111111", "222", "1000000000000000000000");
  392. testexp("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
  393. #ifdef asdf
  394. #endif adsf
  395. print("done\n");
  396. exits(0);
  397. }