Subversion Repositories planix.SVN

Rev

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

Rev Author Line No. Line
2 - 1
.TH MP 2
2
.SH NAME
3
mpsetminbits, mpnew, mpfree, mpbits, mpnorm, mpcopy, mpassign, mprand, strtomp, mpfmt,mptoa, betomp, mptobe, letomp, mptole, mptoui, uitomp, mptoi, itomp, uvtomp, mptouv, vtomp, mptov, mpdigdiv, mpadd, mpsub, mpleft, mpright, mpmul, mpexp, mpmod, mpdiv, mpcmp, mpextendedgcd, mpinvert, mpsignif, mplowbits0, mpvecdigmuladd, mpvecdigmulsub, mpvecadd, mpvecsub, mpveccmp, mpvecmul, mpmagcmp, mpmagadd, mpmagsub, crtpre, crtin, crtout, crtprefree, crtresfree \- extended precision arithmetic
4
.SH SYNOPSIS
5
.B #include <u.h>
6
.br
7
.B #include <libc.h>
8
.br
9
.B #include <mp.h>
10
.PP
11
.ta +\w'\fLCRTpre* \fP'u
12
.B
13
mpint*	mpnew(int n)
14
.PP
15
.B
16
void	mpfree(mpint *b)
17
.PP
18
.B
19
void	mpsetminbits(int n)
20
.PP
21
.B
22
void	mpbits(mpint *b, int n)
23
.PP
24
.B
25
void	mpnorm(mpint *b)
26
.PP
27
.B
28
mpint*	mpcopy(mpint *b)
29
.PP
30
.B
31
void	mpassign(mpint *old, mpint *new)
32
.PP
33
.B
34
mpint*	mprand(int bits, void (*gen)(uchar*, int), mpint *b)
35
.PP
36
.B
37
mpint*	strtomp(char *buf, char **rptr, int base, mpint *b)
38
.PP
39
.B
40
char*	mptoa(mpint *b, int base, char *buf, int blen)
41
.PP
42
.B
43
int	mpfmt(Fmt*)
44
.PP
45
.B
46
mpint*	betomp(uchar *buf, uint blen, mpint *b)
47
.PP
48
.B
49
int	mptobe(mpint *b, uchar *buf, uint blen, uchar **bufp)
50
.PP
51
.B
52
mpint*	letomp(uchar *buf, uint blen, mpint *b)
53
.PP
54
.B
55
int	mptole(mpint *b, uchar *buf, uint blen, uchar **bufp)
56
.PP
57
.B
58
uint	mptoui(mpint*)
59
.PP
60
.B
61
mpint*	uitomp(uint, mpint*)
62
.PP
63
.B
64
int	mptoi(mpint*)
65
.PP
66
.B
67
mpint*	itomp(int, mpint*)
68
.PP
69
.B
70
mpint*	vtomp(vlong, mpint*)
71
.PP
72
.B
73
vlong	mptov(mpint*)
74
.PP
75
.B
76
mpint*	uvtomp(uvlong, mpint*)
77
.PP
78
.B
79
uvlong	mptouv(mpint*)
80
.PP
81
.B
82
void	mpadd(mpint *b1, mpint *b2, mpint *sum)
83
.PP
84
.B
85
void	mpmagadd(mpint *b1, mpint *b2, mpint *sum)
86
.PP
87
.B
88
void	mpsub(mpint *b1, mpint *b2, mpint *diff)
89
.PP
90
.B
91
void	mpmagsub(mpint *b1, mpint *b2, mpint *diff)
92
.PP
93
.B
94
void	mpleft(mpint *b, int shift, mpint *res)
95
.PP
96
.B
97
void	mpright(mpint *b, int shift, mpint *res)
98
.PP
99
.B
100
void	mpmul(mpint *b1, mpint *b2, mpint *prod)
101
.PP
102
.B
103
void	mpexp(mpint *b, mpint *e, mpint *m, mpint *res)
104
.PP
105
.B
106
void	mpmod(mpint *b, mpint *m, mpint *remainder)
107
.PP
108
.B
109
void	mpdiv(mpint *dividend, mpint *divisor,  mpint *quotient,
110
.br
111
.B
112
	mpint *remainder)
113
.PP
114
.B
115
int	mpcmp(mpint *b1, mpint *b2)
116
.PP
117
.B
118
int	mpmagcmp(mpint *b1, mpint *b2)
119
.PP
120
.B
121
void	mpextendedgcd(mpint *a, mpint *b, mpint *d, mpint *x,
122
.br
123
.B
124
	mpint *y)
