NSPR 2.0 libc functions
-----------------------

Last edited: AOF 04 March 1997

This directory contains various libc-types of functions. All functions in
this directory are platform independent, thread friendly (both safe and
efficient). They are contributed from various sources, though the contri-
butions are monitored by the NSPR group (mailto:freier).

All API items exported by these functions will contain the same three
character prefix, "PL_" (Portable Library). Internal function names
that are not exported (static) are of little concern, though some caution
must be used on those elements that are 'extern' but not really intended
to be part of the API. Those should all have a prefix of "_PL_" (is that
legal?).

The responsibility for contributions in this area are distributed among
all interested parties.

NSPR 2.0 libc functions
-----------------------

Last edited: AOF 04 March 1997

This directory contains the API for various libc-types of functions.

NSPR 2.0 libc functions
-----------------------

Last edited: AOF 04 March 1997

This directory contains various libc-types of functions. All functions in
this directory are platform independent, thread friendly (both safe and
efficient). They are contributed from various sources, though the contri-
butions are monitored by the NSPR group (mailto:freier).

All API items exported by these functions will contain the same three
character prefix, "PL_" (Portable Library). Internal function names
that are not exported (static) are of little concern, though some caution
must be used on those elements that are 'extern' but not really intended
to be part of the API. Those should all have a prefix of "_PL_" (is that
legal?).

The responsibility for contributions in this area are distributed among
all interested parties.

NSPR 2.0 evolution
------------------


Phase 1- today

Currently (Oct 10, 1996) NSPR 2.0 has two modes.  Either _PR_NTHREAD 
is defined, in which case the PR_CreateThread() call always creates a 
native kernel thread, or _PR_NTHREAD is not defined and PR_CreateThread() 
always creates user level threads within the single, original process.  This 
source code is reflected in two directories, nspr20/pr/src/threads/native, and 
nspr20/pr/src/threads/user.  Although the PR_CreateThread() function has
a paramter to specify the "scope" of a thread, this parameter is not yet 
used- except on solaris where it uses it to specify bound vs unbound threads.

Phase 2 - next week

The next step is to provide a combination of user and native threads.  The
idea, of course, is to have some small number of native threads and each of 
those threads be able to run user level threads.  The number of native
threads created will most likely be proportional to the number of CPUs in
the system.  For this reason, the specific set of native threads which are
used to run the user-level threads will be called "CPU" threads.  

The user level threads which will be run on the CPU threads are able to
run on any of the CPU threads available, and over the course of a user-level
thread's lifetime, it may drift from one CPU thread to another.  All 
user-level threads will compete for processing time via a single run queue.

Creation of a CPU thread will be primarily controlled by NSPR itself or by
the user running a function PR_Concurrency().  The details of PR_Concurrency()
have not yet been worked out; but the idea is that the user can specify to 
NSPR how many CPU threads are desired.

In this system, user-level threads are created by using PR_CreateThread() and
specifying the PR_LOCAL_SCOPE option.  LOCAL_SCOPE indicates that the thread
will be under the control of the "local" scheduler.  Creating threads with
GLOBAL_SCOPE, on the other hand will create a thread which is under the 
control of the system's scheduler.  In otherwords, this creates a native thread
which is not a CPU thread; it runs a single thread task and never has more 
than one task to run.  LOCAL_SCOPE is much like creating a Solaris unbound 
thread, while GLOBAL_SCOPE is similar to creating a Solaris bound thread.

To implement this architecture, the source code will still maintain the "user"
and "native" directories which is has today.  However a third directory 
"combined" will also exist.  To compile a version of NSPR which only creates
native threads, the user can define _PR_NTHREAD.  For exclusive user-level
threads, do not define _PR_NTHREAD.  To get the combined threads, define
_PR_NTHREAD and _PR_USE_CPUS.


Phase 3 - later than next week

The goal is to eliminate the 3 directories.  Once these three models are in
place, the remaining work will be to eliminate the native and user thread
directories for all platforms, so that the entire thread model is contained
within what is today called the "combined" model.  This new and glorious
source code will attempt to make the "combined" model on any platforms which
provide the necessary underlying native threading, but will also be 
capable of using exclusive user-level threads on systems which don't have
native threads.


sslt.rep : Replacer specfile
sslt.c   : Main source code file for test
sslt.htp : Replacer template for header file
sslt.h   : Replacer-generated header file
sslc.c   : Ciphersuite-related data structures and code
ssls.c   : Data buffer for transmitting data
ssls.h   : Data structures and defines for the main code



This Cryptoki module provides acces to certs and keys stored in
Microsofts CAPI certificate store.

It does not import or export CA Root trust from the CAPI.
It does not import or export CRLs from the CAPI.
It does not handle S/MIME objects (pkcs #7 in capi terms?).
It does not yet handle it's own PIN. (CAPI does all the pin prompting).
This README file explains how to add a builtin root CA certificate to NSS
or remove a builtin root CA certificate from NSS.

The builtin root CA certificates in NSS are stored in the nssckbi PKCS #11
module. The sources to the nssckbi module are in this directory.

I. Adding a Builtin Root CA Certificate

You need to use the addbuiltin command-line tool to add a root CA certificate
to the nssckbi module. In the procedure described below, we assume that the
new root CA certificate is distributed in DER format in the file newroot.der.

1. Add the directory where the addbuiltin executable resides to your PATH
environment variable. Then, add the directory where the NSPR and NSS shared
libraries (DLLs) reside to the platform-specific environment variable that
specifies your shared library search path: LD_LIBRARY_PATH (most Unix
variants), SHLIB_PATH (32-bit HP-UX), LIBPATH (AIX), or PATH (Windows).

2. Copy newroot.der to this directory.

3. In this directory, run addbuiltin to add the new root certificate. The
argument to the -n option should be replaced by the nickname of the root
certificate. Then run "gmake generate".

    % addbuiltin -n "Nickname of the Root Certificate" -t C,C,C < newroot.der >> certdata.txt
    % gmake generate

4. Edit nssckbi.h to bump the version of the module.

5. Run gmake in this directory to build the nssckbi module.

6. After you verify that the new nssckbi module is correct, check in
certdata.txt, certdata.c, and nssckbi.h.

II. Removing a Builtin Root CA Certificate

1. Change directory to this directory.

2. Edit certdata.txt and remove the root CA certificate.

3. Run "gmake generate".

4. Edit nssckbi.h to bump the version of the module.

5. Run gmake in this directory to build the nssckbi module.

6. After you verify that the new nssckbi module is correct, check in
certdata.txt, certdata.c, and nssckbi.h.
***** BEGIN LICENSE BLOCK *****
Version: MPL 1.1/GPL 2.0/LGPL 2.1

The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.

The Original Code is the elliptic curve math library.

The Initial Developer of the Original Code is Sun Microsystems, Inc.
Portions created by Sun Microsystems, Inc. are Copyright (C) 2003
Sun Microsystems, Inc. All Rights Reserved.

Contributor(s):
    Stephen Fung <fungstep@hotmail.com> and
    Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories

Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.

***** END LICENSE BLOCK *****
 
The ECL exposes routines for constructing and converting curve
parameters for internal use.


HEADER FILES
============

ecl-exp.h - Exports data structures and curve names. For use by code
that does not have access to mp_ints.

ecl-curve.h - Provides hex encodings (in the form of ECCurveParams
structs) of standardizes elliptic curve domain parameters and mappings
from ECCurveName to ECCurveParams. For use by code that does not have
access to mp_ints.

ecl.h - Interface to constructors for curve parameters and group object,
and point multiplication operations. Used by higher level algorithms
(like ECDH and ECDSA) to actually perform elliptic curve cryptography.

ecl-priv.h - Data structures and functions for internal use within the
library.

ec2.h - Internal header file that contains all functions for point
arithmetic over binary polynomial fields.

ecp.h - Internal header file that contains all functions for point
arithmetic over prime fields.

DATA STRUCTURES AND TYPES
=========================

ECCurveName (from ecl-exp.h) - Opaque name for standardized elliptic
curve domain parameters.

ECCurveParams (from ecl-exp.h) - Provides hexadecimal encoding
of elliptic curve domain parameters. Can be generated by a user
and passed to ECGroup_fromHex or can be generated from a name by
EC_GetNamedCurveParams. ecl-curve.h contains ECCurveParams structs for
the standardized curves defined by ECCurveName.

ECGroup (from ecl.h and ecl-priv.h) - Opaque data structure that
represents a group of elliptic curve points for a particular set of
elliptic curve domain parameters. Contains all domain parameters (curve
a and b, field, base point) as well as pointers to the functions that
should be used for point arithmetic and the underlying field GFMethod.
Generated by either ECGroup_fromHex or ECGroup_fromName.

GFMethod (from ecl-priv.h) - Represents a field underlying a set of
elliptic curve domain parameters. Contains the irreducible that defines
the field (either the prime or the binary polynomial) as well as
pointers to the functions that should be used for field arithmetic.

ARITHMETIC FUNCTIONS
====================

Higher-level algorithms (like ECDH and ECDSA) should call ECPoint_mul
or ECPoints_mul (from ecl.h) to do point arithmetic. These functions
will choose which underlying algorithms to use, based on the ECGroup
structure.

Point Multiplication
--------------------

ecl_mult.c provides the ECPoints_mul and ECPoint_mul wrappers.
It also provides two implementations for the pts_mul operation -
ec_pts_mul_basic (which computes kP, lQ, and then adds kP + lQ) and
ec_pts_mul_simul_w2 (which does a simultaneous point multiplication
using a table with window size 2*2).

ec_naf.c provides an implementation of an algorithm to calculate a
non-adjacent form of a scalar, minimizing the number of point
additions that need to be done in a point multiplication.

Point Arithmetic over Prime Fields
----------------------------------

ecp_aff.c provides point arithmetic using affine coordinates.

ecp_jac.c provides point arithmetic using Jacobian projective
coordinates and mixed Jacobian-affine coordinates. (Jacobian projective
coordinates represent a point (x, y) as (X, Y, Z), where x=X/Z^2,
y=Y/Z^3).

ecp_jm.c provides point arithmetic using Modified Jacobian
coordinates and mixed Modified_Jacobian-affine coordinates.
(Modified Jacobian coordinates represent a point (x, y)
as (X, Y, Z, a*Z^4), where x=X/Z^2, y=Y/Z^3, and a is
the linear coefficient in the curve defining equation).

ecp_192.c and ecp_224.c provide optimized field arithmetic.

Point Arithmetic over Binary Polynomial Fields
----------------------------------------------

ec2_aff.c provides point arithmetic using affine coordinates.

ec2_proj.c provides point arithmetic using projective coordinates.
(Projective coordinates represent a point (x, y) as (X, Y, Z), where
x=X/Z, y=Y/Z^2).

ec2_mont.c provides point multiplication using Montgomery projective
coordinates.

ec2_163.c, ec2_193.c, and ec2_233.c provide optimized field arithmetic.

Field Arithmetic
----------------

ecl_gf.c provides constructors for field objects (GFMethod) with the
functions GFMethod_cons*. It also provides wrappers around the basic
field operations.

Prime Field Arithmetic
----------------------

The mpi library provides the basic prime field arithmetic.

ecp_mont.c provides wrappers around the Montgomery multiplication
functions from the mpi library and adds encoding and decoding functions.
It also provides the function to construct a GFMethod object using
Montgomery multiplication.

ecp_192.c and ecp_224.c provide optimized modular reduction for the
fields defined by nistp192 and nistp224 primes.

ecl_gf.c provides wrappers around the basic field operations.

Binary Polynomial Field Arithmetic
----------------------------------

../mpi/mp_gf2m.c provides basic binary polynomial field arithmetic,
including addition, multiplication, squaring, mod, and division, as well
as conversion ob polynomial representations between bitstring and int[].

ec2_163.c, ec2_193.c, and ec2_233.c provide optimized field mod, mul,
and sqr operations.

ecl_gf.c provides wrappers around the basic field operations.

Field Encoding
--------------

By default, field elements are encoded in their basic form. It is
possible to use an alternative encoding, however. For example, it is
possible to Montgomery representation of prime field elements and
take advantage of the fast modular multiplication that Montgomery
representation provides. The process of converting from basic form to
Montgomery representation is called field encoding, and the opposite
process would be field decoding. All internal point operations assume
that the operands are field encoded as appropriate. By rewiring the
underlying field arithmetic to perform operations on these encoded
values, the same overlying point arithmetic operations can be used
regardless of field representation.

ALGORITHM WIRING
================

The EC library allows point and field arithmetic algorithms to be
substituted ("wired-in") on a fine-grained basis. This allows for
generic algorithms and algorithms that are optimized for a particular
curve, field, or architecture, to coexist and to be automatically
selected at runtime.

Wiring Mechanism
----------------

The ECGroup and GFMethod structure contain pointers to the point and
field arithmetic functions, respectively, that are to be used in
operations.

The selection of algorithms to use is handled in the function
ecgroup_fromNameAndHex in ecl.c.

Default Wiring
--------------

Curves over prime fields by default use montgomery field arithmetic,
point multiplication using 5-bit window non-adjacent-form with 
Modified Jacobian coordinates, and 2*2-bit simultaneous point 
multiplication using Jacobian coordinates.
(Wiring in function ECGroup_consGFp_mont in ecl.c.)

Curves over prime fields that have optimized modular reduction (i.e.,
secp160r1, nistp192, and nistp224) do not use Montgomery field
arithmetic. Instead, they use basic field arithmetic with their
optimized reduction (as in ecp_192.c and ecp_224.c). They
use the same point multiplication and simultaneous point multiplication
algorithms as other curves over prime fields.

Curves over binary polynomial fields by default use generic field
arithmetic with montgomery point multiplication and basic kP + lQ
computation (multiply, multiply, and add). (Wiring in function
ECGroup_cons_GF2m in ecl.c.)

Curves over binary polynomial fields that have optimized field
arithmetic (i.e., any 163-, 193, or 233-bit field) use their optimized
field arithmetic. They use the same point multiplication and
simultaneous point multiplication algorithms as other curves over binary
fields.

Example
-------

We provide an example for plugging in an optimized implementation for
the Koblitz curve nistk163.

Suppose the file ec2_k163.c contains the optimized implementation. In
particular it contains a point multiplication function:

	mp_err ec_GF2m_nistk163_pt_mul(const mp_int *n, const mp_int *px, 
		const mp_int *py, mp_int *rx, mp_int *ry, const ECGroup *group);

Since only a pt_mul function is provided, the generic pt_add function
will be used.

There are two options for handling the optimized field arithmetic used
by the ..._pt_mul function. Say the optimized field arithmetic includes
the following functions:

	mp_err ec_GF2m_nistk163_add(const mp_int *a, const mp_int *b,
		mp_int *r, const GFMethod *meth);
	mp_err ec_GF2m_nistk163_mul(const mp_int *a, const mp_int *b,
		mp_int *r, const GFMethod *meth);
	mp_err ec_GF2m_nistk163_sqr(const mp_int *a, const mp_int *b,
		mp_int *r, const GFMethod *meth);
	mp_err ec_GF2m_nistk163_div(const mp_int *a, const mp_int *b,
		mp_int *r, const GFMethod *meth);

First, the optimized field arithmetic could simply be called directly
by the ..._pt_mul function. This would be accomplished by changing
the ecgroup_fromNameAndHex function in ecl.c to include the following
statements:

	if (name == ECCurve_NIST_K163) {
		group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx,
			&geny, &order, params->cofactor);
		if (group == NULL) { res = MP_UNDEF; goto CLEANUP; }
		MP_CHECKOK( ec_group_set_nistk163(group) );
	}

