137da2899SCharles.Forsyth #include "lib9.h"
237da2899SCharles.Forsyth #include "kernel.h"
337da2899SCharles.Forsyth #include <isa.h>
437da2899SCharles.Forsyth #include "interp.h"
537da2899SCharles.Forsyth #include "runt.h"
637da2899SCharles.Forsyth #include <mp.h>
737da2899SCharles.Forsyth #include <libsec.h>
837da2899SCharles.Forsyth #include "pool.h"
9*7de2b42dSforsyth #include "ipint.h"
1037da2899SCharles.Forsyth #include "raise.h"
1137da2899SCharles.Forsyth
12*7de2b42dSforsyth #include "ipintsmod.h"
13*7de2b42dSforsyth
14*7de2b42dSforsyth enum
15*7de2b42dSforsyth {
16*7de2b42dSforsyth MaxBigBytes = 1024
17*7de2b42dSforsyth };
18*7de2b42dSforsyth
19*7de2b42dSforsyth /* infinite precision integer */
20*7de2b42dSforsyth struct IPint
21*7de2b42dSforsyth {
22*7de2b42dSforsyth IPints_IPint x;
23*7de2b42dSforsyth mpint* b;
24*7de2b42dSforsyth };
25*7de2b42dSforsyth
26*7de2b42dSforsyth Type *TIPint;
27*7de2b42dSforsyth static uchar IPintmap[] = IPints_IPint_map;
28*7de2b42dSforsyth
2931a18a69SCharles.Forsyth #define MP(x) checkIPint((x))
3037da2899SCharles.Forsyth
31*7de2b42dSforsyth void
ipintsmodinit(void)32*7de2b42dSforsyth ipintsmodinit(void)
33*7de2b42dSforsyth {
34*7de2b42dSforsyth /* can be called from modinit, Keyring or Crypt */
35*7de2b42dSforsyth if(TIPint == nil)
36*7de2b42dSforsyth TIPint = dtype(freeIPint, sizeof(IPint), IPintmap, sizeof(IPintmap));
37*7de2b42dSforsyth builtinmod("$IPints", IPintsmodtab, IPintsmodlen);
38*7de2b42dSforsyth }
39*7de2b42dSforsyth
40*7de2b42dSforsyth //IPints_IPint*
41*7de2b42dSforsyth void*
newIPint(mpint * b)4231a18a69SCharles.Forsyth newIPint(mpint* b)
4337da2899SCharles.Forsyth {
4437da2899SCharles.Forsyth Heap *h;
4537da2899SCharles.Forsyth IPint *ip;
4637da2899SCharles.Forsyth
4737da2899SCharles.Forsyth if(b == nil)
4837da2899SCharles.Forsyth error(exHeap);
4931a18a69SCharles.Forsyth h = heap(TIPint); /* TO DO: caller might lose other values if heap raises error here */
5037da2899SCharles.Forsyth ip = H2D(IPint*, h);
5137da2899SCharles.Forsyth ip->b = b;
52*7de2b42dSforsyth return (IPints_IPint*)ip;
5337da2899SCharles.Forsyth }
5437da2899SCharles.Forsyth
5531a18a69SCharles.Forsyth mpint*
checkIPint(void * a)56*7de2b42dSforsyth checkIPint(void *a)
5731a18a69SCharles.Forsyth {
58*7de2b42dSforsyth IPints_IPint *v;
5931a18a69SCharles.Forsyth IPint *ip;
6031a18a69SCharles.Forsyth
61*7de2b42dSforsyth v = a;
6231a18a69SCharles.Forsyth ip = (IPint*)v;
6331a18a69SCharles.Forsyth if(ip == H || ip == nil)
6431a18a69SCharles.Forsyth error(exNilref);
6531a18a69SCharles.Forsyth if(D2H(ip)->t != TIPint)
6631a18a69SCharles.Forsyth error(exType);
67*7de2b42dSforsyth return ip->b; /* non-nil by construction */
6831a18a69SCharles.Forsyth }
6931a18a69SCharles.Forsyth
7037da2899SCharles.Forsyth void
freeIPint(Heap * h,int swept)7137da2899SCharles.Forsyth freeIPint(Heap *h, int swept)
7237da2899SCharles.Forsyth {
7337da2899SCharles.Forsyth IPint *ip;
7437da2899SCharles.Forsyth
7537da2899SCharles.Forsyth USED(swept);
7637da2899SCharles.Forsyth ip = H2D(IPint*, h);
7737da2899SCharles.Forsyth if(ip->b)
7837da2899SCharles.Forsyth mpfree(ip->b);
7937da2899SCharles.Forsyth freeheap(h, 0);
8037da2899SCharles.Forsyth }
8137da2899SCharles.Forsyth
8237da2899SCharles.Forsyth void
IPint_iptob64z(void * fp)83ca1042d3SCharles.Forsyth IPint_iptob64z(void *fp)
84ca1042d3SCharles.Forsyth {
85ca1042d3SCharles.Forsyth F_IPint_iptob64 *f;
8631a18a69SCharles.Forsyth mpint *b;
87ca1042d3SCharles.Forsyth char buf[MaxBigBytes]; /* TO DO: should allocate these */
88ca1042d3SCharles.Forsyth uchar *p;
89ca1042d3SCharles.Forsyth int n, o;
903d7a0c16SCharles.Forsyth void *v;
91ca1042d3SCharles.Forsyth
92ca1042d3SCharles.Forsyth f = fp;
933d7a0c16SCharles.Forsyth v = *f->ret;
94ca1042d3SCharles.Forsyth *f->ret = H;
953d7a0c16SCharles.Forsyth destroy(v);
96ca1042d3SCharles.Forsyth
97ca1042d3SCharles.Forsyth b = MP(f->i);
98ca1042d3SCharles.Forsyth n = (b->top+1)*Dbytes;
99ca1042d3SCharles.Forsyth p = malloc(n+1);
100ca1042d3SCharles.Forsyth if(p == nil)
101ca1042d3SCharles.Forsyth error(exHeap);
102ca1042d3SCharles.Forsyth n = mptobe(b, p+1, n, nil);
103ca1042d3SCharles.Forsyth if(n < 0){
104ca1042d3SCharles.Forsyth free(p);
105ca1042d3SCharles.Forsyth return;
106ca1042d3SCharles.Forsyth }
107ca1042d3SCharles.Forsyth p[0] = 0;
108ca1042d3SCharles.Forsyth if(n != 0 && (p[1]&0x80)){
109ca1042d3SCharles.Forsyth /* force leading 0 byte for compatibility with older representation */
110ca1042d3SCharles.Forsyth o = 0;
111ca1042d3SCharles.Forsyth n++;
112ca1042d3SCharles.Forsyth }else
113ca1042d3SCharles.Forsyth o = 1;
114ca1042d3SCharles.Forsyth enc64(buf, sizeof(buf), p+o, n);
115ca1042d3SCharles.Forsyth retstr(buf, f->ret);
116ca1042d3SCharles.Forsyth free(p);
117ca1042d3SCharles.Forsyth }
118ca1042d3SCharles.Forsyth
119ca1042d3SCharles.Forsyth void
IPint_iptob64(void * fp)12037da2899SCharles.Forsyth IPint_iptob64(void *fp)
12137da2899SCharles.Forsyth {
12237da2899SCharles.Forsyth F_IPint_iptob64 *f;
12337da2899SCharles.Forsyth char buf[MaxBigBytes];
1243d7a0c16SCharles.Forsyth void *v;
12537da2899SCharles.Forsyth
12637da2899SCharles.Forsyth f = fp;
1273d7a0c16SCharles.Forsyth v = *f->ret;
12837da2899SCharles.Forsyth *f->ret = H;
1293d7a0c16SCharles.Forsyth destroy(v);
13037da2899SCharles.Forsyth
13137da2899SCharles.Forsyth mptoa(MP(f->i), 64, buf, sizeof(buf));
13237da2899SCharles.Forsyth retstr(buf, f->ret);
13337da2899SCharles.Forsyth }
13437da2899SCharles.Forsyth
13537da2899SCharles.Forsyth void
IPint_iptobytes(void * fp)13637da2899SCharles.Forsyth IPint_iptobytes(void *fp)
13737da2899SCharles.Forsyth {
13837da2899SCharles.Forsyth F_IPint_iptobytes *f;
13937da2899SCharles.Forsyth uchar buf[MaxBigBytes];
1403d7a0c16SCharles.Forsyth void *v;
14137da2899SCharles.Forsyth
14237da2899SCharles.Forsyth f = fp;
1433d7a0c16SCharles.Forsyth v = *f->ret;
14437da2899SCharles.Forsyth *f->ret = H;
1453d7a0c16SCharles.Forsyth destroy(v);
14637da2899SCharles.Forsyth
14737da2899SCharles.Forsyth /* TO DO: two's complement or have ipmagtobe? */
14837da2899SCharles.Forsyth *f->ret = mem2array(buf, mptobe(MP(f->i), buf, sizeof(buf), nil)); /* for now we'll ignore sign */
14937da2899SCharles.Forsyth }
15037da2899SCharles.Forsyth
15137da2899SCharles.Forsyth void
IPint_iptobebytes(void * fp)15237da2899SCharles.Forsyth IPint_iptobebytes(void *fp)
15337da2899SCharles.Forsyth {
15437da2899SCharles.Forsyth F_IPint_iptobebytes *f;
15537da2899SCharles.Forsyth uchar buf[MaxBigBytes];
1563d7a0c16SCharles.Forsyth void *v;
15737da2899SCharles.Forsyth
15837da2899SCharles.Forsyth f = fp;
1593d7a0c16SCharles.Forsyth v = *f->ret;
16037da2899SCharles.Forsyth *f->ret = H;
1613d7a0c16SCharles.Forsyth destroy(v);
16237da2899SCharles.Forsyth
16337da2899SCharles.Forsyth *f->ret = mem2array(buf, mptobe(MP(f->i), buf, sizeof(buf), nil));
16437da2899SCharles.Forsyth }
16537da2899SCharles.Forsyth
16637da2899SCharles.Forsyth void
IPint_iptostr(void * fp)16737da2899SCharles.Forsyth IPint_iptostr(void *fp)
16837da2899SCharles.Forsyth {
16937da2899SCharles.Forsyth F_IPint_iptostr *f;
17037da2899SCharles.Forsyth char buf[MaxBigBytes];
1713d7a0c16SCharles.Forsyth void *v;
17237da2899SCharles.Forsyth
17337da2899SCharles.Forsyth f = fp;
1743d7a0c16SCharles.Forsyth v = *f->ret;
17537da2899SCharles.Forsyth *f->ret = H;
1763d7a0c16SCharles.Forsyth destroy(v);
17737da2899SCharles.Forsyth
17837da2899SCharles.Forsyth mptoa(MP(f->i), f->base, buf, sizeof(buf));
17937da2899SCharles.Forsyth retstr(buf, f->ret);
18037da2899SCharles.Forsyth }
18137da2899SCharles.Forsyth
182*7de2b42dSforsyth static IPints_IPint*
strtoipint(String * s,int base)183ca1042d3SCharles.Forsyth strtoipint(String *s, int base)
184ca1042d3SCharles.Forsyth {
185ca1042d3SCharles.Forsyth char *p, *q;
18631a18a69SCharles.Forsyth mpint *b;
187ca1042d3SCharles.Forsyth
188ca1042d3SCharles.Forsyth p = string2c(s);
189ca1042d3SCharles.Forsyth b = strtomp(p, &q, base, nil);
190ca1042d3SCharles.Forsyth if(b == nil)
191ca1042d3SCharles.Forsyth return H;
19260951762SCharles.Forsyth while(*q == '=')
19360951762SCharles.Forsyth q++;
194ca1042d3SCharles.Forsyth if(q == p || *q != 0){
195ca1042d3SCharles.Forsyth mpfree(b);
196ca1042d3SCharles.Forsyth return H;
197ca1042d3SCharles.Forsyth }
198ca1042d3SCharles.Forsyth return newIPint(b);
199ca1042d3SCharles.Forsyth }
200ca1042d3SCharles.Forsyth
20137da2899SCharles.Forsyth void
IPint_b64toip(void * fp)20237da2899SCharles.Forsyth IPint_b64toip(void *fp)
20337da2899SCharles.Forsyth {
20437da2899SCharles.Forsyth F_IPint_b64toip *f;
2053d7a0c16SCharles.Forsyth void *v;
20637da2899SCharles.Forsyth
20737da2899SCharles.Forsyth f = fp;
2083d7a0c16SCharles.Forsyth v = *f->ret;
20937da2899SCharles.Forsyth *f->ret = H;
2103d7a0c16SCharles.Forsyth destroy(v);
21137da2899SCharles.Forsyth
212ca1042d3SCharles.Forsyth *f->ret = strtoipint(f->str, 64);
21337da2899SCharles.Forsyth }
21437da2899SCharles.Forsyth
21537da2899SCharles.Forsyth void
IPint_bytestoip(void * fp)21637da2899SCharles.Forsyth IPint_bytestoip(void *fp)
21737da2899SCharles.Forsyth {
21837da2899SCharles.Forsyth F_IPint_bytestoip *f;
21931a18a69SCharles.Forsyth mpint *b;
2203d7a0c16SCharles.Forsyth void *v;
22137da2899SCharles.Forsyth
22237da2899SCharles.Forsyth f = fp;
2233d7a0c16SCharles.Forsyth v = *f->ret;
22437da2899SCharles.Forsyth *f->ret = H;
2253d7a0c16SCharles.Forsyth destroy(v);
22637da2899SCharles.Forsyth
22737da2899SCharles.Forsyth if(f->buf == H)
22837da2899SCharles.Forsyth error(exNilref);
22937da2899SCharles.Forsyth
23037da2899SCharles.Forsyth b = betomp(f->buf->data, f->buf->len, nil); /* for now we'll ignore sign */
23137da2899SCharles.Forsyth *f->ret = newIPint(b);
23237da2899SCharles.Forsyth }
23337da2899SCharles.Forsyth
23437da2899SCharles.Forsyth void
IPint_bebytestoip(void * fp)23537da2899SCharles.Forsyth IPint_bebytestoip(void *fp)
23637da2899SCharles.Forsyth {
23737da2899SCharles.Forsyth F_IPint_bebytestoip *f;
23831a18a69SCharles.Forsyth mpint *b;
2393d7a0c16SCharles.Forsyth void *v;
24037da2899SCharles.Forsyth
24137da2899SCharles.Forsyth f = fp;
2423d7a0c16SCharles.Forsyth v = *f->ret;
24337da2899SCharles.Forsyth *f->ret = H;
2443d7a0c16SCharles.Forsyth destroy(v);
24537da2899SCharles.Forsyth
24637da2899SCharles.Forsyth if(f->mag == H)
24737da2899SCharles.Forsyth error(exNilref);
24837da2899SCharles.Forsyth
24937da2899SCharles.Forsyth b = betomp(f->mag->data, f->mag->len, nil);
25037da2899SCharles.Forsyth *f->ret = newIPint(b);
25137da2899SCharles.Forsyth }
25237da2899SCharles.Forsyth
25337da2899SCharles.Forsyth void
IPint_strtoip(void * fp)25437da2899SCharles.Forsyth IPint_strtoip(void *fp)
25537da2899SCharles.Forsyth {
25637da2899SCharles.Forsyth F_IPint_strtoip *f;
2573d7a0c16SCharles.Forsyth void *v;
25837da2899SCharles.Forsyth
25937da2899SCharles.Forsyth f = fp;
2603d7a0c16SCharles.Forsyth v = *f->ret;
26137da2899SCharles.Forsyth *f->ret = H;
2623d7a0c16SCharles.Forsyth destroy(v);
26337da2899SCharles.Forsyth
264ca1042d3SCharles.Forsyth *f->ret = strtoipint(f->str, f->base);
26537da2899SCharles.Forsyth }
26637da2899SCharles.Forsyth
26737da2899SCharles.Forsyth /* create a random integer */
26837da2899SCharles.Forsyth void
IPint_random(void * fp)26937da2899SCharles.Forsyth IPint_random(void *fp)
27037da2899SCharles.Forsyth {
27137da2899SCharles.Forsyth F_IPint_random *f;
27231a18a69SCharles.Forsyth mpint *b;
27331a18a69SCharles.Forsyth void *v;
27437da2899SCharles.Forsyth
27537da2899SCharles.Forsyth f = fp;
27631a18a69SCharles.Forsyth v = *f->ret;
27737da2899SCharles.Forsyth *f->ret = H;
27831a18a69SCharles.Forsyth destroy(v);
27937da2899SCharles.Forsyth
28037da2899SCharles.Forsyth release();
281*7de2b42dSforsyth b = mprand(f->nbits, genrandom, nil);
28237da2899SCharles.Forsyth acquire();
28337da2899SCharles.Forsyth *f->ret = newIPint(b);
28437da2899SCharles.Forsyth }
28537da2899SCharles.Forsyth
28637da2899SCharles.Forsyth /* number of bits in number */
28737da2899SCharles.Forsyth void
IPint_bits(void * fp)28837da2899SCharles.Forsyth IPint_bits(void *fp)
28937da2899SCharles.Forsyth {
29037da2899SCharles.Forsyth F_IPint_bits *f;
29137da2899SCharles.Forsyth int n;
29237da2899SCharles.Forsyth
29337da2899SCharles.Forsyth f = fp;
29437da2899SCharles.Forsyth *f->ret = 0;
29537da2899SCharles.Forsyth if(f->i == H)
29637da2899SCharles.Forsyth return;
29737da2899SCharles.Forsyth
29837da2899SCharles.Forsyth n = mpsignif(MP(f->i));
29937da2899SCharles.Forsyth if(n == 0)
30037da2899SCharles.Forsyth n = 1; /* compatibility */
30137da2899SCharles.Forsyth *f->ret = n;
30237da2899SCharles.Forsyth }
30337da2899SCharles.Forsyth
30437da2899SCharles.Forsyth /* create a new IP from an int */
30537da2899SCharles.Forsyth void
IPint_inttoip(void * fp)30637da2899SCharles.Forsyth IPint_inttoip(void *fp)
30737da2899SCharles.Forsyth {
30837da2899SCharles.Forsyth F_IPint_inttoip *f;
3093d7a0c16SCharles.Forsyth void *v;
31037da2899SCharles.Forsyth
31137da2899SCharles.Forsyth f = fp;
3123d7a0c16SCharles.Forsyth v = *f->ret;
31337da2899SCharles.Forsyth *f->ret = H;
3143d7a0c16SCharles.Forsyth destroy(v);
31537da2899SCharles.Forsyth
31637da2899SCharles.Forsyth *f->ret = newIPint(itomp(f->i, nil));
31737da2899SCharles.Forsyth }
31837da2899SCharles.Forsyth
31937da2899SCharles.Forsyth void
IPint_iptoint(void * fp)32037da2899SCharles.Forsyth IPint_iptoint(void *fp)
32137da2899SCharles.Forsyth {
32237da2899SCharles.Forsyth F_IPint_iptoint *f;
32337da2899SCharles.Forsyth
32437da2899SCharles.Forsyth f = fp;
32537da2899SCharles.Forsyth *f->ret = 0;
32637da2899SCharles.Forsyth if(f->i == H)
32737da2899SCharles.Forsyth return;
32837da2899SCharles.Forsyth *f->ret = mptoi(MP(f->i));
32937da2899SCharles.Forsyth }
33037da2899SCharles.Forsyth
33137da2899SCharles.Forsyth /* modular exponentiation */
33237da2899SCharles.Forsyth void
IPint_expmod(void * fp)33337da2899SCharles.Forsyth IPint_expmod(void *fp)
33437da2899SCharles.Forsyth {
33537da2899SCharles.Forsyth F_IPint_expmod *f;
3363d7a0c16SCharles.Forsyth mpint *ret, *mod, *base, *exp;
3373d7a0c16SCharles.Forsyth void *v;
33837da2899SCharles.Forsyth
33937da2899SCharles.Forsyth f = fp;
3403d7a0c16SCharles.Forsyth v = *f->ret;
34137da2899SCharles.Forsyth *f->ret = H;
3423d7a0c16SCharles.Forsyth destroy(v);
34337da2899SCharles.Forsyth
3443d7a0c16SCharles.Forsyth base = MP(f->base);
3453d7a0c16SCharles.Forsyth exp = MP(f->exp);
34637da2899SCharles.Forsyth if(f->mod != H)
34737da2899SCharles.Forsyth mod = MP(f->mod);
3483d7a0c16SCharles.Forsyth else
3493d7a0c16SCharles.Forsyth mod = nil;
35037da2899SCharles.Forsyth ret = mpnew(0);
35137da2899SCharles.Forsyth if(ret != nil)
3523d7a0c16SCharles.Forsyth mpexp(base, exp, mod, ret);
35337da2899SCharles.Forsyth *f->ret = newIPint(ret);
35437da2899SCharles.Forsyth }
35537da2899SCharles.Forsyth
35637da2899SCharles.Forsyth /* multiplicative inverse */
35737da2899SCharles.Forsyth void
IPint_invert(void * fp)35837da2899SCharles.Forsyth IPint_invert(void *fp)
35937da2899SCharles.Forsyth {
36037da2899SCharles.Forsyth F_IPint_invert *f;
36131a18a69SCharles.Forsyth mpint *ret;
3623d7a0c16SCharles.Forsyth void *v;
36337da2899SCharles.Forsyth
36437da2899SCharles.Forsyth f = fp;
3653d7a0c16SCharles.Forsyth v = *f->ret;
36637da2899SCharles.Forsyth *f->ret = H;
3673d7a0c16SCharles.Forsyth destroy(v);
36837da2899SCharles.Forsyth
36937da2899SCharles.Forsyth ret = mpnew(0);
37037da2899SCharles.Forsyth if(ret != nil)
37137da2899SCharles.Forsyth mpinvert(MP(f->base), MP(f->mod), ret);
37237da2899SCharles.Forsyth *f->ret = newIPint(ret);
37337da2899SCharles.Forsyth }
37437da2899SCharles.Forsyth
37537da2899SCharles.Forsyth /* basic math */
37637da2899SCharles.Forsyth void
IPint_add(void * fp)37737da2899SCharles.Forsyth IPint_add(void *fp)
37837da2899SCharles.Forsyth {
37937da2899SCharles.Forsyth F_IPint_add *f;
38031a18a69SCharles.Forsyth mpint *i1, *i2, *ret;
3813d7a0c16SCharles.Forsyth void *v;
38237da2899SCharles.Forsyth
38337da2899SCharles.Forsyth f = fp;
3843d7a0c16SCharles.Forsyth v = *f->ret;
38537da2899SCharles.Forsyth *f->ret = H;
3863d7a0c16SCharles.Forsyth destroy(v);
38737da2899SCharles.Forsyth
3883d7a0c16SCharles.Forsyth i1 = MP(f->i1);
3893d7a0c16SCharles.Forsyth i2 = MP(f->i2);
39037da2899SCharles.Forsyth ret = mpnew(0);
39137da2899SCharles.Forsyth if(ret != nil)
39237da2899SCharles.Forsyth mpadd(i1, i2, ret);
39337da2899SCharles.Forsyth
39437da2899SCharles.Forsyth *f->ret = newIPint(ret);
39537da2899SCharles.Forsyth }
39637da2899SCharles.Forsyth void
IPint_sub(void * fp)39737da2899SCharles.Forsyth IPint_sub(void *fp)
39837da2899SCharles.Forsyth {
39937da2899SCharles.Forsyth F_IPint_sub *f;
40031a18a69SCharles.Forsyth mpint *i1, *i2, *ret;
4013d7a0c16SCharles.Forsyth void *v;
40237da2899SCharles.Forsyth
40337da2899SCharles.Forsyth f = fp;
4043d7a0c16SCharles.Forsyth v = *f->ret;
40537da2899SCharles.Forsyth *f->ret = H;
4063d7a0c16SCharles.Forsyth destroy(v);
40737da2899SCharles.Forsyth
4083d7a0c16SCharles.Forsyth i1 = MP(f->i1);
4093d7a0c16SCharles.Forsyth i2 = MP(f->i2);
41037da2899SCharles.Forsyth ret = mpnew(0);
41137da2899SCharles.Forsyth if(ret != nil)
41237da2899SCharles.Forsyth mpsub(i1, i2, ret);
41337da2899SCharles.Forsyth
41437da2899SCharles.Forsyth *f->ret = newIPint(ret);
41537da2899SCharles.Forsyth }
41637da2899SCharles.Forsyth void
IPint_mul(void * fp)41737da2899SCharles.Forsyth IPint_mul(void *fp)
41837da2899SCharles.Forsyth {
41937da2899SCharles.Forsyth F_IPint_mul *f;
42031a18a69SCharles.Forsyth mpint *i1, *i2, *ret;
4213d7a0c16SCharles.Forsyth void *v;
42237da2899SCharles.Forsyth
42337da2899SCharles.Forsyth f = fp;
4243d7a0c16SCharles.Forsyth v = *f->ret;
42537da2899SCharles.Forsyth *f->ret = H;
4263d7a0c16SCharles.Forsyth destroy(v);
42737da2899SCharles.Forsyth
4283d7a0c16SCharles.Forsyth i1 = MP(f->i1);
4293d7a0c16SCharles.Forsyth i2 = MP(f->i2);
43037da2899SCharles.Forsyth ret = mpnew(0);
43137da2899SCharles.Forsyth if(ret != nil)
43237da2899SCharles.Forsyth mpmul(i1, i2, ret);
43337da2899SCharles.Forsyth
43437da2899SCharles.Forsyth *f->ret = newIPint(ret);
43537da2899SCharles.Forsyth }
43637da2899SCharles.Forsyth void
IPint_div(void * fp)43737da2899SCharles.Forsyth IPint_div(void *fp)
43837da2899SCharles.Forsyth {
43937da2899SCharles.Forsyth F_IPint_div *f;
44031a18a69SCharles.Forsyth mpint *i1, *i2, *quo, *rem;
4413d7a0c16SCharles.Forsyth void *v;
44237da2899SCharles.Forsyth
44337da2899SCharles.Forsyth f = fp;
4443d7a0c16SCharles.Forsyth v = f->ret->t0;
44537da2899SCharles.Forsyth f->ret->t0 = H;
4463d7a0c16SCharles.Forsyth destroy(v);
4473d7a0c16SCharles.Forsyth v = f->ret->t1;
44837da2899SCharles.Forsyth f->ret->t1 = H;
4493d7a0c16SCharles.Forsyth destroy(v);
45037da2899SCharles.Forsyth
4513d7a0c16SCharles.Forsyth i1 = MP(f->i1);
4523d7a0c16SCharles.Forsyth i2 = MP(f->i2);
45337da2899SCharles.Forsyth quo = mpnew(0);
45437da2899SCharles.Forsyth if(quo == nil)
45537da2899SCharles.Forsyth error(exHeap);
45637da2899SCharles.Forsyth rem = mpnew(0);
45737da2899SCharles.Forsyth if(rem == nil){
45837da2899SCharles.Forsyth mpfree(quo);
45937da2899SCharles.Forsyth error(exHeap);
46037da2899SCharles.Forsyth }
46137da2899SCharles.Forsyth mpdiv(i1, i2, quo, rem);
46237da2899SCharles.Forsyth
46337da2899SCharles.Forsyth f->ret->t0 = newIPint(quo);
46437da2899SCharles.Forsyth f->ret->t1 = newIPint(rem);
46537da2899SCharles.Forsyth }
46637da2899SCharles.Forsyth void
IPint_mod(void * fp)467ca1042d3SCharles.Forsyth IPint_mod(void *fp)
468ca1042d3SCharles.Forsyth {
469ca1042d3SCharles.Forsyth F_IPint_mod *f;
47031a18a69SCharles.Forsyth mpint *i1, *i2, *ret;
4713d7a0c16SCharles.Forsyth void *v;
472ca1042d3SCharles.Forsyth
473ca1042d3SCharles.Forsyth f = fp;
4743d7a0c16SCharles.Forsyth v = *f->ret;
475ca1042d3SCharles.Forsyth *f->ret = H;
4763d7a0c16SCharles.Forsyth destroy(v);
477ca1042d3SCharles.Forsyth
4783d7a0c16SCharles.Forsyth i1 = MP(f->i1);
4793d7a0c16SCharles.Forsyth i2 = MP(f->i2);
480ca1042d3SCharles.Forsyth ret = mpnew(0);
481ca1042d3SCharles.Forsyth if(ret != nil)
482ca1042d3SCharles.Forsyth mpmod(i1, i2, ret);
483ca1042d3SCharles.Forsyth
484ca1042d3SCharles.Forsyth *f->ret = newIPint(ret);
485ca1042d3SCharles.Forsyth }
486ca1042d3SCharles.Forsyth void
IPint_neg(void * fp)48737da2899SCharles.Forsyth IPint_neg(void *fp)
48837da2899SCharles.Forsyth {
48937da2899SCharles.Forsyth F_IPint_neg *f;
4903d7a0c16SCharles.Forsyth mpint *ret;
4913d7a0c16SCharles.Forsyth void *v;
49237da2899SCharles.Forsyth
49337da2899SCharles.Forsyth f = fp;
4943d7a0c16SCharles.Forsyth v = *f->ret;
49537da2899SCharles.Forsyth *f->ret = H;
4963d7a0c16SCharles.Forsyth destroy(v);
49737da2899SCharles.Forsyth
4983d7a0c16SCharles.Forsyth ret = mpcopy(MP(f->i));
49937da2899SCharles.Forsyth if(ret == nil)
50037da2899SCharles.Forsyth error(exHeap);
50137da2899SCharles.Forsyth ret->sign = -ret->sign;
50237da2899SCharles.Forsyth
50337da2899SCharles.Forsyth *f->ret = newIPint(ret);
50437da2899SCharles.Forsyth }
50537da2899SCharles.Forsyth
50637da2899SCharles.Forsyth /* copy */
50737da2899SCharles.Forsyth void
IPint_copy(void * fp)50837da2899SCharles.Forsyth IPint_copy(void *fp)
50937da2899SCharles.Forsyth {
51037da2899SCharles.Forsyth F_IPint_copy *f;
5113d7a0c16SCharles.Forsyth void *v;
51237da2899SCharles.Forsyth
51337da2899SCharles.Forsyth f = fp;
5143d7a0c16SCharles.Forsyth v = *f->ret;
51537da2899SCharles.Forsyth *f->ret = H;
5163d7a0c16SCharles.Forsyth destroy(v);
51737da2899SCharles.Forsyth
51837da2899SCharles.Forsyth *f->ret = newIPint(mpcopy(MP(f->i)));
51937da2899SCharles.Forsyth }
52037da2899SCharles.Forsyth
52137da2899SCharles.Forsyth
52237da2899SCharles.Forsyth /* equality */
52337da2899SCharles.Forsyth void
IPint_eq(void * fp)52437da2899SCharles.Forsyth IPint_eq(void *fp)
52537da2899SCharles.Forsyth {
52637da2899SCharles.Forsyth F_IPint_eq *f;
52737da2899SCharles.Forsyth
52837da2899SCharles.Forsyth f = fp;
52937da2899SCharles.Forsyth *f->ret = mpcmp(MP(f->i1), MP(f->i2)) == 0;
53037da2899SCharles.Forsyth }
53137da2899SCharles.Forsyth
53237da2899SCharles.Forsyth /* compare */
53337da2899SCharles.Forsyth void
IPint_cmp(void * fp)53437da2899SCharles.Forsyth IPint_cmp(void *fp)
53537da2899SCharles.Forsyth {
53637da2899SCharles.Forsyth F_IPint_eq *f;
53737da2899SCharles.Forsyth
53837da2899SCharles.Forsyth f = fp;
53937da2899SCharles.Forsyth *f->ret = mpcmp(MP(f->i1), MP(f->i2));
54037da2899SCharles.Forsyth }
54137da2899SCharles.Forsyth
54237da2899SCharles.Forsyth /* shifts */
54337da2899SCharles.Forsyth void
IPint_shl(void * fp)54437da2899SCharles.Forsyth IPint_shl(void *fp)
54537da2899SCharles.Forsyth {
54637da2899SCharles.Forsyth F_IPint_shl *f;
5473d7a0c16SCharles.Forsyth mpint *ret, *i;
5483d7a0c16SCharles.Forsyth void *v;
54937da2899SCharles.Forsyth
55037da2899SCharles.Forsyth f = fp;
5513d7a0c16SCharles.Forsyth v = *f->ret;
55237da2899SCharles.Forsyth *f->ret = H;
5533d7a0c16SCharles.Forsyth destroy(v);
55437da2899SCharles.Forsyth
5553d7a0c16SCharles.Forsyth i = MP(f->i);
55637da2899SCharles.Forsyth ret = mpnew(0);
55737da2899SCharles.Forsyth if(ret != nil)
5583d7a0c16SCharles.Forsyth mpleft(i, f->n, ret);
55937da2899SCharles.Forsyth *f->ret = newIPint(ret);
56037da2899SCharles.Forsyth }
56137da2899SCharles.Forsyth void
IPint_shr(void * fp)56237da2899SCharles.Forsyth IPint_shr(void *fp)
56337da2899SCharles.Forsyth {
56437da2899SCharles.Forsyth F_IPint_shr *f;
5653d7a0c16SCharles.Forsyth mpint *ret, *i;
5663d7a0c16SCharles.Forsyth void *v;
56737da2899SCharles.Forsyth
56837da2899SCharles.Forsyth f = fp;
5693d7a0c16SCharles.Forsyth v = *f->ret;
57037da2899SCharles.Forsyth *f->ret = H;
5713d7a0c16SCharles.Forsyth destroy(v);
57237da2899SCharles.Forsyth
5733d7a0c16SCharles.Forsyth i = MP(f->i);
57437da2899SCharles.Forsyth ret = mpnew(0);
57537da2899SCharles.Forsyth if(ret != nil)
5763d7a0c16SCharles.Forsyth mpright(i, f->n, ret);
57737da2899SCharles.Forsyth *f->ret = newIPint(ret);
57837da2899SCharles.Forsyth }
57937da2899SCharles.Forsyth
5806e425a9dSCharles.Forsyth static void
mpand(mpint * b,mpint * m,mpint * res)5816e425a9dSCharles.Forsyth mpand(mpint *b, mpint *m, mpint *res)
5826e425a9dSCharles.Forsyth {
5836e425a9dSCharles.Forsyth int i;
5846e425a9dSCharles.Forsyth
5856e425a9dSCharles.Forsyth res->sign = b->sign;
5866e425a9dSCharles.Forsyth if(b->top == 0 || m->top == 0){
5876e425a9dSCharles.Forsyth res->top = 0;
5886e425a9dSCharles.Forsyth return;
5896e425a9dSCharles.Forsyth }
5906e425a9dSCharles.Forsyth mpbits(res, b->top*Dbits);
5916e425a9dSCharles.Forsyth res->top = b->top;
5926e425a9dSCharles.Forsyth for(i = b->top; --i >= 0;){
5936e425a9dSCharles.Forsyth if(i < m->top)
5946e425a9dSCharles.Forsyth res->p[i] = b->p[i] & m->p[i];
5956e425a9dSCharles.Forsyth else
5966e425a9dSCharles.Forsyth res->p[i] = 0;
5976e425a9dSCharles.Forsyth }
5986e425a9dSCharles.Forsyth mpnorm(res);
5996e425a9dSCharles.Forsyth }
6006e425a9dSCharles.Forsyth
6016e425a9dSCharles.Forsyth static void
mpor(mpint * b1,mpint * b2,mpint * res)6026e425a9dSCharles.Forsyth mpor(mpint *b1, mpint *b2, mpint *res)
6036e425a9dSCharles.Forsyth {
6046e425a9dSCharles.Forsyth mpint *t;
6056e425a9dSCharles.Forsyth int i;
6066e425a9dSCharles.Forsyth
6076e425a9dSCharles.Forsyth if(b2->top > b1->top){
6086e425a9dSCharles.Forsyth t = b1;
6096e425a9dSCharles.Forsyth b1 = b2;
6106e425a9dSCharles.Forsyth b2 = t;
6116e425a9dSCharles.Forsyth }
6126e425a9dSCharles.Forsyth if(b1->top == 0){
6136e425a9dSCharles.Forsyth mpassign(b2, res);
6146e425a9dSCharles.Forsyth return;
6156e425a9dSCharles.Forsyth }
6166e425a9dSCharles.Forsyth if(b2->top == 0){
6176e425a9dSCharles.Forsyth mpassign(b1, res);
6186e425a9dSCharles.Forsyth return;
6196e425a9dSCharles.Forsyth }
6206e425a9dSCharles.Forsyth mpassign(b1, res);
6216e425a9dSCharles.Forsyth for(i = b2->top; --i >= 0;)
6226e425a9dSCharles.Forsyth res->p[i] |= b2->p[i];
6236e425a9dSCharles.Forsyth mpnorm(res);
6246e425a9dSCharles.Forsyth }
6256e425a9dSCharles.Forsyth
6266e425a9dSCharles.Forsyth static void
mpxor(mpint * b1,mpint * b2,mpint * res)6276e425a9dSCharles.Forsyth mpxor(mpint *b1, mpint *b2, mpint *res)
6286e425a9dSCharles.Forsyth {
6296e425a9dSCharles.Forsyth mpint *t;
6306e425a9dSCharles.Forsyth int i;
6316e425a9dSCharles.Forsyth
6326e425a9dSCharles.Forsyth if(b2->top > b1->top){
6336e425a9dSCharles.Forsyth t = b1;
6346e425a9dSCharles.Forsyth b1 = b2;
6356e425a9dSCharles.Forsyth b2 = t;
6366e425a9dSCharles.Forsyth }
6376e425a9dSCharles.Forsyth if(b1->top == 0){
6386e425a9dSCharles.Forsyth mpassign(b2, res);
6396e425a9dSCharles.Forsyth return;
6406e425a9dSCharles.Forsyth }
6416e425a9dSCharles.Forsyth if(b2->top == 0){
6426e425a9dSCharles.Forsyth mpassign(b1, res);
6436e425a9dSCharles.Forsyth return;
6446e425a9dSCharles.Forsyth }
6456e425a9dSCharles.Forsyth mpassign(b1, res);
6466e425a9dSCharles.Forsyth for(i = b2->top; --i >= 0;)
6476e425a9dSCharles.Forsyth res->p[i] ^= b2->p[i];
6486e425a9dSCharles.Forsyth mpnorm(res);
6496e425a9dSCharles.Forsyth }
6506e425a9dSCharles.Forsyth
6516e425a9dSCharles.Forsyth static void
mpnot(mpint * b1,mpint * res)6526e425a9dSCharles.Forsyth mpnot(mpint *b1, mpint *res)
6536e425a9dSCharles.Forsyth {
6546e425a9dSCharles.Forsyth int i;
6556e425a9dSCharles.Forsyth
6566e425a9dSCharles.Forsyth mpbits(res, Dbits*b1->top);
6576e425a9dSCharles.Forsyth res->sign = 1;
6586e425a9dSCharles.Forsyth res->top = b1->top;
6596e425a9dSCharles.Forsyth for(i = res->top; --i >= 0;)
6606e425a9dSCharles.Forsyth res->p[i] = ~b1->p[i];
6616e425a9dSCharles.Forsyth mpnorm(res);
6626e425a9dSCharles.Forsyth }
6636e425a9dSCharles.Forsyth
6646e425a9dSCharles.Forsyth /* bits */
6656e425a9dSCharles.Forsyth void
IPint_and(void * fp)6666e425a9dSCharles.Forsyth IPint_and(void *fp)
6676e425a9dSCharles.Forsyth {
6686e425a9dSCharles.Forsyth F_IPint_and *f;
6693d7a0c16SCharles.Forsyth mpint *ret, *i1, *i2;
6703d7a0c16SCharles.Forsyth void *v;
6716e425a9dSCharles.Forsyth
6726e425a9dSCharles.Forsyth f = fp;
6733d7a0c16SCharles.Forsyth v = *f->ret;
6746e425a9dSCharles.Forsyth *f->ret = H;
6753d7a0c16SCharles.Forsyth destroy(v);
6766e425a9dSCharles.Forsyth
6773d7a0c16SCharles.Forsyth i1 = MP(f->i1);
6783d7a0c16SCharles.Forsyth i2 = MP(f->i2);
6796e425a9dSCharles.Forsyth ret = mpnew(0);
6806e425a9dSCharles.Forsyth if(ret != nil)
6813d7a0c16SCharles.Forsyth mpand(i1, i2, ret);
6826e425a9dSCharles.Forsyth *f->ret = newIPint(ret);
6836e425a9dSCharles.Forsyth }
6846e425a9dSCharles.Forsyth
6856e425a9dSCharles.Forsyth void
IPint_ori(void * fp)6866e425a9dSCharles.Forsyth IPint_ori(void *fp)
6876e425a9dSCharles.Forsyth {
6886e425a9dSCharles.Forsyth F_IPint_ori *f;
6893d7a0c16SCharles.Forsyth mpint *ret, *i1, *i2;
6903d7a0c16SCharles.Forsyth void *v;
6916e425a9dSCharles.Forsyth
6926e425a9dSCharles.Forsyth f = fp;
6933d7a0c16SCharles.Forsyth v = *f->ret;
6946e425a9dSCharles.Forsyth *f->ret = H;
6953d7a0c16SCharles.Forsyth destroy(v);
6966e425a9dSCharles.Forsyth
6973d7a0c16SCharles.Forsyth i1 = MP(f->i1);
6983d7a0c16SCharles.Forsyth i2 = MP(f->i2);
6996e425a9dSCharles.Forsyth ret = mpnew(0);
7006e425a9dSCharles.Forsyth if(ret != nil)
7013d7a0c16SCharles.Forsyth mpor(i1, i2, ret);
7026e425a9dSCharles.Forsyth *f->ret = newIPint(ret);
7036e425a9dSCharles.Forsyth }
7046e425a9dSCharles.Forsyth
7056e425a9dSCharles.Forsyth void
IPint_xor(void * fp)7066e425a9dSCharles.Forsyth IPint_xor(void *fp)
7076e425a9dSCharles.Forsyth {
7086e425a9dSCharles.Forsyth F_IPint_xor *f;
7093d7a0c16SCharles.Forsyth mpint *ret, *i1, *i2;
7103d7a0c16SCharles.Forsyth void *v;
7116e425a9dSCharles.Forsyth
7126e425a9dSCharles.Forsyth f = fp;
7133d7a0c16SCharles.Forsyth v = *f->ret;
7146e425a9dSCharles.Forsyth *f->ret = H;
7153d7a0c16SCharles.Forsyth destroy(v);
7166e425a9dSCharles.Forsyth
7173d7a0c16SCharles.Forsyth i1 = MP(f->i1);
7183d7a0c16SCharles.Forsyth i2 = MP(f->i2);
7196e425a9dSCharles.Forsyth ret = mpnew(0);
7206e425a9dSCharles.Forsyth if(ret != nil)
7213d7a0c16SCharles.Forsyth mpxor(i1, i2, ret);
7226e425a9dSCharles.Forsyth *f->ret = newIPint(ret);
7236e425a9dSCharles.Forsyth }
7246e425a9dSCharles.Forsyth
7256e425a9dSCharles.Forsyth void
IPint_not(void * fp)7266e425a9dSCharles.Forsyth IPint_not(void *fp)
7276e425a9dSCharles.Forsyth {
7286e425a9dSCharles.Forsyth F_IPint_not *f;
7293d7a0c16SCharles.Forsyth mpint *ret, *i1;
7303d7a0c16SCharles.Forsyth void *v;
7316e425a9dSCharles.Forsyth
7326e425a9dSCharles.Forsyth f = fp;
7333d7a0c16SCharles.Forsyth v = *f->ret;
7346e425a9dSCharles.Forsyth *f->ret = H;
7353d7a0c16SCharles.Forsyth destroy(v);
7366e425a9dSCharles.Forsyth
7373d7a0c16SCharles.Forsyth i1 = MP(f->i1);
7386e425a9dSCharles.Forsyth ret = mpnew(0);
7396e425a9dSCharles.Forsyth if(ret != nil)
7403d7a0c16SCharles.Forsyth mpnot(i1, ret);
7416e425a9dSCharles.Forsyth *f->ret = newIPint(ret);
7426e425a9dSCharles.Forsyth }
743*7de2b42dSforsyth
744*7de2b42dSforsyth /*
745*7de2b42dSforsyth * primes
746*7de2b42dSforsyth */
747*7de2b42dSforsyth
748*7de2b42dSforsyth void
IPints_probably_prime(void * fp)749*7de2b42dSforsyth IPints_probably_prime(void *fp)
750*7de2b42dSforsyth {
751*7de2b42dSforsyth F_IPints_probably_prime *f;
752*7de2b42dSforsyth
753*7de2b42dSforsyth f = fp;
754*7de2b42dSforsyth release();
755*7de2b42dSforsyth *f->ret = probably_prime(checkIPint(f->n), f->nrep);
756*7de2b42dSforsyth acquire();
757*7de2b42dSforsyth }
758*7de2b42dSforsyth
759*7de2b42dSforsyth void
IPints_genprime(void * fp)760*7de2b42dSforsyth IPints_genprime(void *fp)
761*7de2b42dSforsyth {
762*7de2b42dSforsyth F_IPints_genprime *f;
763*7de2b42dSforsyth mpint *p;
764*7de2b42dSforsyth void *r;
765*7de2b42dSforsyth
766*7de2b42dSforsyth f = fp;
767*7de2b42dSforsyth r = *f->ret;
768*7de2b42dSforsyth *f->ret = H;
769*7de2b42dSforsyth destroy(r);
770*7de2b42dSforsyth p = mpnew(0);
771*7de2b42dSforsyth release();
772*7de2b42dSforsyth genprime(p, f->nbits, f->nrep);
773*7de2b42dSforsyth acquire();
774*7de2b42dSforsyth *f->ret = newIPint(p);
775*7de2b42dSforsyth }
776*7de2b42dSforsyth
777*7de2b42dSforsyth void
IPints_genstrongprime(void * fp)778*7de2b42dSforsyth IPints_genstrongprime(void *fp)
779*7de2b42dSforsyth {
780*7de2b42dSforsyth F_IPints_genstrongprime *f;
781*7de2b42dSforsyth mpint *p;
782*7de2b42dSforsyth void *r;
783*7de2b42dSforsyth
784*7de2b42dSforsyth f = fp;
785*7de2b42dSforsyth r = *f->ret;
786*7de2b42dSforsyth *f->ret = H;
787*7de2b42dSforsyth destroy(r);
788*7de2b42dSforsyth p = mpnew(0);
789*7de2b42dSforsyth release();
790*7de2b42dSforsyth genstrongprime(p, f->nbits, f->nrep);
791*7de2b42dSforsyth acquire();
792*7de2b42dSforsyth *f->ret = newIPint(p);
793*7de2b42dSforsyth }
794*7de2b42dSforsyth
795*7de2b42dSforsyth void
IPints_gensafeprime(void * fp)796*7de2b42dSforsyth IPints_gensafeprime(void *fp)
797*7de2b42dSforsyth {
798*7de2b42dSforsyth F_IPints_gensafeprime *f;
799*7de2b42dSforsyth mpint *p, *alpha;
800*7de2b42dSforsyth void *v;
801*7de2b42dSforsyth
802*7de2b42dSforsyth f = fp;
803*7de2b42dSforsyth v = f->ret->t0;
804*7de2b42dSforsyth f->ret->t0 = H;
805*7de2b42dSforsyth destroy(v);
806*7de2b42dSforsyth v = f->ret->t1;
807*7de2b42dSforsyth f->ret->t1 = H;
808*7de2b42dSforsyth destroy(v);
809*7de2b42dSforsyth
810*7de2b42dSforsyth p = mpnew(0);
811*7de2b42dSforsyth alpha = mpnew(0);
812*7de2b42dSforsyth release();
813*7de2b42dSforsyth gensafeprime(p, alpha, f->nbits, f->nrep);
814*7de2b42dSforsyth acquire();
815*7de2b42dSforsyth f->ret->t0 = newIPint(p);
816*7de2b42dSforsyth f->ret->t1 = newIPint(alpha);
817*7de2b42dSforsyth }
818*7de2b42dSforsyth
819*7de2b42dSforsyth void
IPints_DSAprimes(void * fp)820*7de2b42dSforsyth IPints_DSAprimes(void *fp)
821*7de2b42dSforsyth {
822*7de2b42dSforsyth F_IPints_DSAprimes *f;
823*7de2b42dSforsyth mpint *p, *q;
824*7de2b42dSforsyth Heap *h;
825*7de2b42dSforsyth void *v;
826*7de2b42dSforsyth
827*7de2b42dSforsyth f = fp;
828*7de2b42dSforsyth v = f->ret->t0;
829*7de2b42dSforsyth f->ret->t0 = H;
830*7de2b42dSforsyth destroy(v);
831*7de2b42dSforsyth v = f->ret->t1;
832*7de2b42dSforsyth f->ret->t1 = H;
833*7de2b42dSforsyth destroy(v);
834*7de2b42dSforsyth v = f->ret->t2;
835*7de2b42dSforsyth f->ret->t2 = H;
836*7de2b42dSforsyth destroy(v);
837*7de2b42dSforsyth
838*7de2b42dSforsyth h = heaparray(&Tbyte, SHA1dlen);
839*7de2b42dSforsyth f->ret->t2 = H2D(Array*, h);
840*7de2b42dSforsyth
841*7de2b42dSforsyth p = mpnew(0);
842*7de2b42dSforsyth q = mpnew(0);
843*7de2b42dSforsyth release();
844*7de2b42dSforsyth DSAprimes(q, p, f->ret->t2->data);
845*7de2b42dSforsyth acquire();
846*7de2b42dSforsyth f->ret->t0 = newIPint(q);
847*7de2b42dSforsyth f->ret->t1 = newIPint(p);
848*7de2b42dSforsyth }
849