test.c 12 KB

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