Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature-vt/sys/include/ape/mp.h – Rev 33

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#ifndef _PLAN9_SOURCE
2
  This header file is an extension to ANSI/POSIX
3
#endif
4
 
5
#ifndef __LIBMP_H_
6
#define __LIBMP_H_
7
 
8
#pragma	src	"/sys/src/ape/lib/mp"
9
#pragma	lib	"/$M/lib/ape/libmp.a"
10
 
33 7u83 11
#include <u.h>
12
#include <fmt.h>
13
 
2 - 14
typedef unsigned int	mpdigit;	/* from /$objtype/include/u.h */
15
 
16
#define _MPINT 1
17
 
18
/*
19
 * the code assumes mpdigit to be at least an int
20
 * mpdigit must be an atomic type.  mpdigit is defined
21
 * in the architecture specific u.h
22
 */
23
typedef struct mpint mpint;
24
 
25
struct mpint
26
{
27
	int	sign;	/* +1 or -1 */
28
	int	size;	/* allocated digits */
29
	int	top;	/* significant digits */
30
	mpdigit	*p;
31
	char	flags;
32
};
33
 
34
enum
35
{
33 7u83 36
	MPstatic=	0x01,	/* static constant */
37
	MPnorm=		0x02,	/* normalization status */
38
	MPtimesafe=	0x04,	/* request time invariant computation */
39
	MPfield=	0x08,	/* this mpint is a field modulus */
40
 
2 - 41
	Dbytes=		sizeof(mpdigit),	/* bytes per digit */
42
	Dbits=		Dbytes*8		/* bits per digit */
43
};
44
 
45
/* allocation */
46
void	mpsetminbits(int n);	/* newly created mpint's get at least n bits */
47
mpint*	mpnew(int n);		/* create a new mpint with at least n bits */
48
void	mpfree(mpint *b);
49
void	mpbits(mpint *b, int n);	/* ensure that b has at least n bits */
33 7u83 50
mpint*	mpnorm(mpint *b);		/* dump leading zeros */
2 - 51
mpint*	mpcopy(mpint *b);
52
void	mpassign(mpint *old, mpint *new);
53
 
54
/* random bits */
55
mpint*	mprand(int bits, void (*gen)(uchar*, int), mpint *b);
33 7u83 56
/* return uniform random [0..n-1] */
57
mpint*	mpnrand(mpint *n, void (*gen)(uchar*, int), mpint *b);
2 - 58
 
59
/* conversion */
60
mpint*	strtomp(char*, char**, int, mpint*);	/* ascii */
61
int	mpfmt(Fmt*);
62
char*	mptoa(mpint*, int, char*, int);
63
mpint*	letomp(uchar*, uint, mpint*);	/* byte array, little-endian */
64
int	mptole(mpint*, uchar*, uint, uchar**);
33 7u83 65
void	mptolel(mpint *b, uchar *p, int n);
66
mpint*	betomp(uchar*, uint, mpint*);	/* byte array, big-endian */
2 - 67
int	mptobe(mpint*, uchar*, uint, uchar**);
33 7u83 68
void	mptober(mpint *b, uchar *p, int n);
2 - 69
uint	mptoui(mpint*);			/* unsigned int */
70
mpint*	uitomp(uint, mpint*);
71
int	mptoi(mpint*);			/* int */
72
mpint*	itomp(int, mpint*);
73
uvlong	mptouv(mpint*);			/* unsigned vlong */
74
mpint*	uvtomp(uvlong, mpint*);
75
vlong	mptov(mpint*);			/* vlong */
76
mpint*	vtomp(vlong, mpint*);
33 7u83 77
double	mptod(mpint*);			/* double */
78
mpint*	dtomp(double, mpint*);
2 - 79
 
80
/* divide 2 digits by one */
81
void	mpdigdiv(mpdigit *dividend, mpdigit divisor, mpdigit *quotient);
82
 
83
/* in the following, the result mpint may be */
84
/* the same as one of the inputs. */
85
void	mpadd(mpint *b1, mpint *b2, mpint *sum);	/* sum = b1+b2 */
86
void	mpsub(mpint *b1, mpint *b2, mpint *diff);	/* diff = b1-b2 */
87
void	mpleft(mpint *b, int shift, mpint *res);	/* res = b<<shift */
88
void	mpright(mpint *b, int shift, mpint *res);	/* res = b>>shift */
89
void	mpmul(mpint *b1, mpint *b2, mpint *prod);	/* prod = b1*b2 */
90
void	mpexp(mpint *b, mpint *e, mpint *m, mpint *res);	/* res = b**e mod m */
91
void	mpmod(mpint *b, mpint *m, mpint *remainder);	/* remainder = b mod m */
92
 
33 7u83 93
/* logical operations */
94
void	mpand(mpint *b1, mpint *b2, mpint *res);
95
void	mpbic(mpint *b1, mpint *b2, mpint *res);
96
void	mpor(mpint *b1, mpint *b2, mpint *res);
97
void	mpnot(mpint *b, mpint *res);
98
void	mpxor(mpint *b1, mpint *b2, mpint *res);
99
void	mptrunc(mpint *b, int n, mpint *res);
100
void	mpxtend(mpint *b, int n, mpint *res);
101
 
