ipint.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  1. #include "lib9.h"
  2. #include "kernel.h"
  3. #include <isa.h>
  4. #include "interp.h"
  5. #include "runt.h"
  6. #include <mp.h>
  7. #include <libsec.h>
  8. #include "pool.h"
  9. #include "ipint.h"
  10. #include "raise.h"
  11. #include "ipintsmod.h"
  12. enum
  13. {
  14. MaxBigBytes = 1024
  15. };
  16. /* infinite precision integer */
  17. struct IPint
  18. {
  19. IPints_IPint x;
  20. mpint* b;
  21. };
  22. Type *TIPint;
  23. static uchar IPintmap[] = IPints_IPint_map;
  24. #define MP(x) checkIPint((x))
  25. void
  26. ipintsmodinit(void)
  27. {
  28. /* can be called from modinit, Keyring or Crypt */
  29. if(TIPint == nil)
  30. TIPint = dtype(freeIPint, sizeof(IPint), IPintmap, sizeof(IPintmap));
  31. builtinmod("$IPints", IPintsmodtab, IPintsmodlen);
  32. }
  33. //IPints_IPint*
  34. void*
  35. newIPint(mpint* b)
  36. {
  37. Heap *h;
  38. IPint *ip;
  39. if(b == nil)
  40. error(exHeap);
  41. h = heap(TIPint); /* TO DO: caller might lose other values if heap raises error here */
  42. ip = H2D(IPint*, h);
  43. ip->b = b;
  44. return (IPints_IPint*)ip;
  45. }
  46. mpint*
  47. checkIPint(void *a)
  48. {
  49. IPints_IPint *v;
  50. IPint *ip;
  51. v = a;
  52. ip = (IPint*)v;
  53. if(ip == H || ip == nil)
  54. error(exNilref);
  55. if(D2H(ip)->t != TIPint)
  56. error(exType);
  57. return ip->b; /* non-nil by construction */
  58. }
  59. void
  60. freeIPint(Heap *h, int swept)
  61. {
  62. IPint *ip;
  63. USED(swept);
  64. ip = H2D(IPint*, h);
  65. if(ip->b)
  66. mpfree(ip->b);
  67. freeheap(h, 0);
  68. }
  69. void
  70. IPint_iptob64z(void *fp)
  71. {
  72. F_IPint_iptob64 *f;
  73. mpint *b;
  74. char buf[MaxBigBytes]; /* TO DO: should allocate these */
  75. uchar *p;
  76. int n, o;
  77. void *v;
  78. f = fp;
  79. v = *f->ret;
  80. *f->ret = H;
  81. destroy(v);
  82. b = MP(f->i);
  83. n = (b->top+1)*Dbytes;
  84. p = malloc(n+1);
  85. if(p == nil)
  86. error(exHeap);
  87. n = mptobe(b, p+1, n, nil);
  88. if(n < 0){
  89. free(p);
  90. return;
  91. }
  92. p[0] = 0;
  93. if(n != 0 && (p[1]&0x80)){
  94. /* force leading 0 byte for compatibility with older representation */
  95. o = 0;
  96. n++;
  97. }else
  98. o = 1;
  99. enc64(buf, sizeof(buf), p+o, n);
  100. retstr(buf, f->ret);
  101. free(p);
  102. }
  103. void
  104. IPint_iptob64(void *fp)
  105. {
  106. F_IPint_iptob64 *f;
  107. char buf[MaxBigBytes];
  108. void *v;
  109. f = fp;
  110. v = *f->ret;
  111. *f->ret = H;
  112. destroy(v);
  113. mptoa(MP(f->i), 64, buf, sizeof(buf));
  114. retstr(buf, f->ret);
  115. }
  116. void
  117. IPint_iptobytes(void *fp)
  118. {
  119. F_IPint_iptobytes *f;
  120. uchar buf[MaxBigBytes];
  121. void *v;
  122. f = fp;
  123. v = *f->ret;
  124. *f->ret = H;
  125. destroy(v);
  126. /* TO DO: two's complement or have ipmagtobe? */
  127. *f->ret = mem2array(buf, mptobe(MP(f->i), buf, sizeof(buf), nil)); /* for now we'll ignore sign */
  128. }
  129. void
  130. IPint_iptobebytes(void *fp)
  131. {
  132. F_IPint_iptobebytes *f;
  133. uchar buf[MaxBigBytes];
  134. void *v;
  135. f = fp;
  136. v = *f->ret;
  137. *f->ret = H;
  138. destroy(v);
  139. *f->ret = mem2array(buf, mptobe(MP(f->i), buf, sizeof(buf), nil));
  140. }
  141. void
  142. IPint_iptostr(void *fp)
  143. {
  144. F_IPint_iptostr *f;
  145. char buf[MaxBigBytes];
  146. void *v;
  147. f = fp;
  148. v = *f->ret;
  149. *f->ret = H;
  150. destroy(v);
  151. mptoa(MP(f->i), f->base, buf, sizeof(buf));
  152. retstr(buf, f->ret);
  153. }
  154. static IPints_IPint*
  155. strtoipint(String *s, int base)
  156. {
  157. char *p, *q;
  158. mpint *b;
  159. p = string2c(s);
  160. b = strtomp(p, &q, base, nil);
  161. if(b == nil)
  162. return H;
  163. while(*q == '=')
  164. q++;
  165. if(q == p || *q != 0){
  166. mpfree(b);
  167. return H;
  168. }
  169. return newIPint(b);
  170. }
  171. void
  172. IPint_b64toip(void *fp)
  173. {
  174. F_IPint_b64toip *f;
  175. void *v;
  176. f = fp;
  177. v = *f->ret;
  178. *f->ret = H;
  179. destroy(v);
  180. *f->ret = strtoipint(f->str, 64);
  181. }
  182. void
  183. IPint_bytestoip(void *fp)
  184. {
  185. F_IPint_bytestoip *f;
  186. mpint *b;
  187. void *v;
  188. f = fp;
  189. v = *f->ret;
  190. *f->ret = H;
  191. destroy(v);
  192. if(f->buf == H)
  193. error(exNilref);
  194. b = betomp(f->buf->data, f->buf->len, nil); /* for now we'll ignore sign */
  195. *f->ret = newIPint(b);
  196. }
  197. void
  198. IPint_bebytestoip(void *fp)
  199. {
  200. F_IPint_bebytestoip *f;
  201. mpint *b;
  202. void *v;
  203. f = fp;
  204. v = *f->ret;
  205. *f->ret = H;
  206. destroy(v);
  207. if(f->mag == H)
  208. error(exNilref);
  209. b = betomp(f->mag->data, f->mag->len, nil);
  210. *f->ret = newIPint(b);
  211. }
  212. void
  213. IPint_strtoip(void *fp)
  214. {
  215. F_IPint_strtoip *f;
  216. void *v;
  217. f = fp;
  218. v = *f->ret;
  219. *f->ret = H;
  220. destroy(v);
  221. *f->ret = strtoipint(f->str, f->base);
  222. }
  223. /* create a random integer */
  224. void
  225. IPint_random(void *fp)
  226. {
  227. F_IPint_random *f;
  228. mpint *b;
  229. void *v;
  230. f = fp;
  231. v = *f->ret;
  232. *f->ret = H;
  233. destroy(v);
  234. release();
  235. b = mprand(f->nbits, genrandom, nil);
  236. acquire();
  237. *f->ret = newIPint(b);
  238. }
  239. /* number of bits in number */
  240. void
  241. IPint_bits(void *fp)
  242. {
  243. F_IPint_bits *f;
  244. int n;
  245. f = fp;
  246. *f->ret = 0;
  247. if(f->i == H)
  248. return;
  249. n = mpsignif(MP(f->i));
  250. if(n == 0)
  251. n = 1; /* compatibility */
  252. *f->ret = n;
  253. }
  254. /* create a new IP from an int */
  255. void
  256. IPint_inttoip(void *fp)
  257. {
  258. F_IPint_inttoip *f;
  259. void *v;
  260. f = fp;
  261. v = *f->ret;
  262. *f->ret = H;
  263. destroy(v);
  264. *f->ret = newIPint(itomp(f->i, nil));
  265. }
  266. void
  267. IPint_iptoint(void *fp)
  268. {
  269. F_IPint_iptoint *f;
  270. f = fp;
  271. *f->ret = 0;
  272. if(f->i == H)
  273. return;
  274. *f->ret = mptoi(MP(f->i));
  275. }
  276. /* modular exponentiation */
  277. void
  278. IPint_expmod(void *fp)
  279. {
  280. F_IPint_expmod *f;
  281. mpint *ret, *mod, *base, *exp;
  282. void *v;
  283. f = fp;
  284. v = *f->ret;
  285. *f->ret = H;
  286. destroy(v);
  287. base = MP(f->base);
  288. exp = MP(f->exp);
  289. if(f->mod != H)
  290. mod = MP(f->mod);
  291. else
  292. mod = nil;
  293. ret = mpnew(0);
  294. if(ret != nil)
  295. mpexp(base, exp, mod, ret);
  296. *f->ret = newIPint(ret);
  297. }
  298. /* multiplicative inverse */
  299. void
  300. IPint_invert(void *fp)
  301. {
  302. F_IPint_invert *f;
  303. mpint *ret;
  304. void *v;
  305. f = fp;
  306. v = *f->ret;
  307. *f->ret = H;
  308. destroy(v);
  309. ret = mpnew(0);
  310. if(ret != nil)
  311. mpinvert(MP(f->base), MP(f->mod), ret);
  312. *f->ret = newIPint(ret);
  313. }
  314. /* basic math */
  315. void
  316. IPint_add(void *fp)
  317. {
  318. F_IPint_add *f;
  319. mpint *i1, *i2, *ret;
  320. void *v;
  321. f = fp;
  322. v = *f->ret;
  323. *f->ret = H;
  324. destroy(v);
  325. i1 = MP(f->i1);
  326. i2 = MP(f->i2);
  327. ret = mpnew(0);
  328. if(ret != nil)
  329. mpadd(i1, i2, ret);
  330. *f->ret = newIPint(ret);
  331. }
  332. void
  333. IPint_sub(void *fp)
  334. {
  335. F_IPint_sub *f;
  336. mpint *i1, *i2, *ret;
  337. void *v;
  338. f = fp;
  339. v = *f->ret;
  340. *f->ret = H;
  341. destroy(v);
  342. i1 = MP(f->i1);
  343. i2 = MP(f->i2);
  344. ret = mpnew(0);
  345. if(ret != nil)
  346. mpsub(i1, i2, ret);
  347. *f->ret = newIPint(ret);
  348. }
  349. void
  350. IPint_mul(void *fp)
  351. {
  352. F_IPint_mul *f;
  353. mpint *i1, *i2, *ret;
  354. void *v;
  355. f = fp;
  356. v = *f->ret;
  357. *f->ret = H;
  358. destroy(v);
  359. i1 = MP(f->i1);
  360. i2 = MP(f->i2);
  361. ret = mpnew(0);
  362. if(ret != nil)
  363. mpmul(i1, i2, ret);
  364. *f->ret = newIPint(ret);
  365. }
  366. void
  367. IPint_div(void *fp)
  368. {
  369. F_IPint_div *f;
  370. mpint *i1, *i2, *quo, *rem;
  371. void *v;
  372. f = fp;
  373. v = f->ret->t0;
  374. f->ret->t0 = H;
  375. destroy(v);
  376. v = f->ret->t1;
  377. f->ret->t1 = H;
  378. destroy(v);
  379. i1 = MP(f->i1);
  380. i2 = MP(f->i2);
  381. quo = mpnew(0);
  382. if(quo == nil)
  383. error(exHeap);
  384. rem = mpnew(0);
  385. if(rem == nil){
  386. mpfree(quo);
  387. error(exHeap);
  388. }
  389. mpdiv(i1, i2, quo, rem);
  390. f->ret->t0 = newIPint(quo);
  391. f->ret->t1 = newIPint(rem);
  392. }
  393. void
  394. IPint_mod(void *fp)
  395. {
  396. F_IPint_mod *f;
  397. mpint *i1, *i2, *ret;
  398. void *v;
  399. f = fp;
  400. v = *f->ret;
  401. *f->ret = H;
  402. destroy(v);
  403. i1 = MP(f->i1);
  404. i2 = MP(f->i2);
  405. ret = mpnew(0);
  406. if(ret != nil)
  407. mpmod(i1, i2, ret);
  408. *f->ret = newIPint(ret);
  409. }
  410. void
  411. IPint_neg(void *fp)
  412. {
  413. F_IPint_neg *f;
  414. mpint *ret;
  415. void *v;
  416. f = fp;
  417. v = *f->ret;
  418. *f->ret = H;
  419. destroy(v);
  420. ret = mpcopy(MP(f->i));
  421. if(ret == nil)
  422. error(exHeap);
  423. ret->sign = -ret->sign;
  424. *f->ret = newIPint(ret);
  425. }
  426. /* copy */
  427. void
  428. IPint_copy(void *fp)
  429. {
  430. F_IPint_copy *f;
  431. void *v;
  432. f = fp;
  433. v = *f->ret;
  434. *f->ret = H;
  435. destroy(v);
  436. *f->ret = newIPint(mpcopy(MP(f->i)));
  437. }
  438. /* equality */
  439. void
  440. IPint_eq(void *fp)
  441. {
  442. F_IPint_eq *f;
  443. f = fp;
  444. *f->ret = mpcmp(MP(f->i1), MP(f->i2)) == 0;
  445. }
  446. /* compare */
  447. void
  448. IPint_cmp(void *fp)
  449. {
  450. F_IPint_eq *f;
  451. f = fp;
  452. *f->ret = mpcmp(MP(f->i1), MP(f->i2));
  453. }
  454. /* shifts */
  455. void
  456. IPint_shl(void *fp)
  457. {
  458. F_IPint_shl *f;
  459. mpint *ret, *i;
  460. void *v;
  461. f = fp;
  462. v = *f->ret;
  463. *f->ret = H;
  464. destroy(v);
  465. i = MP(f->i);
  466. ret = mpnew(0);
  467. if(ret != nil)
  468. mpleft(i, f->n, ret);
  469. *f->ret = newIPint(ret);
  470. }
  471. void
  472. IPint_shr(void *fp)
  473. {
  474. F_IPint_shr *f;
  475. mpint *ret, *i;
  476. void *v;
  477. f = fp;
  478. v = *f->ret;
  479. *f->ret = H;
  480. destroy(v);
  481. i = MP(f->i);
  482. ret = mpnew(0);
  483. if(ret != nil)
  484. mpright(i, f->n, ret);
  485. *f->ret = newIPint(ret);
  486. }
  487. static void
  488. mpand(mpint *b, mpint *m, mpint *res)
  489. {
  490. int i;
  491. res->sign = b->sign;
  492. if(b->top == 0 || m->top == 0){
  493. res->top = 0;
  494. return;
  495. }
  496. mpbits(res, b->top*Dbits);
  497. res->top = b->top;
  498. for(i = b->top; --i >= 0;){
  499. if(i < m->top)
  500. res->p[i] = b->p[i] & m->p[i];
  501. else
  502. res->p[i] = 0;
  503. }
  504. mpnorm(res);
  505. }
  506. static void
  507. mpor(mpint *b1, mpint *b2, mpint *res)
  508. {
  509. mpint *t;
  510. int i;
  511. if(b2->top > b1->top){
  512. t = b1;
  513. b1 = b2;
  514. b2 = t;
  515. }
  516. if(b1->top == 0){
  517. mpassign(b2, res);
  518. return;
  519. }
  520. if(b2->top == 0){
  521. mpassign(b1, res);
  522. return;
  523. }
  524. mpassign(b1, res);
  525. for(i = b2->top; --i >= 0;)
  526. res->p[i] |= b2->p[i];
  527. mpnorm(res);
  528. }
  529. static void
  530. mpxor(mpint *b1, mpint *b2, mpint *res)
  531. {
  532. mpint *t;
  533. int i;
  534. if(b2->top > b1->top){
  535. t = b1;
  536. b1 = b2;
  537. b2 = t;
  538. }
  539. if(b1->top == 0){
  540. mpassign(b2, res);
  541. return;
  542. }
  543. if(b2->top == 0){
  544. mpassign(b1, res);
  545. return;
  546. }
  547. mpassign(b1, res);
  548. for(i = b2->top; --i >= 0;)
  549. res->p[i] ^= b2->p[i];
  550. mpnorm(res);
  551. }
  552. static void
  553. mpnot(mpint *b1, mpint *res)
  554. {
  555. int i;
  556. mpbits(res, Dbits*b1->top);
  557. res->sign = 1;
  558. res->top = b1->top;
  559. for(i = res->top; --i >= 0;)
  560. res->p[i] = ~b1->p[i];
  561. mpnorm(res);
  562. }
  563. /* bits */
  564. void
  565. IPint_and(void *fp)
  566. {
  567. F_IPint_and *f;
  568. mpint *ret, *i1, *i2;
  569. void *v;
  570. f = fp;
  571. v = *f->ret;
  572. *f->ret = H;
  573. destroy(v);
  574. i1 = MP(f->i1);
  575. i2 = MP(f->i2);
  576. ret = mpnew(0);
  577. if(ret != nil)
  578. mpand(i1, i2, ret);
  579. *f->ret = newIPint(ret);
  580. }
  581. void
  582. IPint_ori(void *fp)
  583. {
  584. F_IPint_ori *f;
  585. mpint *ret, *i1, *i2;
  586. void *v;
  587. f = fp;
  588. v = *f->ret;
  589. *f->ret = H;
  590. destroy(v);
  591. i1 = MP(f->i1);
  592. i2 = MP(f->i2);
  593. ret = mpnew(0);
  594. if(ret != nil)
  595. mpor(i1, i2, ret);
  596. *f->ret = newIPint(ret);
  597. }
  598. void
  599. IPint_xor(void *fp)
  600. {
  601. F_IPint_xor *f;
  602. mpint *ret, *i1, *i2;
  603. void *v;
  604. f = fp;
  605. v = *f->ret;
  606. *f->ret = H;
  607. destroy(v);
  608. i1 = MP(f->i1);
  609. i2 = MP(f->i2);
  610. ret = mpnew(0);
  611. if(ret != nil)
  612. mpxor(i1, i2, ret);
  613. *f->ret = newIPint(ret);
  614. }
  615. void
  616. IPint_not(void *fp)
  617. {
  618. F_IPint_not *f;
  619. mpint *ret, *i1;
  620. void *v;
  621. f = fp;
  622. v = *f->ret;
  623. *f->ret = H;
  624. destroy(v);
  625. i1 = MP(f->i1);
  626. ret = mpnew(0);
  627. if(ret != nil)
  628. mpnot(i1, ret);
  629. *f->ret = newIPint(ret);
  630. }
  631. /*
  632. * primes
  633. */
  634. void
  635. IPints_probably_prime(void *fp)
  636. {
  637. F_IPints_probably_prime *f;
  638. f = fp;
  639. release();
  640. *f->ret = probably_prime(checkIPint(f->n), f->nrep);
  641. acquire();
  642. }
  643. void
  644. IPints_genprime(void *fp)
  645. {
  646. F_IPints_genprime *f;
  647. mpint *p;
  648. void *r;
  649. f = fp;
  650. r = *f->ret;
  651. *f->ret = H;
  652. destroy(r);
  653. p = mpnew(0);
  654. release();
  655. genprime(p, f->nbits, f->nrep);
  656. acquire();
  657. *f->ret = newIPint(p);
  658. }
  659. void
  660. IPints_genstrongprime(void *fp)
  661. {
  662. F_IPints_genstrongprime *f;
  663. mpint *p;
  664. void *r;
  665. f = fp;
  666. r = *f->ret;
  667. *f->ret = H;
  668. destroy(r);
  669. p = mpnew(0);
  670. release();
  671. genstrongprime(p, f->nbits, f->nrep);
  672. acquire();
  673. *f->ret = newIPint(p);
  674. }
  675. void
  676. IPints_gensafeprime(void *fp)
  677. {
  678. F_IPints_gensafeprime *f;
  679. mpint *p, *alpha;
  680. void *v;
  681. f = fp;
  682. v = f->ret->t0;
  683. f->ret->t0 = H;
  684. destroy(v);
  685. v = f->ret->t1;
  686. f->ret->t1 = H;
  687. destroy(v);
  688. p = mpnew(0);
  689. alpha = mpnew(0);
  690. release();
  691. gensafeprime(p, alpha, f->nbits, f->nrep);
  692. acquire();
  693. f->ret->t0 = newIPint(p);
  694. f->ret->t1 = newIPint(alpha);
  695. }
  696. void
  697. IPints_DSAprimes(void *fp)
  698. {
  699. F_IPints_DSAprimes *f;
  700. mpint *p, *q;
  701. Heap *h;
  702. void *v;
  703. f = fp;
  704. v = f->ret->t0;
  705. f->ret->t0 = H;
  706. destroy(v);
  707. v = f->ret->t1;
  708. f->ret->t1 = H;
  709. destroy(v);
  710. v = f->ret->t2;
  711. f->ret->t2 = H;
  712. destroy(v);
  713. h = heaparray(&Tbyte, SHA1dlen);
  714. f->ret->t2 = H2D(Array*, h);
  715. p = mpnew(0);
  716. q = mpnew(0);
  717. release();
  718. DSAprimes(q, p, f->ret->t2->data);
  719. acquire();
  720. f->ret->t0 = newIPint(q);
  721. f->ret->t1 = newIPint(p);
  722. }