and including in ec2_k163.c the following function:

	mp_err ec_group_set_nistk163(ECGroup *group) {
		group->point_mul = &ec_GF2m_nistk163_pt_mul;
		return MP_OKAY;
	}

As a result, ec_GF2m_pt_add and similar functions would use the
basic binary polynomial field arithmetic ec_GF2m_add, ec_GF2m_mul,
ec_GF2m_sqr, and ec_GF2m_div.

Alternatively, the optimized field arithmetic could be wired into the
group's GFMethod. This would be accomplished by putting the following
function in ec2_k163.c:

	mp_err ec_group_set_nistk163(ECGroup *group) {
		group->meth->field_add = &ec_GF2m_nistk163_add;
		group->meth->field_mul = &ec_GF2m_nistk163_mul;
		group->meth->field_sqr = &ec_GF2m_nistk163_sqr;
		group->meth->field_div = &ec_GF2m_nistk163_div;
		group->point_mul = &ec_GF2m_nistk163_pt_mul;
		return MP_OKAY;
	}

For an example of functions that use special field encodings, take a
look at ecp_mont.c.

TESTING
=======

The ecl/tests directory contains a collection of standalone tests that
verify the correctness of the elliptic curve library.

Both ecp_test and ec2_test take the following arguments:

	--print     Print out results of each point arithmetic test.
	--time      Benchmark point operations and print results.

The set of curves over which ecp_test and ec2_test run is coded into the
program, but can be changed by editing the source files.

BUILDING
========

The ecl can be built as a standalone library, separate from NSS,
dependent only on the mpi library. To build the library:

	> cd ../mpi
	> make libs
	> cd ../ecl
	> make libs
	> make tests # to build test files
	> make test  # to run automated tests
***** BEGIN LICENSE BLOCK *****
Version: MPL 1.1/GPL 2.0/LGPL 2.1

The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.

The Original Code is the MPI Arbitrary Precision Integer Arithmetic
library.

The Initial Developer of the Original Code is
Michael J. Fromberger <sting@linguist.dartmouth.edu>
Portions created by the Initial Developer are Copyright (C) 1998, 2000
the Initial Developer. All Rights Reserved.

Contributor(s):

Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.

***** END LICENSE BLOCK *****

Additional MPI utilities
------------------------

The files 'mpprime.h' and 'mpprime.c' define some useful extensions to
the MPI library for dealing with prime numbers (in particular, testing
for divisbility, and the Rabin-Miller probabilistic primality test).

The files 'mplogic.h' and 'mplogic.c' define extensions to the MPI
library for doing bitwise logical operations and shifting.

This document assumes you have read the help file for the MPI library
and understand its conventions.

Divisibility (mpprime.h)
------------

To test a number for divisibility by another number:

mpp_divis(a, b)		- test if b|a
mpp_divis_d(a, d)	- test if d|a

Each of these functions returns MP_YES if its initial argument is
divisible by its second, or MP_NO if it is not.  Other errors may be
returned as appropriate (such as MP_RANGE if you try to test for
divisibility by zero).

Randomness (mpprime.h)
----------

To generate random data:

mpp_random(a)		- fill a with random data
mpp_random_size(a, p)   - fill a with p digits of random data

The mpp_random_size() function increases the precision of a to at
least p, then fills all those digits randomly.  The mp_random()
function fills a to its current precision (as determined by the number
of significant digits, USED(a))

Note that these functions simply use the C library's rand() function
to fill a with random digits up to its precision.  This should be
adequate for primality testing, but should not be used for
cryptographic applications where truly random values are required for
security.  

You should call srand() in your driver program in order to seed the
random generator; this function doesn't call it.

Primality Testing (mpprime.h)
-----------------

mpp_divis_vector(a, v, s, w)   - is a divisible by any of the s values
                                 in v, and if so, w = which.
mpp_divis_primes(a, np)   - is a divisible by any of the first np primes?
mpp_fermat(a, w)          - is a pseudoprime with respect to witness w?
mpp_pprime(a, nt)	  - run nt iterations of Rabin-Miller on a.

The mpp_divis_vector() function tests a for divisibility by each
member of an array of digits.  The array is v, the size of that array
is s.  Returns MP_YES if a is divisible, and stores the index of the
offending digit in w.  Returns MP_NO if a is not divisible by any of
the digits in the array.

A small table of primes is compiled into the library (typically the
first 128 primes, although you can change this by editing the file
'primes.c' before you build).  The global variable prime_tab_size
contains the number of primes in the table, and the values themselves
are in the array prime_tab[], which is an array of mp_digit.

