Charles.Forsyth20061220965a0ca19 years agoHistory
704 lines · 9.6 KB · C
RawDownload
#include "lib9.h"#include "kernel.h"#include <isa.h>#include "interp.h"#include "runt.h"#include <mp.h>#include <libsec.h>#include "pool.h"#include "../libkeyring/keys.h"#include "raise.h" enum {	PSEUDO=0,	REALLY,}; void getRandBetween(BigInt p, BigInt q, BigInt result, int type); extern Type	*TIPint;#define	MP(x)	(((IPint*)(x))->b) Keyring_IPint*newIPint(BigInt b){	Heap *h;	IPint *ip; 	if(b == nil)		error(exHeap);	h = heap(TIPint);	/* TO DO: loss if heap fails */	ip = H2D(IPint*, h);	ip->b = b;	return (Keyring_IPint*)ip;} voidfreeIPint(Heap *h, int swept){	IPint *ip; 	USED(swept);	ip = H2D(IPint*, h);	if(ip->b)		mpfree(ip->b);	freeheap(h, 0);} voidIPint_iptob64(void *fp){	F_IPint_iptob64 *f;	char buf[MaxBigBytes]; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->i == H)		error(exNilref); 	mptoa(MP(f->i), 64, buf, sizeof(buf));	retstr(buf, f->ret);} voidIPint_iptobytes(void *fp){	F_IPint_iptobytes *f;	uchar buf[MaxBigBytes]; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->i == H)		error(exNilref); 	/* TO DO: two's complement or have ipmagtobe? */	*f->ret = mem2array(buf, mptobe(MP(f->i), buf, sizeof(buf), nil));	/* for now we'll ignore sign */} voidIPint_iptobebytes(void *fp){	F_IPint_iptobebytes *f;	uchar buf[MaxBigBytes]; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->i == H)		error(exNilref); 	*f->ret = mem2array(buf, mptobe(MP(f->i), buf, sizeof(buf), nil));} voidIPint_iptostr(void *fp){	F_IPint_iptostr *f;	char buf[MaxBigBytes]; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->i == H)		error(exNilref); 	mptoa(MP(f->i), f->base, buf, sizeof(buf));	retstr(buf, f->ret);} voidIPint_b64toip(void *fp){	F_IPint_b64toip *f;	BigInt b; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->str == H)		error(exNilref); 	b = strtomp(string2c(f->str), nil, 64, nil);	*f->ret = newIPint(b);} voidIPint_bytestoip(void *fp){	F_IPint_bytestoip *f;	BigInt b; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->buf == H)		error(exNilref); 	b = betomp(f->buf->data, f->buf->len, nil);	/* for now we'll ignore sign */	*f->ret = newIPint(b);} voidIPint_bebytestoip(void *fp){	F_IPint_bebytestoip *f;	BigInt b; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->mag == H)		error(exNilref); 	b = betomp(f->mag->data, f->mag->len, nil);	*f->ret = newIPint(b);} voidIPint_strtoip(void *fp){	F_IPint_strtoip *f;	BigInt b; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->str == H)		return; 	b = strtomp(string2c(f->str), nil, f->base, nil);	*f->ret = newIPint(b);} /* create a random integer */voidIPint_random(void *fp){	F_IPint_random *f;	BigInt b, min, max; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	b = itomp(1, nil);	min = mpnew(0);	max = mpnew(0);	mpleft(b, f->minbits, min);	mpleft(b, f->maxbits, max);		release();	getRandBetween(min, max, b, PSEUDO);	/* TO DO */	acquire(); 	mpfree(min);	mpfree(max);	*f->ret = newIPint(b);} /* number of bits in number */voidIPint_bits(void *fp){	F_IPint_bits *f;	int n; 	f = fp;	*f->ret = 0;	if(f->i == H)		return; 	n = mpsignif(MP(f->i));	if(n == 0)		n = 1;	/* compatibility */	*f->ret = n;} /* create a new IP from an int */voidIPint_inttoip(void *fp){	F_IPint_inttoip *f; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	*f->ret = newIPint(itomp(f->i, nil));} voidIPint_iptoint(void *fp){	F_IPint_iptoint *f; 	f = fp;	*f->ret = 0;	if(f->i == H)		return;	*f->ret = mptoi(MP(f->i));} /* modular exponentiation */voidIPint_expmod(void *fp){	F_IPint_expmod *f;	BigInt ret, mod; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->base == H || f->exp == H)		error(exNilref); 	mod = nil;	if(f->mod != H)		mod = MP(f->mod);	ret = mpnew(0);	if(ret != nil)		mpexp(MP(f->base), MP(f->exp), mod, ret);	*f->ret = newIPint(ret);} /* multiplicative inverse */voidIPint_invert(void *fp){	F_IPint_invert *f;	BigInt ret; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	ret = mpnew(0);	if(ret != nil)		mpinvert(MP(f->base), MP(f->mod), ret);	*f->ret = newIPint(ret);} /* basic math */voidIPint_add(void *fp){	F_IPint_add *f;	BigInt i1, i2, ret; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->i1 == H || f->i2 == H)		error(exNilref); 	i1 = ((IPint*)f->i1)->b;	i2 = ((IPint*)f->i2)->b;	ret = mpnew(0);	if(ret != nil)		mpadd(i1, i2, ret); 	*f->ret = newIPint(ret);}voidIPint_sub(void *fp){	F_IPint_sub *f;	BigInt i1, i2, ret; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->i1 == H || f->i2 == H)		error(exNilref); 	i1 = ((IPint*)f->i1)->b;	i2 = ((IPint*)f->i2)->b;	ret = mpnew(0);	if(ret != nil)		mpsub(i1, i2, ret); 	*f->ret = newIPint(ret);}voidIPint_mul(void *fp){	F_IPint_mul *f;	BigInt i1, i2, ret; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->i1 == H || f->i2 == H)		error(exNilref); 	i1 = ((IPint*)f->i1)->b;	i2 = ((IPint*)f->i2)->b;	ret = mpnew(0);	if(ret != nil)		mpmul(i1, i2, ret); 	*f->ret = newIPint(ret);}voidIPint_div(void *fp){	F_IPint_div *f;	BigInt i1, i2, quo, rem; 	f = fp;	destroy(f->ret->t0);	f->ret->t0 = H;	destroy(f->ret->t1);	f->ret->t1 = H; 	if(f->i1 == H || f->i2 == H)		error(exNilref); 	i1 = ((IPint*)f->i1)->b;	i2 = ((IPint*)f->i2)->b;	quo = mpnew(0);	if(quo == nil)		error(exHeap);	rem = mpnew(0);	if(rem == nil){		mpfree(quo);		error(exHeap);	}	mpdiv(i1, i2, quo, rem); 	f->ret->t0 = newIPint(quo);	f->ret->t1 = newIPint(rem);}voidIPint_neg(void *fp){	F_IPint_neg *f;	BigInt i, ret; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->i == H)		error(exNilref); 	i = ((IPint*)f->i)->b;	ret = mpcopy(i);	if(ret == nil)		error(exHeap);	ret->sign = -ret->sign; 	*f->ret = newIPint(ret);} /* copy */voidIPint_copy(void *fp){	F_IPint_copy *f; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->i == H)		return; 	*f->ret = newIPint(mpcopy(MP(f->i)));}  /* equality */voidIPint_eq(void *fp){	F_IPint_eq *f; 	f = fp;	*f->ret = 0; 	if(f->i1 == H || f->i2 == H)		return; 	*f->ret = mpcmp(MP(f->i1), MP(f->i2)) == 0;} /* compare */voidIPint_cmp(void *fp){	F_IPint_eq *f; 	f = fp;	*f->ret = 0; 	if(f->i1 == H || f->i2 == H)		error(exNilref); 	*f->ret = mpcmp(MP(f->i1), MP(f->i2));} /* shifts */voidIPint_shl(void *fp){	F_IPint_shl *f;	BigInt ret; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->i == H)		error(exNilref); 	ret = mpnew(0);	if(ret != nil)		mpleft(MP(f->i), f->n, ret);	*f->ret = newIPint(ret);}voidIPint_shr(void *fp){	F_IPint_shr *f;	BigInt ret; 	f = fp;	destroy(*f->ret);	*f->ret = H; 	if(f->i == H)		error(exNilref); 	ret = mpnew(0);	if(ret != nil)		mpright(MP(f->i), f->n, ret);	*f->ret = newIPint(ret);} static voidmpand(mpint *b, mpint *m, mpint *res){	int i; 	res->sign = b->sign;	if(b->top == 0 || m->top == 0){		res->top = 0;

Lines 1–500 of 704.