summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--INSTALL8
-rw-r--r--cipher/ChangeLog10
-rw-r--r--cipher/Makefile.am21
-rw-r--r--cipher/blowfish.c10
-rw-r--r--cipher/cast5.c12
-rw-r--r--cipher/dsa.c2
-rw-r--r--cipher/dynload.c26
-rw-r--r--cipher/md.c3
-rw-r--r--cipher/rand-unix.c12
-rw-r--r--cipher/random.c60
-rw-r--r--configure.in18
-rw-r--r--mpi/ChangeLog4
-rw-r--r--mpi/mips3/distfiles9
-rw-r--r--mpi/mips3/mpih-add1.S122
-rw-r--r--mpi/mips3/mpih-lshift.S95
-rw-r--r--mpi/mips3/mpih-mul1.S87
-rw-r--r--mpi/mips3/mpih-mul2.S99
-rw-r--r--mpi/mips3/mpih-mul3.S99
-rw-r--r--mpi/mips3/mpih-rshift.S93
-rw-r--r--mpi/mips3/mpih-sub1.S123
21 files changed, 858 insertions, 59 deletions
diff --git a/ChangeLog b/ChangeLog
index 5db61423..d4b01c74 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Thu Jun 25 11:18:49 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (--disable-dynload): New.
+
Wed Jun 10 07:48:59 1998 Werner Koch,mobil,,, (wk@tobold)
* configure.in (GNUPG_LIBDIR): New.
diff --git a/INSTALL b/INSTALL
index 4950ba94..23fa6b98 100644
--- a/INSTALL
+++ b/INSTALL
@@ -25,12 +25,16 @@ Configure options for GNUPG
side-effect, this removes all debugging code and uses
the -O2 flag for all C files.
+--disable-dynload If you have problems with dynamic loading, this option
+ disables all dynamic loading stuff.
+
+
Problems
========
-If you have compile problems, try the configure options "--with-included-zlib"
-or "--disable-nls" (See ABOUT-NLS).
+If you have compile problems, try the configure options "--with-included-zlib",
+"--disable-nls" (See ABOUT-NLS) or --disable-dynload.
I can't check all assembler files, so if you have problems assembling them
(or the program crashes), simply delete the files in the mpi/<cpu> directory.
diff --git a/cipher/ChangeLog b/cipher/ChangeLog
index 35420646..92ca470d 100644
--- a/cipher/ChangeLog
+++ b/cipher/ChangeLog
@@ -1,6 +1,14 @@
+Thu Jun 25 11:18:25 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * Makefile.am: Support for extensions
+
+Thu Jun 18 12:09:38 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (mix_pool): simpler handling for level 0
+
Mon Jun 15 14:40:48 1998 Werner Koch (wk@isil.d.shuttle.de)
- * tiger.c: Removed from dis, will reappear as dynload module
+ * tiger.c: Removed from dist, will reappear as dynload module
Sat Jun 13 14:16:57 1998 Werner Koch (wk@isil.d.shuttle.de)
diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index d0c0202c..f01bb784 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -1,9 +1,15 @@
## Process this file with automake to produce Makefile.in
+gnupg_extensions = tiger
+
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
-EXTRA_DIST = tiger.c
noinst_LIBRARIES = libcipher.a
+if ENABLE_GNUPG_EXTENSIONS
+pkglib_PROGRAMS = $(gnupg_extensions)
+else
+pkglib_PROGRAMS =
+endif
libcipher_a_SOURCES = cipher.c \
@@ -18,6 +24,7 @@ libcipher_a_SOURCES = cipher.c \
elgamal.c \
elgamal.h \
md5.c \
+ md5.h \
primegen.c \
random.h \
random.c \
@@ -34,4 +41,16 @@ libcipher_a_SOURCES = cipher.c \
g10c.c \
smallprime.c
+EXTRA_tiger_SOURCES = tiger.c
+
+tiger: tiger.c
+ $(COMPILE) -shared -fPIC -o tiger tiger.c
+
+install-exec-hook:
+ @list='$(pkglib_PROGRAMS)'; for p in $$list; do \
+ if test -f $(pkglibdir)/$$p; then \
+ echo "chmod 644 $(pkglibdir)/$$p"; \
+ chmod 644 $(pkglibdir)/$$p; \
+ fi; \
+ done
diff --git a/cipher/blowfish.c b/cipher/blowfish.c
index 65a408ef..3ed2ed85 100644
--- a/cipher/blowfish.c
+++ b/cipher/blowfish.c
@@ -55,7 +55,7 @@ typedef struct {
u32 p[BLOWFISH_ROUNDS+2];
} BLOWFISH_context;
-static void setkey( BLOWFISH_context *c, byte *key, unsigned keylen );
+static void bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen );
static void encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf );
static void decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf );
@@ -461,7 +461,7 @@ selftest()
byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 };
byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 };
- setkey( &c, "abcdefghijklmnopqrstuvwxyz", 26 );
+ bf_setkey( &c, "abcdefghijklmnopqrstuvwxyz", 26 );
encrypt_block( &c, buffer, plain );
if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) )
log_error("wrong blowfish encryption\n");
@@ -469,7 +469,7 @@ selftest()
if( memcmp( buffer, plain, 8 ) )
log_bug("blowfish failed\n");
- setkey( &c, key3, 8 );
+ bf_setkey( &c, key3, 8 );
encrypt_block( &c, buffer, plain3 );
if( memcmp( buffer, cipher3, 8 ) )
log_error("wrong blowfish encryption (3)\n");
@@ -481,7 +481,7 @@ selftest()
static void
-setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
+bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
{
int i, j;
u32 data, datal, datar;
@@ -563,7 +563,7 @@ blowfish_get_info( int algo, size_t *keylen,
*keylen = algo == CIPHER_ALGO_BLOWFISH ? 128 : 160;
*blocksize = BLOWFISH_BLOCKSIZE;
*contextsize = sizeof(BLOWFISH_context);
- *r_setkey = FNCCAST_SETKEY(setkey);
+ *r_setkey = FNCCAST_SETKEY(bf_setkey);
*r_encrypt= FNCCAST_CRYPT(encrypt_block);
*r_decrypt= FNCCAST_CRYPT(decrypt_block);
diff --git a/cipher/cast5.c b/cipher/cast5.c
index 0bd90f9d..6b2e5a96 100644
--- a/cipher/cast5.c
+++ b/cipher/cast5.c
@@ -57,7 +57,7 @@ typedef struct {
byte Kr[16];
} CAST5_context;
-static void setkey( CAST5_context *c, byte *key, unsigned keylen );
+static void cast_setkey( CAST5_context *c, byte *key, unsigned keylen );
static void encrypt_block( CAST5_context *bc, byte *outbuf, byte *inbuf );
static void decrypt_block( CAST5_context *bc, byte *outbuf, byte *inbuf );
@@ -465,7 +465,7 @@ selftest()
byte cipher[8]= { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
byte buffer[8];
- setkey( &c, key, 16 );
+ cast_setkey( &c, key, 16 );
encrypt_block( &c, buffer, plain );
if( memcmp( buffer, cipher, 8 ) )
log_error("wrong cast5-128 encryption\n");
@@ -486,10 +486,10 @@ selftest()
0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E };
for(i=0; i < 1000000; i++ ) {
- setkey( &c, b0, 16 );
+ cast_setkey( &c, b0, 16 );
encrypt_block( &c, a0, a0 );
encrypt_block( &c, a0+8, a0+8 );
- setkey( &c, a0, 16 );
+ cast_setkey( &c, a0, 16 );
encrypt_block( &c, b0, b0 );
encrypt_block( &c, b0+8, b0+8 );
}
@@ -550,7 +550,7 @@ key_schedule( u32 *x, u32 *z, u32 *k )
static void
-setkey( CAST5_context *c, byte *key, unsigned keylen )
+cast_setkey( CAST5_context *c, byte *key, unsigned keylen )
{
static int initialized;
int i;
@@ -602,7 +602,7 @@ cast5_get_info( int algo, size_t *keylen,
*keylen = 128;
*blocksize = CAST5_BLOCKSIZE;
*contextsize = sizeof(CAST5_context);
- *r_setkey = FNCCAST_SETKEY(setkey);
+ *r_setkey = FNCCAST_SETKEY(cast_setkey);
*r_encrypt= FNCCAST_CRYPT(encrypt_block);
*r_decrypt= FNCCAST_CRYPT(decrypt_block);
diff --git a/cipher/dsa.c b/cipher/dsa.c
index 19a59d90..46484c1e 100644
--- a/cipher/dsa.c
+++ b/cipher/dsa.c
@@ -150,7 +150,7 @@ generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors )
* is the secret part. */
if( DBG_CIPHER )
log_debug("choosing a random x ");
- assert( qbits >= 16 );
+ assert( qbits >= 160 );
x = mpi_alloc_secure( mpi_get_nlimbs(q) );
mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
rndbuf = NULL;
diff --git a/cipher/dynload.c b/cipher/dynload.c
index 767372a7..e2273170 100644
--- a/cipher/dynload.c
+++ b/cipher/dynload.c
@@ -34,6 +34,7 @@ typedef struct ext_list {
void *handle; /* handle from dlopen() */
int failed; /* already tried but failed */
void * (*enumfunc)(int, int*, int*, int*);
+ char *hintstr; /* pointer into name */
char name[1];
} *EXTLIST;
@@ -48,12 +49,19 @@ typedef struct {
/****************
* Register an extension module. The last registered module will
- * be loaded first.
+ * be loaded first. A name may have a list of classes
+ * appended; e.g:
+ * mymodule.so(1:17,3:20,3:109)
+ * means that this module provides digest algorithm 17 and public key
+ * algorithms 20 and 109. This is only a hint but if it is there the
+ * loader may decide to only load a module which claims to have a
+ * requested algorithm.
*/
void
register_cipher_extension( const char *fname )
{
EXTLIST r, el;
+ char *p, *pe;
if( *fname != '/' ) { /* do tilde expansion etc */
char *p ;
@@ -70,6 +78,14 @@ register_cipher_extension( const char *fname )
el = m_alloc_clear( sizeof *el + strlen(fname) );
strcpy(el->name, fname );
}
+ /* check whether we have a class hint */
+ if( (p=strchr(el->name,'(')) && (pe=strchr(p+1,')')) && !pe[1] ) {
+ *p = *pe = 0;
+ el->hintstr = p+1;
+ }
+ else
+ el->hintstr = NULL;
+
/* check that it is not already registered */
for(r = extensions; r; r = r->next )
if( !compare_filenames(r->name, el->name) ) {
@@ -77,8 +93,6 @@ register_cipher_extension( const char *fname )
m_free(el);
return;
}
- if( DBG_CIPHER )
- log_debug("extension '%s' registered\n", el->name );
/* and register */
el->next = extensions;
extensions = el;
@@ -95,6 +109,7 @@ load_extension( EXTLIST el )
int seq = 0;
int class, vers;
+
el->handle = dlopen(el->name, RTLD_NOW);
if( !el->handle ) {
log_error("%s: error loading extension: %s\n", el->name, dlerror() );
@@ -107,7 +122,10 @@ load_extension( EXTLIST el )
}
if( g10_opt_verbose )
- log_info("%s: version '%s'\n", el->name, *name );
+ log_info("%s: %s%s%s%s\n", el->name, *name,
+ el->hintstr? " (":"",
+ el->hintstr? el->hintstr:"",
+ el->hintstr? ")":"");
sym = dlsym(el->handle, "gnupgext_enum_func");
if( (err=dlerror()) ) {
diff --git a/cipher/md.c b/cipher/md.c
index 3fd7581d..56f639cf 100644
--- a/cipher/md.c
+++ b/cipher/md.c
@@ -314,8 +314,9 @@ md_final(MD_HANDLE a)
if( a->bufcount )
md_write( a, NULL, 0 );
- for(r=a->list; r; r = r->next )
+ for(r=a->list; r; r = r->next ) {
(*r->final)( &r->context );
+ }
}
diff --git a/cipher/rand-unix.c b/cipher/rand-unix.c
index 93afba13..855b23b8 100644
--- a/cipher/rand-unix.c
+++ b/cipher/rand-unix.c
@@ -129,23 +129,11 @@ read_random_source( byte *buffer, size_t length, int level )
fd_random = open_device( "/dev/random", 8 );
fd = fd_random;
}
- else if( level == 1 ) {
- if( fd_urandom == -1 )
- fd_urandom = open_device( "/dev/urandom", 9 );
- fd = fd_urandom;
- }
else {
- /* This is level 0, which only yields simple random bytes.
- * We do not use /dev/urandom as this would remove entropy
- * from the kernel entropy pool */
- /* FIXME !!!! */
-
if( fd_urandom == -1 )
fd_urandom = open_device( "/dev/urandom", 9 );
fd = fd_urandom;
}
-
-
do {
fd_set rfds;
struct timeval tv;
diff --git a/cipher/random.c b/cipher/random.c
index ea6b9080..f44e4c3a 100644
--- a/cipher/random.c
+++ b/cipher/random.c
@@ -211,10 +211,6 @@ read_pool( byte *buffer, size_t length, int level )
if( length >= POOLSIZE )
BUG(); /* not allowed */
- if( !level ) { /* read simple random bytes */
- read_random_source( buffer, length, level );
- return;
- }
/* for level 2 make sure that there is enough random in the pool */
if( level == 2 && pool_balance < length ) {
@@ -236,33 +232,45 @@ read_pool( byte *buffer, size_t length, int level )
/* make sure the pool is filled */
while( !pool_filled )
random_poll();
+
/* do always a fast random poll */
fast_random_poll();
- /* mix the pool (if add_randomness() didn't it) */
- if( !just_mixed )
+ if( !level ) { /* no need for cryptographic strong random */
+ /* create a new pool */
+ for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
+ i < POOLWORDS; i++, dp++, sp++ )
+ *dp = *sp + ADD_VALUE;
+ /* must mix both pools */
mix_pool(rndpool);
-
- /* create a new pool */
- for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
- i < POOLWORDS; i++, dp++, sp++ )
- *dp = *sp + ADD_VALUE;
- /* and mix both pools */
- mix_pool(rndpool);
- mix_pool(keypool);
- /* read the required data
- * we use a readpoiter to read from a different postion each
- * time */
- while( length-- ) {
- *buffer++ = keypool[pool_readpos++];
- if( pool_readpos >= POOLSIZE )
- pool_readpos = 0;
- pool_balance--;
+ mix_pool(keypool);
+ memcpy( buffer, keypool, length );
+ }
+ else {
+ /* mix the pool (if add_randomness() didn't it) */
+ if( !just_mixed )
+ mix_pool(rndpool);
+ /* create a new pool */
+ for(i=0,dp=(ulong*)keypool, sp=(ulong*)rndpool;
+ i < POOLWORDS; i++, dp++, sp++ )
+ *dp = *sp + ADD_VALUE;
+ /* and mix both pools */
+ mix_pool(rndpool);
+ mix_pool(keypool);
+ /* read the required data
+ * we use a readpoiter to read from a different postion each
+ * time */
+ while( length-- ) {
+ *buffer++ = keypool[pool_readpos++];
+ if( pool_readpos >= POOLSIZE )
+ pool_readpos = 0;
+ pool_balance--;
+ }
+ if( pool_balance < 0 )
+ pool_balance = 0;
+ /* and clear the keypool */
+ memset( keypool, 0, POOLSIZE );
}
- if( pool_balance < 0 )
- pool_balance = 0;
- /* and clear the keypool */
- memset( keypool, 0, POOLSIZE );
}
diff --git a/configure.in b/configure.in
index 37e0bc6b..005a1b5f 100644
--- a/configure.in
+++ b/configure.in
@@ -31,6 +31,10 @@ AC_ARG_ENABLE(dev-random,
[ --disable-dev-random disable the use of dev random],
try_dev_random=$enableval, try_dev_random=yes)
+AC_ARG_ENABLE(dynload,
+[ --disable-dynload disable dynamic loading],
+ try_dynload=$enableval, try_dynload=yes)
+
AC_MSG_CHECKING([whether memory debugging is requested])
AC_ARG_ENABLE(m-debug,
[ --enable-m-debug enable debugging of memory allocation],
@@ -114,18 +118,32 @@ AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME")
dnl Checks for libraries.
+
+if test "$try_dynload" = yes ; then
AC_CHECK_LIB(dl,dlopen)
if test "$ac_cv_lib_dl_dlopen" = "yes"; then
AC_DEFINE(USE_DYNAMIC_LINKING)
AC_DEFINE(HAVE_DL_DLOPEN)
+ DYNLINK_LDFLAGS=-rdynamic
+ use_gnupg_extensions=yes
else
AC_CHECK_LIB(dld,dld_link)
if test "$ac_cv_lib_dld_dld_link" = "yes"; then
AC_DEFINE(USE_DYNAMIC_LINKING)
AC_DEFINE(HAVE_DLD_DLD_LINK)
+ DYNLINK_LDFLAGS=-rdynamic
+ use_gnupg_extensions=yes
fi
fi
+else
+ AC_MSG_CHECKING(for dynamic loading)
+ DYNLINK_LDFLAGS=
+ use_gnupg_extensions=no
+ AC_MSG_RESULT(has been disabled)
+fi
+AM_CONDITIONAL(ENABLE_GNUPG_EXTENSIONS, test "$use_gnupg_extensions" = yes )
+AC_SUBST(DYNLINK_LDFLAGS)
dnl Checks for header files.
AC_HEADER_STDC
diff --git a/mpi/ChangeLog b/mpi/ChangeLog
index 15da105f..0519495c 100644
--- a/mpi/ChangeLog
+++ b/mpi/ChangeLog
@@ -1,3 +1,7 @@
+Thu Jun 25 11:50:01 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mips3/*.S: New
+
Mon May 18 13:47:06 1998 Werner Koch (wk@isil.d.shuttle.de)
* config.links: split mpih-shift into mpih-[lr]shift and
diff --git a/mpi/mips3/distfiles b/mpi/mips3/distfiles
new file mode 100644
index 00000000..b88f4f86
--- /dev/null
+++ b/mpi/mips3/distfiles
@@ -0,0 +1,9 @@
+README
+mpih-add1.S
+mpih-sub1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+
diff --git a/mpi/mips3/mpih-add1.S b/mpi/mips3/mpih-add1.S
new file mode 100644
index 00000000..7ac5f38b
--- /dev/null
+++ b/mpi/mips3/mpih-add1.S
@@ -0,0 +1,122 @@
+/* mips3 add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ * Copyright (C) 1995, 1998 Free Software Foundation, Inc.
+ *
+ * This file is part of GNUPG.
+ *
+ * GNUPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * mpihelp_add_n( mpi_ptr_t res_ptr, ($4)
+ * mpi_ptr_t s1_ptr, ($5)
+ * mpi_ptr_t s2_ptr, ($6)
+ * mpi_size_t size) ($7)
+ */
+
+ .text
+ .align 2
+ .globl mpihelp_add_n
+ .ent mpihelp_add_n
+mpihelp_add_n:
+ .set noreorder
+ .set nomacro
+
+ ld $10,0($5)
+ ld $11,0($6)
+
+ daddiu $7,$7,-1
+ and $9,$7,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ move $2,$0
+
+ dsubu $7,$7,$9
+
+.Loop0: daddiu $9,$9,-1
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,0($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,8
+ daddiu $6,$6,8
+ move $10,$12
+ move $11,$13
+ bne $9,$0,.Loop0
+ daddiu $4,$4,8
+
+.L0: beq $7,$0,.Lend
+ nop
+
+.Loop: daddiu $7,$7,-4
+
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,0($4)
+ or $2,$2,$8
+
+ ld $10,16($5)
+ daddu $13,$13,$2
+ ld $11,16($6)
+ sltu $8,$13,$2
+ daddu $13,$12,$13
+ sltu $2,$13,$12
+ sd $13,8($4)
+ or $2,$2,$8
+
+ ld $12,24($5)
+ daddu $11,$11,$2
+ ld $13,24($6)
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,16($4)
+ or $2,$2,$8
+
+ ld $10,32($5)
+ daddu $13,$13,$2
+ ld $11,32($6)
+ sltu $8,$13,$2
+ daddu $13,$12,$13
+ sltu $2,$13,$12
+ sd $13,24($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,32
+ daddiu $6,$6,32
+
+ bne $7,$0,.Loop
+ daddiu $4,$4,32
+
+.Lend: daddu $11,$11,$2
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,0($4)
+ j $31
+ or $2,$2,$8
+
+ .end mpihelp_add_n
+
diff --git a/mpi/mips3/mpih-lshift.S b/mpi/mips3/mpih-lshift.S
new file mode 100644
index 00000000..37e9a5e1
--- /dev/null
+++ b/mpi/mips3/mpih-lshift.S
@@ -0,0 +1,95 @@
+/* mips3 lshift
+ * Copyright (C) 1995, 1998 Free Software Foundation, Inc.
+ *
+ * This file is part of GNUPG.
+ *
+ * GNUPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*******************
+ * mpi_limb_t
+ * mpihelp_lshift( mpi_ptr_t wp, ($4)
+ * mpi_ptr_t up, ($5)
+ * mpi_size_t usize, ($6)
+ * unsigned cnt) ($7)
+ */
+
+ .text
+ .align 2
+ .globl mpihelp_lshift
+ .ent mpihelp_lshift
+mpihelp_lshift:
+ .set noreorder
+ .set nomacro
+
+ dsll $2,$6,3
+ daddu $5,$5,$2 # make r5 point at end of src
+ ld $10,-8($5) # load first limb
+ dsubu $13,$0,$7
+ daddu $4,$4,$2 # make r4 point at end of res
+ daddiu $6,$6,-1
+ and $9,$6,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ dsrl $2,$10,$13 # compute function result
+
+ dsubu $6,$6,$9
+
+.Loop0: ld $3,-16($5)
+ daddiu $4,$4,-8
+ daddiu $5,$5,-8
+ daddiu $9,$9,-1
+ dsll $11,$10,$7
+ dsrl $12,$3,$13
+ move $10,$3
+ or $8,$11,$12
+ bne $9,$0,.Loop0
+ sd $8,0($4)
+
+.L0: beq $6,$0,.Lend
+ nop
+
+.Loop: ld $3,-16($5)
+ daddiu $4,$4,-32
+ daddiu $6,$6,-4
+ dsll $11,$10,$7
+ dsrl $12,$3,$13
+
+ ld $10,-24($5)
+ dsll $14,$3,$7
+ or $8,$11,$12
+ sd $8,24($4)
+ dsrl $9,$10,$13
+
+ ld $3,-32($5)
+ dsll $11,$10,$7
+ or $8,$14,$9
+ sd $8,16($4)
+ dsrl $12,$3,$13
+
+ ld $10,-40($5)
+ dsll $14,$3,$7
+ or $8,$11,$12
+ sd $8,8($4)
+ dsrl $9,$10,$13
+
+ daddiu $5,$5,-32
+ or $8,$14,$9
+ bgtz $6,.Loop
+ sd $8,0($4)
+
+.Lend: dsll $8,$10,$7
+ j $31
+ sd $8,-8($4)
+ .end mpihelp_lshift
diff --git a/mpi/mips3/mpih-mul1.S b/mpi/mips3/mpih-mul1.S
new file mode 100644
index 00000000..fd349ee9
--- /dev/null
+++ b/mpi/mips3/mpih-mul1.S
@@ -0,0 +1,87 @@
+/* mips3 mpih-mul1.S -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ * Copyright (C) 1992, 1994, 1995, 1998 Free Software Foundation, Inc.
+ *
+ * This file is part of GNUPG.
+ *
+ * GNUPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * mpihelp_mul_1( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_size_t s1_size, (r6)
+ * mpi_limb_t s2_limb) (r7)
+ */
+
+ .text
+ .align 4
+ .globl mpihelp_mul_1
+ .ent mpihelp_mul_1
+mpihelp_mul_1:
+ .set noreorder
+ .set nomacro
+
+ # warm up phase 0
+ ld $8,0($5)
+
+ # warm up phase 1
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 # zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) # load new s1 limb as early as possible
+
+Loop: mflo $10
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $10,$10,$2 # add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) # load new s1 limb as early as possible
+ daddiu $6,$6,-1 # decrement loop counter
+ sltu $2,$10,$2 # carry from previous addition -> $2
+ sd $10,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ # cool down phase 1
+$LC1: mflo $10
+ mfhi $9
+ daddu $10,$10,$2
+ sltu $2,$10,$2
+ dmultu $8,$7
+ sd $10,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ # cool down phase 0
+$LC0: mflo $10
+ mfhi $9
+ daddu $10,$10,$2
+ sltu $2,$10,$2
+ sd $10,0($4)
+ j $31
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ .end mpihelp_mul_1
+
diff --git a/mpi/mips3/mpih-mul2.S b/mpi/mips3/mpih-mul2.S
new file mode 100644
index 00000000..1474b4f0
--- /dev/null
+++ b/mpi/mips3/mpih-mul2.S
@@ -0,0 +1,99 @@
+/* MIPS3 addmul_1 -- Multiply a limb vector with a single limb and
+ * add the product to a second limb vector.
+ * Copyright (C) 1992, 1994, 1995, 1998 Free Software Foundation, Inc.
+ *
+ * This file is part of GNUPG.
+ *
+ * GNUPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * mpihelp_addmul_1( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_size_t s1_size, (r6)
+ * mpi_limb_t s2_limb) (r7)
+ */
+
+ .text
+ .align 4
+ .globl mpihelp_addmul_1
+ .ent mpihelp_addmul_1
+mpihelp_addmul_1:
+ .set noreorder
+ .set nomacro
+
+ # warm up phase 0
+ ld $8,0($5)
+
+ # warm up phase 1
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 # zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) # load new s1 limb as early as possible
+
+Loop: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $3,$3,$2 # add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) # load new s1 limb as early as possible
+ daddiu $6,$6,-1 # decrement loop counter
+ sltu $2,$3,$2 # carry from previous addition -> $2
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ # cool down phase 1
+$LC1: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dmultu $8,$7
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ # cool down phase 0
+$LC0: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ j $31
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ .end mpihelp_addmul_1
+
diff --git a/mpi/mips3/mpih-mul3.S b/mpi/mips3/mpih-mul3.S
new file mode 100644
index 00000000..4616732f
--- /dev/null
+++ b/mpi/mips3/mpih-mul3.S
@@ -0,0 +1,99 @@
+/* MIPS3 submul_1 -- Multiply a limb vector with a single limb and
+ * subtract the product from a second limb vector.
+ * Copyright (C) 1992, 1994, 1995, 1998 Free Software Foundation, Inc.
+ *
+ * This file is part of GNUPG.
+ *
+ * GNUPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * mpihelp_submul_1( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_size_t s1_size, (r6)
+ * mpi_limb_t s2_limb) (r7)
+ */
+
+ .text
+ .align 4
+ .globl mpihelp_submul_1
+ .ent mpihelp_submul_1
+mpihelp_submul_1:
+ .set noreorder
+ .set nomacro
+
+ # warm up phase 0
+ ld $8,0($5)
+
+ # warm up phase 1
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 # zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) # load new s1 limb as early as possible
+
+Loop: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $3,$3,$2 # add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) # load new s1 limb as early as possible
+ daddiu $6,$6,-1 # decrement loop counter
+ sltu $2,$3,$2 # carry from previous addition -> $2
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ # cool down phase 1
+$LC1: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dmultu $8,$7
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ # cool down phase 0
+$LC0: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ j $31
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ .end mpihelp_submul_1
+
diff --git a/mpi/mips3/mpih-rshift.S b/mpi/mips3/mpih-rshift.S
new file mode 100644
index 00000000..7bc08450
--- /dev/null
+++ b/mpi/mips3/mpih-rshift.S
@@ -0,0 +1,93 @@
+/* mips3 rshift
+ * Copyright (C) 1995, 1998 Free Software Foundation, Inc.
+ *
+ * This file is part of GNUPG.
+ *
+ * GNUPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*******************
+ * mpi_limb_t
+ * mpihelp_rshift( mpi_ptr_t wp, ($4)
+ * mpi_ptr_t up, ($5)
+ * mpi_size_t usize, ($6)
+ * unsigned cnt) ($7)
+ */
+
+ .text
+ .align 2
+ .globl mpihelp_rshift
+ .ent mpihelp_rshift
+mpihelp_rshift:
+ .set noreorder
+ .set nomacro
+
+ ld $10,0($5) # load first limb
+ dsubu $13,$0,$7
+ daddiu $6,$6,-1
+ and $9,$6,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ dsll $2,$10,$13 # compute function result
+
+ dsubu $6,$6,$9
+
+.Loop0: ld $3,8($5)
+ daddiu $4,$4,8
+ daddiu $5,$5,8
+ daddiu $9,$9,-1
+ dsrl $11,$10,$7
+ dsll $12,$3,$13
+ move $10,$3
+ or $8,$11,$12
+ bne $9,$0,.Loop0
+ sd $8,-8($4)
+
+.L0: beq $6,$0,.Lend
+ nop
+
+.Loop: ld $3,8($5)
+ daddiu $4,$4,32
+ daddiu $6,$6,-4
+ dsrl $11,$10,$7
+ dsll $12,$3,$13
+
+ ld $10,16($5)
+ dsrl $14,$3,$7
+ or $8,$11,$12
+ sd $8,-32($4)
+ dsll $9,$10,$13
+
+ ld $3,24($5)
+ dsrl $11,$10,$7
+ or $8,$14,$9
+ sd $8,-24($4)
+ dsll $12,$3,$13
+
+ ld $10,32($5)
+ dsrl $14,$3,$7
+ or $8,$11,$12
+ sd $8,-16($4)
+ dsll $9,$10,$13
+
+ daddiu $5,$5,32
+ or $8,$14,$9
+ bgtz $6,.Loop
+ sd $8,-8($4)
+
+.Lend: dsrl $8,$10,$7
+ j $31
+ sd $8,0($4)
+ .end mpihelp_rshift
+
diff --git a/mpi/mips3/mpih-sub1.S b/mpi/mips3/mpih-sub1.S
new file mode 100644
index 00000000..f4ad4c99
--- /dev/null
+++ b/mpi/mips3/mpih-sub1.S
@@ -0,0 +1,123 @@
+/* mips3 sub_n -- Subtract two limb vectors of the same length > 0 and
+ * store difference in a third limb vector.
+ * Copyright (C) 1995, 1998 Free Software Foundation, Inc.
+ *
+ * This file is part of GNUPG.
+ *
+ * GNUPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * mpihelp_sub_n( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_ptr_t s2_ptr, (r6)
+ * mpi_size_t size) (r7)
+ */
+
+
+ .text
+ .align 2
+ .globl mpihelp_sub_n
+ .ent mpihelp_sub_n
+mpihelp_sub_n:
+ .set noreorder
+ .set nomacro
+
+ ld $10,0($5)
+ ld $11,0($6)
+
+ daddiu $7,$7,-1
+ and $9,$7,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ move $2,$0
+
+ dsubu $7,$7,$9
+
+.Loop0: daddiu $9,$9,-1
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,0($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,8
+ daddiu $6,$6,8
+ move $10,$12
+ move $11,$13
+ bne $9,$0,.Loop0
+ daddiu $4,$4,8
+
+.L0: beq $7,$0,.Lend
+ nop
+
+.Loop: daddiu $7,$7,-4
+
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,0($4)
+ or $2,$2,$8
+
+ ld $10,16($5)
+ daddu $13,$13,$2
+ ld $11,16($6)
+ sltu $8,$13,$2
+ dsubu $13,$12,$13
+ sltu $2,$12,$13
+ sd $13,8($4)
+ or $2,$2,$8
+
+ ld $12,24($5)
+ daddu $11,$11,$2
+ ld $13,24($6)
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,16($4)
+ or $2,$2,$8
+
+ ld $10,32($5)
+ daddu $13,$13,$2
+ ld $11,32($6)
+ sltu $8,$13,$2
+ dsubu $13,$12,$13
+ sltu $2,$12,$13
+ sd $13,24($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,32
+ daddiu $6,$6,32
+
+ bne $7,$0,.Loop
+ daddiu $4,$4,32
+
+.Lend: daddu $11,$11,$2
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,0($4)
+ j $31
+ or $2,$2,$8
+
+ .end mpihelp_sub_n
+ n