xref: /inferno-os/libinterp/ipint.c (revision 7de2b42d50e3c05cc143e7b51284009b5e185581)
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