The mpp_divis_primes() function is basically just a wrapper around
mpp_divis_vector() that uses prime_tab[] as the test vector.  The np
parameter is a pointer to an mp_digit -- on input, it should specify
the number of primes to be tested against.  If a is divisible by any
of the primes, MP_YES is returned and np is given the prime value that
divided a (you can use this if you're factoring, for example).
Otherwise, MP_NO is returned and np is untouched.

The function mpp_fermat() performs Fermat's test, using w as a
witness.  This test basically relies on the fact that if a is prime,
and w is relatively prime to a, then:

	w^a = w (mod a)

That is,

	w^(a - 1) = 1 (mod a)

The function returns MP_YES if the test passes, MP_NO if it fails.  If
w is relatively prime to a, and the test fails, a is definitely
composite.  If w is relatively prime to a and the test passes, then a
is either prime, or w is a false witness (the probability of this
happening depends on the choice of w and of a ... consult a number
theory textbook for more information about this).  

Note:  If (w, a) != 1, the output of this test is meaningless.
----

The function mpp_pprime() performs the Rabin-Miller probabilistic
primality test for nt rounds.  If all the tests pass, MP_YES is
returned, and a is probably prime.  The probability that an answer of
MP_YES is incorrect is no greater than 1 in 4^nt, and in fact is
usually much less than that (this is a pessimistic estimate).  If any
test fails, MP_NO is returned, and a is definitely composite.

Bruce Schneier recommends at least 5 iterations of this test for most
cryptographic applications; Knuth suggests that 25 are reasonable.
Run it as many times as you feel are necessary.

See the programs 'makeprime.c' and 'isprime.c' for reasonable examples
of how to use these functions for primality testing.


Bitwise Logic (mplogic.c)
-------------

The four commonest logical operations are implemented as:

mpl_not(a, b)		- Compute bitwise (one's) complement, b = ~a

mpl_and(a, b, c)	- Compute bitwise AND, c = a & b

mpl_or(a, b, c)		- Compute bitwise OR, c = a | b

mpl_xor(a, b, c)	- Compute bitwise XOR, c = a ^ b

Left and right shifts are available as well.  These take a number to
shift, a destination, and a shift amount.  The shift amount must be a
digit value between 0 and DIGIT_BIT inclusive; if it is not, MP_RANGE
will be returned and the shift will not happen.

mpl_rsh(a, b, d)	- Compute logical right shift, b = a >> d

mpl_lsh(a, b, d)	- Compute logical left shift, b = a << d

Since these are logical shifts, they fill with zeroes (the library
uses a signed magnitude representation, so there are no sign bits to
extend anyway).


Command-line Utilities
----------------------

A handful of interesting command-line utilities are provided.  These
are:

lap.c		- Find the order of a mod m.  Usage is 'lap <a> <m>'.
                  This uses a dumb algorithm, so don't use it for 
                  a really big modulus.

invmod.c	- Find the inverse of a mod m, if it exists.  Usage
		  is 'invmod <a> <m>'

sieve.c		- A simple bitmap-based implementation of the Sieve
		  of Eratosthenes.  Used to generate the table of 
		  primes in primes.c.  Usage is 'sieve <nbits>'

prng.c          - Uses the routines in bbs_rand.{h,c} to generate
                  one or more 32-bit pseudo-random integers.  This
                  is mainly an example, not intended for use in a
                  cryptographic application (the system time is 
                  the only source of entropy used)

dec2hex.c       - Convert decimal to hexadecimal

hex2dec.c       - Convert hexadecimal to decimal

basecvt.c       - General radix conversion tool (supports 2-64)

isprime.c       - Probabilistically test an integer for primality
                  using the Rabin-Miller pseudoprime test combined
                  with division by small primes.

primegen.c      - Generate primes at random.

exptmod.c       - Perform modular exponentiation

ptab.pl		- A Perl script to munge the output of the sieve
		  program into a compilable C structure.


Other Files
-----------

PRIMES		- Some randomly generated numbers which are prime with
		  extremely high probability.

README		- You're reading me already.


About the Author
----------------

This software was written by Michael J. Fromberger.  You can contact
the author as follows:

E-mail:	  <sting@linguist.dartmouth.edu>

Postal:	  8000 Cummings Hall, Thayer School of Engineering
	  Dartmouth College, Hanover, New Hampshire, USA

PGP key:  http://linguist.dartmouth.edu/~sting/keys/mjf.html
          9736 188B 5AFA 23D6 D6AA  BE0D 5856 4525 289D 9907

Last updated:  $Id: README,v 1.3 2005/02/02 22:28:23 gerv%gerv.net Exp $
***** BEGIN LICENSE BLOCK *****
Version: MPL 1.1/GPL 2.0/LGPL 2.1

The contents of this file are subject to the Mozilla Public License Version
1.1 (the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
for the specific language governing rights and limitations under the
License.

The Original Code is the MPI Arbitrary Precision Integer Arithmetic
library.

The Initial Developer of the Original Code is
Michael J. Fromberger <sting@linguist.dartmouth.edu>
Portions created by the Initial Developer are Copyright (C) 1997-2000
the Initial Developer. All Rights Reserved.

Contributor(s):

Alternatively, the contents of this file may be used under the terms of
either the GNU General Public License Version 2 or later (the "GPL"), or
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
in which case the provisions of the GPL or the LGPL are applicable instead
of those above. If you wish to allow use of your version of this file only
under the terms of either the GPL or the LGPL, and not to allow others to
use your version of this file under the terms of the MPL, indicate your
decision by deleting the provisions above and replace them with the notice
and other provisions required by the GPL or the LGPL. If you do not delete
the provisions above, a recipient may use your version of this file under
the terms of any one of the MPL, the GPL or the LGPL.

***** END LICENSE BLOCK *****

About the MPI Library
---------------------

The files 'mpi.h' and 'mpi.c' define a simple, arbitrary precision
signed integer arithmetic package.  The implementation is not the most
efficient possible, but the code is small and should be fairly easily
portable to just about any machine that supports an ANSI C compiler,
as long as it is capable of at least 16-bit arithmetic (but also see
below for more on this).

This library was written with an eye to cryptographic applications;
thus, some care is taken to make sure that temporary values are not
left lying around in memory when they are no longer in use.  This adds
some overhead for zeroing buffers before they are released back into
the free pool; however, it gives you the assurance that there is only
one copy of your important values residing in your process's address
space at a time.  Obviously, it is difficult to guarantee anything, in
a pre-emptive multitasking environment, but this at least helps you
keep a lid on the more obvious ways your data can get spread around in
memory.


Using the Library
-----------------

To use the MPI library in your program, you must include the header:

#include "mpi.h"

This header provides all the type and function declarations you'll
need to use the library.  Almost all the names defined by the library
begin with the prefix 'mp_', so it should be easy to keep them from
clashing with your program's namespace (he says, glibly, knowing full
well there are always pathological cases).

There are a few things you may want to configure about the library.
By default, the MPI library uses an unsigned short for its digit type,
and an unsigned int for its word type.  The word type must be big
enough to contain at least two digits, for the primitive arithmetic to
work out.  On my machine, a short is 2 bytes and an int is 4 bytes --
but if you have 64-bit ints, you might want to use a 4-byte digit and
an 8-byte word.  I have tested the library using 1-byte digits and
2-byte words, as well.  Whatever you choose to do, the things you need
to change are:

(1) The type definitions for mp_digit and mp_word.

(2) The macro DIGIT_FMT which tells mp_print() how to display a
    single digit.  This is just a printf() format string, so you
    can adjust it appropriately.

(3) The macros DIGIT_MAX and MP_WORD_MAX, which specify the 
    largest value expressible in an mp_digit and an mp_word,
    respectively.

Both the mp_digit and mp_word should be UNSIGNED integer types.  The
code relies on having the full positive precision of the type used for
digits and words.

The remaining type definitions should be left alone, for the most
part.  The code in the library does not make any significant
assumptions about the sizes of things, but there is little if any
reason to change the other parameters, so I would recommend you leave
them as you found them.

The library comes with a Perl script, 'types.pl', which will scan your
current Makefile settings, and attempt to find good definitions for
these types.  It relies on a Unix sort of build environment, so it
probably won't work under MacOS or Windows, but it can be convenient
if you're porting to a new flavour of Unix.  Just run 'types.pl' at
the command line, and it will spit out its results to the standard
output.


Conventions
-----------

Most functions in the library return a value of type mp_err.  This
permits the library to communicate success or various kinds of failure
to the calling program.  The return values currently defined are:

        MP_OKAY         - okay, operation succeeded, all's well
        MP_YES          - okay, the answer is yes (same as MP_OKAY)
        MP_NO           - okay, but answer is no (not MP_OKAY)
        MP_MEM          - operation ran out of memory
        MP_RANGE        - input parameter was out of range
        MP_BADARG       - an invalid input parameter was provided
        MP_UNDEF        - no output value is defined for this input

The only function which currently uses MP_UNDEF is mp_invmod().
Division by zero is undefined, but the division functions will return
MP_RANGE for a zero divisor.  MP_BADARG usually means you passed a
bogus mp_int structure to the function.  MP_YES and MP_NO are not used
by the library itself; they're defined so you can use them in your own
extensions.

If you need a readable interpretation of these error codes in your
program, you may also use the mp_strerror() function.  This function
takes an mp_err as input, and returns a pointer to a human-readable
string describing the meaning of the error.  These strings are stored
as constants within the library, so the caller should not attempt to
modify or free the memory associated with these strings.

The library represents values in signed-magnitude format.  Values
strictly less than zero are negative, all others are considered
positive (zero is positive by fiat).  You can access the 'sign' member
of the mp_int structure directly, but better is to use the mp_cmp_z()
function, to find out which side of zero the value lies on.

Most arithmetic functions have a single-digit variant, as well as the
full arbitrary-precision.  An mp_digit is an unsigned value between 0
and DIGIT_MAX inclusive.  The radix is available as RADIX.  The number
of bits in a given digit is given as DIGIT_BIT.

Generally, input parameters are given before output parameters.
Unless otherwise specified, any input parameter can be re-used as an
output parameter, without confusing anything.

The basic numeric type defined by the library is an mp_int.  Virtually
all the functions in the library take a pointer to an mp_int as one of
their parameters.  An explanation of how to create and use these
<HR>
<A NAME="p23">
<H3>Problem 23:</H3>

structures follows.  And so, without further ado...


Initialization and Cleanup
--------------------------

The basic numeric type defined by the library is an 'mp_int'.
However, it is not sufficient to simply declare a variable of type
mp_int in your program.  These variables also need to be initialized
before they can be used, to allocate the internal storage they require
for computation.

This is done using one of the following functions:

        mp_init(mp_int *mp);
        mp_init_copy(mp_int *mp, mp_int *from);
        mp_init_size(mp_int *mp, mp_size p);

Each of these requires a pointer to a structure of type mp_int.  The
basic mp_init() simply initializes the mp_int to a default size, and
sets its value to zero.  If you would like to initialize a copy of an
existing mp_int, use mp_init_copy(), where the 'from' parameter is the
mp_int you'd like to make a copy of.  The third function,
mp_init_size(), permits you to specify how many digits of precision
should be preallocated for your mp_int.  This can help the library
avoid unnecessary re-allocations later on.

The default precision used by mp_init() can be retrieved using:

        precision = mp_get_prec();

This returns the number of digits that will be allocated.  You can
change this value by using:

        mp_set_prec(unsigned int prec);

Any positive value is acceptable -- if you pass zero, the default
precision will be re-set to the compiled-in library default (this is
specified in the header file 'mpi-config.h', and typically defaults to
8 or 16).

Just as you must allocate an mp_int before you can use it, you must
clean up the structure when you are done with it.  This is performed
using the mp_clear() function.  Remember that any mp_int that you
create as a local variable in a function must be mp_clear()'d before
that function exits, or else the memory allocated to that mp_int will
be orphaned and unrecoverable.

To set an mp_int to a given value, the following functions are given:

        mp_set(mp_int *mp, mp_digit d);
        mp_set_int(mp_int *mp, long z);

The mp_set() function sets the mp_int to a single digit value, while
mp_set_int() sets the mp_int to a signed long integer value.

To set an mp_int to zero, use:

        mp_zero(mp_int *mp);


Copying and Moving
------------------

If you have two initialized mp_int's, and you want to copy the value
of one into the other, use:

        mp_copy(from, to)

This takes care of clearing the old value of 'to', and copies the new
value into it.  If 'to' is not yet initialized, use mp_init_copy()
instead (see above).

Note:   The library tries, whenever possible, to avoid allocating
----    new memory.  Thus, mp_copy() tries first to satisfy the needs
        of the copy by re-using the memory already allocated to 'to'.
        Only if this proves insufficient will mp_copy() actually
        allocate new memory.

        For this reason, if you know a priori that 'to' has enough
        available space to hold 'from', you don't need to check the
        return value of mp_copy() for memory failure.  The USED()
        macro tells you how many digits are used by an mp_int, and
        the ALLOC() macro tells you how many are allocated.

If you have two initialized mp_int's, and you want to exchange their
values, use:

        mp_exch(a, b)

This is better than using mp_copy() with a temporary, since it will
not (ever) touch the memory allocator -- it just swaps the exact
contents of the two structures.  The mp_exch() function cannot fail;
if you pass it an invalid structure, it just ignores it, and does
nothing.


Basic Arithmetic
----------------

Once you have initialized your integers, you can operate on them.  The
basic arithmetic functions on full mp_int values are:

mp_add(a, b, c)         - computes c = a + b
mp_sub(a, b, c)         - computes c = a - b
mp_mul(a, b, c)         - computes c = a * b
mp_sqr(a, b)            - computes b = a * a
mp_div(a, b, q, r)      - computes q, r such that a = bq + r
mp_div_2d(a, d, q, r)   - computes q = a / 2^d, r = a % 2^d
mp_expt(a, b, c)        - computes c = a ** b
mp_2expt(a, k)          - computes a = 2^k
mp_sqrt(a, c)           - computes c = floor(sqrt(a))

The mp_div_2d() function efficiently computes division by powers of
two.  Either the q or r parameter may be NULL, in which case that
portion of the computation will be discarded.

The algorithms used for some of the computations here are described in
the following files which are included with this distribution:

mul.txt         Describes the multiplication algorithm
div.txt         Describes the division algorithm
expt.txt        Describes the exponentiation algorithm
sqrt.txt        Describes the square-root algorithm
square.txt      Describes the squaring algorithm

There are single-digit versions of most of these routines, as well.
In the following prototypes, 'd' is a single mp_digit:

mp_add_d(a, d, c)       - computes c = a + d
mp_sub_d(a, d, c)       - computes c = a - d
mp_mul_d(a, d, c)       - computes c = a * d
mp_mul_2(a, c)          - computes c = a * 2
mp_div_d(a, d, q, r)    - computes q, r such that a = bq + r
mp_div_2(a, c)          - computes c = a / 2
mp_expt_d(a, d, c)      - computes c = a ** d

The mp_mul_2() and mp_div_2() functions take advantage of the internal
representation of an mp_int to do multiplication by two more quickly
than mp_mul_d() would.  Other basic functions of an arithmetic variety
include:

mp_zero(a)              - assign 0 to a
mp_neg(a, c)            - negate a: c = -a
mp_abs(a, c)            - absolute value: c = |a|


Comparisons
-----------

Several comparison functions are provided.  Each of these, unless
otherwise specified, returns zero if the comparands are equal, < 0 if
the first is less than the second, and > 0 if the first is greater
than the second:

mp_cmp_z(a)             - compare a <=> 0
mp_cmp_d(a, d)          - compare a <=> d, d is a single digit
mp_cmp(a, b)            - compare a <=> b
mp_cmp_mag(a, b)        - compare |a| <=> |b|
mp_cmp_int(a, z)        - compare a <=> z, z is a signed long integer
mp_isodd(a)             - return nonzero if odd, zero otherwise
mp_iseven(a)            - return nonzero if even, zero otherwise


Modular Arithmetic
------------------

Modular variations of the basic arithmetic functions are also
supported.  These are available if the MP_MODARITH parameter in
mpi-config.h is turned on (it is by default).  The modular arithmetic
functions are:

mp_mod(a, m, c)         - compute c = a (mod m), 0 <= c < m
mp_mod_d(a, d, c)       - compute c = a (mod d), 0 <= c < d (see below)
mp_addmod(a, b, m, c)   - compute c = (a + b) mod m
mp_submod(a, b, m, c)   - compute c = (a - b) mod m
mp_mulmod(a, b, m, c)   - compute c = (a * b) mod m
mp_sqrmod(a, m, c)      - compute c = (a * a) mod m
mp_exptmod(a, b, m, c)  - compute c = (a ** b) mod m
mp_exptmod_d(a, d, m, c)- compute c = (a ** d) mod m

The mp_sqr() function squares its input argument.  A call to mp_sqr(a,
c) is identical in meaning to mp_mul(a, a, c); however, if the
MP_SQUARE variable is set true in mpi-config.h (see below), then it
will be implemented with a different algorithm, that is supposed to
take advantage of the redundant computation that takes place during
squaring.  Unfortunately, some compilers result in worse performance
on this code, so you can change the behaviour at will.  There is a
utility program "mulsqr.c" that lets you test which does better on
your system.

The mp_sqrmod() function is analogous to the mp_sqr() function; it
uses the mp_sqr() function rather than mp_mul(), and then performs the
modular reduction.  This probably won't help much unless you are doing
a lot of them.

See the file 'square.txt' for a synopsis of the algorithm used.

Note:   The mp_mod_d() function computes a modular reduction around
----    a single digit d.  The result is a single digit c.

Because an inverse is defined for a (mod m) if and only if (a, m) = 1
(that is, if a and m are relatively prime), mp_invmod() may not be
able to compute an inverse for the arguments.  In this case, it
returns the value MP_UNDEF, and does not modify c.  If an inverse is
defined, however, it returns MP_OKAY, and sets c to the value of the
inverse (mod m).

See the file 'redux.txt' for a description of the modular reduction
algorithm used by mp_exptmod().


Greatest Common Divisor
-----------------------

If The greates common divisor of two values can be found using one of the
following functions:

mp_gcd(a, b, c)         - compute c = (a, b) using binary algorithm
mp_lcm(a, b, c)         - compute c = [a, b] = ab / (a, b)
mp_xgcd(a, b, g, x, y)  - compute g, x, y so that ax + by = g = (a, b)

Also provided is a function to compute modular inverses, if they
exist:

mp_invmod(a, m, c)      - compute c = a^-1 (mod m), if it exists

The function mp_xgcd() computes the greatest common divisor, and also
returns values of x and y satisfying Bezout's identity.  This is used
by mp_invmod() to find modular inverses.  However, if you do not need
these values, you will find that mp_gcd() is MUCH more efficient,
since it doesn't need all the intermediate values that mp_xgcd()
requires in order to compute x and y. 

The mp_gcd() (and mp_xgcd()) functions use the binary (extended) GCD
algorithm due to Josef Stein.


Input & Output Functions
------------------------

The following basic I/O routines are provided.  These are present at
all times:

mp_read_radix(mp, str, r)  - convert a string in radix r to an mp_int
mp_read_raw(mp, s, len)    - convert a string of bytes to an mp_int
mp_radix_size(mp, r)       - return length of buffer needed by mp_toradix()
mp_raw_size(mp)            - return length of buffer needed by mp_toraw()
mp_toradix(mp, str, r)     - convert an mp_int to a string of radix r 
                             digits
mp_toraw(mp, str)          - convert an mp_int to a string of bytes
mp_tovalue(ch, r)          - convert ch to its value when taken as
                             a radix r digit, or -1 if invalid
mp_strerror(err)           - get a string describing mp_err value 'err'

If you compile the MPI library with MP_IOFUNC defined, you will also
have access to the following additional I/O function:

mp_print(mp, ofp)       - print an mp_int as text to output stream ofp

Note that mp_radix_size() returns a size in bytes guaranteed to be AT
LEAST big enough for the digits output by mp_toradix().  Because it
uses an approximation technique to figure out how many digits will be
needed, it may return a figure which is larger than necessary.  Thus,
the caller should not rely on the value to determine how many bytes
will actually be written by mp_toradix().  The string mp_toradix()
creates will be NUL terminated, so the standard C library function
strlen() should be able to ascertain this for you, if you need it.

The mp_read_radix() and mp_toradix() functions support bases from 2 to
64 inclusive.  If you require more general radix conversion facilities
than this, you will need to write them yourself (that's why mp_div_d()
is provided, after all).

Note:   mp_read_radix() will accept as digits either capital or 
----    lower-case letters.  However, the current implementation of
        mp_toradix() only outputs upper-case letters, when writing
        bases betwee 10 and 36.  The underlying code supports using
        lower-case letters, but the interface stub does not have a
        selector for it.  You can add one yourself if you think it
        is worthwhile -- I do not.  Bases from 36 to 64 use lower-
        case letters as distinct from upper-case.  Bases 63 and
        64 use the characters '+' and '/' as digits.

        Note also that compiling with MP_IOFUNC defined will cause
        inclusion of <stdio.h>, so if you are trying to write code
        which does not depend on the standard C library, you will
        probably want to avoid this option.  This is needed because
        the mp_print() function takes a standard library FILE * as
        one of its parameters, and uses the fprintf() function.

The mp_toraw() function converts the integer to a sequence of bytes,
in big-endian ordering (most-significant byte first).  Assuming your
bytes are 8 bits wide, this corresponds to base 256.  The sign is
encoded as a single leading byte, whose value is 0 for zero or
positive values, or 1 for negative values.  The mp_read_raw() function
reverses this process -- it takes a buffer of bytes, interprets the
first as a sign indicator (0 = zero/positive, nonzero = negative), and
the rest as a sequence of 1-byte digits in big-endian ordering.

The mp_raw_size() function returns the exact number of bytes required
to store the given integer in "raw" format (as described in the
previous paragraph).  Zero is returned in case of error; a valid
integer will require at least three bytes of storage.

In previous versions of the MPI library, an "external representation
format" was supported.  This was removed, however, because I found I
was never using it, it was not as portable as I would have liked, and
I decided it was a waste of space.


Other Functions
---------------

The files 'mpprime.h' and 'mpprime.c' define some routines which are
useful for divisibility testing and probabilistic primality testing.
The routines defined are:

mpp_divis(a, b)          - is a divisible by b?
mpp_divis_d(a, d)        - is a divisible by digit d?
mpp_random(a)            - set a to random value at current precision
mpp_random_size(a, prec) - set a to random value at given precision

Note:  The mpp_random() and mpp_random_size() functions use the C
----   library's rand() function to generate random values.  It is
       up to the caller to seed this generator before it is called.
       These functions are not suitable for generating quantities
       requiring cryptographic-quality randomness; they are intended
       primarily for use in primality testing.

       Note too that the MPI library does not call srand(), so your
       application should do this, if you ever want the sequence
       to change.

mpp_divis_vector(a, v, s, w)  - is a divisible by any of the s digits
                                in v?  If so, let w be the index of 
                                that digit

mpp_divis_primes(a, np)       - is a divisible by any of the first np
                                primes?  If so, set np to the prime 
                                which divided a.

mpp_fermat(a, d)              - test if w^a = w (mod a).  If so, 
                                returns MP_YES, otherwise MP_NO.

mpp_pprime(a, nt)             - perform nt iterations of the Rabin-
                                Miller probabilistic primality test
                                on a.  Returns MP_YES if all tests
                                passed, or MP_NO if any test fails.

The mpp_fermat() function works based on Fermat's little theorem, a
consequence of which is that if p is a prime, and (w, p) = 1, then:

        w^p = w (mod p)

Put another way, if w^p != w (mod p), then p is not prime.  The test
is expensive to compute, but it helps to quickly eliminate an enormous
class of composite numbers prior to Rabin-Miller testing.

Building the Library
--------------------

The MPI library is designed to be as self-contained as possible.  You
should be able to compile it with your favourite ANSI C compiler, and
link it into your program directly.  If you are on a Unix system using
the GNU C compiler (gcc), the following should work:

% gcc -ansi -pedantic -Wall -O2 -c mpi.c

The file 'mpi-config.h' defines several configurable parameters for
the library, which you can adjust to suit your application.  At the
time of this writing, the available options are:

MP_IOFUNC       - Define true to include the mp_print() function, 
                  which is moderately useful for debugging.  This
                  implicitly includes <stdio.h>.

MP_MODARITH     - Define true to include the modular arithmetic
                  functions.  If you don't need modular arithmetic
                  in your application, you can set this to zero to
                  leave out all the modular routines.

MP_NUMTH        - Define true to include number theoretic functions
                  such as mp_gcd(), mp_lcm(), and mp_invmod().

MP_LOGTAB       - If true, the file "logtab.h" is included, which
                  is basically a static table of base 2 logarithms.
                  These are used to compute how big the buffers for
                  radix conversion need to be.  If you set this false,
                  the library includes <math.h> and uses log().  This
                  typically forces you to link against math libraries.

MP_MEMSET       - If true, use memset() to zero buffers.  If you run
                  into weird alignment related bugs, set this to zero
                  and an explicit loop will be used.

MP_MEMCPY       - If true, use memcpy() to copy buffers.  If you run
                  into weird alignment bugs, set this to zero and an
                  explicit loop will be used.

MP_CRYPTO       - If true, whenever arrays of digits are free'd, they
                  are zeroed first.  This is useful if you're using
                  the library in a cryptographic environment; however,
                  it does add overhead to each free operation.  For
                  performance, if you don't care about zeroing your
                  buffers, set this to false.

MP_ARGCHK       - Set to 0, 1, or 2.  This defines how the argument
                  checking macro, ARGCHK(), gets expanded.  If this 
                  is set to zero, ARGCHK() expands to nothing; no 
                  argument checks are performed.  If this is 1, the
                  ARGCHK() macro expands to code that returns MP_BADARG
                  or similar at runtime.  If it is 2, ARGCHK() expands 
                  to an assert() call that aborts the program on a 
                  bad input.

MP_DEBUG        - Turns on debugging output.  This is probably not at
                  all useful unless you are debugging the library.  It
                  tends to spit out a LOT of output.

MP_DEFPREC      - The default precision of a newly-created mp_int, in
                  digits.  The precision can be changed at runtime by
                  the mp_set_prec() function, but this is its initial
                  value.

MP_SQUARE       - If this is set to a nonzero value, the mp_sqr() 
                  function will use an alternate algorithm that takes
                  advantage of the redundant inner product computation
                  when both multiplicands are identical.  Unfortunately,
                  with some compilers this is actually SLOWER than just
                  calling mp_mul() with the same argument twice.  So
                  if you set MP_SQUARE to zero, mp_sqr() will be expan-
                  ded into a call to mp_mul().  This applies to all 
                  the uses of mp_sqr(), including mp_sqrmod() and the
                  internal calls to s_mp_sqr() inside mpi.c

                  The program 'mulsqr' (mulsqr.c) can be used to test
                  which works best for your configuration.  Set up the
                  CC and CFLAGS variables in the Makefile, then type:

                        make mulsqr

                  Invoke it with arguments similar to the following:

                        mulsqr 25000 1024

                  That is, 25000 products computed on 1024-bit values.
                  The output will compare the two timings, and recommend
                  a setting for MP_SQUARE.  It is off by default.

If you would like to use the mp_print() function (see above), be sure
to define MP_IOFUNC in mpi-config.h.  Many of the test drivers in the
'tests' subdirectory expect this to be defined (although the test
driver 'mpi-test' doesn't need it)

The Makefile which comes with the library should take care of building
the library for you, if you have set the CC and CFLAGS variables at
the top of the file appropriately.  By default, they are set up to
use the GNU C compiler:

CC=gcc
CFLAGS=-ansi -pedantic -Wall -O2

If all goes well, the library should compile without warnings using
this combination.  You should, of course, make whatever adjustments
you find necessary.  

The MPI library distribution comes with several additional programs
which are intended to demonstrate the use of the library, and provide
a framework for testing it.  There are a handful of test driver
programs, in the files named 'mptest-X.c', where X is a digit.  Also,
there are some simple command-line utilities (in the 'utils'
directory) for manipulating large numbers.  These include:

basecvt.c       A radix-conversion program, supporting bases from
                2 to 64 inclusive.

bbsrand.c       A BBS (quadratic residue) pseudo-random number 
                generator.  The file 'bbsrand.c' is just the driver
                for the program; the real code lives in the files
                'bbs_rand.h' and 'bbs_rand.c'

dec2hex.c       Converts decimal to hexadecimal

gcd.c           Computes the greatest common divisor of two values.
                If invoked as 'xgcd', also computes constants x and
                y such that (a, b) = ax + by, in accordance with
                Bezout's identity.

hex2dec.c       Converts hexadecimal to decimal

invmod.c        Computes modular inverses

isprime.c       Performs the Rabin-Miller probabilistic primality
                test on a number.  Values which fail this test are
                definitely composite, and those which pass are very
                likely to be prime (although there are no guarantees)

lap.c           Computes the order (least annihilating power) of
                a value v modulo m.  Very dumb algorithm.

primegen.c      Generates large (probable) primes.

prng.c          A pseudo-random number generator based on the
                BBS generator code in 'bbs_rand.c'

sieve.c         Implements the Sieve of Eratosthenes, using a big
                bitmap, to generate a list of prime numbers.

fact.c          Computes the factorial of an arbitrary precision
                integer (iterative).

exptmod.c       Computes arbitrary precision modular exponentiation
                from the command line (exptmod a b m -> a^b (mod m))

Most of these can be built from the Makefile that comes with the
library.  Try 'make tools', if your environment supports it.  (If you
are compiling on a Macintosh, I'm afraid you'll have to build them by
hand -- fortunately, this is not difficult -- the library itself
should compile just fine under Metrowerks CodeWarrior).


Testing the Library
-------------------

Automatic test vectors are included, in the form of a program called
'mpi-test'.  To build this program and run all the tests, simply
invoke the shell script 'all-tests'.  If all the tests pass, you
should see a message:

        All tests passed

If something went wrong, you'll get:

        One or more tests failed.

If this happens, scan back through the preceding lines, to see which
test failed.  Any failure indicates a bug in the library, which needs
to be fixed before it will give accurate results.  If you get any such
thing, please let me know, and I'll try to fix it.  Please let me know
what platform and compiler you were using, as well as which test
failed.  If a reason for failure was given, please send me that text
as well.

If you're on a system such as the Macintosh, where the standard Unix
build tools don't work, you can build the 'mpi-test' program manually,
and run it by hand.  This is tedious and obnoxious, sorry.

Further manual testing can be performed by building the manual testing
programs, whose source is found in the 'tests' subdirectory.  Each
test is in a source file called 'mptest-X.c'.  The Makefile contains a
target to build all of them at once:

        make tests

Read the comments at the top of each source file to see what the
driver is supposed to test.  You probably don't need to do this; these
programs were only written to help me as I was developing the library.

The relevant files are:

mpi-test.c              The source for the test driver

make-test-arrays        A Perl script to generate some of the internal
                        data structures used by mpi-test.c

test-arrays.txt         The source file for make-test-arrays

all-tests               A Bourne shell script which runs all the
                        tests in the mpi-test suite

Running 'make mpi-test' should build the mpi-test program.  If you
cannot use make, here is what needs to be done:

(1) Use 'make-test-arrays' to generate the file 'test-info.c' from
    the 'test-arrays.txt' file.  Since Perl can be found everywhere,
    even on the Macintosh, this should be no trouble.  Under Unix, 
    this looks like:

        make-test-arrays test-arrays.txt > test-info.c

(2) Build the MPI library:

        gcc -ansi -pedantic -Wall -c mpi.c

(3) Build the mpi-test program:

        gcc -ansi -pedantic -Wall -o mpi-test mpi.o mpi-test.c

When you've got mpi-test, you can use 'all-tests' to run all the tests
made available by mpi-test.  If any of them fail, there should be a
diagnostic indicating what went wrong.  These are fairly high-level
diagnostics, and won't really help you debug the problem; they're
simply intended to help you isolate which function caused the problem.
If you encounter a problem of this sort, feel free to e-mail me, and I
will certainly attempt to help you debug it.

Note:   Several of the tests hard-wired into 'mpi-test' operate under
----    the assumption that you are using at least a 16-bit mp_digit 
        type.  If that is not true, several tests might fail, because 
        of range problems with the maximum digit value.

        If you are using an 8-bit digit, you will also need to 
        modify the code for mp_read_raw(), which assumes that
        multiplication by 256 can be done with mp_mul_d(), a
        fact that fails when DIGIT_MAX is 255.  You can replace
        the call with s_mp_lshd(), which will give you the same
        effect, and without doing as much work. :)

Acknowledgements:
----------------

The algorithms used in this library were drawn primarily from Volume
2 of Donald Knuth's magnum opus, _The Art of Computer Programming_, 
"Semi-Numerical Methods".  Barrett's algorithm for modular reduction
came from Menezes, Oorschot, and Vanstone's _Handbook of Applied
Cryptography_, Chapter 14.

Thanks are due to Tom St. Denis, for finding an obnoxious sign-related
bug in mp_read_raw() that made things break on platforms which use
signed chars.

About the Author
----------------

This software was written by Michael J. Fromberger.  You can contact
the author as follows:

E-mail:   <sting@linguist.dartmouth.edu>

Postal:   8000 Cummings Hall, Thayer School of Engineering
          Dartmouth College, Hanover, New Hampshire, USA

PGP key:  http://linguist.dartmouth.edu/~sting/keys/mjf.html
          9736 188B 5AFA 23D6 D6AA  BE0D 5856 4525 289D 9907

Last updated:  16-Jan-2000
                      Signing Tool (signtool)
                         3.10 Release Notes
               ========================================

Documentation is provided online at mozilla.org

Problems or questions not covered by the online documentation can be
discussed in the DevEdge Security Newsgroup.

=== New Features in 3.10
=======================
One new option (-X) has been added to create a Mozilla aware signed XPI archive. 
The option must be accompanied by the -Z option. This new option
creates a JAR file with the META-INF/zigbert.rsa/dsa file as the first file in 
the archive instead of the default third to last. This will enable the archive
to be seen as signed by products incorporating XPInstall. i.e. .xpi extensions
for FireFox or Mozilla.

=== New Features in 1.3
=======================

The security library components have been upgraded to utilize NSS_2_7_1_RTM.
This means that the maximum RSA keysize now supported should be 4096 bits.

=== Zigbert 0.6 Support
=======================
This program was previously named Zigbert.  The last version of zigbert
was Zigbert 0.6.  Because all the functionality of Zigbert is maintained in
signtool 1.2, Zigbert is no longer supported.  If you have problems
using Zigbert, please upgrade to signtool 1.2.

=== New Features in 1.2
=======================

Certificate Generation Improvements
-----------------------------------
Two new options have been added to control generation of self-signed object
signing certificates with the -G option. The -s option takes the size (in bits)
of the generated RSA private key.  The -t option takes the name of the PKCS #11
token on which to generate the keypair and install the certificate.  Both
options are optional.  By default, the private key is 1024 bits and is generated
on the internal software token.


=== New Features in 1.1
=======================

File I/O
--------
Signtool can now read its options from a command file specified with the -f
option on the command line. The format for the file is described in the
documentation.
Error messages and informational output can be redirected to an output file
by supplying the "--outfile" option on the command line or the "outfile="
option in the command file.

New Options
-----------
"--norecurse" tells Signtool not to recurse into subdirectories when signing
directories or parsing HTML with the -J option.
"--leavearc" tells Signtool not to delete the temporary .arc directories
produced by the -J option.  This can aid debugging.
"--verbosity" tells Signtool how much information to display. 0 is the
default. -1 suppresses most messages, except for errors.

=== Bug Fixes in 1.1
====================

-J option revamped
------------------
The -J option, which parses HTML files, extracts Java and Javascript code,
and stores them in signed JAR files, has been re-implemented. Several bugs
have been fixed:
- CODEBASE attribute is no longer ignored
- CLASS and SRC attributes can be be paths ("xxx/xxx/x.class") rather than
  just filenames ("x.class").
- LINK tags are handled correctly
- various HTML parsing bugs fixed
- error messages are more informative

No Password on Key Database
---------------------------
If you had not yet set a Communicator password (which locks key3.db, the
key database), signtool would fail with a cryptic error message whenever it
attempted to verify the password.  Now this condition is detected at the
beginning of the program, and a more informative message is displayed.

-x and -e Options
-----------------
Previously, only one of each of these options could be specified on the command
line. Now arbitrarily many can be specified.  For example, to sign only files
with .class or .js extensions, the arguments "-eclass -ejs" could both be
specified. To exclude the directories "subdir1" and "subdir2" from signing,
the arguments "-x subdir1 -x subdir2" could both be specified.

New Features in 1.0
===================

Creation of JAR files
----------------------
The -Z option causes signtool to output a JAR file formed by storing the
signed archive in ZIP format.  This eliminates the need to use a separate ZIP
utility.  The -c option specifies the compression level of the resulting
JAR file.

Generation of Object-Signing Certificates and Keys
--------------------------------------------------
The -G option will create a new, self-signed object-signing certificate
which can be used for testing purposes.  The generated certificate and 
associated public and private keys will be installed in the cert7.db and
key3.db files in the directory specified with the -d option (unless the key
is generated on an external token using the -t option). On Unix systems,
if no directory is specified, the user's Netscape directory (~/.netscape)
will be used. In addition, the certificate is output in X509 format to the
files x509.raw and x509.cacert in the current directory.  x509.cacert can
be published on a web page and imported into browsers that visit that page.

Extraction and Signing of JavaScript from HTML
----------------------------------------------
The -J option activates the same functionality provided by the signpages
Perl script.  It will parse a directory of html files, creating archives
of the JavaScript called from the HTML. These archives are then signed and
made into JAR files.

Enhanced Smart Card Support
---------------------------
Certificates that reside on smart cards are displayed when using the -L and
-l options.
These sample programs can be built in either of two ways:
1) is the NSS source tree, using the coreconf build system, and 
2) stand alone (as part of the NSS distribution).