125
.PP
126
.B
127
void	mpinvert(mpint *b, mpint *m, mpint *res)
128
.PP
129
.B
130
int	mpsignif(mpint *b)
131
.PP
132
.B
133
int	mplowbits0(mpint *b)
134
.PP
135
.B
136
void	mpdigdiv(mpdigit *dividend, mpdigit divisor,
137
.br
138
.B
139
	mpdigit *quotient)
140
.PP
141
.B
142
void	mpvecadd(mpdigit *a, int alen, mpdigit *b, int blen,
143
.br
144
.B
145
	mpdigit *sum)
146
.PP
147
.B
148
void	mpvecsub(mpdigit *a, int alen, mpdigit *b, int blen,
149
.br
150
.B
151
	mpdigit *diff)
152
.PP
153
.B
154
void	mpvecdigmuladd(mpdigit *b, int n, mpdigit m, mpdigit *p)
155
.PP
156
.B
157
int	mpvecdigmulsub(mpdigit *b, int n, mpdigit m, mpdigit *p)
158
.PP
159
.B
160
void	mpvecmul(mpdigit *a, int alen, mpdigit *b, int blen,
161
.br
162
.B
163
	mpdigit *p)
164
.PP
165
.B
166
int	mpveccmp(mpdigit *a, int alen, mpdigit *b, int blen)
167
.PP
168
.B
169
CRTpre*	crtpre(int nfactors, mpint **factors)
170
.PP
171
.B
172
CRTres*	crtin(CRTpre *crt, mpint *x)
173
.PP
174
.B
175
void	crtout(CRTpre *crt, CRTres *r, mpint *x)
176
.PP
177
.B
178
void	crtprefree(CRTpre *cre)
179
.PP
180
.B
181
void	crtresfree(CRTres *res)
182
.PP
183
.B
184
mpint	*mpzero, *mpone, *mptwo
185
.DT
186
.SH DESCRIPTION
187
These routines perform extended precision integer arithmetic.
188
The basic type is
189
.BR mpint ,
190
which points to an array of
191
.BR mpdigit s,
192
stored in little-endian order:
193
.IP
194
.EX
195
typedef struct mpint mpint;
196
struct mpint
197
{
198
	int	sign;   /* +1 or -1 */
199
	int	size;   /* allocated digits */
200
	int	top;    /* significant digits */
201
	mpdigit	*p;
202
	char	flags;
203
};
204
.EE
205
.PP
206
The sign of 0 is +1.
207
.PP
208
The size of
209
.B mpdigit
210
is architecture-dependent and defined in
211
.BR /$cputype/include/u.h .
212
.BR Mpint s
213
are dynamically allocated and must be explicitly freed.  Operations
214
grow the array of digits as needed.
215
.PP
216
In general, the result parameters are last in the
217
argument list.
218
.PP
219
Routines that return an
220
.B mpint
221
will allocate the
222
.B mpint
223
if the result parameter is
224
.BR nil .
225
This includes
226
.IR strtomp ,
227
.IR itomp ,
228
.IR uitomp ,
229
and
230
.IR btomp .
231
These functions, in addition to
232
.I mpnew
233
and
234
.IR mpcopy ,
235
will return
236
.B nil
237
if the allocation fails.
238
.PP
239
Input and result parameters may point to the same
240
.BR mpint .
241
The routines check and copy where necessary.
242
.PP
243
.I Mpnew
244
creates an
245
.B mpint
246
with an initial allocation of
247
.I n
248
bits.
249
If
250
.I n
251
is zero, the allocation will be whatever was specified in the
252
last call to
253
.I mpsetminbits
254
or to the initial value, 1056.
255
.I Mpfree
256
frees an
257
.BR mpint .
258
.I Mpbits
259
grows the allocation of
260
.I b
261
to fit at least
262
.I n
263
bits.  If
264
.B b->top
265
doesn't cover
266
.I n
267
bits,
268
.I mpbits
269
increases it to do so.
270
Unless you are writing new basic operations, you
271
can restrict yourself to
272
.B mpnew(0)
273
and
274
.BR mpfree(b) .
275
.PP
276
.I Mpnorm
277
normalizes the representation by trimming any high order zero
278
digits.  All routines except
279
.B mpbits
280
return normalized results.
281
.PP
282
.I Mpcopy
283
creates a new
284
.B mpint
285
with the same value as
286
.I b
287
while
288
.I mpassign
289
sets the value of
290
.I new
291
to be that of
292
.IR old .
293
.PP
294
.I Mprand
295
creates an
296
.I n
297
bit random number using the generator
298
.IR gen .
299
.I Gen
300
takes a pointer to a string of uchar's and the number
301
to fill in.
302
.PP
303
.I Strtomp
304
and
305
.I mptoa
306
convert between
307
.SM ASCII
308
and
309
.B mpint
310
representations using the base indicated.
311
Only the bases 10, 16, 32, and 64 are
312
supported.  Anything else defaults to 16.
313
.IR Strtomp
314
skips any leading spaces or tabs.
315
.IR Strtomp 's
316
scan stops when encountering a digit not valid in the
317
base.  If
318
.I rptr
319
is not zero,
320
.I *rptr
321
is set to point to the character immediately after the
322
string converted.
323
If the parse pterminates before any digits are found,
324
.I strtomp
325
return
326
.BR nil .
327
.I Mptoa
328
returns a pointer to the filled buffer.
329
If the parameter
330
.I buf
331
is
332
.BR nil ,
333
the buffer is allocated.
334
.I Mpfmt
335
can be used with
336
.IR fmtinstall (2)
337
and
338
.IR print (2)
339
to print hexadecimal representations of
340
.BR mpint s.
341
The conventional verb is
342
.LR B ,
343
for which
344
.I mp.h
345
provides a
346
.LR pragma .
347
.PP
348
.I Mptobe
349
and
350
.I mptole
351
convert an
352
.I mpint
353
to a byte array.  The former creates a big endian representation,
354
the latter a little endian one.
355
If the destination
356
.I buf
357
is not
358
.BR nil ,
359
it specifies the buffer of length
360
.I blen
361
for the result.  If the representation
362
is less than
363
.I blen
364
bytes, the rest of the buffer is zero filled.
365
If
366
.I buf
367
is
368
.BR nil ,
369
then a buffer is allocated and a pointer to it is
370
deposited in the location pointed to by
371
.IR bufp .
372
Sign is ignored in these conversions, i.e., the byte
373
array version is always positive.
374
.PP
375
.IR Betomp ,
376
and
377
.I letomp
378
convert from a big or little endian byte array at
379
.I buf
380
of length
381
.I blen
382
to an
383
.IR mpint .
384
If
385
.I b
386
is not
387
.IR nil ,
388
it refers to a preallocated
389
.I mpint
390
for the result.
391
If
392
.I b
393
is
394
.BR nil ,
395
a new integer is allocated and returned as the result.
396
.PP
397
The integer conversions are:
398
.TF Mptouv
399
.TP
400
.I mptoui
401
.BR mpint -> "unsigned int"
402
.TP
403
.I uitomp
404
.BR "unsigned int" -> mpint
405
.TP
406
.I mptoi
407
.BR mpint -> "int"
408
.TP
409
.I itomp
410
.BR "int" -> mpint
411
.TP
412
.I mptouv
413
.BR mpint -> "unsigned vlong"
414
.TP
415
.I uvtomp
416
.BR "unsigned vlong" -> mpint
417
.TP
418
.I mptov
419
.BR mpint -> "vlong"
420
.TP
421
.I vtomp
422
.BR "vlong" -> mpint
423
.PD
424
.PP
425
When converting to the base integer types, if the integer is too large,
426
the largest integer of the appropriate sign
427
and size is returned.
428
.PP
429
The mathematical functions are:
430
.TF mpmagadd
431
.TP
432
.I mpadd
433
.BR "sum = b1 + b2" .
434
.TP
435
.I mpmagadd
436
.BR "sum = abs(b1) + abs(b2)" . 
437
.TP
438
.I mpsub
439
.BR "diff = b1 - b2" .
440
.TP
441
.I mpmagsub
442
.BR "diff = abs(b1) - abs(b2)" .
443
.TP
444
.I mpleft
445
.BR "res = b<<shift" .
446
.TP
447
.I mpright
448
.BR "res = b>>shift" .
449
.TP
450
.I mpmul
451
.BR "prod = b1*b2" .
452
.TP
453
.I mpexp
454
if
455
.I m
456
is nil,
457
.BR "res = b**e" .
458
Otherwise,
459
.BR "res = b**e mod m" .
460
.TP
461
.I mpmod
462
.BR "remainder = b % m" .
463
.TP
464
.I mpdiv
465
.BR "quotient = dividend/divisor" .
466
.BR "remainder = dividend % divisor" .
467
.TP
468
.I mpcmp
469
returns -1, 0, or +1 as
470
.I b1
471
is less than, equal to, or greater than
472
.IR b2 .
473
.TP
474
.I mpmagcmp
475
the same as
476
.I mpcmp
477
but ignores the sign and just compares magnitudes.
478
.PD
479
.PP
480
.I Mpextendedgcd
481
computes the greatest common denominator,
482
.IR d ,
483
of
484
.I a
485
and
486
.IR b .
487
It also computes
488
.I x
489
and
490
.I y
491
such that
492
.BR "a*x + b*y = d" .
493
Both
494
.I a
495
and
496
.I b
497
are required to be positive.
498
If called with negative arguments, it will
499
return a gcd of 0.
500
.PP
501
.I Mpinverse
502
computes the multiplicative inverse of
503
.I b
504
.B mod
505
.IR m .
506
.PP
507
.I Mpsignif
508
returns the number of significant bits in
509
.IR b .
510
.I Mplowbits0
511
returns the number of consecutive zero bits
512
at the low end of the significant bits.
513
For example, for 0x14,
514
.I mpsignif
515
returns 5 and
516
.I mplowbits0
517
returns 2.
518
For 0, 
519
.I mpsignif
520
and
521
.I mplowbits0
522
both return 0.
523
.PP
524
The remaining routines all work on arrays of
525
.B mpdigit
526
rather than
527
.BR mpint 's.
528
They are the basis of all the other routines.  They are separated out
529
to allow them to be rewritten in assembler for each architecture.  There
530
is also a portable C version for each one.
531
.TF mpvecdigmuladd
532
.TP
533
.I mpdigdiv
534
.BR "quotient = dividend[0:1] / divisor" .
535
.TP
536
.I mpvecadd
537
.BR "sum[0:alen] = a[0:alen-1] + b[0:blen-1]" .
538
We assume alen >= blen and that sum has room for alen+1 digits.
539
.TP
540
.I mpvecsub
541
.BR "diff[0:alen-1] = a[0:alen-1] - b[0:blen-1]" .
542
We assume that alen >= blen and that diff has room for alen digits.
543
.TP
544
.I mpvecdigmuladd
545
.BR "p[0:n] += m * b[0:n-1]" .
546
This multiplies a an array of digits times a scalar and adds it to another array.
547
We assume p has room for n+1 digits.
548
.TP
549
.I mpvecdigmulsub
550
.BR "p[0:n] -= m * b[0:n-1]" .
551
This multiplies a an array of digits times a scalar and subtracts it fromo another array.
552
We assume p has room for n+1 digits.  It returns +1 is the result is positive and
553
-1 if negative.
554
.TP
555
.I mpvecmul
556
.BR "p[0:alen*blen] = a[0:alen-1] * b[0:blen-1]" .
557
We assume that p has room for alen*blen+1 digits.
558
.TP
559
.I mpveccmp
560
This returns -1, 0, or +1 as a - b is negative, 0, or positive.
561
.PD
562
.PP
563
.IR mptwo ,
564
.I mpone
565
and
566
.I mpzero
567
are the constants 2, 1 and 0.  These cannot be freed.
568
.SS "Chinese remainder theorem
569
.PP
570
When computing in a non-prime modulus, 
571
.IR n,
572
it is possible to perform the computations on the residues modulo the prime
573
factors of
574
.I n
575
instead.  Since these numbers are smaller, multiplication and exponentiation
576
can be much faster.
577
.PP
578
.I Crtin
579
computes the residues of
580
.I x
581
and returns them in a newly allocated structure:
582
.IP
583
.EX
584
typedef struct CRTres	CRTres;	
585
{
586
	int	n;	/* number of residues */
587
	mpint	*r[n];	/* residues */
588
};
589
.EE
590
.PP
591
.I Crtout
592
takes a residue representation of a number and converts it back into
593
the number.  It also frees the residue structure.
594
.PP
595
.I Crepre
596
saves a copy of the factors and precomputes the constants necessary
597
for converting the residue form back into a number modulo
598
the product of the factors.  It returns a newly allocated structure
599
containing values.
600
.PP
601
.I Crtprefree
602
and
603
.I crtresfree
604
free
605
.I CRTpre
606
and
607
.I CRTres
608
structures respectively.
609
.SH SOURCE
610
.B /sys/src/libmp