102
/* modular arithmetic, time invariant when 0≤b1≤m-1 and 0≤b2≤m-1 */
103
void	mpmodadd(mpint *b1, mpint *b2, mpint *m, mpint *sum);	/* sum = b1+b2 % m */
104
void	mpmodsub(mpint *b1, mpint *b2, mpint *m, mpint *diff);	/* diff = b1-b2 % m */
105
void	mpmodmul(mpint *b1, mpint *b2, mpint *m, mpint *prod);	/* prod = b1*b2 % m */
106
 
2 - 107
/* quotient = dividend/divisor, remainder = dividend % divisor */
108
void	mpdiv(mpint *dividend, mpint *divisor,  mpint *quotient, mpint *remainder);
109
 
110
/* return neg, 0, pos as b1-b2 is neg, 0, pos */
111
int	mpcmp(mpint *b1, mpint *b2);
112
 
33 7u83 113
/* res = s != 0 ? b1 : b2 */
114
void	mpsel(int s, mpint *b1, mpint *b2, mpint *res);
115
 
2 - 116
/* extended gcd return d, x, and y, s.t. d = gcd(a,b) and ax+by = d */
117
void	mpextendedgcd(mpint *a, mpint *b, mpint *d, mpint *x, mpint *y);
118
 
119
/* res = b**-1 mod m */
120
void	mpinvert(mpint *b, mpint *m, mpint *res);
121
 
122
/* bit counting */
123
int	mpsignif(mpint*);	/* number of sigificant bits in mantissa */
124
int	mplowbits0(mpint*);	/* k, where n = 2**k * q for odd q */
125
 
126
/* well known constants */
127
extern mpint	*mpzero, *mpone, *mptwo;
128
 
129
/* sum[0:alen] = a[0:alen-1] + b[0:blen-1] */
130
/* prereq: alen >= blen, sum has room for alen+1 digits */
131
void	mpvecadd(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *sum);
132
 
133
/* diff[0:alen-1] = a[0:alen-1] - b[0:blen-1] */
134
/* prereq: alen >= blen, diff has room for alen digits */
135
void	mpvecsub(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *diff);
136
 
137
/* p[0:n] += m * b[0:n-1] */
138
/* prereq: p has room for n+1 digits */
139
void	mpvecdigmuladd(mpdigit *b, int n, mpdigit m, mpdigit *p);
140
 
141
/* p[0:n] -= m * b[0:n-1] */
142
/* prereq: p has room for n+1 digits */
143
int	mpvecdigmulsub(mpdigit *b, int n, mpdigit m, mpdigit *p);
144
 
33 7u83 145
/* p[0:alen+blen-1] = a[0:alen-1] * b[0:blen-1] */
2 - 146
/* prereq: alen >= blen, p has room for m*n digits */
147
void	mpvecmul(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *p);
33 7u83 148
void	mpvectsmul(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *p);
2 - 149
 
150
/* sign of a - b or zero if the same */
151
int	mpveccmp(mpdigit *a, int alen, mpdigit *b, int blen);
33 7u83 152
int	mpvectscmp(mpdigit *a, int alen, mpdigit *b, int blen);
2 - 153
 
154
/* divide the 2 digit dividend by the one digit divisor and stick in quotient */
155
/* we assume that the result is one digit - overflow is all 1's */
156
void	mpdigdiv(mpdigit *dividend, mpdigit divisor, mpdigit *quotient);
157
 
158
/* playing with magnitudes */
159
int	mpmagcmp(mpint *b1, mpint *b2);
160
void	mpmagadd(mpint *b1, mpint *b2, mpint *sum);	/* sum = b1+b2 */
161
void	mpmagsub(mpint *b1, mpint *b2, mpint *sum);	/* sum = b1+b2 */
162
 
163
/* chinese remainder theorem */
164
typedef struct CRTpre	CRTpre;		/* precomputed values for converting */
165
					/*  twixt residues and mpint */
166
typedef struct CRTres	CRTres;		/* residue form of an mpint */
167
 
168
#pragma incomplete CRTpre
169
 
170
struct CRTres
171
{
172
	int	n;		/* number of residues */
173
	mpint	*r[1];		/* residues */
174
};
175
 
176
CRTpre*	crtpre(int, mpint**);			/* precompute conversion values */
177
CRTres*	crtin(CRTpre*, mpint*);			/* convert mpint to residues */
178
void	crtout(CRTpre*, CRTres*, mpint*);	/* convert residues to mpint */
179
void	crtprefree(CRTpre*);
180
void	crtresfree(CRTres*);
181
 
33 7u83 182
/* fast field arithmetic */
183
typedef struct Mfield	Mfield;
2 - 184
 
33 7u83 185
struct Mfield
186
{
187
	mpint;
188
	int	(*reduce)(Mfield*, mpint*, mpint*);
189
};
190
 
191
mpint *mpfield(mpint*);
192
 
193
Mfield *gmfield(mpint*);
194
Mfield *cnfield(mpint*);
195
 
2 - 196
#pragma	varargck	type	"B"	mpint*
33 7u83 197
 
2 - 198
#endif