The following makefiles are used only when building in the NSS source tree
using coreconf.  These are NOT part of the distribution.

Makefile
client.mn
server.mn
config.mk
make.client
make.server

The following source files are common to both build environments and are
part of the distribution.

NSPRerrs.h
SECerrs.h
SSLerrs.h
client.c
getopt.c
server.c
sslerror.h

In the NSS 2.0 distribution, the sample code and makefiles are in a 
directory named "samples".  The directories relevant to building 
in the distributed tree are:

./samples
./include/dbm
./include/nspr
./include/security
./lib

0  secp160k1
1  secp160r1
2  secp160r2
3  nistk163
4  sect163r1
5  nistb163
6  secp192k1
7  nistp192
8  secp224k1
9  nistp224
10 nistk233
11 nistb233
12 nistp256
13 nistk283
14 nistb283
15 nistp384
16 nistk409
17 nistb409
18 nistk571
19 nistb571
# the following tests are not yet implemented
#20 nistp521
This directory contains a set of tests for each cipher supported by
BLAPI.  Each subdirectory contains known plaintext and ciphertext pairs
(and keys and/or iv's if needed).  The tests can be run as a full set
with:
    bltest -T
or as subsets, for example:
    bltest -T -m des_ecb,md2,rsa

In each subdirectory, the plaintext, key, and iv are ascii, and treated
as such.  The ciphertext is base64-encoded to avoid the hassle of binary
files.

To add a test, incremement the value in the numtests file.  Create a
plaintext, key, and iv file, such that the name of the file is
incrememted one from the last set of tests.  For example, if you are
adding the second test, put your data in files named plaintext1, key1,
and iv1 (ignoring key and iv if they are not needed, of course).  Make
sure your key and iv are the correct number of bytes for your cipher (a
trailing \n is okay, but any other trailing bytes will be used!).  Once
you have your input data, create output data by running bltest on a
trusted implementation.  For example, for a new DES ECB test, run
    bltest -E -m des_ecb -i plaintext1 -k key1 -o ciphertext1 -a in the
tests/des_ecb directory.  Then run
    bltest -T des_ecb from the cmd/bltest directory in the tree of the
implementation you want to test.

Note that the -a option above is important, it tells bltest to expect
the input to be straight ASCII, and not base64 encoded binary!

Special cases:

RC5:
RC5 can take additional parameters, the number of rounds to perform and
the wordsize to use.  The number of rounds is between is between 0 and
255, and the wordsize is either is either 16, 32, or 64 bits (at this
time only 32-bit is supported).  These parameters are specified in a
paramsN file, where N is an index as above.  The format of the file is
"rounds=R\nwordsize=W\n".

public key modes (RSA and DSA):
Asymmetric key ciphers use keys with special properties, so creating a
key file with "Mozilla!" in it will not get you very far!  To create a
public key, run bltest with the plaintext you want to encrypt, using a
trusted implementation.  bltest will generate a key and store it in
"tmp.key", rename that file to keyN.  For example:
    bltest -E -m rsa -i plaintext0 -o ciphertext0 -e 65537 -g 32 -a
    mv tmp.key key0

[note: specifying a keysize (-g) when using RSA is important!]
                    CRYPTOGRAPHIC MODULE UTILITY (modutil)
                                VERSION 1.0
              ===============================================

The file specification.html documentats the software.

The file pk11jar.html documents the PKCS #11 JAR format.
ZLIB DATA COMPRESSION LIBRARY

zlib 1.2.3 is a general purpose data compression library.  All the code is
thread safe.  The data format used by the zlib library is described by RFCs
(Request for Comments) 1950 to 1952 in the files
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
and rfc1952.txt (gzip format). These documents are also available in other
formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html

All functions of the compression library are documented in the file zlib.h
(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
of the library is given in the file example.c which also tests that the library
is working correctly. Another example is given in the file minigzip.c. The
compression library itself is composed of all source files except example.c and
minigzip.c.

To compile all files and run the test program, follow the instructions given at
the top of Makefile. In short "make test; make install" should work for most
machines. For Unix: "./configure; make test; make install". For MSDOS, use one
of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.

Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
<info@winimage.com> for the Windows DLL version. The zlib home page is
http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
please check this site to verify that you have the latest version of zlib;
otherwise get the latest version and check whether the problem still exists or
not.

PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
for help.

Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
issue of  Dr. Dobb's Journal; a copy of the article is available in
http://dogma.net/markn/articles/zlibtool/zlibtool.htm

The changes made in version 1.2.3 are documented in the file ChangeLog.

Unsupported third party contributions are provided in directory "contrib".

A Java implementation of zlib is available in the Java Development Kit
http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
See the zlib home page http://www.zlib.org for details.

A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
CPAN (Comprehensive Perl Archive Network) sites
http://www.cpan.org/modules/by-module/Compress/

A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
available in Python 1.5 and later versions, see
http://www.python.org/doc/lib/module-zlib.html

A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> is
availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html

An experimental package to read and write files in .zip format, written on top
of zlib by Gilles Vollant <info@winimage.com>, is available in the
contrib/minizip directory of zlib.


Notes for some targets:

- For Windows DLL versions, please see win32/DLL_FAQ.txt

- For 64-bit Irix, deflate.c must be compiled without any optimization. With
  -O, one libpng test fails. The test works in 32 bit mode (with the -n32
  compiler flag). The compiler bug has been reported to SGI.

- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
  when compiled with cc.

- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
  necessary to get gzprintf working correctly. This is done by configure.

- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
  other compilers. Use "make test" to check your compiler.

- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.

- For PalmOs, see http://palmzlib.sourceforge.net/

- When building a shared, i.e. dynamic library on Mac OS X, the library must be
  installed before testing (do "make install" before "make test"), since the
  library location is specified in the library.


Acknowledgments:

  The deflate format used by zlib was defined by Phil Katz. The deflate
  and zlib specifications were written by L. Peter Deutsch. Thanks to all the
  people who reported problems and suggested various improvements in zlib;
  they are too numerous to cite here.

Copyright notice:

 (C) 1995-2004 Jean-loup Gailly and Mark Adler

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.

  Jean-loup Gailly        Mark Adler
  jloup@gzip.org          madler@alumni.caltech.edu

If you use the zlib library in a product, we would appreciate *not*
receiving lengthy legal documents to sign. The sources are provided
for free but without warranty of any kind.  The library has been
entirely written by Jean-loup Gailly and Mark Adler; it does not
include third-party code.

If you redistribute modified sources, we would appreciate that you include
in the file ChangeLog history information documenting your changes. Please
read the FAQ for more information on the distribution of modified source
versions.
OVERVIEW of "ns/coreconf":

    This README file is an attempt to provide the reader with a simple
    synopsis of the "ns/coreconf" build system which was originally
    fundamentally designed and built to accomodate Netscape's binary
    release model.  Wherever possible, an attempt has been made to
    comply with the NSPR 2.0 build system, including mimicing the
    compiler/linker flags, and directory naming structure.  The reader
    should keep in mind that the system builds binary releases of
    header files, class files, libraries, and executables on numerous
    flavors of UNIX and Windows operating systems.  Unfortunately,
    no serious attempt has ever been made to incorporate an ability to
    generate cross-platform binaries on an Apple MacIntosh platform.

    Note that this file will not attempt to redefine or document the
    architecture of this system.  However, documents on this subject
    are available at the following URL:

        http://warp/hardcore/prj-ttools/specs/release/index.html



DEPENDENCIES of "ns/coreconf":

    The "ns/coreconf" build system requires the specified versions of
    the following platform-dependent tools:

        UNIX Platforms:
        --------------
        gmake (version 3.74 or later)
        perl 4.0 (NOTE:  perl 5.003 or later recommended)
        uname

        Windows Platforms:
        -----------------
        gmake 3.74 (must use hacked Netscape version)
        shmsdos.exe (contained in Netscape gmake.exe)
        nsinstall.exe (contained in Netscape gmake.exe)
        perl.exe (version 4.0 for everything except testing;
                  NOTE:  MKS toolkit perl 5.002 is broken)
        perl5.exe (for testing;
                   NOTE:  perl 5.003 or later recommended;
                          MKS toolkit perl 5.002 is broken)
        uname.exe (use nstools version)

ENHANCEMENTS to "ns/coreconf":

    With the advent of Certificate Server 4.0 using the ns/coreconf
    build system, several changes had to be made to enhance
    ns/coreconf support for building Java/JNI classes/programs, as
    well as libraries slated to be released as binaries.  While the
    following may not represent an exhaustive list of these changes,
    it does attempt to be at least somewhat comprehensive:

        (1) During the course of these enhancements, a total of
            four files have been modified, and four new files have
            been added.

            The following files have been modified:

                - command.mk:    removed old definition of JAR

                - config.mk:     added include statement of new
                                 "jdk.mk" file

                - ruleset.mk:    allowed the $(MKPROG) variable to be
                                 overridden by supplying it with a
                                 default value of $(CC); augmented
                                 numerous definitions to enhance
                                 ability of ns/coreconf to produce
                                 a more robust set of libraries;
                                 added some JNI definitions; PACKAGE
                                 definition may be overridden by new
                                 "jdk.mk" file

                - rules.mk:      separated the compile phase of a
                                 program from the link phase of a
                                 program such that a developer can
                                 now strictly override program linkage
                                 by simply supplying a $(MKPROG)
                                 variable; augmented NETLIBDEPTH
                                 to use CORE_DEPTH but retain backward
                                 compatibility; added JNI section;
                                 modified .PRECIOUS rule;

            The following files have been added:

                - README:        this file; an ASCII-based text
                                 document used to summarize the
                                 ns/coreconf build system and
                                 suitable (paginated) for printing

                - jdk.mk:        a file comprising most (if not all)
                                 of the default Java related build
                                 information; the definitions in this
                                 file are only included if NS_USE_JDK
                                 has been defined

                - jniregen.pl:   a perl script used to create a
                                 dependency for when JNI files should
                                 be regenerated (based upon any change
                                 to the ".class" file from which the
                                 ".h" file was originally generated)

                - outofdate.pl:  a perl script used to create a
                                 dependency for when ".class" files
                                 should be regenerated (based upon
                                 any change to the ".java" file
                                 from which the ".class" file was
                                 originally generated)

        (2) As stated above, the ns/coreconf build system now separates
            the link phase of a program from its compilation phase.
            While ns/coreconf still works exactly as it used to because
            the $(MKPROG) variable is assigned $(CC) by default, a developer
            may now override this behavior by simply supplying their
            own unique value for $(MKPROG) on every platform.  This allows
            a program compiled with $(CC) to link with external libraries
            that may contain "C++" linkage.  Before this change, a
            programmer would need to reference their own local copy of
            rules.mk (see the ns/sectools/cmd/pk12util program for
            an example of how this used to be accomplished).

        (3) Currently, the ns/coreconf build system differs from the
            NSPR 2.0 build system which utilizes an "_s" to denote
            static libraries from import libraries.  In fact, the
            ns/coreconf build system adds no prefixes or suffixes to
            distinguish one version of static libraries from another.
            Note that both the ns/coreconf build system as well as the
            NSPR 2.0 build system do nothing to provide a method of
            distinguishing 16-bit from 32-bit static libraries on the
            same machine, either, since:

                a) this might only provide difficulty during
                   development, since static libraries always
                   need to be embedded within a program
                   (note this is highly unlikely, since libraries
                    for different platforms are subdivided via
                    a well-known subdirectory structure, and
                    a developer may use multiple trees for
                    development),

                b) this maintains backwards compatibility,
                   something very important since no legacy
                   programs will need to change their link phase, and

                c) Netscape as a company has dropped any plans
                   of future development of 16-bit products.

        (4) Since several members of the Hardcore Security group did
            not favor NSPR 2.0's solution of adding an "_s" to static
            libraries on Windows platforms as a method to distinguish
            them from their import library cousins, a different solution
            was proposed and has been recently implemented for ns/coreconf:

                - a 16 has been added as a suffix to both dynamic and
                  import libraries built on 16-bit Windows platforms

                - a 32 has been added as a suffix to both dynamic and
                  import libraries built on 32-bit Windows platforms

            Since the HCL release process currently only contains a
            single instance of building a dynamic library,
            ns/security/lib/fortcrypt/fort12.dll, the impact of this
            change should be relatively small.  (Note: HCL was the
            old name of NSS.)

            It should be noted that although this would additionally
            limit the 8.3 namespace on 16-bit platforms, it is highly
            unlikely that any future development will be performed on
            this platform.

        (5) The $(LIBRARY_VERSION) tag has been added to all non-static
            libraries created on UNIX operating systems to alleviate
            any future confusion for binary releases which utilize this
            tag.  Again, it should be noted that this tag is only
            utilized on non-static libraries, since more than one
            version of the library may need to exist simultaneously
            if multiple products are utilized.

            Currently, only one HCL released library utilizes this tag:

                ns/security/lib/fortcrypt/fort12.a
                (e. g. - in this library, the tag has been set to '12')

            Again, it should be noted that although this would
            additionally limit the 8.3 namespace on 16-bit platforms,
            it is highly unlikely that any future development will be
            performed on this platform.

        (6) The $(JDK_DEBUG_SUFFIX) extension has been added to all
            library and program names to support debug versions of
            Java programs (e. g. - java_g, javac_g, etc).

            Once again, it should be noted that although this would
            additionally limit the 8.3 namespace on 16-bit platforms,
            it is highly unlikely that any future Java development
            will be performed on this platform.

        (7) Most (if not all) default definitions for java have been
            encapsulated within their own file, jdk.mk, which is
            always included by default in ns/coreconf/config.mk.
            However, the definitions within this file are only ever
            activated if NS_USE_JDK has been set to be 1.


        (8) Two perl scripts (jniregen.pl and outofdate.pl) have been
            added to the system to foster a more robust development
            environment for composing Java and JNI programs
            utilizing the ns/coreconf build system.  Both of these
            perl scripts are related to resolving dependencies which
            can not be accomplished through normal makefile dependencies.

        (9) This file, README, was created in an attempt to allow
            developers who have familiarity with ns/coreconf a simple
            roadmap for what has changed, as well as a top-level view of
            what comprises ns/coreconf.  This file was written in
            ASCII (rather than HTML) primarily to promote simple
            paginated printing.

