summaryrefslogtreecommitdiff
path: root/man
diff options
context:
space:
mode:
authorforsyth <forsyth@vitanuova.com>2010-08-10 23:06:28 +0100
committerforsyth <forsyth@vitanuova.com>2010-08-10 23:06:28 +0100
commit7de2b42d50e3c05cc143e7b51284009b5e185581 (patch)
tree42fffe0c9804551c120ef89c3f505059bbd31cfb /man
parent99c84fef96ccd10bb6cabb823384c033090293e9 (diff)
20100810-2306
Diffstat (limited to 'man')
-rw-r--r--man/2/crypt-0intro98
-rw-r--r--man/2/crypt-crypt142
-rw-r--r--man/2/crypt-dsagen94
-rw-r--r--man/2/crypt-gensk159
-rw-r--r--man/2/crypt-rc449
-rw-r--r--man/2/crypt-sha1144
-rw-r--r--man/2/ipints193
-rw-r--r--man/2/ipints-genprime112
8 files changed, 991 insertions, 0 deletions
diff --git a/man/2/crypt-0intro b/man/2/crypt-0intro
new file mode 100644
index 00000000..3add273e
--- /dev/null
+++ b/man/2/crypt-0intro
@@ -0,0 +1,98 @@
+.TH CRYPT-INTRO 2
+.SH NAME
+Crypt intro \- introduction to the
+.B Crypt
+cryptography
+module
+.SH SYNOPSIS
+.EX
+include "ipints.m";
+ipints := load IPints IPints->PATH;
+IPint: import ipints;
+
+include "crypt.m";
+crypt := load Crypt Crypt->PATH;
+.EE
+.SH DESCRIPTION
+.B Crypt
+contains a mixed set of functions that variously:
+.IP \(bu
+form cryptographically secure digests; see
+.IR crypt-sha1 (2)
+.IP \(bu
+generate public/private key pairs; see
+.IR crypt-gensk (2)
+.IP \(bu
+encrypt data, using AES, DES, or IDEA; see
+.IR crypt-crypt (2)
+.IP \(bu
+create and verify cryptographic signatures using the
+public keys; see
+.IR crypt-sign (2)
+.SS "Public Key Cryptography"
+Public key cryptography has many uses.
+Inferno relies on it only for digital signatures.
+The private key may be used to digitally
+sign data, the public one to verify the signature.
+.PP
+Inferno provides three data types to represent the different components of the public key signature scheme.
+The
+.B PK
+adt contains the data necessary to construct a public key;
+the
+.B SK
+adt contains the data necessary to construct a secret key.
+A key contains the public or secret parameters for the signature algorithm specified by the adt's pick tag.
+Ownership of a key is not recorded in the key value itself but in a separate certificate.
+Finally,
+the
+.B PKsig
+adt contains one or more values representing a given form of digital signature.
+.PP
+Certificates and indeed signature representations are varied, and implemented by other modules.
+.SS "Large Precision Arithmetic"
+Many
+.B Crypt
+operations require integers much larger than
+.B int
+or
+.BR big .
+It therefore uses the multiple-precision package
+.IR ipints (2).
+That module's
+.B IPint
+adt
+stands for infinite precision integer, though, for
+space considerations, our
+implementation limits the maximum integer to
+2\u\s-2\&8192\s0\d-1.
+.PP
+An
+.B IPint
+can be converted into two external formats.
+The first is
+an array of bytes in which the first byte is the highest order
+byte of the integer. This format is useful when
+communicating with the
+.IR ssl (3)
+device.
+The second is similar but represents the array of bytes as text, using either base 16 or a MIME base 64 format,
+allowing
+.BR IPint s
+to be stored in files or transmitted across
+networks in a human readable form.
+.SH SOURCE
+.br
+.B /libinterp/crypt.c
+.br
+.B /libinterp/ipint.c
+.br
+.B /libmp
+.br
+.B /libsec
+.SH SEE ALSO
+.IR security-intro (2)
+.br
+B. Schneier,
+.IR "Applied Cryptography" ,
+1996, J. Wiley & Sons, Inc.
diff --git a/man/2/crypt-crypt b/man/2/crypt-crypt
new file mode 100644
index 00000000..5d079ca4
--- /dev/null
+++ b/man/2/crypt-crypt
@@ -0,0 +1,142 @@
+.TH CRYPT-CRYPT 2
+.SH NAME
+crypt: aessetup, aescbc, dessetup, descbc, desecb, ideasetup, ideacbc, ideaecb \- data encryption
+.SH SYNOPSIS
+.EX
+include "ipints.m";
+include "crypt.m";
+crypt := load Crypt Crypt->PATH;
+
+Encrypt: con 0;
+Decrypt: con 1;
+
+AESbsize: con 16;
+
+aessetup: fn(key: array of byte, ivec: array of byte): ref AESstate;
+aescbc: fn(state: ref AESstate, buf: array of byte,
+ n: int, direction: int);
+
+BFbsize: con 8;
+
+blowfishsetup: fn(key: array of byte, ivec: array of byte): ref BFstate;
+blowfishcbc: fn(state: ref BFstate, buf: array of byte,
+ n: int, direction: int);
+
+DESbsize: con 8;
+
+dessetup: fn(key: array of byte, ivec: array of byte): ref DESstate;
+descbc: fn(state: ref DESstate, buf: array of byte,
+ n: int, direction: int);
+desecb: fn(state: ref DESstate, buf: array of byte,
+ n: int, direction: int);
+
+IDEAbsize: con 8;
+
+ideasetup: fn(key: array of byte, ivec: array of byte): ref IDEAstate;
+ideacbc: fn(state: ref IDEAstate, buf: array of byte,
+ n: int, direction: int);
+ideaecb: fn(state: ref IDEAstate, buf: array of byte,
+ n: int, direction: int);
+.EE
+.SH DESCRIPTION
+These functions encrypt and decrypt blocks of data using different
+encryption algorithms.
+The interfaces are similar.
+.PP
+Each algorithm has an adt that holds the current state for a given encryption.
+It is produced by the setup function for the algorithm,
+.IB alg setup ,
+which is given a secret
+.I key
+and an initialisation vector
+.IR ivec .
+A sequence of blocks of data can then be encrypted or decrypted by repeatedly calling
+.IB alg cbc
+(for `cipher block chaining'), or
+.IB alg ebc
+(the less secure `electronic code book', if provided).
+On each call,
+.I buf
+provides
+.I n
+bytes of the data to encrypt or decrypt.
+.I N
+must be a multiple of the encryption block size
+.IB ALG bsize .
+Exceptionally,
+.B aescbc
+allows
+.I n
+to be other than a multiple of
+.B AESbsize
+in length, but then
+for successful decryption, the decryptor must use the same
+sequence of buffer sizes as the encryptor.
+.I Direction
+is the constant
+.B Encrypt
+or
+.B Decrypt
+as required.
+.I State
+maintains the encryption state, initially produced by the setup function,
+and updated as each buffer is encrypted or decrypted.
+.PP
+The algorithms currently available are:
+.TP
+.B aes
+The Advanced Encryption Standard, AES (also known as Rijndael).
+The
+.I key
+should be 16, 24 or 32 bytes long (128, 192 or 256 bits).
+.I Ivec
+should be
+.B AESbsize
+bytes of random data: random enough to be unlikely to be reused but
+not cryptographically strongly unpredictable.
+.TP
+.B blowfish
+Bruce Schneier's symmetric block cipher.
+The
+.I key
+is any length from 4 to 56 bytes.
+.I Ivec
+if non-nil is
+.B BFbsize
+bytes of random data.
+For
+.BR blowfishcbc ,
+.I n
+must be a multiple of
+.BR BFbsize .
+.TP
+.B des
+The older Data Encryption Standard, DES.
+.I Key
+is 8 bytes (64 bits), containing a 56-bit key
+encoded into 64 bits where every eighth bit is parity.
+.I Ivec
+is
+.B DESbsize
+bytes of random data.
+.TP
+.B idea
+The International Data Encryption Standard, IDEA™.
+The
+.I key
+is 16 bytes long (128 bits).
+.I Ivec
+is
+.B IDEAbsize
+bytes of random data.
+.SH SEE ALSO
+.IR crypt-intro (2),
+.IR crypt-rc4 (2),
+.IR security-random (2)
+.PP
+IDEA was patented by Ascom-Tech AG (EP 0 482 154 B1, US005214703),
+currently held by iT_SEC Systec Ltd.
+At time of writing, there was no licence fee required for noncommercial use
+but check
+the current licensing policy of iT_SEC Systec Ltd,
+especially for commercial use.
diff --git a/man/2/crypt-dsagen b/man/2/crypt-dsagen
new file mode 100644
index 00000000..7ccedc16
--- /dev/null
+++ b/man/2/crypt-dsagen
@@ -0,0 +1,94 @@
+.TH CRYPT-DSAGEN 2
+.SH NAME
+crypt: dsagen, eggen, rsagen, rsafill, rsaencrypt, rsadecrypt \- specific public key systems
+.SH SYNOPSIS
+.EX
+include "ipints.m";
+ipints := load IPints IPints->PATH;
+IPint: import ipints;
+
+include "crypt.m";
+crypt := load Crypt Crypt->PATH;
+
+dsagen: fn(oldpk: ref PK.DSA): ref SK.DSA;
+
+eggen: fn(nlen: int, nrep: int): ref SK.Elgamal;
+
+rsagen: fn(nlen: int, elen: int, nrep: int): ref SK.RSA;
+rsafill: fn(n: ref IPint, ek: ref IPint, dk: ref IPint,
+ p: ref IPint, q: ref IPint): ref SK.RSA;
+rsaencrypt: fn(k: ref PK.RSA, m: ref IPint): ref IPint;
+rsadecrypt: fn(k: ref SK.RSA, m: ref IPint): ref IPint;
+.EE
+.SH DESCRIPTION
+.IR Crypt-gensk (2)
+describes a set of functions that generate public/private key pairs given an algorithm name
+and a key length.
+Some key types allow further parameters for key generation or support further operations.
+.PP
+.B Dsagen
+generates a DSA public/private key pair, represented by the pick adt
+.BR SK.DSA ,
+and compatible with the containing type
+.BR SK .
+If the parameter
+.B oldpk
+is not nil,
+.B dsagen
+takes the new key's modulus and group order from the existing key;
+otherwise it generates a new pair of primes.
+.PP
+.B Eggen
+generates a new El-Gamal key pair, represented by the pick adt
+.BR SK.Elgamal .
+.I Nlen
+is the length of the modulus;
+.I nrep
+is the number of repetitions of the Miller-Rabin primality test (0 gives the default, currently 18).
+.PP
+.B Rsagen
+generates an RSA public/private key pair, represented by the pick adt
+.BR SK.RSA ,
+and compatible with the containing type
+.BR SK .
+.I Nlen
+gives the length of the key modulus in bits;
+.I elen
+gives the exponent length in bits; and
+.I nrep
+is as above.
+.PP
+The RSA private key representation used by Inferno includes some extra values to speed computation.
+.B Rsagen
+provides those values but keys imported from other systems might not.
+Given the essential set of RSA private key parameters for a given key, represented as IPints,
+.B rsafill
+returns a suitable
+.B SK.RSA
+for that key, including the extra values.
+.PP
+The public key of type
+.B PK.RSA
+can be extracted from a given private key value
+.I sk
+by referencing the field
+.BI sk .pk .
+.PP
+.B Rsaencrypt
+encrypts a message
+.IR m ,
+represented by an IPint,
+using the public key
+.IR pk .
+.PP
+.B Rsadecrypt
+decrypts
+.I m
+using private key
+.IR sk .
+The result is again returned as an IPint.
+.SH SEE ALSO
+.IR crypt-gensk (2),
+.IR crypt-sha1 (2),
+.IR security-auth (2),
+.IR security-oldauth (2)
diff --git a/man/2/crypt-gensk b/man/2/crypt-gensk
new file mode 100644
index 00000000..df51b4ee
--- /dev/null
+++ b/man/2/crypt-gensk
@@ -0,0 +1,159 @@
+.TH CRYPT-GENSK 2
+.SH NAME
+crypt: genSK, genSKfromPK, sktopk, dhparams, sign, verify \- generate keys and digital signatures
+.SH SYNOPSIS
+.EX
+include "ipints.m";
+ipints := load IPints IPints->PATH;
+IPint: import ipints;
+
+include "crypt.m";
+crypt := load Crypt Crypt->PATH;
+
+PK: adt
+{
+ pick {
+ RSA =>
+ n: ref IPint; # modulus
+ ek: ref IPint; # exp (encryption key)
+ Elgamal =>
+ p: ref IPint; # modulus
+ alpha: ref IPint; # generator
+ key: ref IPint; # encryption key (alpha**secret mod p)
+ DSA =>
+ p: ref IPint; # modulus
+ q: ref IPint; # group order, q divides p-1
+ alpha: ref IPint; # group generator
+ key: ref IPint; # encryption key (alpha**secret mod p)
+ }
+};
+
+SK: adt
+{
+ pick {
+ RSA =>
+ pk: ref PK.RSA;
+ dk: ref IPint; # exp (decryption key)
+ p: ref IPint; # q in pkcs
+ q: ref IPint; # p in pkcs
+ # precomputed crt values
+ kp: ref IPint; # k mod p-1
+ kq: ref IPint; # k mod q-1
+ c2: ref IPint; # for converting residues to number
+ Elgamal =>
+ pk: ref PK.Elgamal;
+ secret: ref IPint; # decryption key
+ DSA =>
+ pk: ref PK.DSA;
+ secret: ref IPint; # decryption key
+ }
+};
+
+PKsig: adt
+{
+ pick {
+ RSA =>
+ n: ref IPint;
+ Elgamal =>
+ r: ref IPint;
+ s: ref IPint;
+ DSA =>
+ r: ref IPint;
+ s: ref IPint;
+ }
+};
+
+genSK: fn(algname: string, length: int): ref SK;
+genSKfromPK: fn(pk: ref PK): ref SK;
+sktopk: fn(sk: ref SK): ref PK;
+
+sign: fn(sk: ref SK, m: ref IPint): ref PKsig;
+verify: fn(pk: ref PK, sig: ref PKsig, m: ref IPint): int;
+
+dhparams: fn(nbits: int): (ref IPint, ref IPint);
+.EE
+.SH DESCRIPTION
+.B Crypt
+implements a set of public-key signature algorithms.
+The public/private key pairs are represented by values of the adt
+.BR SK ,
+containing both the private (secret) and public parts of the pair,
+and
+.BR PK ,
+containing only the public part.
+The several algorithms are represented by different pick variants.
+.PP
+.B GenSK
+generates a new public/private key pair, represented by
+.BR SK .
+.I Algname
+is the name of the algorithm to use; in the current implementation,
+.BR dsa ,
+.B elgamal
+and
+.B rsa
+are possible.
+.I Length
+gives the length of the key modulus in bits.
+.B GenSK
+returns nil if an unknown algorithm has been specified.
+.PP
+.B GenSKfromPK
+generates a private key that has the system parameters as the public key
+.IR pk .
+It is used to generate new keys that are of the same complexity as old keys.
+.PP
+.B Sktopk
+returns a reference to the public part of private key
+.IR sk .
+.PP
+.B Sign
+creates a digital signature of a message
+.IR m ,
+represented by an IPint,
+using the private key
+.IR sk .
+Typically
+.I m
+represents a secure hash (eg, using
+.IR crypt-sha1 (2))
+of a much larger message.
+.PP
+.B Verify
+uses public key
+.I pk
+to verify that the value
+.I sig
+is a digital signature of the message
+.I m
+using the private key corresponding to
+.IR pk .
+It returns non-zero (true) if the signature is valid; zero (false) otherwise.
+.PP
+Most applications use generic operations on public and private keys,
+referring to
+.B PK
+and
+.BR SK ,
+but specific variants can be named, such as
+.BR PK.RSA
+for RSA keys, allowing use of RSA-specific operations.
+.IR Crypt-dsagen (2)
+describes functions for key generation that are specific to various algorithms,
+using algorithm-specific parameters.
+.PP
+.B Dhparams
+creates Diffie-Hellman parameters. It returns
+a tuple of IPints
+.RI ( alpha , p ).
+.I P
+is an
+.I nbits
+long prime number that serves as the modulus.
+.I Alpha
+is a primitive root in the integer field defined by that modulus.
+.SH SEE ALSO
+.IR crypt-dsagen (2),
+.IR crypt-sha1 (2),
+.IR security-auth (2),
+.IR security-oldauth (2)
diff --git a/man/2/crypt-rc4 b/man/2/crypt-rc4
new file mode 100644
index 00000000..8f04705e
--- /dev/null
+++ b/man/2/crypt-rc4
@@ -0,0 +1,49 @@
+.TH CRYPT-RC4 2
+.SH NAME
+crypt: rc4setup, rc4, rc4skip, rc4back \- RC4 encryption
+.SH SYNOPSIS
+.EX
+include "ipints.m";
+ipints := load IPints IPints->PATH;
+IPint: import ipints;
+
+include "crypt.m";
+crypt := load Crypt Crypt->PATH;
+
+rc4setup: fn(seed: array of byte): ref RC4state;
+rc4: fn(state: ref RC4state, buf: array of byte, n: int);
+rc4skip: fn(state: ref RC4state, n: int);
+rc4back: fn(state: ref RC4state, n: int);
+.EE
+.SH DESCRIPTION
+These functions implement the stream encryption algorithm that is claimed to
+be equivalent to RSA Security's RC4.
+It is a pseudo-random number generator with a 256
+byte state and a long cycle.
+.PP
+.B Rc4setup
+sets the initial
+.IR seed ,
+which can be any non-zero length, and
+returns a representation of the initial state of the algorithm,
+which is used in subsequent calls.
+.PP
+.B Rc4
+runs the generator starting with the given
+.IR state ,
+and XORs the output of the generator with
+the first
+.I n
+bytes of
+.IR buf ,
+updating the
+.IR state .
+.B Rc4
+is symmetric and is used both to encrypt and decrypt.
+.B Rc4skip
+skips over bytes (eg, to account for lost transmissions);
+.B rc4back
+runs the generator backwards (eg, to account for retransmissions).
+.SH SEE ALSO
+.IR crypt-intro (2),
+.IR crypt-crypt (2)
diff --git a/man/2/crypt-sha1 b/man/2/crypt-sha1
new file mode 100644
index 00000000..adfe763a
--- /dev/null
+++ b/man/2/crypt-sha1
@@ -0,0 +1,144 @@
+.TH CRYPT-SHA1 2
+.SH NAME
+crypt: sha1, sha224, sha256, sha384, sha512, md4, md5, hmac_sha1, hmac_md5 \- cryptographic digests
+.SH SYNOPSIS
+.EX
+include "ipints.m";
+ipints := load IPints IPints->PATH;
+IPint: import ipints;
+
+include "crypt.m";
+crypt := load Crypt Crypt->PATH;
+
+DigestState: adt
+{
+ # hidden state
+ copy: fn(d: self ref DigestState): ref DigestState;
+};
+
+.ta \w'verify:\ 'u +\w'fn(\ \ \ 'u
+sha1: fn(buf: array of byte, n: int, digest: array of byte,
+ state: ref DigestState): ref DigestState;
+sha224: fn(buf: array of byte, n: int, digest: array of byte,
+ state: ref DigestState): ref DigestState;
+sha256: fn(buf: array of byte, n: int, digest: array of byte,
+ state: ref DigestState): ref DigestState;
+sha384: fn(buf: array of byte, n: int, digest: array of byte,
+ state: ref DigestState): ref DigestState;
+sha512: fn(buf: array of byte, n: int, digest: array of byte,
+ state: ref DigestState): ref DigestState;
+md4: fn(buf: array of byte, n: int, digest: array of byte,
+ state: ref DigestState): ref DigestState;
+md5: fn(buf: array of byte, n: int, digest: array of byte,
+ state: ref DigestState): ref DigestState;
+
+SHA1dlen, SHA224dlen, SHA256dlen, SHA384dlen, SHA512dlen, MD4dlen, MD5dlen: con ...;
+
+hmac_sha1: fn(buf: array of byte, n: int, key: array of byte,
+ digest: array of byte,
+ state: ref DigestState): ref DigestState;
+hmac_md5: fn(buf: array of byte, n: int, key: array of byte,
+ digest: array of byte,
+ state: ref DigestState): ref DigestState;
+.EE
+.SH DESCRIPTION
+.BR Sha1 ,
+.BR sha224 ,
+.BR sha256 ,
+.BR sha384 ,
+.BR sha512 ,
+.B md4
+and
+.B md5
+are cryptographically secure hash functions that produce output called a message digest.
+Each function computes a hash of
+.I n
+bytes of the data in
+.IR buf ,
+using the named algorithm,
+and updates the current
+.IR state .
+They can be called iteratively to form a single digest for many data blocks.
+The state is kept in the
+.B DigestState
+value referenced by
+.I state
+between calls.
+.I State
+should be
+.B nil
+on the first call, and a newly allocated
+.B DigestState
+will be returned for use in subsequent calls.
+On a call in which
+.I digest
+is not
+.BR nil ,
+the hash is completed and copied into the
+.I digest
+array.
+.B Sha1
+produces a 20-byte hash
+.RB ( SHA1dlen ),
+.B sha224
+a 28-byte hash
+.RB ( SHA224dlen ),
+.B sha256
+a 32-byte hash
+.RB ( SHA256dlen ),
+.B sha384
+a 48-byte hash
+.RB ( SHA384dlen ),
+.B sha256
+a 64-byte hash
+.RB ( SHA512dlen ),
+.B md4
+and
+.B md5
+a 16-byte one
+.RB ( MD4len
+and
+.BR MD5len ).
+.PP
+.B Hmac_sha1
+and
+.B hmac_md5
+are keyed versions of the hashing functions, following Internet RFC2104.
+The
+.I key
+must be provided in each call, but otherwise
+the calling conventions are those of
+.BR sha1 .
+The
+.I key
+must currently be no more than 64 bytes.
+.PP
+.B DigestState
+hides the state of partially completed hash functions during processing.
+Its
+.B copy
+operation returns a reference to a new copy of a given state.
+.SH EXAMPLES
+A program to read a file and hash it using SHA might contain the following inner loop:
+.IP
+.EX
+state: ref DigestState = nil;
+while((n := sys->read(fd, buf, len buf)) > 0)
+ state = kr->sha1(buf, n, nil, state);
+digest := array[kr->SHA1dlen] of byte;
+kr->sha1(buf, 0, digest, state);
+.EE
+.SH SOURCE
+.B /libinterp/crypt.c
+.br
+.B /libsec/port/hmac.c
+.br
+.B /libsec/port/md4.c
+.br
+.B /libsec/port/md5.c
+.br
+.B /libsec/port/sha1.c
+.SH BUGS
+The MD4 algorithm is included only to allow communication with software
+that might still use it; it should not otherwise be used now, because it
+is easily broken.
diff --git a/man/2/ipints b/man/2/ipints
new file mode 100644
index 00000000..2d4bdb8b
--- /dev/null
+++ b/man/2/ipints
@@ -0,0 +1,193 @@
+.TH IPINTS 2
+.SH NAME
+ipints: IPint \- `infinite' precision integer utility functions
+.SH SYNOPSIS
+.EX
+include "ipints.m"
+ipints:= load IPints IPints->PATH;
+
+IPint: adt
+{
+ iptob64: fn(i: self ref IPint): string;
+ iptob64z: fn(i: self ref IPint): string;
+ b64toip: fn(str: string) : ref IPint;
+ iptobytes: fn(i: self ref IPint): array of byte;
+ bytestoip: fn(buf: array of byte): ref IPint;
+ iptobebytes: fn(i: self ref IPint): array of byte;
+ bebytestoip: fn(buf: array of byte): ref IPint;
+ inttoip: fn(i: int): ref IPint;
+ iptoint: fn(i: self ref IPint): int;
+ iptostr: fn(i: self ref IPint, base: int): string;
+ strtoip: fn(str: string, base: int): ref IPint;
+ random: fn(nbits: int): ref IPint;
+ copy: fn(i: self ref IPint): ref IPint;
+ bits: fn(i: self ref IPint): int;
+ expmod: fn(base: self ref IPint, exp, mod: ref IPint):ref IPint;
+ add: fn(i1: self ref IPint, i2: ref IPint): ref IPint;
+ sub: fn(i1: self ref IPint, i2: ref IPint): ref IPint;
+ neg: fn(i: self ref IPint): ref IPint;
+ mul: fn(i1: self ref IPint, i2: ref IPint): ref IPint;
+ div: fn(i1: self ref IPint, i2: ref IPint): (ref IPint, ref IPint);
+ mod: fn(i1: self ref IPint, i2: ref IPint): ref IPint;
+ eq: fn(i1: self ref IPint, i2: ref IPint): int;
+ cmp: fn(i1: self ref IPint, i2: ref IPint): int;
+ shl: fn(i: self ref IPint, n: int): ref IPint;
+ shr: fn(i: self ref IPint, n: int): ref IPint;
+ and: fn(i1: self ref IPint, i2: ref IPint): ref IPint;
+ ori: fn(i1: self ref IPint, i2: ref IPint): ref IPint;
+ not: fn(i: self ref IPint): ref IPint;
+ xor: fn(i1: self ref IPint, i2: ref IPint): ref IPint;
+};
+.EE
+.SH DESCRIPTION
+.B IPint
+provides the following arbitrary-length integer manipulation functions required for cryptographic support in Limbo:
+.TP
+.IB i .iptob64()
+Returns a string that represents a large integer textually in base 64 for convenient transmission over a network connection.
+.TP
+.IB i .iptob64z()
+Returns a similar representation to
+.B iptob64
+but ensures that the top bit of the received value is zero.
+.TP
+.BI b64toip( str )
+Returns the
+.B IPint
+represented by the base-64 encoded
+.IR str .
+.TP
+.IB i .iptobytes()
+Returns an array of bytes representing a large integer. The representation includes both positive and negative numbers.
+.TP
+.BI bytestoip( buf )
+The inverse operation of
+.BR iptobytes .
+.TP
+.IB i .iptobebytes()
+Returns an array of bytes in big-endian format representing the magnitude of a large integer; used for instance to pass a value to
+.IR ssl (3).
+Only non-negative numbers are represented.
+.TP
+.BI bebytestoip( buf )
+The inverse operation of
+.BR iptobebytes .
+.TP
+.BI inttoip( i )
+Creates a new large integer from integer
+.IR i .
+.TP
+.IB i .iptoint()
+Converts a large integer
+.I i
+to an
+.BR int ;
+returns 0 on error.
+.TP
+.IB i .iptostr( base )
+Converts a large integer to a string in base
+.IR base ;
+returns nil on error.
+Only the bases 10, 16, 32, and 64 are
+supported. Anything else defaults to 16.
+.TP
+.BI strtoip( str , base )
+Converts a string
+.I str
+representing a number in in base
+.I base
+to a large integer; returns nil on error.
+Only the bases 10, 16, 32, and 64 are
+supported.
+.TP
+.BI random( nbits )
+Returns a large random number of length at most
+.IR minbits .
+The largest number allowed in the current implementation is
+2^8192-1 .
+The seed for the generator is obtained by duelling clocks.
+.TP
+.IB i .copy()
+Returns a reference to the same value as
+.IR i .
+.TP
+.IB i .bits()
+Returns the number of bits of precision of
+.IR i .
+.TP
+.IB base .expmod( "exp , mod" )
+Returns
+.BI ( base ** exp ") mod " mod.
+.TP
+.IB i1 .add( i2 )
+Returns
+.RI ( i1 + i2 ).
+.TP
+.IB i1 .sub( i2 )
+Returns
+.RI ( i1 - i2 ).
+.TP
+.IB i1 .mul ( i2 )
+Returns
+.IR i1*i2 .
+.TP
+.IB i1 .div ( i2 )
+Returns
+.RI ( i1 / i2,
+.IR i1 rem i2 ).
+.TP
+.IB i1 .mod ( i2 )
+Returns
+.RI ( i1 mod i2 ).
+.TP
+.IB i1 .eq( i2 )
+Returns 1 if
+.I i1
+and
+.I i2
+are equal; 0 otherwise.
+.TP
+.IB i1 .cmp( i2 )
+Compares two large integers, returning 1 if
+.I i1
+is larger,
+-1 if
+.I i2
+is larger, and 0 if they are equal.
+.TP
+.IB i .shl( n )
+Returns
+.IR i << n
+.TP
+.IB i .shr( n )
+Returns
+.IR i >> n
+.TP
+.IB i1 .and( i2 )
+Returns
+.IR i & n ,
+bitwise AND
+.TP
+.IB i1 .ori( i2 )
+Returns
+.IR i | n ,
+bitwise inclusive-OR
+(it is
+.B ori
+because plain
+.B or
+is a Limbo keyword)
+.TP
+.IB i .not()
+Returns
+.RI ~ i ,
+bitwise ones-complement
+.TP
+.IB i1 .xor( i2 )
+Returns
+.IR i ^ n ,
+bitwise exclusive-OR
+.SH SOURCE
+.B /libinterp/ipint.c
+.br
+.B /libmp
diff --git a/man/2/ipints-genprime b/man/2/ipints-genprime
new file mode 100644
index 00000000..5ec5f66c
--- /dev/null
+++ b/man/2/ipints-genprime
@@ -0,0 +1,112 @@
+.TH IPINTS-GENPRIME 2
+.SH NAME
+ipints: genprime, gensafeprime, genstrongprime, DSAprimes, probably_prime \- prime number generation
+.SH SYNOPSIS
+.EX
+include "ipints.m";
+ipints := load IPints IPints->PATH;
+IPint: import ipints;
+
+probably_prime: fn(n: ref IPint, nrep: int): int;
+
+genprime: fn(nbits: int, nrep: int): ref IPint;
+gensafeprime: fn(nbits: int, nrep: int): (ref IPint, ref IPint); # p, alpha
+genstrongprime: fn(nbits: int, nrep: int): ref IPint;
+DSAprimes: fn(): (ref IPint, ref IPint, array of byte); # q, p, seed
+.EE
+.SH DESCRIPTION
+This set of functions in
+.B IPints
+(see
+.IR ipints (2))
+helps Limbo applications
+generate and test large prime numbers with relative efficiency.
+The numbers are all represented by
+.BR IPint .
+.PP
+.I Probably_prime
+uses the Miller-Rabin test to test
+.IR n .
+It returns true (non-zero) if
+.I P
+is probably prime. The probability of
+.I n
+not being prime is
+1/4**\fInrep\fR.
+If
+.I probably_prime
+returns false (zero),
+.I n
+is certainly not prime.
+.PP
+.I Genprime
+returns a random prime of length
+.IR nbits .
+Since it uses the Miller-Rabin test,
+.I nrep
+is the repetition count passed to
+.IR probably_prime .
+.PP
+.I Gensafeprime
+returns a tuple
+.BI ( p,\ alpha ),
+where
+.I p
+is a prime of length
+.I nbits
+and
+.I alpha
+is a generator of the multiplicative group of integers mod \fIp\fR;
+there is a prime \fIq\fR such that \fIp-1=2*q\fR.
+.PP
+.I Genstrongprime
+returns a prime
+.I p
+with the following properties:
+.IP \-
+(\fIp\fR-1)/2 is prime. Therefore
+.IR p -1
+has a large prime factor,
+.IR p '.
+.IP \-
+.IR p '-1
+has a large prime factor
+.IP \-
+.IR p +1
+has a large prime factor
+.PP
+.I DSAprimes
+uses the NIST recommended algorithm for generating DSA primes and
+returns a tuple
+.BI ( q,\ p,\ seed ) ,
+where
+.I p
+and
+.I q
+are primes, and
+.I q
+divides
+.IR p -1.
+The random
+.I seed
+used is also returned, so that sceptics
+can later confirm the computation.
+.SH SOURCE
+.B /libinterp/ipint.c
+.br
+.B /libsec/port/probably_prime.c
+.br
+.B /libsec/port/dsaprimes.c
+.br
+.B /libsec/port/genprime.c
+.br
+.B /libsec/port/gensafeprime.c
+.br
+.B /libsec/port/genstrongprime.c
+.br
+.SH SEE ALSO
+.IR crypt-intro (2),
+.IR crypt-crypt (2),
+.IR crypt-dsagen (2),
+.IR crypt-gensk (2),
+.IR ipints (2)