1*8ccd4a63SDavid du Colombier #include "os.h"
2*8ccd4a63SDavid du Colombier #include <mp.h>
3*8ccd4a63SDavid du Colombier #include "dat.h"
4*8ccd4a63SDavid du Colombier
5*8ccd4a63SDavid du Colombier static mpdigit _mptwodata[1] = { 2 };
6*8ccd4a63SDavid du Colombier static mpint _mptwo =
7*8ccd4a63SDavid du Colombier {
8*8ccd4a63SDavid du Colombier 1,
9*8ccd4a63SDavid du Colombier 1,
10*8ccd4a63SDavid du Colombier 1,
11*8ccd4a63SDavid du Colombier _mptwodata,
12*8ccd4a63SDavid du Colombier MPstatic
13*8ccd4a63SDavid du Colombier };
14*8ccd4a63SDavid du Colombier mpint *mptwo = &_mptwo;
15*8ccd4a63SDavid du Colombier
16*8ccd4a63SDavid du Colombier static mpdigit _mponedata[1] = { 1 };
17*8ccd4a63SDavid du Colombier static mpint _mpone =
18*8ccd4a63SDavid du Colombier {
19*8ccd4a63SDavid du Colombier 1,
20*8ccd4a63SDavid du Colombier 1,
21*8ccd4a63SDavid du Colombier 1,
22*8ccd4a63SDavid du Colombier _mponedata,
23*8ccd4a63SDavid du Colombier MPstatic
24*8ccd4a63SDavid du Colombier };
25*8ccd4a63SDavid du Colombier mpint *mpone = &_mpone;
26*8ccd4a63SDavid du Colombier
27*8ccd4a63SDavid du Colombier static mpdigit _mpzerodata[1] = { 0 };
28*8ccd4a63SDavid du Colombier static mpint _mpzero =
29*8ccd4a63SDavid du Colombier {
30*8ccd4a63SDavid du Colombier 1,
31*8ccd4a63SDavid du Colombier 1,
32*8ccd4a63SDavid du Colombier 0,
33*8ccd4a63SDavid du Colombier _mpzerodata,
34*8ccd4a63SDavid du Colombier MPstatic
35*8ccd4a63SDavid du Colombier };
36*8ccd4a63SDavid du Colombier mpint *mpzero = &_mpzero;
37*8ccd4a63SDavid du Colombier
38*8ccd4a63SDavid du Colombier static int mpmindigits = 33;
39*8ccd4a63SDavid du Colombier
40*8ccd4a63SDavid du Colombier // set minimum digit allocation
41*8ccd4a63SDavid du Colombier void
mpsetminbits(int n)42*8ccd4a63SDavid du Colombier mpsetminbits(int n)
43*8ccd4a63SDavid du Colombier {
44*8ccd4a63SDavid du Colombier if(n == 0)
45*8ccd4a63SDavid du Colombier n = 1;
46*8ccd4a63SDavid du Colombier mpmindigits = DIGITS(n);
47*8ccd4a63SDavid du Colombier }
48*8ccd4a63SDavid du Colombier
49*8ccd4a63SDavid du Colombier // allocate an n bit 0'd number
50*8ccd4a63SDavid du Colombier mpint*
mpnew(int n)51*8ccd4a63SDavid du Colombier mpnew(int n)
52*8ccd4a63SDavid du Colombier {
53*8ccd4a63SDavid du Colombier mpint *b;
54*8ccd4a63SDavid du Colombier
55*8ccd4a63SDavid du Colombier b = mallocz(sizeof(mpint), 1);
56*8ccd4a63SDavid du Colombier if(b == nil)
57*8ccd4a63SDavid du Colombier sysfatal("mpnew: %r");
58*8ccd4a63SDavid du Colombier n = DIGITS(n);
59*8ccd4a63SDavid du Colombier if(n < mpmindigits)
60*8ccd4a63SDavid du Colombier n = mpmindigits;
61*8ccd4a63SDavid du Colombier n = n;
62*8ccd4a63SDavid du Colombier b->p = (mpdigit*)mallocz(n*Dbytes, 1);
63*8ccd4a63SDavid du Colombier if(b->p == nil)
64*8ccd4a63SDavid du Colombier sysfatal("mpnew: %r");
65*8ccd4a63SDavid du Colombier b->size = n;
66*8ccd4a63SDavid du Colombier b->sign = 1;
67*8ccd4a63SDavid du Colombier
68*8ccd4a63SDavid du Colombier return b;
69*8ccd4a63SDavid du Colombier }
70*8ccd4a63SDavid du Colombier
71*8ccd4a63SDavid du Colombier // guarantee at least n significant bits
72*8ccd4a63SDavid du Colombier void
mpbits(mpint * b,int m)73*8ccd4a63SDavid du Colombier mpbits(mpint *b, int m)
74*8ccd4a63SDavid du Colombier {
75*8ccd4a63SDavid du Colombier int n;
76*8ccd4a63SDavid du Colombier
77*8ccd4a63SDavid du Colombier n = DIGITS(m);
78*8ccd4a63SDavid du Colombier if(b->size >= n){
79*8ccd4a63SDavid du Colombier if(b->top >= n)
80*8ccd4a63SDavid du Colombier return;
81*8ccd4a63SDavid du Colombier memset(&b->p[b->top], 0, Dbytes*(n - b->top));
82*8ccd4a63SDavid du Colombier b->top = n;
83*8ccd4a63SDavid du Colombier return;
84*8ccd4a63SDavid du Colombier }
85*8ccd4a63SDavid du Colombier b->p = (mpdigit*)realloc(b->p, n*Dbytes);
86*8ccd4a63SDavid du Colombier if(b->p == nil)
87*8ccd4a63SDavid du Colombier sysfatal("mpbits: %r");
88*8ccd4a63SDavid du Colombier memset(&b->p[b->top], 0, Dbytes*(n - b->top));
89*8ccd4a63SDavid du Colombier b->size = n;
90*8ccd4a63SDavid du Colombier b->top = n;
91*8ccd4a63SDavid du Colombier }
92*8ccd4a63SDavid du Colombier
93*8ccd4a63SDavid du Colombier void
mpfree(mpint * b)94*8ccd4a63SDavid du Colombier mpfree(mpint *b)
95*8ccd4a63SDavid du Colombier {
96*8ccd4a63SDavid du Colombier if(b == nil)
97*8ccd4a63SDavid du Colombier return;
98*8ccd4a63SDavid du Colombier if(b->flags & MPstatic)
99*8ccd4a63SDavid du Colombier sysfatal("freeing mp constant");
100*8ccd4a63SDavid du Colombier memset(b->p, 0, b->top*Dbytes); // information hiding
101*8ccd4a63SDavid du Colombier free(b->p);
102*8ccd4a63SDavid du Colombier free(b);
103*8ccd4a63SDavid du Colombier }
104*8ccd4a63SDavid du Colombier
105*8ccd4a63SDavid du Colombier void
mpnorm(mpint * b)106*8ccd4a63SDavid du Colombier mpnorm(mpint *b)
107*8ccd4a63SDavid du Colombier {
108*8ccd4a63SDavid du Colombier int i;
109*8ccd4a63SDavid du Colombier
110*8ccd4a63SDavid du Colombier for(i = b->top-1; i >= 0; i--)
111*8ccd4a63SDavid du Colombier if(b->p[i] != 0)
112*8ccd4a63SDavid du Colombier break;
113*8ccd4a63SDavid du Colombier b->top = i+1;
114*8ccd4a63SDavid du Colombier if(b->top == 0)
115*8ccd4a63SDavid du Colombier b->sign = 1;
116*8ccd4a63SDavid du Colombier }
117*8ccd4a63SDavid du Colombier
118*8ccd4a63SDavid du Colombier mpint*
mpcopy(mpint * old)119*8ccd4a63SDavid du Colombier mpcopy(mpint *old)
120*8ccd4a63SDavid du Colombier {
121*8ccd4a63SDavid du Colombier mpint *new;
122*8ccd4a63SDavid du Colombier
123*8ccd4a63SDavid du Colombier new = mpnew(Dbits*old->size);
124*8ccd4a63SDavid du Colombier new->top = old->top;
125*8ccd4a63SDavid du Colombier new->sign = old->sign;
126*8ccd4a63SDavid du Colombier memmove(new->p, old->p, Dbytes*old->top);
127*8ccd4a63SDavid du Colombier return new;
128*8ccd4a63SDavid du Colombier }
129*8ccd4a63SDavid du Colombier
130*8ccd4a63SDavid du Colombier void
mpassign(mpint * old,mpint * new)131*8ccd4a63SDavid du Colombier mpassign(mpint *old, mpint *new)
132*8ccd4a63SDavid du Colombier {
133*8ccd4a63SDavid du Colombier mpbits(new, Dbits*old->top);
134*8ccd4a63SDavid du Colombier new->sign = old->sign;
135*8ccd4a63SDavid du Colombier new->top = old->top;
136*8ccd4a63SDavid du Colombier memmove(new->p, old->p, Dbytes*old->top);
137*8ccd4a63SDavid du Colombier }
138*8ccd4a63SDavid du Colombier
139*8ccd4a63SDavid du Colombier // number of significant bits in mantissa
140*8ccd4a63SDavid du Colombier int
mpsignif(mpint * n)141*8ccd4a63SDavid du Colombier mpsignif(mpint *n)
142*8ccd4a63SDavid du Colombier {
143*8ccd4a63SDavid du Colombier int i, j;
144*8ccd4a63SDavid du Colombier mpdigit d;
145*8ccd4a63SDavid du Colombier
146*8ccd4a63SDavid du Colombier if(n->top == 0)
147*8ccd4a63SDavid du Colombier return 0;
148*8ccd4a63SDavid du Colombier for(i = n->top-1; i >= 0; i--){
149*8ccd4a63SDavid du Colombier d = n->p[i];
150*8ccd4a63SDavid du Colombier for(j = Dbits-1; j >= 0; j--){
151*8ccd4a63SDavid du Colombier if(d & (((mpdigit)1)<<j))
152*8ccd4a63SDavid du Colombier return i*Dbits + j + 1;
153*8ccd4a63SDavid du Colombier }
154*8ccd4a63SDavid du Colombier }
155*8ccd4a63SDavid du Colombier return 0;
156*8ccd4a63SDavid du Colombier }
157*8ccd4a63SDavid du Colombier
158*8ccd4a63SDavid du Colombier // k, where n = 2**k * q for odd q
159*8ccd4a63SDavid du Colombier int
mplowbits0(mpint * n)160*8ccd4a63SDavid du Colombier mplowbits0(mpint *n)
161*8ccd4a63SDavid du Colombier {
162*8ccd4a63SDavid du Colombier int k, bit, digit;
163*8ccd4a63SDavid du Colombier mpdigit d;
164*8ccd4a63SDavid du Colombier
165*8ccd4a63SDavid du Colombier if(n->top==0)
166*8ccd4a63SDavid du Colombier return 0;
167*8ccd4a63SDavid du Colombier k = 0;
168*8ccd4a63SDavid du Colombier bit = 0;
169*8ccd4a63SDavid du Colombier digit = 0;
170*8ccd4a63SDavid du Colombier d = n->p[0];
171*8ccd4a63SDavid du Colombier for(;;){
172*8ccd4a63SDavid du Colombier if(d & (1<<bit))
173*8ccd4a63SDavid du Colombier break;
174*8ccd4a63SDavid du Colombier k++;
175*8ccd4a63SDavid du Colombier bit++;
176*8ccd4a63SDavid du Colombier if(bit==Dbits){
177*8ccd4a63SDavid du Colombier if(++digit >= n->top)
178*8ccd4a63SDavid du Colombier return 0;
179*8ccd4a63SDavid du Colombier d = n->p[digit];
180*8ccd4a63SDavid du Colombier bit = 0;
181*8ccd4a63SDavid du Colombier }
182*8ccd4a63SDavid du Colombier }
183*8ccd4a63SDavid du Colombier return k;
184*8ccd4a63SDavid du Colombier }
185*8ccd4a63SDavid du Colombier
186