OVERVIEW of "config.mk":

    This file contains the configuration information necessary to
    build each "Core Components" source module:

        include file name       Purpose
        ===================     =======================================
        arch.mk                 source and release <architecture> tags

        command.mk              default command macros 
				(NOTE: may be overridden in $(OS_CONFIG).mk)

        $(OS_CONFIG).mk         <architecture>-specific macros
                                (dependent upon <architecture> tags)

        tree.mk                 release <tree> tags 
				(dependent upon <architecture> tags)

        module.mk               source and release <component> tags 
				(NOTE:  A component is also called a module 
				or a subsystem.  This file is dependent upon
                                $(MODULE) being defined on the command
                                line, as an environment variable, or in
                                individual makefiles, or more
                                appropriately, manifest.mn)

        version.mk              release <version> tags 
				(dependent upon $(MODULE) being defined on 
				the command line, as an environment variable, 
				or in individual makefiles, or more
                                appropriately, manifest.mn)

        location.mk             macros to figure out binary code location
                                (dependent upon <platform> tags)

        source.mk               <component>-specific source path
                                (dependent upon <user_source_tree>,
                                <source_component>, <version>, and
                                <platform> tags)

        headers.mk              include switch for support header files 
				(dependent upon <tree>, <component>, <version>,
                                and <platform> tags)

        prefix.mk               compute program prefixes

        suffix.mk               compute program suffixes 
				(dependent upon <architecture> tags)

        jdk.mk                  define JDK 
				(dependent upon <architecture>,
                                <source>, and <suffix> tags)

        ruleset.mk              Master "Core Components" rule set
                                (should always be the last file
                                included by config.mk)



