123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604 |
- .TH MP 2
- .SH NAME
- 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
- .SH SYNOPSIS
- .B #include <u.h>
- .br
- .B #include <libc.h>
- .br
- .B #include <mp.h>
- .PP
- .ta +\w'\fLCRTpre* \fP'u
- .B
- mpint* mpnew(int n)
- .PP
- .B
- void mpfree(mpint *b)
- .PP
- .B
- void mpsetminbits(int n)
- .PP
- .B
- void mpbits(mpint *b, int n)
- .PP
- .B
- void mpnorm(mpint *b)
- .PP
- .B
- mpint* mpcopy(mpint *b)
- .PP
- .B
- void mpassign(mpint *old, mpint *new)
- .PP
- .B
- mpint* mprand(int bits, void (*gen)(uchar*, int), mpint *b)
- .PP
- .B
- mpint* strtomp(char *buf, char **rptr, int base, mpint *b)
- .PP
- .B
- char* mptoa(mpint *b, int base, char *buf, int blen)
- .PP
- .B
- int mpfmt(Fmt*)
- .PP
- .B
- mpint* betomp(uchar *buf, uint blen, mpint *b)
- .PP
- .B
- int mptobe(mpint *b, uchar *buf, uint blen, uchar **bufp)
- .PP
- .B
- mpint* letomp(uchar *buf, uint blen, mpint *b)
- .PP
- .B
- int mptole(mpint *b, uchar *buf, uint blen, uchar **bufp)
- .PP
- .B
- uint mptoui(mpint*)
- .PP
- .B
- mpint* uitomp(uint, mpint*)
- .PP
- .B
- int mptoi(mpint*)
- .PP
- .B
- mpint* itomp(int, mpint*)
- .PP
- .B
- mpint* vtomp(vlong, mpint*)
- .PP
- .B
- vlong mptov(mpint*)
- .PP
- .B
- mpint* uvtomp(uvlong, mpint*)
- .PP
- .B
- uvlong mptouv(mpint*)
- .PP
- .B
- void mpadd(mpint *b1, mpint *b2, mpint *sum)
- .PP
- .B
- void mpmagadd(mpint *b1, mpint *b2, mpint *sum)
- .PP
- .B
- void mpsub(mpint *b1, mpint *b2, mpint *diff)
- .PP
- .B
- void mpmagsub(mpint *b1, mpint *b2, mpint *diff)
- .PP
- .B
- void mpleft(mpint *b, int shift, mpint *res)
- .PP
- .B
- void mpright(mpint *b, int shift, mpint *res)
- .PP
- .B
- void mpmul(mpint *b1, mpint *b2, mpint *prod)
- .PP
- .B
- void mpexp(mpint *b, mpint *e, mpint *m, mpint *res)
- .PP
- .B
- void mpmod(mpint *b, mpint *m, mpint *remainder)
- .PP
- .B
- void mpdiv(mpint *dividend, mpint *divisor, mpint *quotient,
- .br
- .B
- mpint *remainder)
- .PP
- .B
- int mpcmp(mpint *b1, mpint *b2)
- .PP
- .B
- int mpmagcmp(mpint *b1, mpint *b2)
- .PP
- .B
- void mpextendedgcd(mpint *a, mpint *b, mpint *d, mpint *x,
- .br
- .B
- mpint *y)
- .PP
- .B
- void mpinvert(mpint *b, mpint *m, mpint *res)
- .PP
- .B
- int mpsignif(mpint *b)
- .PP
- .B
- int mplowbits0(mpint *b)
- .PP
- .B
- void mpdigdiv(mpdigit *dividend, mpdigit divisor,
- .br
- .B
- mpdigit *quotient)
- .PP
- .B
- void mpvecadd(mpdigit *a, int alen, mpdigit *b, int blen,
- .br
- .B
- mpdigit *sum)
- .PP
- .B
- void mpvecsub(mpdigit *a, int alen, mpdigit *b, int blen,
- .br
- .B
- mpdigit *diff)
- .PP
- .B
- void mpvecdigmuladd(mpdigit *b, int n, mpdigit m, mpdigit *p)
- .PP
- .B
- int mpvecdigmulsub(mpdigit *b, int n, mpdigit m, mpdigit *p)
- .PP
- .B
- void mpvecmul(mpdigit *a, int alen, mpdigit *b, int blen,
- .br
- .B
- mpdigit *p)
- .PP
- .B
- int mpveccmp(mpdigit *a, int alen, mpdigit *b, int blen)
- .PP
- .B
- CRTpre* crtpre(int nfactors, mpint **factors)
- .PP
- .B
- CRTres* crtin(CRTpre *crt, mpint *x)
- .PP
- .B
- void crtout(CRTpre *crt, CRTres *r, mpint *x)
- .PP
- .B
- void crtprefree(CRTpre *cre)
- .PP
- .B
- void crtresfree(CRTres *res)
- .PP
- .B
- mpint *mpzero, *mpone, *mptwo
- .DT
- .SH DESCRIPTION
- These routines perform extended precision integer arithmetic.
- The basic type is
- .BR mpint ,
- which points to an array of
- .BR mpdigit s,
- stored in little-endian order:
- .IP
- .EX
- typedef struct mpint mpint;
- struct mpint
- {
- int sign; /* +1 or -1 */
- int size; /* allocated digits */
- int top; /* significant digits */
- mpdigit *p;
- char flags;
- };
- .EE
- .PP
- The sign of 0 is +1.
- .PP
- The size of
- .B mpdigit
- is architecture-dependent and defined in
- .BR /$cputype/include/u.h .
- .BR Mpint s
- are dynamically allocated and must be explicitly freed. Operations
- grow the array of digits as needed.
- .PP
- In general, the result parameters are last in the
- argument list.
- .PP
- Routines that return an
- .B mpint
- will allocate the
- .B mpint
- if the result parameter is
- .BR nil .
- This includes
- .IR strtomp ,
- .IR itomp ,
- .IR uitomp ,
- and
- .IR btomp .
- These functions, in addition to
- .I mpnew
- and
- .IR mpcopy ,
- will return
- .B nil
- if the allocation fails.
- .PP
- Input and result parameters may point to the same
- .BR mpint .
- The routines check and copy where necessary.
- .PP
- .I Mpnew
- creates an
- .B mpint
- with an initial allocation of
- .I n
- bits.
- If
- .I n
- is zero, the allocation will be whatever was specified in the
- last call to
- .I mpsetminbits
- or to the initial value, 1056.
- .I Mpfree
- frees an
- .BR mpint .
- .I Mpbits
- grows the allocation of
- .I b
- to fit at least
- .I n
- bits. If
- .B b->top
- doesn't cover
- .I n
- bits,
- .I mpbits
- increases it to do so.
- Unless you are writing new basic operations, you
- can restrict yourself to
- .B mpnew(0)
- and
- .BR mpfree(b) .
- .PP
- .I Mpnorm
- normalizes the representation by trimming any high order zero
- digits. All routines except
- .B mpbits
- return normalized results.
- .PP
- .I Mpcopy
- creates a new
- .B mpint
- with the same value as
- .I b
- while
- .I mpassign
- sets the value of
- .I new
- to be that of
- .IR old .
- .PP
- .I Mprand
- creates an
- .I n
- bit random number using the generator
- .IR gen .
- .I Gen
- takes a pointer to a string of uchar's and the number
- to fill in.
- .PP
- .I Strtomp
- and
- .I mptoa
- convert between
- .SM ASCII
- and
- .B mpint
- representations using the base indicated.
- Only the bases 10, 16, 32, and 64 are
- supported. Anything else defaults to 16.
- .IR Strtomp
- skips any leading spaces or tabs.
- .IR Strtomp 's
- scan stops when encountering a digit not valid in the
- base. If
- .I rptr
- is not zero,
- .I *rptr
- is set to point to the character immediately after the
- string converted.
- If the parse pterminates before any digits are found,
- .I strtomp
- return
- .BR nil .
- .I Mptoa
- returns a pointer to the filled buffer.
- If the parameter
- .I buf
- is
- .BR nil ,
- the buffer is allocated.
- .I Mpfmt
- can be used with
- .IR fmtinstall (2)
- and
- .IR print (2)
- to print hexadecimal representations of
- .BR mpint s.
- .PP
- .I Mptobe
- and
- .I mptole
- convert an
- .I mpint
- to a byte array. The former creates a big endian representation,
- the latter a little endian one.
- If the destination
- .I buf
- is not
- .BR nil ,
- it specifies the buffer of length
- .I blen
- for the result. If the representation
- is less than
- .I blen
- bytes, the rest of the buffer is zero filled.
- If
- .I buf
- is
- .BR nil ,
- then a buffer is allocated and a pointer to it is
- deposited in the location pointed to by
- .IR bufp .
- Sign is ignored in these conversions, i.e., the byte
- array version is always positive.
- .PP
- .IR Betomp ,
- and
- .I letomp
- convert from a big or little endian byte array at
- .I buf
- of length
- .I blen
- to an
- .IR mpint .
- If
- .I b
- is not
- .IR nil ,
- it refers to a preallocated
- .I mpint
- for the result.
- If
- .I b
- is
- .BR nil ,
- a new integer is allocated and returned as the result.
- .PP
- The integer conversions are:
- .TF Mptouv
- .TP
- .I mptoui
- .BR mpint -> "unsigned int"
- .TP
- .I uitomp
- .BR "unsigned int" -> mpint
- .TP
- .I mptoi
- .BR mpint -> "int"
- .TP
- .I itomp
- .BR "int" -> mpint
- .TP
- .I mptouv
- .BR mpint -> "unsigned vlong"
- .TP
- .I uvtomp
- .BR "unsigned vlong" -> mpint
- .TP
- .I mptov
- .BR mpint -> "vlong"
- .TP
- .I vtomp
- .BR "vlong" -> mpint
- .PD
- .PP
- When converting to the base integer types, if the integer is too large,
- the largest integer of the appropriate sign
- and size is returned.
- .PP
- The mathematical functions are:
- .TF mpmagadd
- .TP
- .I mpadd
- .BR "sum = b1 + b2" .
- .TP
- .I mpmagadd
- .BR "sum = abs(b1) + abs(b2)" .
- .TP
- .I mpsub
- .BR "diff = b1 - b2" .
- .TP
- .I mpmagsub
- .BR "diff = abs(b1) - abs(b2)" .
- .TP
- .I mpleft
- .BR "res = b<<shift" .
- .TP
- .I mpright
- .BR "res = b>>shift" .
- .TP
- .I mpmul
- .BR "prod = b1*b2" .
- .TP
- .I mpexp
- if
- .I m
- is nil,
- .BR "res = b**e" .
- Otherwise,
- .BR "res = b**e mod m" .
- .TP
- .I mpmod
- .BR "remainder = b % m" .
- .TP
- .I mpdiv
- .BR "quotient = dividend/divisor" .
- .BR "remainder = dividend % divisor" .
- .TP
- .I mpcmp
- returns -1, 0, or +1 as
- .I b1
- is less than, equal to, or greater than
- .IR b2 .
- .TP
- .I mpmagcmp
- the same as
- .I mpcmp
- but ignores the sign and just compares magnitudes.
- .PD
- .PP
- .I Mpextendedgcd
- computes the greatest common denominator,
- .IR d ,
- of
- .I a
- and
- .IR b .
- It also computes
- .I x
- and
- .I y
- such that
- .BR "a*x + b*y = d" .
- Both
- .I a
- and
- .I b
- are required to be positive.
- If called with negative arguments, it will
- return a gcd of 0.
- .PP
- .I Mpinverse
- computes the multiplicative inverse of
- .I b
- .B mod
- .IR m .
- .PP
- .I Mpsignif
- returns the number of significant bits in
- .IR b .
- .I Mplowbits0
- returns the number of consecutive zero bits
- at the low end of the significant bits.
- For example, for 0x14,
- .I mpsignif
- returns 5 and
- .I mplowbits0
- returns 2.
- For 0,
- .I mpsignif
- and
- .I mplowbits0
- both return 0.
- .PP
- The remaining routines all work on arrays of
- .B mpdigit
- rather than
- .BR mpint 's.
- They are the basis of all the other routines. They are separated out
- to allow them to be rewritten in assembler for each architecture. There
- is also a portable C version for each one.
- .TF mpvecdigmuladd
- .TP
- .I mpdigdiv
- .BR "quotient = dividend[0:1] / divisor" .
- .TP
- .I mpvecadd
- .BR "sum[0:alen] = a[0:alen-1] + b[0:blen-1]" .
- We assume alen >= blen and that sum has room for alen+1 digits.
- .TP
- .I mpvecsub
- .BR "diff[0:alen-1] = a[0:alen-1] - b[0:blen-1]" .
- We assume that alen >= blen and that diff has room for alen digits.
- .TP
- .I mpvecdigmuladd
- .BR "p[0:n] += m * b[0:n-1]" .
- This multiplies a an array of digits times a scalar and adds it to another array.
- We assume p has room for n+1 digits.
- .TP
- .I mpvecdigmulsub
- .BR "p[0:n] -= m * b[0:n-1]" .
- This multiplies a an array of digits times a scalar and subtracts it fromo another array.
- We assume p has room for n+1 digits. It returns +1 is the result is positive and
- -1 if negative.
- .TP
- .I mpvecmul
- .BR "p[0:alen*blen] = a[0:alen-1] * b[0:blen-1]" .
- We assume that p has room for alen*blen+1 digits.
- .TP
- .I mpveccmp
- This returns -1, 0, or +1 as a - b is negative, 0, or positive.
- .PD
- .PP
- .IR mptwo ,
- .I mpone
- and
- .I mpzero
- are the constants 2, 1 and 0. These cannot be freed.
- .SS "Chinese remainder theorem
- .PP
- When computing in a non-prime modulus,
- .IR n,
- it is possible to perform the computations on the residues modulo the prime
- factors of
- .I n
- instead. Since these numbers are smaller, multiplication and exponentiation
- can be much faster.
- .PP
- .I Crtin
- computes the residues of
- .I x
- and returns them in a newly allocated structure:
- .IP
- .EX
- typedef struct CRTres CRTres;
- {
- int n; /* number of residues */
- mpint *r[n]; /* residues */
- };
- .EE
- .PP
- .I Crtout
- takes a residue representation of a number and converts it back into
- the number. It also frees the residue structure.
- .PP
- .I Crepre
- saves a copy of the factors and precomputes the constants necessary
- for converting the residue form back into a number modulo
- the product of the factors. It returns a newly allocated structure
- containing values.
- .PP
- .I Crtprefree
- and
- .I crtresfree
- free
- .I CRTpre
- and
- .I CRTres
- structures respectively.
- .SH SOURCE
- .B /sys/src/libmp
|