OVERVIEW of "rules.mk":

    The "rules.mk" file consists of four sections.  The first section
    contains the "master" build rules for all binary releases.  While
    this section can (and should) largely be thought of as "language"
    independent, it does utilize the "perl" scripting language to
    perform both the "import" and "release" of binary modules.

    The rules which dwell in this section and their purpose:


        CATEGORY/rule::         Purpose
        ===================     =======================================

        GENERAL
        -------
        all::                   "default" all-encompassing rule which
                                performs "export libs program install"

        export::                recursively copy specified
                                cross-platform header files to the
                                $(SOURCE_XPHEADERS_DIR) directory;
                                recursively copy specified
                                machine-dependent header files to the
                                $(SOURCE_MDHEADERS_DIR) directory;
                                although all rules can be written to
                                repetively "chain" into other sections,
                                this rule is the most commonly used
                                rule to "chain" into other sections
                                such as Java providing a simple
                                mechanism which allows no need for
                                developers to memorize specialized
                                rules

        libs::                  recursively build
                                static (archival) $(LIBRARY), shared
                                (dynamic link) $(SHARED_LIBRARY),
                                and/or import $(IMPORT_LIBRARY)
                                libraries

        program::               recursively build $(PROGRAM)
                                executable

        install::               recursively copy all libraries to
                                $(SOURCE_LIB_DIR) directory;
                                recursively copy all executables to
                                $(SOURCE_BIN_DIR) directory

        clean::                 remove all files specified in the
                                $(ALL_TRASH) variable

        clobber::               synonym for "clean::" rule

        realclean::             remove all files specified by
                                $(wildcard *.OBJ), dist, and in
                                the $(ALL_TRASH) variable

        clobber_all::           synonym for "realclean::" rule

        private_export::        recursively copy specified
                                cross-platform header files to the
                                $(SOURCE_XPPRIVATE_DIR) directory


        IMPORT
        ------
        import::                uses perl script to retrieve specified
                                VERSION of the binary release from
                                $(RELEASE_TREE)

        RELEASE
        -------
        release_clean::         remove all files from the
                                $(SOURCE_RELEASE_PREFIX) directory

        release::               place specified VERSION of the
                                binary release in the appropriate
                                $(RELEASE_TREE) directory

        release_export::        recursively copy specified
                                cross-platform header files to the
                                $(SOURCE_XPHEADERS_DIR)/include
                                directory

        release_md::            recursively copy all libraries to
                                $(SOURCE_RELEASE_PREFIX)/
                                $(SOURCE_RELEASE_LIB_DIR) directory;
                                recursively copy all executables to
                                $(SOURCE_RELEASE_PREFIX)/
                                $(SOURCE_RELEASE_BIN_DIR) directory

        release_jars::          use perl script to package appropriate
                                files in the $(XPCLASS_JAR),
                                $(XPHEADER_JAR), $(MDHEADER_JAR), and
                                $(MDBINARY_JAR) jar files

        release_cpdistdir::     use perl script to copy the
                                $(XPCLASS_JAR), $(XPHEADER_JAR),
                                $(MDHEADER_JAR), and $(MDBINARY_JAR)
                                jar files to the specified VERSION
                                of the $(RELEASE_TREE) directory



        TOOLS and AUTOMATION
        --------------------
        platform::              tool used to display the platform name
                                as composed within the "arch.mk" file

        autobuild::             automation rule used by "Bonsai" and
                                "Tinderbox" to automatically generate
                                binary releases on various platforms

        tests::                 automation tool used to run the
                                "regress" and "reporter" tools 
                                on various regression test suites

    The second section of "rules.mk" primarily contains several
    "language" dependent build rules for binary releases.  These are
    generally "computed" rules (created on the "fly"), and include
    rules used by "C", "C++", assembly, the preprocessor, perl, and
    the shell.

    The rules which dwell in this section and their purpose:


        CATEGORY/rule::                   Purpose
        ===================               =============================

        LIBRARIES
        ---------
        $(LIBRARY):                       build the static library
                                          specified by the $(LIBRARY)
                                          variable

        $(IMPORT_LIBRARY):                build the import library
                                          specified by the
                                          $(IMPORT_LIBRARY) variable

        $(SHARED_LIBRARY):                build the shared
                                          (dynamic link) library
                                          specified by the
                                          $(SHARED_LIBRARY) variable


        PROGRAMS
        --------
        $(PROGRAM):                       build the binary executable
                                          specified by the $(PROGRAM)
                                          rule

        $(OBJDIR)/
        $(PROG_PREFIX)%.pure:             build the "purified" binary
                                          executable specified by this
                                          rule


        OBJECTS
        -------
        $(OBJDIR)/
        $(PROG_PREFIX)%$(OBJ_SUFFIX):     build the object file
                                          associated with the
                                          makefile rule dependency:

                                              %.c   = C file
                                              %.cpp = C++ file
                                              %.cc  = C++ file
                                              %.s   = assembly file
                                              %.S   = assembly file

        $(OBJDIR)/
        $(PROG_PREFIX)%:                  (NOTE: deprecated rule)
                                          build the object file
                                          associated with the
                                          makefile rule dependency:

                                              %.cpp = C++ file

        MISCELLANEOUS
        -------------
        $(DIRS)::                         specifies a helper method
                                          used by $(LOOP_THROUGH_DIRS)
                                          to recursively change
                                          directories and invoke
                                          $(MAKE)

        %.i:                              build the preprocessor file
                                          associated with the
                                          makefile rule dependency:

                                              %.c   = C file
                                              %.cpp = C++ file

        %:                                process the specified file
                                          using the method associated
                                          with the makefile rule
                                          dependency:

                                              %.pl = perl script
                                              %.sh = shell script

        alltags:                          tool used to recursively
                                          create a "ctags"-style
                                          file for reference

    The third section of "rules.mk' primarily contains several JAVA
    "language" build rules for binary releases.  These are also
    generally "computed" rules (created on the "fly").

    The rules which dwell in this section and their purpose:


        CATEGORY/rule::                   Purpose
        ===================               =============================
        $(JAVA_DESTPATH)::                create directory specified
                                          as the Java destination path
                                          for where classes are
                                          deposited

        $(JAVA_DESTPATH)/$(PACKAGE)::     create directories specified
                                          within the $(PACKAGE)
                                          variable

        $(JMCSRCDIR)::                    create directory specified
                                          as the JMC destination path

        $(JRI_HEADER_CFILES):             used to generate/regenerate
                                          JRI header files for "C"

        $(JRI_STUB_CFILES):               used to generate/regenerate
                                          JRI stub files for "C"

        $(JNI_HEADERS):                   used to generate/regenerate
                                          JNI header files for "C"

    The fourth section of "rules.mk" primarily contains miscellaneous
    build rules for binary releases.  Many of these rules are here to
    create new subdirectories, manage dependencies, and/or override
    standard gmake "Makefile" rules.

    The rules which dwell in this section and their purpose:


        CATEGORY/rule::                   Purpose
        ===================               =============================

        $(PUBLIC_EXPORT_DIR)::            create directory used to
                                          house public "C" header files

        $(PRIVATE_EXPORT_DIR)::           create directory used to
                                          house private "C" header
                                          files

        $(SOURCE_XP_DIR)/
        release/include::                 create directory used to
                                          house "C" header files
                                          contained in a release

        $(MKDEPENDENCIES)::               for UNIX systems, create
                                          a directory used to house
                                          dependencies and utilize
                                          the $(MKDEPEND) rule to
                                          create them

        $(MKDEPEND)::                     cd to the dependency
                                          directory and create them

        depend::                          if $(OBJS) exist, perform the
                                          $(MKDEPEND) rule followed by
                                          the $(MKDEPENDENCIES) rule

        dependclean::                     remove all files contained
                                          in the dependency repository

        .DEFAULT:                         standard gmake rule

        .SUFFIXES:                        standard gmake rule

        .PRECIOUS:                        standard gmake rule

        .PHONY:                           standard gmake rule

