diff -u5prk.orig gnupg-1.2.1.orig/checks/encrypt_nush.test gnupg-1.2.1/checks/encrypt_nush.test
--- gnupg-1.2.1.orig/checks/encrypt_nush.test	1970-01-01 03:00:00 +0300
+++ gnupg-1.2.1/checks/encrypt_nush.test	2002-12-20 17:33:42 +0300
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+. $srcdir/defs.inc || exit 3
+
+#info Checking encryption with NUSH
+
+for ca in nush128 nush192 nush256 ; do
+  for i in $plain_files $data_files ; do
+    $GPG --always-trust -e -o x --yes -r "$usrname2" --cipher-algo $ca $i
+    $GPG -o y --yes x
+    cmp $i y || error "$i: mismatch"
+  done
+done
diff -u5prk.orig gnupg-1.2.1.orig/checks/encrypt_wicker.test gnupg-1.2.1/checks/encrypt_wicker.test
--- gnupg-1.2.1.orig/checks/encrypt_wicker.test	1970-01-01 03:00:00 +0300
+++ gnupg-1.2.1/checks/encrypt_wicker.test	2002-12-20 17:33:42 +0300
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+. $srcdir/defs.inc || exit 3
+
+#info Checking encryption with WICKER
+
+for i in $plain_files $data_files ; do
+    $GPG --always-trust -e -o x --yes -r "$usrname2" --cipher-algo wicker $i
+    $GPG -o y --yes x
+    cmp $i y || error "$i: mismatch"
+done
+
diff -u5prk.orig gnupg-1.2.1.orig/checks/genkey1024.test gnupg-1.2.1/checks/genkey1024.test
--- gnupg-1.2.1.orig/checks/genkey1024.test	2002-06-29 17:29:54 +0400
+++ gnupg-1.2.1/checks/genkey1024.test	2002-12-20 17:33:42 +0300
@@ -20,7 +20,15 @@ Name-Real: Harry A.
 Name-Comment: RSA test key 
 Name-Email: hh@@ddorf.de
 Expire-Date: 2
 Passphrase: abc
 %commit
+Key-Type: LANS
+Key-Length: 1024
+Name-Real: Harry H.
+Name-Comment: test key 
+Name-Email: hh@@ddorf.de
+Expire-Date: 3
+Passphrase: abc
+%commit
 EOF
 
diff -u5prk.orig gnupg-1.2.1.orig/checks/lanspubring.asc gnupg-1.2.1/checks/lanspubring.asc
--- gnupg-1.2.1.orig/checks/lanspubring.asc	1970-01-01 03:00:00 +0300
+++ gnupg-1.2.1/checks/lanspubring.asc	2002-12-20 17:33:42 +0300
@@ -0,0 +1,18 @@
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v1.2.1 (GNU/Linux)
+Comment: Use "gpg --dearmor" for unpacking
+
+mQGmBD4CwHFlBACxyDwtLXNJ+7nyq/MiCI1GenqcqCk+UTgMMRJg18EGtYlG52wX
+H3GkjizWhQuPKkNIPsV/MJr8RHuond+dS0qyMjpU+EtTFKsFhBlj+cIe7dAFsdA/
+ihKobbP7hvT0Pmp+iVS4z/unrrIXdKNq2xs8v1jg9dFRo/joy+1bj//E7wDAhUN7
+PWITxeJGl4F/ngkDlknsdTXoXLDjA/47gRHmfp08WC8Zb7o+SCm9PkfXxxzcOOem
+DYYRq8Kq5Bk5hBdNo9TrIPFELAV9q+t7R/SwzCB4tfe4vg2ekWXAJIHoDR4clqlM
+cH/l3cYGWQgAtdFj9r5pTidc2RSZWZnjPPcpkwZBCNA/Jk1XOvwTmM0hsJP1dnOX
+RDD3ZdEdlAP8DW8jE6mv9X+kAOMuNmEFW/pV78+CvsHxBfD2jnDiDzeDqDnuGal4
+coWCBVUJld5cnP4XMAzbolcBFARHeDcNCN3ltHoIuEfxGYeE5ZNKtcne9WdULUMf
+tDVVWiWEVZ2chooN5XPvkdRiAO72bfl9eThkluzYZ2j7dWQwASvtjPi0L2xhbmNy
+eXB0byAobGFuY3J5cHRvKSA8bGFuY3J5cHRvQGxhbmNyeXB0by5jb20+iFgEE2UC
+ABwFAj4CwHECGwMECwcDAgMVAgMDFgIBAh4BAheAAAoJEA+2cVHMqEEffjkAv1rs
+zoOGFGVe76SfHbJJrES00ve3PZ6lHwBgktZ3xIhLcl9Am2i5sAIAAA==
+=Nube
+-----END PGP ARMORED FILE-----
diff -u5prk.orig gnupg-1.2.1.orig/checks/lanssecring.asc gnupg-1.2.1/checks/lanssecring.asc
--- gnupg-1.2.1.orig/checks/lanssecring.asc	1970-01-01 03:00:00 +0300
+++ gnupg-1.2.1/checks/lanssecring.asc	2002-12-20 17:33:42 +0300
@@ -0,0 +1,19 @@
+-----BEGIN PGP ARMORED FILE-----
+Version: GnuPG v1.2.1 (GNU/Linux)
+Comment: Use "gpg --dearmor" for unpacking
+
+lQHDBD4CwHFlBACxyDwtLXNJ+7nyq/MiCI1GenqcqCk+UTgMMRJg18EGtYlG52wX
+H3GkjizWhQuPKkNIPsV/MJr8RHuond+dS0qyMjpU+EtTFKsFhBlj+cIe7dAFsdA/
+ihKobbP7hvT0Pmp+iVS4z/unrrIXdKNq2xs8v1jg9dFRo/joy+1bj//E7wDAhUN7
+PWITxeJGl4F/ngkDlknsdTXoXLDjA/47gRHmfp08WC8Zb7o+SCm9PkfXxxzcOOem
+DYYRq8Kq5Bk5hBdNo9TrIPFELAV9q+t7R/SwzCB4tfe4vg2ekWXAJIHoDR4clqlM
+cH/l3cYGWQgAtdFj9r5pTidc2RSZWZnjPPcpkwZBCNA/Jk1XOvwTmM0hsJP1dnOX
+RDD3ZdEdlAP8DW8jE6mv9X+kAOMuNmEFW/pV78+CvsHxBfD2jnDiDzeDqDnuGal4
+coWCBVUJld5cnP4XMAzbolcBFARHeDcNCN3ltHoIuEfxGYeE5ZNKtcne9WdULUMf
+tDVVWiWEVZ2chooN5XPvkdRiAO72bfl9eThkluzYZ2j7dWQwASvtjPgAAL471MVH
+EWZ12pWFIcBK0NkKK6LNQdB3lTcMhbQvbGFuY3J5cHRvIChsYW5jcnlwdG8pIDxs
+YW5jcnlwdG9AbGFuY3J5cHRvLmNvbT6IWAQTZQIAHAUCPgLAcQIbAwQLBwMCAxUC
+AwMWAgECHgECF4AACgkQD7ZxUcyoQR9+OQC+LzwhtkdqRGedJtw0aKYzWZfXM1XK
+WtB4AGD5xJ7xIYcyWHRoo36wAgAA
+=vBHF
+-----END PGP ARMORED FILE-----
diff -u5prk.orig gnupg-1.2.1.orig/checks/Makefile.am gnupg-1.2.1/checks/Makefile.am
--- gnupg-1.2.1.orig/checks/Makefile.am	2002-06-29 17:29:54 +0400
+++ gnupg-1.2.1/checks/Makefile.am	2002-12-20 17:33:42 +0300
@@ -18,13 +18,16 @@
 
 # Process this file with automake to create Makefile.in
 
 GPG_IMPORT  = ../g10/gpg --homedir . --quiet --yes --import
 
+TESTS_ENVIRONMENT = /bin/sh
+
 TESTS = version.test mds.test \
 	decrypt.test decrypt-dsa.test \
-	sigs.test sigs-dsa.test \
+	sigs.test sigs-dsa.test sigs-lans.test \
+	encrypt_wicker.test encrypt_nush.test \
 	encrypt.test encrypt-dsa.test  \
 	seat.test clearsig.test encryptp.test detach.test \
 	armsigs.test armencrypt.test armencryptp.test \
 	signencrypt.test signencrypt-dsa.test \
 	armsignencrypt.test armdetach.test \
@@ -33,30 +36,32 @@ TESTS = version.test mds.test \
 	multisig.test
 
 
 TEST_FILES = pubring.asc secring.asc plain-1o.asc plain-2o.asc plain-3o.asc \
 	     plain-1.asc plain-2.asc plain-3.asc plain-1-pgp.asc \
-	     pubring.pkr.asc secring.skr.asc secdemo.asc pubdemo.asc options.in
+	     pubring.pkr.asc secring.skr.asc lanspubring.asc lanssecring.asc secdemo.asc pubdemo.asc options.in
 
 DATA_FILES = data-500 data-9000 data-32000 data-80000 plain-large
 
 EXTRA_DIST = defs.inc $(TESTS) $(TEST_FILES) \
 	     mkdemodirs signdemokey
 CLEANFILES = prepared.stamp x y yy z out err  $(DATA_FILES) \
 	     plain-1 plain-2 plain-3 trustdb.gpg *.lock .\#lk* \
 	     *.test.log options gpg_dearmor \
-	     pubring.gpg secring.gpg pubring.pkr secring.skr
-DISTCLEANFILES = pubring.gpg~ random_seed
+	     pubring.gpg secring.gpg pubring.pkr secring.skr \
+	     lanspubring.gpg lanssecring.gpg
+DISTCLEANFILES = pubring.gpg~ lanspubring.gpg~ random_seed
 
 
 all-local: prepared.stamp
 
 distclean-local:
 	$(srcdir)/mkdemodirs --clean
 
 prepared.stamp: ./pubring.gpg ./secring.gpg ./plain-1 ./plain-2 ./plain-3 \
 		./pubring.pkr ./secring.skr ./options ./gpg_dearmor \
+		./lanspubring.gpg ./lanssecring.gpg \
 		$(DATA_FILES)
 	 $(GPG_IMPORT) $(srcdir)/pubdemo.asc	 
 	 echo timestamp >./prepared.stamp
 
 ./options: $(srcdir)/options.in
@@ -80,10 +85,16 @@ prepared.stamp: ./pubring.gpg ./secring.
 	./gpg_dearmor > ./pubring.pkr < $(srcdir)/pubring.pkr.asc
 
 ./secring.skr: $(srcdir)/secring.skr.asc ./gpg_dearmor
 	./gpg_dearmor > ./secring.skr < $(srcdir)/secring.skr.asc
 
+./lanspubring.gpg: $(srcdir)/lanspubring.asc ./gpg_dearmor
+	./gpg_dearmor > ./lanspubring.gpg < $(srcdir)/lanspubring.asc
+
+./lanssecring.gpg: $(srcdir)/lanssecring.asc ./gpg_dearmor
+	./gpg_dearmor > ./lanssecring.gpg < $(srcdir)/lanssecring.asc
+
 ./plain-1: $(srcdir)/plain-1o.asc ./gpg_dearmor
 	./gpg_dearmor > ./plain-1 < $(srcdir)/plain-1o.asc
 
 ./plain-2: $(srcdir)/plain-2o.asc ./gpg_dearmor
 	./gpg_dearmor > ./plain-2 < $(srcdir)/plain-2o.asc
diff -u5prk.orig gnupg-1.2.1.orig/checks/sigs-lans.test gnupg-1.2.1/checks/sigs-lans.test
--- gnupg-1.2.1.orig/checks/sigs-lans.test	1970-01-01 03:00:00 +0300
+++ gnupg-1.2.1/checks/sigs-lans.test	2002-12-20 17:33:42 +0300
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+. $srcdir/defs.inc || exit 3
+
+#info Checking LANS signature (default digest algo)
+
+lans_keyrings="--keyring ./lanspubring.gpg --secret-keyring ./lanssecring.gpg"
+
+for da in gas48 sha1 md5; do
+  for i in $plain_files; do
+     $GPG $lans_keyrings --digest-algo $da -u lancrypto -o x --yes -s $i
+     $GPG $lans_keyrings -o y --yes x
+     cmp $i y || error "$i: mismatch"
+     # process only the first one
+     break
+  done
+done
diff -u5prk.orig gnupg-1.2.1.orig/cipher/algorithms.h gnupg-1.2.1/cipher/algorithms.h
--- gnupg-1.2.1.orig/cipher/algorithms.h	2002-08-05 02:00:32 +0400
+++ gnupg-1.2.1/cipher/algorithms.h	2002-12-20 17:33:42 +0300
@@ -50,10 +50,21 @@ sha1_get_info (int algo, size_t *context
 	       void (**r_write)( void *c, byte *buf, size_t nbytes ),
 	       void (**r_final)( void *c ),
 	       byte *(**r_read)( void *c )
                );
 
+/* LAN Crypto algorithm GAS48 */
+
+const char *
+gas48_get_info (int algo, size_t *contextsize,
+	       byte **r_asnoid, int *r_asnlen, int *r_mdlen,
+	       void (**r_init)( void *c ),
+	       void (**r_write)( void *c, byte *buf, size_t nbytes ),
+	       void (**r_final)( void *c ),
+	       byte *(**r_read)( void *c )
+               );
+
 const char *
 tiger_get_info (int algo, size_t *contextsize,
                 byte **r_asnoid, int *r_asnlen, int *r_mdlen,
                 void (**r_init)( void *c ),
                 void (**r_write)( void *c, byte *buf, size_t nbytes ),
@@ -112,7 +123,27 @@ idea_get_info( int algo, size_t *keylen,
                void (**encryptf)( void *c, byte *outbuf, byte *inbuf ),
                void (**decryptf)( void *c, byte *outbuf, byte *inbuf )
                );
 
 
+/* LAN Crypto algorithm WICKER */
+
+const char *
+wicker_get_info( int algo, size_t *keylen,
+               size_t *blocksize, size_t *contextsize,
+               int	(**setkeyf)( void *c, byte *key, unsigned keylen ),
+               void (**encryptf)( void *c, byte *outbuf, byte *inbuf ),
+               void (**decryptf)( void *c, byte *outbuf, byte *inbuf )
+               );
+
+/* LAN Crypto algorithm NUSH */
+
+const char *
+nush_get_info( int algo, size_t *keylen,
+               size_t *blocksize, size_t *contextsize,
+               int	(**setkeyf)( void *c, byte *key, unsigned keylen ),
+               void (**encryptf)( void *c, byte *outbuf, byte *inbuf ),
+               void (**decryptf)( void *c, byte *outbuf, byte *inbuf )
+               );
+
 
 #endif /*GNUPG_ALGORITHMS_H*/
diff -u5prk.orig gnupg-1.2.1.orig/cipher/cipher.c gnupg-1.2.1/cipher/cipher.c
--- gnupg-1.2.1.orig/cipher/cipher.c	2002-09-10 12:41:44 +0400
+++ gnupg-1.2.1/cipher/cipher.c	2002-12-20 17:33:42 +0300
@@ -175,10 +175,62 @@ setup_cipher_table(void)
 					 &cipher_table[i].encrypt,
 					 &cipher_table[i].decrypt     );
     if (cipher_table[i].name)
       i++;  /* Note that IDEA is usually not available. */
 
+    /* LAN Crypto algorithm WICKER */
+
+    cipher_table[i].algo = CIPHER_ALGO_WICKER;
+    cipher_table[i].name = wicker_get_info( cipher_table[i].algo,
+					 &cipher_table[i].keylen,
+					 &cipher_table[i].blocksize,
+					 &cipher_table[i].contextsize,
+					 &cipher_table[i].setkey,
+					 &cipher_table[i].encrypt,
+					 &cipher_table[i].decrypt     );
+    if( !cipher_table[i].name )
+      BUG();
+    i++;
+
+    /* LAN Crypto algorithm NUSH */
+
+    cipher_table[i].algo = CIPHER_ALGO_NUSH128;
+    cipher_table[i].name = nush_get_info( cipher_table[i].algo,
+					 &cipher_table[i].keylen,
+					 &cipher_table[i].blocksize,
+					 &cipher_table[i].contextsize,
+					 &cipher_table[i].setkey,
+					 &cipher_table[i].encrypt,
+					 &cipher_table[i].decrypt     );
+    if( !cipher_table[i].name )
+      BUG();
+    i++;
+
+    cipher_table[i].algo = CIPHER_ALGO_NUSH192;
+    cipher_table[i].name = nush_get_info( cipher_table[i].algo,
+					 &cipher_table[i].keylen,
+					 &cipher_table[i].blocksize,
+					 &cipher_table[i].contextsize,
+					 &cipher_table[i].setkey,
+					 &cipher_table[i].encrypt,
+					 &cipher_table[i].decrypt     );
+    if( !cipher_table[i].name )
+      BUG();
+    i++;
+
+    cipher_table[i].algo = CIPHER_ALGO_NUSH256;
+    cipher_table[i].name = nush_get_info( cipher_table[i].algo,
+					 &cipher_table[i].keylen,
+					 &cipher_table[i].blocksize,
+					 &cipher_table[i].contextsize,
+					 &cipher_table[i].setkey,
+					 &cipher_table[i].encrypt,
+					 &cipher_table[i].decrypt     );
+    if( !cipher_table[i].name )
+      BUG();
+    i++;
+
 #ifdef ALLOW_DUMMY
     cipher_table[i].algo = CIPHER_ALGO_DUMMY;
     cipher_table[i].name = "DUMMY";
     cipher_table[i].blocksize = 8;
     cipher_table[i].keylen = 128;
diff -u5prk.orig gnupg-1.2.1.orig/cipher/gas48.c gnupg-1.2.1/cipher/gas48.c
--- gnupg-1.2.1.orig/cipher/gas48.c	1970-01-01 03:00:00 +0300
+++ gnupg-1.2.1/cipher/gas48.c	2002-12-20 17:33:42 +0300
@@ -0,0 +1,293 @@
+/* gas48.c - GAS48 hash function
+ *	Copyright (C) 2002 LAN Crypto (www.lancrypto.com)
+ *
+ * Please see below for more legal information!
+ *
+ * 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
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "util.h"
+#include "memory.h"
+#include "algorithms.h"
+#include "bithelp.h"
+#include "cipher.h"
+
+static const u32 P1 = 4107U;
+static const u32 P2 = 34821U;
+static const u32 PaddingS1 = 167U;
+static const u32 PaddingS2	= 137U;
+
+typedef struct {
+
+   u16  X[ 124 ];
+   u16  Y[ 62 ];
+   u16  U[ 3 ];
+   u16  W;
+   u16  V;
+   u16  R;
+   u16  end_u;
+   u16  start_u;
+   u16  flag;
+   u16  poshash;
+   byte block[ 60 ];
+	byte hash[ 48 ];
+	u32  hashlen;
+
+} GAS48_CONTEXT;
+
+
+static void
+gas48_init( GAS48_CONTEXT * hd )
+{
+   memset( hd->X, 0, sizeof( hd->X ) );
+   memset( hd->Y, 0, sizeof( hd->Y ) );
+   memset( hd->U, 0, sizeof( hd->U ) );
+   hd->W = 0;
+   hd->V = 0;
+   hd->R = 0;
+   hd->start_u	= 0;
+   hd->end_u = 1;
+   hd->flag = 0;
+   hd->poshash	= 0;
+   memset( hd->block, 0, sizeof( hd->block ) );	
+   memset( hd->hash, 0, sizeof( hd->hash ) );
+   hd->hashlen = 0;
+}
+
+
+static void 
+CalcX( GAS48_CONTEXT * hd, const byte * data, u16 c )
+{
+   if( c == 0 ) 
+      ( hd->X[ c ] )++;
+   else if ( c < 31 )
+      hd->X[ c ] = ( ( ( u16 )data[ 2 * c - 2 ] | ( ( u16 )data[ 2 * c - 1 ] << 8 ) ) ^ 
+                   hd->Y[ 61 - 39 + ( c - 1 ) ] ) + hd->X[ 123 - 29 + ( c - 1 ) ];
+   else 
+      hd->X[ c ] = hd->X[ c - 18 ] + hd->X[ c - 31 ];
+}
+
+
+static void 
+HashRoundStep1( GAS48_CONTEXT * hd, const byte * data, u16 cX, u16 cV )
+{
+   CalcX( hd, data, cX );
+   hd->V += hd->X[ cV ];
+   hd->W = ( ( hd->W >> 1 ) | ( hd->W << 15 ) ) + hd->X[ cX ];
+   hd->U[ hd->end_u++ ] = hd->V ^ hd->W;
+   hd->end_u %= 3;
+}
+
+
+static void 
+HashRoundStep2( GAS48_CONTEXT * hd, u16 cY, u16 cY1, u16 cY2 )
+{
+   hd->R = hd->U[ ( hd->start_u + 1 ) % 3 ] + ( hd->U[ hd->start_u ] >> 8 ) & 0xFF +
+           ( ( hd->U[ ( hd->start_u + 3 ) % 3 ] + ( hd->U[ ( hd->start_u + 1 ) % 3 ] >> 7 ) & 0xFF ) << 8 );
+   hd->start_u = ( hd->start_u + 2 ) % 3;
+   hd->Y[ cY ] = hd->R ^ ( hd->Y[ cY1 ] >> 1 ) ^ ( ( 0U - ( hd->Y[ cY1 ] & 0x01U ) ) & P2 ) ^
+                 ( hd->Y[ cY2 ] << 1 ) ^ ( ( 0U - ( hd->Y[ cY2 ] >> 15 ) ) & P1 );
+}
+
+
+static void 
+CalcHashFistRound( GAS48_CONTEXT * hd, const byte * data )
+{
+   int i;
+
+   hd->X[ 0 ] = 1;
+
+   for( i = 1; i < 20; i++ ) 
+      hd->X[ i ] = ( u16 )data[ 2 * ( i - 1 ) ] | ( ( u16 )data[ 2 * ( i - 1 ) + 1 ] << 8 );
+
+   for( i = 0; i < 52; i++ )
+   {
+      HashRoundStep1( hd, data, 20 + 2 * i, 2 * i );
+      HashRoundStep1( hd, data, 20 + 2 * i + 1, 2 * i + 1 );
+      HashRoundStep2( hd, i, ( 31 + i ) % 62, ( 59 + i ) % 62 );
+   }
+
+   hd->flag = 1;
+}
+
+
+static void 
+CalcHashNextRound( GAS48_CONTEXT * hd, const byte * data )
+{
+   int i;
+
+   for( i = 0; i < 62; i++ )
+   {
+   	HashRoundStep1( hd, data, 2 * i, ( 104 + 2 * i ) % 124 );
+   	HashRoundStep1( hd, data, 2 * i + 1, ( 104 + 2 * i + 1 ) % 124 );
+   	HashRoundStep2( hd, ( 52 + i ) % 62, ( 21 + i ) % 62, ( 49 + i ) % 62 );
+   }
+}
+
+
+static void
+gas48_write( GAS48_CONTEXT * hd, byte * inbuf, size_t inlen )
+{
+   int i;
+
+   if( !inlen )
+      return;
+	
+   hd->hashlen += inlen;
+
+   if( hd->poshash )
+   {
+      if( inlen + hd->poshash < 60 )
+      {
+         memcpy( &hd->block[ hd->poshash ], inbuf, inlen );
+         hd->poshash += inlen;
+         return;
+      }
+
+      i = 60 - hd->poshash;
+      memcpy( &hd->block[ hd->poshash ], inbuf, i );
+      inlen -= i;
+      inbuf += i;
+
+      if( hd->flag ) 
+         CalcHashNextRound( hd, hd->block );
+      else       		 
+         CalcHashFistRound( hd, hd->block );
+
+      hd->poshash = 0;
+   }
+
+   while( inlen >= 60 )
+   {
+      if( hd->flag ) 
+         CalcHashNextRound( hd, inbuf );
+      else       		 
+         CalcHashFistRound( hd, inbuf );
+
+      inlen -= 60;
+      inbuf += 60;
+   }
+
+   if( inlen != 0 ) 
+	{
+      hd->poshash = inlen;
+      memcpy( hd->block, inbuf, inlen );
+	}
+}
+
+
+static void
+gas48_final( GAS48_CONTEXT * hd )
+{
+   int i, j;
+
+   hd->block[ hd->poshash++ ] = PaddingS1;
+
+   if( hd->poshash == 60 )
+   {
+      if( hd->flag ) 
+         CalcHashNextRound( hd, hd->block );
+      else			 
+         CalcHashFistRound( hd, hd->block );
+
+      hd->poshash = 0;
+   }
+
+   hd->block[ hd->poshash++ ] = PaddingS2;
+
+   for( i = hd->poshash; i < 60; i++ ) 
+      hd->block[ i ] = 0;
+
+   if( hd->poshash > 2 )
+   {
+      for( i = hd->poshash + 54, j = 0; j < 4 && i < 60; i++, j++ )
+         hd->block[ i ] = ( byte )( hd->hashlen >> ( 8 * j ) );
+
+      if( hd->flag ) 
+         CalcHashNextRound( hd, hd->block );
+      else			 
+         CalcHashFistRound( hd, hd->block );
+
+      for( i = 0; j < 4 && i < 60; i++, j++ )
+         hd->block[ i ] = ( byte )( hd->hashlen >> ( 8 * j ) );
+
+      for( ; i < 60; i++ ) 
+         hd->block[ i ] = 0;
+   } 
+   else 
+   {
+      for( i = hd->poshash + 54, j = 0; j < 4; i++, j++ )
+         hd->block[ i ] = ( byte )( hd->hashlen >> ( 8 * j ) );
+   }
+
+   if( hd->flag ) 
+      CalcHashNextRound( hd, hd->block );
+   else			 
+      CalcHashFistRound( hd, hd->block );
+
+   hd->poshash = 0;
+
+   for( i = 47, j = 51; i >= 0 ; j-- )
+   {
+      hd->hash[ i-- ] = ( byte )( hd->Y[ j ] >> 8 );
+      if( i < 0 ) 
+         break;
+      hd->hash[ i-- ] = ( byte )hd->Y[ j ];
+   }
+}
+
+
+static byte *
+gas48_read( GAS48_CONTEXT * hd )
+{
+    return hd->hash;
+}
+
+
+const char *
+gas48_get_info( int algo, 
+                size_t * contextsize,
+	             byte ** r_asnoid, 
+                int * r_asnlen, 
+                int * r_mdlen,
+	             void ( ** r_init )( void * c ),
+	             void ( ** r_write )( void * c, byte * buf, size_t nbytes ),
+        	       void ( ** r_final )( void * c ),
+	             byte * ( * *r_read )( void * c ) )
+{
+   static byte asn[ 19 ] = 
+	{ 0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xA6, 0x41, 0x03, 0x04, 0x05, 0x00, 0x04, 0x30 };
+
+   if( algo != DIGEST_ALGO_GAS48 )
+	   return NULL;
+
+    *contextsize = sizeof( GAS48_CONTEXT );
+    *r_asnoid    = asn;
+    *r_asnlen    = 19;
+    *r_mdlen     = 48;
+    *( void   (**)( GAS48_CONTEXT * ) )r_init                  = gas48_init;
+    *( void   (**)( GAS48_CONTEXT *, byte *, size_t ) )r_write = gas48_write;
+    *( void   (**)( GAS48_CONTEXT * ) )r_final		            = gas48_final;
+    *( byte * (**)( GAS48_CONTEXT * ) )r_read 		            = gas48_read;
+
+    return "GAS48";
+}
diff -u5prk.orig gnupg-1.2.1.orig/cipher/lans.c gnupg-1.2.1/cipher/lans.c
--- gnupg-1.2.1.orig/cipher/lans.c	1970-01-01 03:00:00 +0300
+++ gnupg-1.2.1/cipher/lans.c	2002-12-20 17:33:42 +0300
@@ -0,0 +1,554 @@
+/* lans.c  - LANS signature algorithm
+ *	Copyright (C) 1998-2002 LAN Crypto (www.lancrypto.com)
+ *
+ * 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
+ */
+
+/* Description
+ * ===========
+ * LANS is a signature algorithm from DSA family with short signature
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "util.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "lans.h"
+
+
+// Debug and selftest
+
+//#define LANS_DEBUG
+//#define LANS_SELFTEST
+
+#if defined( LANS_DEBUG ) || defined( LANS_SELFTEST )
+
+static void 
+print_bin( MPI m )
+{
+	unsigned n;
+   byte * p = mpi_get_buffer( m, &n, NULL );
+   int i;
+   for( i = 0; i < n; i++ )
+      printf( "%02x ", p[ i ] );
+   printf( "\n" );
+	m_free( p );
+}
+
+#endif
+
+
+// LANS algorithm
+
+typedef struct {
+
+   MPI p;	    // prime
+   MPI q;	    // group order
+   MPI a;	    // group generator
+   MPI y;	    // a^x mod p
+
+} LANS_public_key;
+
+typedef struct {
+
+    MPI p;	    // prime
+    MPI q;	    // group order
+    MPI a;	    // group generator
+    MPI y;	    // a^x mod p
+    MPI x;	    // secret exponent
+
+} LANS_secret_key;
+
+
+static const byte P_1024[ 128 ] = {
+	0xB1, 0xC8, 0x3C, 0x2D, 0x2D, 0x73, 0x49, 0xFB, 
+	0xB9, 0xF2, 0xAB, 0xF3, 0x22, 0x08, 0x8D, 0x46, 
+	0x7A, 0x7A, 0x9C, 0xA8, 0x29, 0x3E, 0x51, 0x38, 
+	0x0C, 0x31, 0x12, 0x60, 0xD7, 0xC1, 0x06, 0xB5, 
+	0x89, 0x46, 0xE7, 0x6C, 0x17, 0x1F, 0x71, 0xA4, 
+	0x8E, 0x2C, 0xD6, 0x85, 0x0B, 0x8F, 0x2A, 0x43, 
+	0x48, 0x3E, 0xC5, 0x7F, 0x30, 0x9A, 0xFC, 0x44, 
+	0x7B, 0xA8, 0x9D, 0xDF, 0x9D, 0x4B, 0x4A, 0xB2, 
+	0x32, 0x3A, 0x54, 0xF8, 0x4B, 0x53, 0x14, 0xAB, 
+	0x05, 0x84, 0x19, 0x63, 0xF9, 0xC2, 0x1E, 0xED, 
+	0xD0, 0x05, 0xB1, 0xD0, 0x3F, 0x8A, 0x12, 0xA8, 
+	0x6D, 0xB3, 0xFB, 0x86, 0xF4, 0xF4, 0x3E, 0x6A, 
+	0x7E, 0x89, 0x54, 0xB8, 0xCF, 0xFB, 0xA7, 0xAE, 
+	0xB2, 0x17, 0x74, 0xA3, 0x6A, 0xDB, 0x1B, 0x3C, 
+	0xBF, 0x58, 0xE0, 0xF5, 0xD1, 0x51, 0xA3, 0xF8, 
+	0xE8, 0xCB, 0xED, 0x5B, 0x8F, 0xFF, 0xC4, 0xEF  
+}; 
+
+static const byte Q_1024[ 24 ] = {
+	0x85, 0x43, 0x7B, 0x3D, 0x62, 0x13, 0xC5, 0xE2, 
+	0x46, 0x97, 0x81, 0x7F, 0x9E, 0x09, 0x03, 0x96, 
+	0x49, 0xEC, 0x75, 0x35, 0xE8, 0x5C, 0xB0, 0xE3  
+}; 
+
+static const byte A_1024[ 128 ] = {
+	0x3B, 0x81, 0x11, 0xE6, 0x7E, 0x9D, 0x3C, 0x58, 
+	0x2F, 0x19, 0x6F, 0xBA, 0x3E, 0x48, 0x29, 0xBD, 
+	0x3E, 0x47, 0xD7, 0xC7, 0x1C, 0xDC, 0x38, 0xE7, 
+	0xA6, 0x0D, 0x86, 0x11, 0xAB, 0xC2, 0xAA, 0xE4, 
+	0x19, 0x39, 0x84, 0x17, 0x4D, 0xA3, 0xD4, 0xEB, 
+	0x20, 0xF1, 0x44, 0x2C, 0x05, 0x7D, 0xAB, 0xEB, 
+	0x7B, 0x47, 0xF4, 0xB0, 0xCC, 0x20, 0x78, 0xB5, 
+	0xF7, 0xB8, 0xBE, 0x0D, 0x9E, 0x91, 0x65, 0xC0, 
+	0x24, 0x81, 0xE8, 0x0D, 0x1E, 0x1C, 0x96, 0xA9, 
+	0x4C, 0x70, 0x7F, 0xE5, 0xDD, 0xC6, 0x06, 0x59, 
+	0x08, 0x00, 0xB5, 0xD1, 0x63, 0xF6, 0xBE, 0x69, 
+	0x4E, 0x27, 0x5C, 0xD9, 0x14, 0x99, 0x59, 0x99, 
+	0xE3, 0x3C, 0xF7, 0x29, 0x93, 0x06, 0x41, 0x08, 
+	0xD0, 0x3F, 0x26, 0x4D, 0x57, 0x3A, 0xFC, 0x13, 
+	0x98, 0xCD, 0x21, 0xB0, 0x93, 0xF5, 0x76, 0x73, 
+	0x97, 0x44, 0x30, 0xF7, 0x65, 0xD1, 0x1D, 0x94  
+};
+
+
+static void
+_lans_gen_random( MPI x, MPI q, int seclevel )
+{
+   u32 qbits = mpi_get_nbits( q );
+
+   // random 0 < x < q
+
+   do 
+   {
+      byte * r = get_random_bits( qbits, seclevel, 1 );
+	   mpi_set_buffer( x, r, qbits / 8, 0 );
+      m_free( r );
+
+	   mpi_fdiv_r( x, x, q );
+
+   } while( !mpi_cmp_ui( x, 0 ) );
+}
+
+
+static void
+_lans_generate( LANS_secret_key * sk, unsigned nbits, MPI ** ret_factors )
+{
+   MPI p = mpi_alloc( 0 );     // the prime
+   MPI q = mpi_alloc( 0 );     // the 160 bit prime factor
+   MPI a = mpi_alloc( 0 );     // the generator
+   MPI x = mpi_alloc( 0 );     // the secret exponent
+   MPI y;                      // a^x mod p
+
+   assert( nbits == 1024 );
+
+   // apq parameters
+
+   mpi_set_buffer( p, P_1024, sizeof( P_1024 ), 0 );
+   mpi_set_buffer( q, Q_1024, sizeof( Q_1024 ), 0 );
+   mpi_set_buffer( a, A_1024, sizeof( A_1024 ), 0 );
+
+   // private key 0 < x < q
+
+   _lans_gen_random( x, q, 2 );
+
+   // public key y = a ^ x mod p
+
+   y = mpi_alloc( mpi_get_nlimbs( p ) );
+   mpi_powm( y, a, x, p );
+
+   sk->p = p;
+   sk->q = q;
+   sk->a = a;
+   sk->y = y;
+   sk->x = x;
+
+#ifdef LANS_SELFTEST
+	printf( "\n_lans_generate p = ");
+   print_bin( sk->p );
+	printf( "\n_lans_generate q = ");
+   print_bin( sk->q );
+	printf( "\n_lans_generate a = ");
+   print_bin( sk->a );
+	printf( "\n_lans_generate x = ");
+   print_bin( sk->x );
+   printf( "\n_lans_generate y = ");
+   print_bin( sk->y );
+#endif
+}
+
+
+static int
+_lans_check_secret_key( LANS_secret_key * sk )
+{
+   int res;
+   MPI y = mpi_alloc( mpi_get_nlimbs( sk->y ) );
+   mpi_powm( y, sk->a, sk->x, sk->p );
+   res = !mpi_cmp( y, sk->y );
+   mpi_free( y );
+   return res;
+}
+
+
+static void
+_lans_hash( MPI res, MPI h1, MPI h2, int nbytes )
+{
+   MD_HANDLE md;
+   int       hashalgo = DIGEST_ALGO_GAS48;
+   byte *    hash;
+	unsigned  nh1;
+   byte *    ph1 = mpi_get_buffer( h1, &nh1, NULL );
+	unsigned  nh2;
+   byte *    ph2 = mpi_get_buffer( h2, &nh2, NULL );
+
+   assert( ph1 && ph2 );
+
+   if( ph1 && ph2 )
+   {
+      md = md_open( hashalgo, 0 );
+      md_write( md, ph1, nh1 );
+      md_write( md, ph2, nh2 );
+      md_final( md );
+
+      hash = md_read( md, hashalgo );
+      assert( hash );
+
+      if( hash )
+		{
+         assert( nbytes <= md_digest_length( hashalgo ) );
+         mpi_set_buffer( res, hash, nbytes, 0 );
+		}
+
+      md_close( md );
+      m_free( ph1 );
+      m_free( ph2 );
+   }
+}
+
+
+static void
+_lans_sign( MPI r, MPI s, MPI hash, LANS_secret_key * sk )
+{
+   MPI k = mpi_alloc( 0 );
+   MPI t = mpi_alloc( 0 );
+
+   do
+   {
+      // select random 0 < k < q
+
+      _lans_gen_random( k, sk->q, 1 );
+
+     // s = _lans_hash( hash, a ^ k mod p, sizeof( q ) / 2 )
+
+      mpi_powm( t, sk->a, k, sk->p );
+      
+		_lans_hash( s, hash, t, mpi_get_nbits( sk->q ) / 16 );
+
+	} while( !mpi_cmp_ui( s, 0 ) );
+
+   mpi_free( t );
+
+   // r = k - x * s mod q
+
+   t = mpi_alloc( mpi_get_nlimbs( sk->p ) ); 
+	mpi_mulm( t, sk->x, s, sk->q );
+	mpi_subm( r, k, t, sk->q );
+
+#ifdef LANS_SELFTEST
+	printf( "\n_lans_sign p = ");
+   print_bin( sk->p );
+	printf( "\n_lans_sign q = ");
+   print_bin( sk->q );
+	printf( "\n_lans_sign a = ");
+   print_bin( sk->a );
+	printf( "\n_lans_sign x = ");
+   print_bin( sk->x );
+   printf( "\n_lans_sign y = ");
+   print_bin( sk->y );
+   printf( "\n_lans_sign r = ");
+   print_bin( r );
+   printf( "\n_lans_sign s = ");
+   print_bin( s );
+   printf( "\n_lans_sign hash = ");
+   print_bin( hash );
+   printf( "\n_lans_sign k = ");
+   print_bin( k );
+   printf( "\n_lans_sign t = ");
+   print_bin( t );
+#endif
+
+   mpi_free( t );
+   mpi_free( k );
+}
+
+
+static int
+_lans_verify( MPI r, MPI s, MPI hash, LANS_public_key * pk )
+{
+   int res;
+   MPI h = mpi_alloc( 0 );
+   MPI t;
+   MPI base[ 3 ];
+   MPI exp[ 3 ];
+
+   if( mpi_cmp_ui( s, 0 ) <= 0 ||
+		 mpi_cmp_ui( r, 0 ) <= 0 || 
+		 mpi_cmp( r, pk->q ) >= 0 )
+
+	   return 0; // 0 < s, 0 < r < q
+
+	base[ 0 ] = pk->a; exp[ 0 ] = r;
+   base[ 1 ] = pk->y; exp[ 1 ] = s;
+   base[ 2 ] = NULL;  exp[ 2 ] = NULL;
+
+	t  = mpi_alloc( mpi_get_nlimbs( pk->p ) );
+   mpi_mulpowm( t, base, exp, pk->p );
+ 
+   _lans_hash( h, hash, t, mpi_get_nbits( pk->q ) / 16 );
+
+   res = !mpi_cmp( h, s );
+
+#ifdef LANS_SELFTEST
+	printf( "\n_lans_verify p = ");
+   print_bin( pk->p );
+	printf( "\n_lans_verify q = ");
+   print_bin( pk->q );
+	printf( "\n_lans_verify a = ");
+   print_bin( pk->a );
+   printf( "\n_lans_verify y = ");
+   print_bin( pk->y );
+   printf( "\n_lans_verify r = ");
+   print_bin( r );
+   printf( "\n_lans_verify s = ");
+   print_bin( s );
+   printf( "\n_lans_verify hash = ");
+   print_bin( hash );
+   printf( "\n_lans_verify h = ");
+   print_bin( h );
+   printf( "\n_lans_verify t = ");
+   print_bin( t );
+   printf( "\n_lans_verify res = %d\n", res );
+#endif
+
+   mpi_free( t );
+   mpi_free( h );
+
+   return res;
+}
+
+
+// Interface functions
+
+int
+lans_generate( int algo, unsigned nbits, MPI * skey, MPI ** retfactors )
+{
+   LANS_secret_key sk;
+
+#ifdef LANS_DEBUG
+   printf( "\nlans_generate\n");
+#endif
+
+   if( algo != PUBKEY_ALGO_LANS )
+	   return G10ERR_PUBKEY_ALGO;
+
+   _lans_generate( &sk, nbits, retfactors );
+
+   skey[ 0 ] = sk.p;
+   skey[ 1 ] = sk.q;
+   skey[ 2 ] = sk.a;
+   skey[ 3 ] = sk.y;
+   skey[ 4 ] = sk.x;
+
+   return 0;
+}
+
+
+int
+lans_check_secret_key( int algo, MPI * skey )
+{
+   LANS_secret_key sk;
+
+#ifdef LANS_DEBUG
+   printf( "\nlans_check_secret_key\n");
+#endif
+
+   if( algo != PUBKEY_ALGO_LANS )
+	   return G10ERR_PUBKEY_ALGO;
+
+   if( !skey[ 0 ] || !skey[ 1 ] || !skey[ 2 ] || !skey[ 3 ] || !skey[ 4 ] )
+	   return G10ERR_BAD_MPI;
+
+   sk.p = skey[ 0 ];
+   sk.q = skey[ 1 ];
+   sk.a = skey[ 2 ];
+   sk.y = skey[ 3 ];
+   sk.x = skey[ 4 ];
+
+   if( !_lans_check_secret_key( &sk ) )
+	   return G10ERR_BAD_SECKEY;
+
+   return 0;
+}
+
+
+int
+lans_sign( int algo, MPI * resarr, MPI data, MPI * skey )
+{
+   LANS_secret_key sk;
+
+#ifdef LANS_DEBUG
+   printf( "\nlans_sign\n");
+#endif
+
+   if( !data || !skey[ 0 ] || !skey[ 1 ] || !skey[ 2 ] || !skey[ 3 ] || !skey[ 4 ] )
+	   return G10ERR_BAD_MPI;
+
+   sk.p = skey[ 0 ];
+   sk.q = skey[ 1 ];
+   sk.a = skey[ 2 ];
+   sk.y = skey[ 3 ];
+   sk.x = skey[ 4 ];
+
+   resarr[ 0 ] = mpi_alloc( mpi_get_nlimbs( sk.q ) );
+   resarr[ 1 ] = mpi_alloc( mpi_get_nlimbs( sk.q ) / 2 );
+    
+	_lans_sign( resarr[ 0 ], resarr[ 1 ], data, &sk );
+
+   return 0;
+}
+
+
+int
+lans_verify( int algo, MPI hash, MPI * data, MPI * pkey, int ( * cmp )( void *, MPI ), void * opaquev )
+{
+   LANS_public_key pk;
+   int res = 0;
+
+#ifdef LANS_DEBUG
+   printf( "\nlans_verify\n");
+#endif
+
+   if( !data[ 0 ] || !data[ 1 ] || !hash || !pkey[ 0 ] || !pkey[ 1 ] || !pkey[ 2 ] || !pkey[ 3 ] )
+	   return G10ERR_BAD_MPI;
+
+   pk.p = pkey[ 0 ];
+   pk.q = pkey[ 1 ];
+   pk.a = pkey[ 2 ];
+   pk.y = pkey[ 3 ];
+
+   if( !_lans_verify( data[ 0 ], data[ 1 ], hash, &pk ) )
+	   res = G10ERR_BAD_SIGN;
+
+   return res;
+}
+
+
+unsigned
+lans_get_nbits( int algo, MPI * pkey )
+{
+#ifdef LANS_DEBUG
+   printf( "\nlans_get_nbits\n");
+#endif
+
+   if( algo != PUBKEY_ALGO_LANS )
+	   return 0;
+
+   return mpi_get_nbits( pkey[ 0 ] );
+}
+
+// Selftest
+
+#ifdef LANS_SELFTEST
+
+static void
+lans_selftest( void )
+{
+   MPI * sk   = m_alloc_secure_clear( 5 * sizeof( MPI ) );
+   MPI * sign = m_alloc_clear( 2 * sizeof( MPI ) );
+   MPI   hash = mpi_alloc( 0 );
+   int   res;
+   int   i;
+
+   mpi_set_buffer( hash, "12345678901234567890", 20, 0 );
+
+   res = lans_generate( PUBKEY_ALGO_LANS, 1024, sk, NULL );
+   if( res )
+	{
+      printf( "\nLANS selftest failed to generate keys\n" );
+      return;
+	}
+
+   res = lans_check_secret_key( PUBKEY_ALGO_LANS, sk );
+   if( res )
+	{
+      printf( "\nLANS selftest failed to check keys\n" );
+      return;
+	}
+
+   res = lans_sign( DIGEST_ALGO_SHA1, sign, hash, sk );
+   if( res )
+	{
+      printf( "\nLANS selftest failed to create signature\n" );
+      return;
+	}
+
+   res = lans_verify( DIGEST_ALGO_SHA1, hash, sign, sk, NULL, NULL );
+   if( res )
+	{
+      printf( "\nLANS selftest failed to verify siganture\n" );
+      return;
+	}
+
+   mpi_free( hash );
+
+   for( i = 0; i < 5; i++ )
+      mpi_free( sk[ i ] );
+
+   for( i = 0; i < 2; i++ )
+      mpi_free( sign[ i ] );
+
+   m_free( sk );
+   m_free( sign );
+
+	printf( "\nLANS selftest passed\n" );
+}
+
+#endif
+
+
+// Return information about the algorithm
+
+const char *
+lans_get_info( int algo, int * npkey, int * nskey, int * nenc, int * nsig, int * use )
+{
+#ifdef LANS_DEBUG
+   printf( "\nlans_get_info\n");
+#endif
+#ifdef LANS_SELFTEST
+	lans_selftest();
+#endif
+
+   if( algo == PUBKEY_ALGO_LANS )
+	{
+      *npkey = 4;
+      *nskey = 5;
+      *nenc  = 0;
+      *nsig  = 2;
+      *use   = PUBKEY_USAGE_SIG; 
+
+      return "LANS";
+   }
+
+   return NULL;
+}
diff -u5prk.orig gnupg-1.2.1.orig/cipher/lans.h gnupg-1.2.1/cipher/lans.h
--- gnupg-1.2.1.orig/cipher/lans.h	1970-01-01 03:00:00 +0300
+++ gnupg-1.2.1/cipher/lans.h	2002-12-20 17:33:42 +0300
@@ -0,0 +1,31 @@
+/* lans.h  - LANS signature algorithm
+ *	Copyright (C) 1998-2002 LAN Crypto (www.lancrypto.com)
+ *
+ * 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
+ */
+
+#ifndef LANS_H
+#define LANS_H
+
+int lans_generate( int algo, unsigned nbits, MPI * skey, MPI ** retfactors );
+int lans_check_secret_key( int algo, MPI * skey );
+int lans_sign( int algo, MPI * resarr, MPI data, MPI * skey );
+int lans_verify( int algo, MPI hash, MPI * data, MPI * pkey, int ( * cmp )( void *, MPI ), void * opaquev );
+unsigned lans_get_nbits( int algo, MPI * pkey );
+const char * lans_get_info( int algo, int * npkey, int * nskey, int * nenc, int * nsig, int * use );
+
+#endif // LANS_H
diff -u5prk.orig gnupg-1.2.1.orig/cipher/Makefile.am gnupg-1.2.1/cipher/Makefile.am
--- gnupg-1.2.1.orig/cipher/Makefile.am	2002-08-08 23:41:30 +0400
+++ gnupg-1.2.1/cipher/Makefile.am	2002-12-20 17:33:42 +0300
@@ -49,11 +49,16 @@ libcipher_a_SOURCES = cipher.c	\
 		 rndunix.c 	\
 		 rndegd.c  	\
 		 rndw32.c  	\
 		 md5.c     	\
 		 rmd160.c  	\
-		 sha1.c
+		 sha1.c		\
+		 gas48.c        \
+		 wicker.c       \
+		 nush.c         \
+		 lans.h         \
+		 lans.c
 
 EXTRA_libcipher_a_SOURCES = idea-stub.c tiger.c
 
 libcipher_a_DEPENDENCIES = @IDEA_O@ @TIGER_O@
 libcipher_a_LIBADD = @IDEA_O@ @TIGER_O@
diff -u5prk.orig gnupg-1.2.1.orig/cipher/md.c gnupg-1.2.1/cipher/md.c
--- gnupg-1.2.1.orig/cipher/md.c	2002-08-08 23:41:30 +0400
+++ gnupg-1.2.1/cipher/md.c	2002-12-20 17:33:42 +0300
@@ -103,10 +103,12 @@ load_digest_module (void)
     BUG ();
   if (!new_list_item (DIGEST_ALGO_RMD160, rmd160_get_info)) 
     BUG ();
   if (!new_list_item (DIGEST_ALGO_SHA1, sha1_get_info)) 
     BUG ();
+  if (!new_list_item (DIGEST_ALGO_GAS48, gas48_get_info)) 
+    BUG ();
 
   return 1;
 }      
 
 
diff -u5prk.orig gnupg-1.2.1.orig/cipher/nush.c gnupg-1.2.1/cipher/nush.c
--- gnupg-1.2.1.orig/cipher/nush.c	1970-01-01 03:00:00 +0300
+++ gnupg-1.2.1/cipher/nush.c	2002-12-20 17:33:42 +0300
@@ -0,0 +1,585 @@
+/* nush.c - NUSH encryption/decryption algorithm
+ *	Copyright (C) 1998-2002 LAN Crypto (www.lancrypto.com)
+ *
+ * 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
+ */
+
+/* Description
+ * ===========
+ * key length   = 256 bit
+ * block length = 128 bit
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "types.h"
+#include "errors.h"
+#include "algorithms.h"
+#include "cipher.h"
+
+// Debug and selftest
+
+//#define NUSH_DEBUG
+//#define NUSH_SELFTEST
+
+#define NUSH_TEST_KEY_256          "12345678901234567890123456789012"
+#define NUSH_TEST_PLAIN_256        "1234567890123456"
+#define NUSH_TEST_CIPHER_256       "\x96\x7e\x84\x87\xc1\xef\x62\xe8\xba\x46\x8c\x92\xd1\x45\xb3\xcc"
+
+// NUSH algorithm
+
+#define NUSH_KEY_SIZE_128           16
+#define NUSH_KEY_SIZE_192           24
+#define NUSH_KEY_SIZE_256           32
+#define NUSH_BLOCK_SIZE             16
+#define NUSH_L                      (17*4)
+
+#define ROTR32( p, t )                             (((p)>>(t))|((p)<<(32-(t))))
+#define ROTL32( p, t )                             (((p)<<(t))|((p)>>(32-(t))))
+#define Iter_OR( a1, b1, c1, d1, k, r, s, i )      c1=(c1^(k[i]+r[i]))+ b1;if(s[i])c1=ROTR32(c1,s[i]);a1+=(c1|d1);
+#define Iter_AND( a1, b1, c1, d1, k, r, s, i )     c1=(c1^(k[i]+r[i]))+b1;if(s[i])c1=ROTR32(c1,s[i]);a1+=(c1&d1);
+#define Iter_OR_1( a1, b1, c1, d1, k, r, s, i )    a1-=(c1|d1);if(s[i])c1=ROTL32(c1,s[i]);c1=(c1-b1)^(k[i]+r[i]);
+#define Iter_AND_1( a1, b1, c1, d1, k, r, s, i )   a1-=(c1&d1);if(s[i])c1=ROTL32(c1,s[i]);c1=(c1-b1)^(k[i]+r[i]);
+
+#ifdef BIG_ENDIAN_HOST
+#define U32TOBYTES( u, b )          b[0]=((byte*)&u)[0];b[1]=((byte*)&u)[1];b[2]=((byte*)&u)[2];b[3]=((byte*)&u)[3];
+#else
+#define U32TOBYTES( u, b )          b[0]=((byte*)&u)[3];b[1]=((byte*)&u)[2];b[2]=((byte*)&u)[1];b[3]=((byte*)&u)[0];
+#endif
+
+#ifdef BIG_ENDIAN_HOST
+#define BYTESTOU32( u, b )          ((byte*)&u)[0]=b[0];((byte*)&u)[1]=b[1];((byte*)&u)[2]=b[2];((byte*)&u)[3]=b[3];
+#else
+#define BYTESTOU32( u, b )          ((byte*)&u)[0]=b[3];((byte*)&u)[1]=b[2];((byte*)&u)[2]=b[1];((byte*)&u)[3]=b[0];
+#endif
+
+static const u32 C_128[ NUSH_L ] =
+{
+	0x9B28A37B, 0x9DE5B521, 0x0B8EE0D7, 0x672AA715,
+	0x0E356C9F, 0xBF54692A, 0xDC9E15C8, 0x06D736E8,
+	0x9263E8CF, 0x1FCD682D, 0x7368B074, 0x2654F15A,
+	0x00EB3E4D, 0x18D62F6D, 0x632A557A, 0x1D953D21,
+	0xCD4B2ACD, 0x49A0D3F4, 0xC443F6CC, 0xE84C5BCB,
+	0xF750A732, 0x2CDE9942, 0x370C437A, 0xDA8B5654,
+	0x99A76750, 0xA1559437, 0x9EA46718, 0x83E984F8,
+	0xAB5692E4, 0xA6C5C46A, 0x25FB110E, 0x55955B2E,
+	0xFA639063, 0x027E4DC6, 0x919E96B2, 0x62E96D0C,
+	0xAA7DE138, 0xA674A66C, 0xB3F54983, 0xAE29D0DB,
+	0x599470CB, 0x3B2E3FA0, 0xA354CC6F, 0x516AF8C4,
+	0xADE11D33, 0x860D95F2, 0xBC2731A4, 0xCCD12BAA,
+	0xBA518E95, 0x22F7583A, 0x6C0A5FE8, 0x8FAC2D74,
+	0xD129E934, 0x11DCE4C9, 0x362F2F4A, 0x6CCB630D,
+	0x97919D88, 0x823F95AC, 0x67C99A98, 0x8E91D0CB,
+	0xAB796817, 0x356459A7, 0x668D9FA8, 0x0D4DBF40,
+	0x1ACCE5D8, 0xF53B24C1, 0x6DB89876, 0x5C965DA5
+};
+
+
+static const u16 S_128[ NUSH_L ] =
+{
+	7,  5,  15, 14,
+	3,  30, 4,  23,
+	13, 12, 26, 16,
+	9,  28, 8,  18,
+	23, 8,  26, 4,
+	29, 16, 2,  22,
+	23, 11, 26, 13,
+	20, 5,  28, 17,
+	19, 22, 6,  25,
+	12, 24, 27, 10,
+	16, 24, 9,  13,
+	5,  10, 26, 30,
+	9,  16, 28, 24,
+	27, 6,  7,  15,
+	1,  13, 15, 1,
+	23, 28, 12, 2,
+	28, 14, 15, 12
+};
+
+
+typedef struct {
+
+   u32 CC[ NUSH_L ];
+   u32 KS[ 4 ];       // start key
+   u32 KF[ 4 ];       // final key
+   u32 KR[ NUSH_L ];  // iteration key
+
+} NUSH_context;
+
+
+static int
+_nush_setkey( NUSH_context * ctx, byte * key, unsigned keylen )
+{
+   unsigned l = keylen / 4;
+   u32 k[ NUSH_KEY_SIZE_256 / 4 ];
+
+   u32 * ks = ctx->KS;
+   u32 * kf = ctx->KF;
+   u32 * kr = ctx->KR;
+   u32 * cc = ctx->CC;
+   int i;
+
+   for( i = 0; i < l; i++, key += 4 ) 
+	{
+      BYTESTOU32( k[ i ], key )
+   }
+
+   if( keylen == NUSH_KEY_SIZE_256 )
+   {
+      ks[ 0 ] = k[ 4 ];
+      ks[ 1 ] = k[ 5 ];
+      ks[ 2 ] = k[ 6 ];
+      ks[ 3 ] = k[ 7 ];
+      kf[ 0 ] = k[ 5 ];
+      kf[ 1 ] = k[ 4 ];
+      kf[ 2 ] = k[ 7 ];
+      kf[ 3 ] = k[ 6 ];
+	}
+   else if( keylen == NUSH_KEY_SIZE_192 )
+   {
+      ks[ 0 ] = k[ 2 ];
+      ks[ 1 ] = k[ 3 ];
+      ks[ 2 ] = k[ 4 ];
+      ks[ 3 ] = k[ 5 ];
+      kf[ 0 ] = k[ 0 ];
+      kf[ 1 ] = k[ 1 ];
+      kf[ 2 ] = k[ 2 ];
+      kf[ 3 ] = k[ 3 ];
+   }
+   else if( keylen == NUSH_KEY_SIZE_128 )
+   {		
+      ks[ 0 ] = k[ 3 ];
+      ks[ 1 ] = k[ 2 ];
+      ks[ 2 ] = k[ 1 ];
+      ks[ 3 ] = k[ 0 ];
+      kf[ 0 ] = k[ 1 ];
+      kf[ 1 ] = k[ 0 ];
+      kf[ 2 ] = k[ 3 ];
+      kf[ 3 ] = k[ 2 ];
+   }
+
+   for( i = 0; i < NUSH_L; i++ )
+   {
+      kr[ i ] = k[ i % l ];
+      cc[ i ] = C_128[ i ];
+   }
+
+   return 0;
+}
+
+
+static void
+_nush_encrypt( NUSH_context * ctx, byte * outbuf, byte * inbuf )
+{
+   u32 a, b, c, d;
+   u32 * ks = ctx->KS;
+   u32 * kf = ctx->KF;
+   u32 * kr = ctx->KR;
+   u32 * cc = ctx->CC;
+
+   BYTESTOU32( a, inbuf ) 
+	inbuf += 4;
+   BYTESTOU32( b, inbuf )
+	inbuf += 4;
+   BYTESTOU32( c, inbuf ) 
+	inbuf += 4;
+   BYTESTOU32( d, inbuf )
+
+   // start
+   a ^= ks[ 0 ];
+   b ^= ks[ 1 ];
+   c ^= ks[ 2 ];
+   d ^= ks[ 3 ];
+   // round 1
+   Iter_AND( a, b, c, d, kr, cc, S_128, 0 )
+   Iter_OR( b, c, d, a, kr, cc, S_128, 1 )
+   Iter_AND( c, d, a, b, kr, cc, S_128, 2 )
+   Iter_OR( d, a, b, c, kr, cc, S_128, 3 )
+   // round 2
+   Iter_OR( a, b, c, d, kr, cc, S_128, 4 )
+   Iter_OR( b, c, d, a, kr, cc, S_128, 5 )
+   Iter_OR( c, d, a, b, kr, cc, S_128, 6 )
+   Iter_OR( d, a, b, c, kr, cc, S_128, 7 )
+   // round 3
+   Iter_AND( a, b, c, d, kr, cc, S_128, 8 )
+   Iter_OR( b, c, d, a, kr, cc, S_128, 9 )
+   Iter_OR( c, d, a, b, kr, cc, S_128, 10 )
+   Iter_AND( d, a, b, c, kr, cc, S_128, 11 )
+   // round 4
+   Iter_OR( a, b, c, d, kr, cc, S_128, 12 )
+   Iter_AND( b, c, d, a, kr, cc, S_128, 13 )
+   Iter_OR( c, d, a, b, kr, cc, S_128, 14 )
+   Iter_OR( d, a, b, c, kr, cc, S_128, 15 )
+   // round 5
+   Iter_OR( a, b, c, d, kr, cc, S_128, 16 )
+   Iter_OR( b, c, d, a, kr, cc, S_128, 17 )
+   Iter_AND( c, d, a, b, kr, cc, S_128, 18 )
+   Iter_AND( d, a, b, c, kr, cc, S_128, 19 )
+   // round 6
+   Iter_AND( a, b, c, d, kr, cc, S_128, 20 )
+   Iter_AND( b, c, d, a, kr, cc, S_128, 21 )
+   Iter_AND( c, d, a, b, kr, cc, S_128, 22 )
+   Iter_OR( d, a, b, c, kr, cc, S_128, 23 )
+   // round 7
+   Iter_AND( a, b, c, d, kr, cc, S_128, 24 )
+   Iter_OR( b, c, d, a, kr, cc, S_128, 25 )
+   Iter_OR( c, d, a, b, kr, cc, S_128, 26 )
+   Iter_OR( d, a, b, c, kr, cc, S_128, 27 )
+   // round 8
+   Iter_AND( a, b, c, d, kr, cc, S_128, 28 )
+   Iter_OR( b, c, d, a, kr, cc, S_128, 29 )
+   Iter_AND( c, d, a, b, kr, cc, S_128, 30 )
+   Iter_AND( d, a, b, c, kr, cc, S_128, 31 )
+   // round 9
+   Iter_OR( a, b, c, d, kr, cc, S_128, 32 )
+   Iter_OR( b, c, d, a, kr, cc, S_128, 33 )
+   Iter_AND( c, d, a, b, kr, cc, S_128, 34 )
+   Iter_OR( d, a, b, c, kr, cc, S_128, 35 )
+   // round 10
+   Iter_OR( a, b, c, d, kr, cc, S_128, 36 )
+   Iter_AND( b, c, d, a, kr, cc, S_128, 37 )
+   Iter_OR( c, d, a, b, kr, cc, S_128, 38 )
+   Iter_AND( d, a, b, c, kr, cc, S_128, 39 )
+   // round 11
+   Iter_OR( a, b, c, d, kr, cc, S_128, 40 )
+   Iter_AND( b, c, d, a, kr, cc, S_128, 41 )
+   Iter_AND( c, d, a, b, kr, cc, S_128, 42 )
+   Iter_OR( d, a, b, c, kr, cc, S_128, 43 )
+   // round 12
+   Iter_OR( a, b, c, d, kr, cc, S_128, 44 )
+   Iter_AND( b, c, d, a, kr, cc, S_128, 45 )
+   Iter_AND( c, d, a, b, kr, cc, S_128, 46 )
+   Iter_AND( d, a, b, c, kr, cc, S_128, 47 )
+   // round 13
+   Iter_AND( a, b, c, d, kr, cc, S_128, 48 )
+   Iter_AND( b, c, d, a, kr, cc, S_128, 49 )
+   Iter_AND( c, d, a, b, kr, cc, S_128, 50 )
+   Iter_AND( d, a, b, c, kr, cc, S_128, 51 )
+   // round 14
+   Iter_AND( a, b, c, d, kr, cc, S_128, 52 )
+   Iter_AND( b, c, d, a, kr, cc, S_128, 53 )
+   Iter_OR( c, d, a, b, kr, cc, S_128, 54 )
+   Iter_AND( d, a, b, c, kr, cc, S_128, 55 )
+   // round 15
+   Iter_OR( a, b, c, d, kr, cc, S_128, 56 )
+   Iter_OR( b, c, d, a, kr, cc, S_128, 57 )
+   Iter_OR( c, d, a, b, kr, cc, S_128, 58 )
+   Iter_AND( d, a, b, c, kr, cc, S_128, 59 )
+   // round 16
+   Iter_AND( a, b, c, d, kr, cc, S_128, 60 )
+   Iter_AND( b, c, d, a, kr, cc, S_128, 61 )
+   Iter_OR( c, d, a, b, kr, cc, S_128, 62 )
+   Iter_OR( d, a, b, c, kr, cc, S_128, 63 )
+   // round 17
+   Iter_AND( a, b, c, d, kr, cc, S_128, 64 )
+   Iter_OR( b, c, d, a, kr, cc, S_128, 65 )
+   Iter_AND( c, d, a, b, kr, cc, S_128, 66 )
+   Iter_OR( d, a, b, c, kr, cc, S_128, 67 )
+   // final
+   a ^= kf[ 0 ];
+   b ^= kf[ 1 ];
+   c ^= kf[ 2 ];
+   d ^= kf[ 3 ];
+
+   U32TOBYTES( a, outbuf )
+	outbuf += 4;
+   U32TOBYTES( b, outbuf )
+	outbuf += 4;
+   U32TOBYTES( c, outbuf )
+	outbuf += 4;
+   U32TOBYTES( d, outbuf )
+}
+
+
+static void
+_nush_decrypt( NUSH_context * ctx, byte * outbuf, byte * inbuf )
+{
+   u32 a, b, c, d;
+   u32 * ks = ctx->KS;
+   u32 * kf = ctx->KF;
+   u32 * kr = ctx->KR;
+   u32 * cc = ctx->CC;
+
+   BYTESTOU32( a, inbuf ) 
+	inbuf += 4;
+   BYTESTOU32( b, inbuf )
+	inbuf += 4;
+   BYTESTOU32( c, inbuf ) 
+	inbuf += 4;
+   BYTESTOU32( d, inbuf )
+
+   // final-1
+   a ^= kf[ 0 ];
+   b ^= kf[ 1 ];
+   c ^= kf [2 ];
+   d ^= kf[ 3 ];
+   // round 17
+   Iter_OR_1( d, a, b, c, kr, cc, S_128, 67 )
+   Iter_AND_1( c, d, a, b, kr, cc, S_128, 66 )
+   Iter_OR_1( b, c, d, a, kr, cc, S_128, 65 )
+   Iter_AND_1( a, b, c, d, kr, cc, S_128, 64 )
+   // round 16
+   Iter_OR_1( d, a, b, c, kr, cc, S_128, 63 )
+   Iter_OR_1( c, d, a, b, kr, cc, S_128, 62 )
+   Iter_AND_1( b, c, d, a, kr, cc, S_128, 61 )
+   Iter_AND_1( a, b, c, d, kr, cc, S_128, 60 )
+   // round 15
+   Iter_AND_1( d, a, b, c, kr, cc, S_128, 59 )
+   Iter_OR_1( c, d, a, b, kr, cc, S_128, 58 )
+   Iter_OR_1( b, c, d, a, kr, cc, S_128, 57 )
+   Iter_OR_1( a, b, c, d, kr, cc, S_128, 56 )
+   // round 14
+   Iter_AND_1( d, a, b, c, kr, cc, S_128, 55 )
+   Iter_OR_1( c, d, a, b, kr, cc, S_128, 54 )
+   Iter_AND_1( b, c, d, a, kr, cc, S_128, 53 )
+   Iter_AND_1( a, b, c, d, kr, cc, S_128, 52 )
+   // round 13
+   Iter_AND_1( d, a, b, c, kr, cc, S_128, 51 )
+   Iter_AND_1( c, d, a, b, kr, cc, S_128, 50 )
+   Iter_AND_1( b, c, d, a, kr, cc, S_128, 49 )
+   Iter_AND_1( a, b, c, d, kr, cc, S_128, 48 )
+   // round 12
+   Iter_AND_1( d, a, b, c, kr, cc, S_128, 47 )
+   Iter_AND_1( c, d, a, b, kr, cc, S_128, 46 )
+   Iter_AND_1( b, c, d, a, kr, cc, S_128, 45 )
+   Iter_OR_1( a, b, c, d, kr, cc, S_128, 44 )
+   // round 11
+   Iter_OR_1( d, a, b, c, kr, cc, S_128, 43 )
+   Iter_AND_1( c, d, a, b, kr, cc, S_128, 42 )
+   Iter_AND_1( b, c, d, a, kr, cc, S_128, 41 )
+   Iter_OR_1( a, b, c, d, kr, cc, S_128, 40 )
+   // round 10
+   Iter_AND_1( d, a, b, c, kr, cc, S_128, 39 )
+   Iter_OR_1( c, d, a, b, kr, cc, S_128, 38 )
+   Iter_AND_1( b, c, d, a, kr, cc, S_128, 37 )
+   Iter_OR_1( a, b, c, d, kr, cc, S_128, 36 )
+   // round 9
+   Iter_OR_1( d, a, b, c, kr, cc, S_128, 35 )
+   Iter_AND_1( c, d, a, b, kr, cc, S_128, 34 )
+   Iter_OR_1( b, c, d, a, kr, cc, S_128, 33 )
+   Iter_OR_1( a, b, c, d, kr, cc, S_128, 32 )
+   // round 8
+   Iter_AND_1( d, a, b, c, kr, cc, S_128, 31 )
+   Iter_AND_1( c, d, a, b, kr, cc, S_128, 30 )
+   Iter_OR_1( b, c, d, a, kr, cc, S_128, 29 )
+   Iter_AND_1( a, b, c, d, kr, cc, S_128, 28 )
+   // round 7
+   Iter_OR_1( d, a, b, c, kr, cc, S_128, 27 )
+   Iter_OR_1( c, d, a, b, kr, cc, S_128, 26 )
+   Iter_OR_1( b, c, d, a, kr, cc, S_128, 25 )
+   Iter_AND_1( a, b, c, d, kr, cc, S_128, 24 )
+   // round 6
+   Iter_OR_1( d, a, b, c, kr, cc, S_128, 23 )
+   Iter_AND_1( c, d, a, b, kr, cc, S_128, 22 )
+   Iter_AND_1( b, c, d, a, kr, cc, S_128, 21 )
+   Iter_AND_1( a, b, c, d, kr, cc, S_128, 20 )
+   // round 5
+   Iter_AND_1( d, a, b, c, kr, cc, S_128, 19 )
+   Iter_AND_1( c, d, a, b, kr, cc, S_128, 18 )
+   Iter_OR_1( b, c, d, a, kr, cc, S_128, 17 )
+   Iter_OR_1( a, b, c, d, kr, cc, S_128, 16 )
+   // round 4
+   Iter_OR_1( d, a, b, c, kr, cc, S_128, 15 )
+   Iter_OR_1( c, d, a, b, kr, cc, S_128, 14 )
+   Iter_AND_1( b, c, d, a, kr, cc, S_128, 13 )
+   Iter_OR_1( a, b, c, d, kr, cc, S_128, 12 )
+   // round 3
+   Iter_AND_1( d, a, b, c, kr, cc, S_128, 11 )
+   Iter_OR_1( c, d, a, b, kr, cc, S_128, 10 )
+   Iter_OR_1( b, c, d, a, kr, cc, S_128, 9 )
+   Iter_AND_1( a, b, c, d, kr, cc, S_128, 8 )
+   // round 2
+   Iter_OR_1( d, a, b, c, kr, cc, S_128, 7 )
+   Iter_OR_1( c, d, a, b, kr, cc, S_128, 6 )
+   Iter_OR_1( b, c, d, a, kr, cc, S_128, 5 )
+   Iter_OR_1( a, b, c, d, kr, cc, S_128, 4 )
+   // round 1
+   Iter_OR_1( d, a, b, c, kr, cc, S_128, 3 )
+   Iter_AND_1( c, d, a, b, kr, cc, S_128, 2 )
+   Iter_OR_1( b, c, d, a, kr, cc, S_128, 1 )
+   Iter_AND_1( a, b, c, d, kr, cc, S_128, 0 )
+   // start-1
+   a ^= ks[ 0 ];
+   b ^= ks[ 1 ];
+   c ^= ks[ 2 ];
+   d ^= ks[ 3 ];
+
+   U32TOBYTES( a, outbuf )
+	outbuf += 4;
+   U32TOBYTES( b, outbuf )
+	outbuf += 4;
+   U32TOBYTES( c, outbuf )
+	outbuf += 4;
+   U32TOBYTES( d, outbuf )
+}
+
+
+// Callback functions
+
+static void
+burn_stack( int bytes )
+{
+   byte buf[ 64 ];
+   memset( buf, 0, 64 );
+   bytes -= 64;
+   if( bytes > 0 )
+      burn_stack( bytes );
+}
+
+
+static int
+nush_setkey( NUSH_context * c, byte * key, unsigned keylen )
+{
+   int res;
+
+#ifdef NUSH_DEBUG
+   printf( "\nnush_setkey\n" );
+#endif
+
+   res = _nush_setkey( c, key, keylen );
+   burn_stack( 64 );
+   return res;
+}
+
+
+static void
+nush_encrypt_block( NUSH_context * c, byte * outbuf, byte * inbuf )
+{
+#ifdef NUSH_DEBUG
+   printf( "\nnush_encrypt_block\n" );
+#endif
+
+   _nush_encrypt( c, outbuf, inbuf );
+   burn_stack( 64 );
+}
+
+
+static void
+nush_decrypt_block( NUSH_context * c, byte * outbuf, byte * inbuf )
+{
+#ifdef NUSH_DEBUG
+   printf( "\nnush_decrypt_block\n" );
+#endif
+
+   _nush_decrypt( c, outbuf, inbuf );
+   burn_stack( 64 );
+}
+
+
+// Self-test
+
+#ifdef NUSH_SELFTEST
+
+static void 
+print_bin( byte * p, int n )
+{
+   int i;
+   for( i = 0; i < n; i++ )
+      printf( "%02x ", p[ i ] );
+   printf( "\n" );
+}
+
+static void
+nush_selftest( void )
+{
+   NUSH_context c;
+   byte plain[ NUSH_BLOCK_SIZE + 1 ] = NUSH_TEST_PLAIN_256;
+   byte buffer[ NUSH_BLOCK_SIZE ];
+
+ 	printf( "\nNUSH selftest:" );
+   printf( "\n key = " );
+   print_bin( NUSH_TEST_KEY_256, NUSH_KEY_SIZE_256 );
+   printf( "\n plain = " );
+   print_bin( plain, NUSH_BLOCK_SIZE );
+   printf( "\n cipher = " );
+   print_bin( NUSH_TEST_CIPHER_256, NUSH_BLOCK_SIZE );
+
+   nush_setkey( &c, NUSH_TEST_KEY_256, NUSH_KEY_SIZE_256 );
+
+   nush_encrypt_block( &c, buffer, plain );
+
+   if( memcmp( buffer, NUSH_TEST_CIPHER_256, NUSH_BLOCK_SIZE ) )
+	{
+      printf( "\nNUSH selftest failed to encrypt" );
+      printf( "\n buffer = " );
+      print_bin( buffer, NUSH_BLOCK_SIZE );
+	}
+
+   nush_decrypt_block( &c, buffer, buffer );
+
+   if( memcmp( buffer, plain, NUSH_BLOCK_SIZE ) )
+	{
+      printf( "\nNUSH selftest failed to decrypt" );
+      printf( "\n buffer = " );
+      print_bin( buffer, NUSH_BLOCK_SIZE );
+	}
+}
+
+#endif
+
+
+// Return information about the algorithm
+
+const char *
+nush_get_info(       int algo, 
+                     size_t * keylen,
+                     size_t * blocksize, 
+                     size_t * contextsize,
+                     int  ( ** r_setkey  )( void * c, byte * key, unsigned keylen ),
+                     void ( ** r_encrypt )( void * c, byte * outbuf, byte * inbuf ),
+                     void ( ** r_decrypt )( void * c, byte * outbuf, byte * inbuf ) )
+{
+#ifdef NUSH_DEBUG
+   printf( "\nnush_get_info\n" );
+#endif
+#ifdef NUSH_SELFTEST
+	nush_selftest();
+#endif
+
+   const char * strName;
+
+   switch( algo )
+   {
+      case CIPHER_ALGO_NUSH256:
+         strName = "NUSH256";
+         *keylen = NUSH_KEY_SIZE_256 * 8;
+         break;
+
+      case CIPHER_ALGO_NUSH192:
+         strName = "NUSH192";
+         *keylen = NUSH_KEY_SIZE_192 * 8;
+         break;
+
+      case CIPHER_ALGO_NUSH128:
+         strName = "NUSH128";
+         *keylen = NUSH_KEY_SIZE_128 * 8;
+         break;
+
+      default:
+         return NULL;
+   }
+
+   *blocksize = NUSH_BLOCK_SIZE;
+   *contextsize = sizeof( NUSH_context );
+   *( int (**)( NUSH_context *, byte *, unsigned ) )r_setkey = nush_setkey;
+   *( void (**)( NUSH_context *, byte *, byte * ) )r_encrypt  = nush_encrypt_block;
+   *( void (**)( NUSH_context *, byte *, byte * ) )r_decrypt  = nush_decrypt_block;
+
+   return strName;
+}
diff -u5prk.orig gnupg-1.2.1.orig/cipher/pubkey.c gnupg-1.2.1/cipher/pubkey.c
--- gnupg-1.2.1.orig/cipher/pubkey.c	2002-08-03 14:50:38 +0400
+++ gnupg-1.2.1/cipher/pubkey.c	2002-12-20 17:33:42 +0300
@@ -29,10 +29,11 @@
 #include "mpi.h"
 #include "cipher.h"
 #include "elgamal.h"
 #include "dsa.h"
 #include "rsa.h"
+#include "lans.h"
 
 #define TABLE_SIZE 10
 
 struct pubkey_table_s {
     const char *name;
@@ -202,10 +203,30 @@ setup_pubkey_table(void)
     pubkey_table[i].get_nbits	     = rsa_get_nbits;
     if( !pubkey_table[i].name )
 	BUG();
     i++;
 
+    /* LAN Crypto LANS signature algorithm */
+
+    pubkey_table[i].algo = PUBKEY_ALGO_LANS;
+    pubkey_table[i].name = lans_get_info( pubkey_table[i].algo,
+					 &pubkey_table[i].npkey,
+					 &pubkey_table[i].nskey,
+					 &pubkey_table[i].nenc,
+					 &pubkey_table[i].nsig,
+					 &pubkey_table[i].use );
+    pubkey_table[i].generate	       = lans_generate;
+    pubkey_table[i].check_secret_key  = lans_check_secret_key;
+    pubkey_table[i].encrypt	       = dummy_encrypt;
+    pubkey_table[i].decrypt	       = dummy_decrypt;
+    pubkey_table[i].sign	       = lans_sign;
+    pubkey_table[i].verify	       = lans_verify;
+    pubkey_table[i].get_nbits	       = lans_get_nbits;
+    if( !pubkey_table[i].name )
+	BUG();
+    i++;
+
     for( ; i < TABLE_SIZE; i++ )
 	pubkey_table[i].name = NULL;
 }
 
 
diff -u5prk.orig gnupg-1.2.1.orig/cipher/wicker.c gnupg-1.2.1/cipher/wicker.c
--- gnupg-1.2.1.orig/cipher/wicker.c	1970-01-01 03:00:00 +0300
+++ gnupg-1.2.1/cipher/wicker.c	2002-12-20 17:33:42 +0300
@@ -0,0 +1,351 @@
+/* wicker.c - WICKER encryption/decryption algorithm
+ *	Copyright (C) 1998-2002 LAN Crypto (www.lancrypto.com)
+ *
+ * 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
+ */
+
+/* Description
+ * ===========
+ * key length   = 128 bit
+ * block length = 128 bit
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "types.h"
+#include "errors.h"
+#include "algorithms.h"
+#include "cipher.h"
+
+// Debug and selftest
+
+//#define WICKER_DEBUG
+//#define WICKER_SELFTEST
+
+#define WICKER_TEST_KEY             "1234567890123456"
+#define WICKER_TEST_PLAIN           "1234567890123456"
+#define WICKER_TEST_CIPHER          "\x73\xa6\x8a\x9f\x0f\x73\x6a\xf0\xa5\x37\xd5\xfa\x10\xbf\xa3\xfb"
+
+// WICKER algorithm
+
+#define WICKER_KEY_SIZE             16
+#define WICKER_BLOCK_SIZE           16
+
+typedef struct {
+
+   u32 KS[ 44 ];
+
+} WICKER_context;
+
+
+#ifdef BIG_ENDIAN_HOST
+#define U32TOBYTES( u, b )          b[0]=((byte*)&u)[0];b[1]=((byte*)&u)[1];b[2]=((byte*)&u)[2];b[3]=((byte*)&u)[3];
+#else
+#define U32TOBYTES( u, b )          b[0]=((byte*)&u)[3];b[1]=((byte*)&u)[2];b[2]=((byte*)&u)[1];b[3]=((byte*)&u)[0];
+#endif
+
+#ifdef BIG_ENDIAN_HOST
+#define BYTESTOU32( u, b )          ((byte*)&u)[0]=b[0];((byte*)&u)[1]=b[1];((byte*)&u)[2]=b[2];((byte*)&u)[3]=b[3];
+#else
+#define BYTESTOU32( u, b )          ((byte*)&u)[0]=b[3];((byte*)&u)[1]=b[2];((byte*)&u)[2]=b[1];((byte*)&u)[3]=b[0];
+#endif
+
+
+static int
+_wicker_setkey( WICKER_context * ctx, byte * key, unsigned keylen )
+{
+   u32 * ks = ctx->KS;
+   int i;
+
+   for( i = 0; i < 4; i++, key += 4 ) 
+	{
+		BYTESTOU32( ks[ i ], key )
+	}
+
+   for( i = 0; i < 40; i++ ) 
+      ks[ i + 4 ] = ks[ i ];
+
+   return 0;
+}
+
+
+static void
+_wicker_encrypt( WICKER_context * ctx, byte * outbuf, byte * inbuf )
+{
+   u32 a, b, c, d, r, rr;
+   u32 * ks = ctx->KS;
+
+   BYTESTOU32( a, inbuf ) 
+	inbuf += 4;
+   BYTESTOU32( b, inbuf )
+	inbuf += 4;
+   BYTESTOU32( c, inbuf ) 
+	inbuf += 4;
+   BYTESTOU32( d, inbuf )
+
+   a+=ks[0]; b+=ks[1]; c+=ks[2]; d+=ks[3]; c+=ks[4]; c+=b;
+   r=c; c>>=1;  r<<=31; rr=d; c^=r; r=ks[5];  rr&=c; d^=r; a+=rr; d+=c;
+   r=d; d>>=2;  r<<=30; rr=a; d^=r; r=ks[6];  rr&=d; a+=r; b+=rr; a^=d;
+   r=a; a>>=4;  r<<=28; rr=b; a^=r; r=ks[7];  rr&=a; b^=r; c+=rr; b^=a;
+   r=b; b>>=8;  r<<=24; rr=c; b^=r; r=ks[8];  rr&=b; c+=r; d+=rr; c+=b;
+   r=c; c>>=16; r<<=16; rr=d; c^=r; r=ks[9];  rr&=c; d^=r; a^=rr; d+=c;
+   r=d; d>>=21; r<<=11; rr=a; d^=r; r=ks[10]; rr|=d; a+=r; b^=rr; a^=d;
+   r=a; a>>=6;  r<<=26; rr=b; a^=r; r=ks[11]; rr|=a; b+=r; c^=rr; b+=a;
+   r=b; b>>=12; r<<=20; rr=c; b^=r; r=ks[12]; rr&=b; c^=r; d+=rr; c+=b;
+   r=c; c>>=24; r<<=8;  rr=d; c^=r; r=ks[13]; rr|=c; d+=r; a+=rr; d^=c;
+   r=d; d>>=16; r<<=16; rr=a; d^=r; r=ks[14]; rr&=d; a^=r; b+=rr; a^=d;
+   r=a; a>>=11; r<<=21; rr=b; a^=r; r=ks[15]; rr&=a; b+=r; c+=rr; b+=a;
+   r=b; b>>=10; r<<=22; rr=c; b^=r; r=ks[16]; rr|=b; c^=r; d^=rr; c+=b;
+   r=c; c>>=20; r<<=12; rr=d; c^=r; r=ks[17]; rr&=c; d+=r; a^=rr; d^=c;
+   r=d; d>>=8;  r<<=24; rr=a; d^=r; r=ks[18]; rr|=d; a+=r; b^=rr; a+=d;
+   r=a; a>>=16; r<<=16; rr=b; a^=r; r=ks[19]; rr&=a; b^=r; c+=rr; b+=a;
+   r=b; b>>=25; r<<=7;  rr=c; b^=r; r=ks[20]; rr|=b; c+=r; d+=rr; c^=b;
+   r=c; c>>=14; r<<=18; rr=d; c^=r; r=ks[21]; rr|=c; d^=r; a+=rr; d^=c;
+   r=d; d>>=28; r<<=4;  rr=a; d^=r; r=ks[22]; rr|=d; a+=r; b+=rr; a+=d;
+   r=a; a>>=24; r<<=8;  rr=b; a^=r; r=ks[23]; rr|=a; b^=r; c^=rr; b+=a;
+   r=b; b>>=16; r<<=16; rr=c; b^=r; r=ks[24]; rr|=b; c+=r; d^=rr; c^=b;
+   r=c; c>>=19; r<<=13; rr=d; c^=r; r=ks[25]; rr|=c; d+=r; a^=rr; d+=c;
+   r=d; d>>=22; r<<=10; rr=a; d^=r; r=ks[26]; rr|=d; a^=r; b+=rr; a+=d;
+   r=a; a>>=12; r<<=20; rr=b; a^=r; r=ks[27]; rr&=a; b+=r; c+=rr; b^=a;
+   r=b; b>>=24; r<<=8;  rr=c; b^=r; r=ks[28]; rr&=b; c^=r; d+=rr; c^=b;
+   r=c; c>>=16; r<<=16; rr=d; c^=r; r=ks[29]; rr|=c; d+=r; a+=rr; d+=c;
+   r=d; d>>=27; r<<=5;  rr=a; d^=r; r=ks[30]; rr&=d; a^=r; b^=rr; a+=d;
+   r=a; a>>=26; r<<=6;  rr=b; a^=r; r=ks[31]; rr|=a; b+=r; c^=rr; b^=a;
+   r=b; b>>=20; r<<=12; rr=c; b^=r; r=ks[32]; rr&=b; c+=r; d^=rr; c+=b;
+   r=c; c>>=8;  r<<=24; rr=d; c^=r; r=ks[33]; rr&=c; d^=r; a+=rr; d+=c;
+   r=d; d>>=16; r<<=16; rr=a; d^=r; r=ks[34]; rr&=d; a+=r; b+=rr; a^=d;
+   r=a; a>>=25; r<<=7;  rr=b; a^=r; r=ks[35]; rr|=a; b^=r; c+=rr; b^=a;
+   r=b; b>>=18; r<<=14; rr=c; b^=r; r=ks[36]; rr|=b; c+=r; d+=rr; c+=b;
+   r=c; c>>=4;  r<<=28; rr=d; c^=r; r=ks[37]; rr&=c; d^=r; a^=rr; d+=c;
+   r=d; d>>=8;  r<<=24; rr=a; d^=r; r=ks[38]; rr&=d; a+=r; b^=rr; a^=d;
+   r=a; a>>=16; r<<=16; rr=b; a^=r; r=ks[39]; rr&=a; b+=r; c^=rr; b+=a;
+   r=b; b>>=1;  r<<=31; rr=c; b^=r; rr&=b; d+=rr;
+   a^=ks[41]; b^=ks[40]; c^=ks[43]; d^=ks[42];
+
+   U32TOBYTES( a, outbuf )
+	outbuf += 4;
+   U32TOBYTES( b, outbuf )
+	outbuf += 4;
+   U32TOBYTES( c, outbuf )
+	outbuf += 4;
+   U32TOBYTES( d, outbuf )
+}
+
+
+static void
+_wicker_decrypt( WICKER_context * ctx, byte * outbuf, byte * inbuf )
+{
+   u32 a, b, c, d, r, rr;
+   u32 * ks = ctx->KS;
+
+   BYTESTOU32( a, inbuf ) 
+	inbuf += 4;
+   BYTESTOU32( b, inbuf )
+	inbuf += 4;
+   BYTESTOU32( c, inbuf ) 
+	inbuf += 4;
+   BYTESTOU32( d, inbuf )
+
+   a^=ks[41]; b^=ks[40]; c^=ks[43]; d^=ks[42];
+   rr=b; r=b; b>>=31; r<<=1;  rr&=c; b^=r; r=ks[39]; b-=a; d-=rr; b-=r;
+   rr=a; r=a; a>>=16; r<<=16; rr&=b; a^=r; r=ks[38]; a^=d; c^=rr; a-=r;
+   rr=d; r=d; d>>=24; r<<=8;  rr&=a; d^=r; r=ks[37]; d-=c; b^=rr; d^=r;
+   rr=c; r=c; c>>=28; r<<=4;  rr&=d; c^=r; r=ks[36]; c-=b; a^=rr; c-=r;
+   rr=b; r=b; b>>=14; r<<=18; rr|=c; b^=r; r=ks[35]; b^=a; d-=rr; b^=r;
+   rr=a; r=a; a>>=7;  r<<=25; rr|=b; a^=r; r=ks[34]; a^=d; c-=rr; a-=r;
+   rr=d; r=d; d>>=16; r<<=16; rr&=a; d^=r; r=ks[33]; d-=c; b-=rr; d^=r;
+   rr=c; r=c; c>>=24; r<<=8;  rr&=d; c^=r; r=ks[32]; c-=b; a-=rr; c-=r;
+   rr=b; r=b; b>>=12; r<<=20; rr&=c; b^=r; r=ks[31]; b^=a; d^=rr; b-=r;
+   rr=a; r=a; a>>=6;  r<<=26; rr|=b; a^=r; r=ks[30]; a-=d; c^=rr; a^=r;
+   rr=d; r=d; d>>=5;  r<<=27; rr&=a; d^=r; r=ks[29]; d-=c; b^=rr; d-=r;
+   rr=c; r=c; c>>=16; r<<=16; rr|=d; c^=r; r=ks[28]; c^=b; a-=rr; c^=r;
+   rr=b; r=b; b>>=8;  r<<=24; rr&=c; b^=r; r=ks[27]; b^=a; d-=rr; b-=r;
+   rr=a; r=a; a>>=20; r<<=12; rr&=b; a^=r; r=ks[26]; a-=d; c-=rr; a^=r;
+   rr=d; r=d; d>>=10; r<<=22; rr|=a; d^=r; r=ks[25]; d-=c; b-=rr; d-=r;
+   rr=c; r=c; c>>=13; r<<=19; rr|=d; c^=r; r=ks[24]; c^=b; a^=rr; c-=r;
+   rr=b; r=b; b>>=16; r<<=16; rr|=c; b^=r; r=ks[23]; b-=a; d^=rr; b^=r;
+   rr=a; r=a; a>>=8;  r<<=24; rr|=b; a^=r; r=ks[22]; a-=d; c^=rr; a-=r;
+   rr=d; r=d; d>>=4;  r<<=28; rr|=a; d^=r; r=ks[21]; d^=c; b-=rr; d^=r;
+   rr=c; r=c; c>>=18; r<<=14; rr|=d; c^=r; r=ks[20]; c^=b; a-=rr; c-=r;
+   rr=b; r=b; b>>=7;  r<<=25; rr|=c; b^=r; r=ks[19]; b-=a; d-=rr; b^=r;
+   rr=a; r=a; a>>=16; r<<=16; rr&=b; a^=r; r=ks[18]; a-=d; c-=rr; a-=r;
+   rr=d; r=d; d>>=24; r<<=8;  rr|=a; d^=r; r=ks[17]; d^=c; b^=rr; d-=r;
+   rr=c; r=c; c>>=12; r<<=20; rr&=d; c^=r; r=ks[16]; c-=b; a^=rr; c^=r;
+   rr=b; r=b; b>>=22; r<<=10; rr|=c; b^=r; r=ks[15]; b-=a; d^=rr; b-=r;
+   rr=a; r=a; a>>=21; r<<=11; rr&=b; a^=r; r=ks[14]; a^=d; c-=rr; a^=r;
+   rr=d; r=d; d>>=16; r<<=16; rr&=a; d^=r; r=ks[13]; d^=c; b-=rr; d-=r;
+   rr=c; r=c; c>>=8;  r<<=24; rr|=d; c^=r; r=ks[12]; c-=b; a-=rr; c^=r;
+   rr=b; r=b; b>>=20; r<<=12; rr&=c; b^=r; r=ks[11]; b-=a; d-=rr; b-=r;
+   rr=a; r=a; a>>=26; r<<=6;  rr|=b; a^=r; r=ks[10]; a^=d; c^=rr; a-=r;
+   rr=d; r=d; d>>=11; r<<=21; rr|=a; d^=r; r=ks[9];  d-=c; b^=rr; d^=r;
+   rr=c; r=c; c>>=16; r<<=16; rr&=d; c^=r; r=ks[8];  c-=b; a^=rr; c-=r;
+   rr=b; r=b; b>>=24; r<<=8;  rr&=c; b^=r; r=ks[7];  b^=a; d-=rr; b^=r;
+   rr=a; r=a; a>>=28; r<<=4;  rr&=b; a^=r; r=ks[6];  a^=d; c-=rr; a-=r;
+   rr=d; r=d; d>>=30; r<<=2;  rr&=a; d^=r; r=ks[5];  d-=c; b-=rr; d^=r;
+   rr=c; r=c; c>>=31; r<<=1;  rr&=d; c^=r; r=ks[4];  c-=b; a-=rr; c-=r;
+   a-=ks[0]; b-=ks[1]; c-=ks[2]; d-=ks[3];
+
+   U32TOBYTES( a, outbuf )
+	outbuf += 4;
+   U32TOBYTES( b, outbuf )
+	outbuf += 4;
+   U32TOBYTES( c, outbuf )
+	outbuf += 4;
+   U32TOBYTES( d, outbuf )
+}
+
+
+// Callback functions
+
+static void
+burn_stack( int bytes )
+{
+   byte buf[ 64 ];
+   memset( buf, 0, 64 );
+   bytes -= 64;
+   if( bytes > 0 )
+      burn_stack( bytes );
+}
+
+
+static int
+wicker_setkey( WICKER_context * c, byte * key, unsigned keylen )
+{
+   int res;
+
+#ifdef WICKER_DEBUG
+   printf( "\nwicker_setkey\n" );
+#endif
+
+	res = _wicker_setkey( c, key, keylen );
+   burn_stack( 64 );
+   return res;
+}
+
+
+static void
+wicker_encrypt_block( WICKER_context * c, byte * outbuf, byte * inbuf )
+{
+#ifdef WICKER_DEBUG
+   printf( "\nwicker_encrypt_block\n" );
+#endif
+
+	_wicker_encrypt( c, outbuf, inbuf );
+   burn_stack( 64 );
+}
+
+
+static void
+wicker_decrypt_block( WICKER_context * c, byte * outbuf, byte * inbuf )
+{
+#ifdef WICKER_DEBUG
+   printf( "\nwicker_decrypt_block\n" );
+#endif
+
+	_wicker_decrypt( c, outbuf, inbuf );
+   burn_stack( 64 );
+}
+
+
+// Self-test
+
+#ifdef WICKER_SELFTEST
+
+static void 
+print_bin( byte * p, int n )
+{
+   int i;
+   for( i = 0; i < n; i++ )
+      printf( "%02x ", p[ i ] );
+   printf( "\n" );
+}
+
+static void
+wicker_selftest( void )
+{
+   WICKER_context c;
+   byte plain[ WICKER_BLOCK_SIZE + 1 ] = WICKER_TEST_PLAIN;
+   byte buffer[ WICKER_BLOCK_SIZE ];
+
+	printf( "\nWICKER selftest:" );
+   printf( "\n key = " );
+   print_bin( WICKER_TEST_KEY, WICKER_KEY_SIZE );
+   printf( "\n plain = " );
+   print_bin( plain, WICKER_BLOCK_SIZE );
+   printf( "\n cipher = " );
+   print_bin( WICKER_TEST_CIPHER, WICKER_BLOCK_SIZE );
+
+   wicker_setkey( &c, WICKER_TEST_KEY, WICKER_KEY_SIZE );
+
+   wicker_encrypt_block( &c, buffer, plain );
+
+   if( memcmp( buffer, WICKER_TEST_CIPHER, WICKER_BLOCK_SIZE ) )
+	{
+      printf( "\nWICKER selftest failed to encrypt" );
+      printf( "\n buffer = " );
+      print_bin( buffer, WICKER_BLOCK_SIZE );
+  }
+
+   wicker_decrypt_block( &c, buffer, buffer );
+
+   if( memcmp( buffer, plain, WICKER_BLOCK_SIZE ) )
+	{
+      printf( "\nWICKER selftest failed to decrypt" );
+      printf( "\n buffer = " );
+      print_bin( buffer, WICKER_BLOCK_SIZE );
+	}
+}
+
+#endif
+
+
+// Return information about the algorithm
+
+const char *
+wicker_get_info(     int algo, 
+                     size_t * keylen,
+                     size_t * blocksize, 
+                     size_t * contextsize,
+                     int  ( ** r_setkey  )( void * c, byte * key, unsigned keylen ),
+                     void ( ** r_encrypt )( void * c, byte * outbuf, byte * inbuf ),
+                     void ( ** r_decrypt )( void * c, byte * outbuf, byte * inbuf )
+                 )
+{
+#ifdef WICKER_DEBUG
+//   printf( "\nwicker_get_info\n" );
+#endif
+#ifdef WICKER_SELFTEST
+	wicker_selftest();
+#endif
+
+   if( algo == CIPHER_ALGO_WICKER )
+	{
+      *keylen = WICKER_KEY_SIZE * 8;
+      *blocksize = WICKER_BLOCK_SIZE;
+      *contextsize = sizeof( WICKER_context );
+
+      *( int  (**)( WICKER_context *, byte *, unsigned ) )r_setkey = wicker_setkey;
+      *( void (**)( WICKER_context *, byte *, byte * ) )r_encrypt  = wicker_encrypt_block;
+      *( void (**)( WICKER_context *, byte *, byte * ) )r_decrypt  = wicker_decrypt_block;
+
+      return "WICKER";
+	}
+
+   return NULL;
+}
diff -u5prk.orig gnupg-1.2.1.orig/g10/getkey.c gnupg-1.2.1/g10/getkey.c
--- gnupg-1.2.1.orig/g10/getkey.c	2002-10-12 15:39:35 +0400
+++ gnupg-1.2.1/g10/getkey.c	2002-12-20 17:33:42 +0300
@@ -129,10 +129,11 @@ cache_public_key( PKT_public_key *pk )
     if( pk->dont_cache )
         return;
 
     if( is_ELGAMAL(pk->pubkey_algo)
 	|| pk->pubkey_algo == PUBKEY_ALGO_DSA
+ 	|| pk->pubkey_algo == PUBKEY_ALGO_LANS
 	|| is_RSA(pk->pubkey_algo) ) {
 	keyid_from_pk( pk, keyid );
     }
     else
 	return; /* don't know how to get the keyid */
diff -u5prk.orig gnupg-1.2.1.orig/g10/keygen.c gnupg-1.2.1/g10/keygen.c
--- gnupg-1.2.1.orig/g10/keygen.c	2002-10-12 15:31:38 +0400
+++ gnupg-1.2.1/g10/keygen.c	2002-12-20 17:34:19 +0300
@@ -897,10 +897,87 @@ gen_rsa(int algo, unsigned nbits, KBNODE
 
     return 0;
 }
 
 
+/* Generate a LANS key */
+
+static int
+gen_lans( unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK * dek,
+	       STRING2KEY * s2k, PKT_secret_key ** ret_sk, u32 expireval )
+{
+    int rc;
+    int i;
+    PACKET * pkt;
+    PKT_secret_key * sk;
+    PKT_public_key * pk;
+    MPI skey[ 5 ];
+
+    if( nbits != 1024 ) 
+    {
+	    nbits = 1024;
+	    log_info( _( "keysize invalid; using %u bits\n" ), nbits );
+    }
+
+    rc = pubkey_generate( PUBKEY_ALGO_LANS, nbits, skey, NULL );
+    if( rc ) 
+    {
+	    log_error( "pubkey_generate failed: %s\n", g10_errstr( rc ) );
+	    return rc;
+    }
+
+    sk = m_alloc_clear( sizeof *sk );
+    pk = m_alloc_clear( sizeof *pk );
+    sk->timestamp = pk->timestamp = make_timestamp();
+    sk->version = pk->version = 4;
+    if( expireval )
+	   sk->expiredate = pk->expiredate = sk->timestamp + expireval;
+    sk->pubkey_algo = pk->pubkey_algo = PUBKEY_ALGO_LANS;
+	 pk->pkey[0] = mpi_copy( skey[0] );
+	 pk->pkey[1] = mpi_copy( skey[1] );
+	 pk->pkey[2] = mpi_copy( skey[2] );
+	 pk->pkey[3] = mpi_copy( skey[3] );
+    sk->skey[0] = skey[0];
+    sk->skey[1] = skey[1];
+    sk->skey[2] = skey[2];
+    sk->skey[3] = skey[3];
+    sk->skey[4] = skey[4];
+    sk->is_protected = 0;
+    sk->protect.algo = 0;
+    sk->csum = checksum_mpi ( sk->skey[4] );
+
+    if( ret_sk )
+	   *ret_sk = copy_secret_key( NULL, sk );
+
+    if( dek ) 
+    {
+	    sk->protect.algo = dek->algo;
+	    sk->protect.s2k = *s2k;
+	    rc = protect_secret_key( sk, dek );
+	    if( rc ) 
+       {
+	       log_error( "protect_secret_key failed: %s\n", g10_errstr( rc ) );
+	       free_public_key( pk );
+	       free_secret_key( sk );
+	       return rc;
+	    }
+    }
+
+    pkt = m_alloc_clear( sizeof *pkt );
+    pkt->pkttype = ret_sk ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
+    pkt->pkt.public_key = pk;
+    add_kbnode( pub_root, new_kbnode( pkt ) );
+
+    pkt = m_alloc_clear( sizeof *pkt );
+    pkt->pkttype = ret_sk ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY;
+    pkt->pkt.secret_key = sk;
+    add_kbnode( sec_root, new_kbnode( pkt ) );
+
+    return 0;
+}
+
+
 /****************
  * check valid days:
  * return 0 on error or the multiplier
  */
 static int
@@ -949,20 +1026,26 @@ ask_algo (int addmode, unsigned int *r_u
     tty_printf(    _("   (%d) RSA (sign only)\n"), 5 );
     if (addmode)
         tty_printf(    _("   (%d) RSA (encrypt only)\n"), 6 );
     if (opt.expert)
       tty_printf(    _("   (%d) RSA (sign and encrypt)\n"), 7 );
+    tty_printf( _( "   (%d) LANS (sign only)\n" ), 8 );
 
     for(;;) {
 	answer = cpr_get("keygen.algo",_("Your selection? "));
 	cpr_kill_prompt();
 	algo = *answer? atoi(answer): 1;
 	m_free(answer);
 	if( algo == 1 && !addmode ) {
 	    algo = 0;	/* create both keys */
 	    break;
 	}
+	else if( algo == 8 ) {
+	    algo = PUBKEY_ALGO_LANS;
+	    *r_usage = PUBKEY_USAGE_SIG;
+	    break;
+	}
 	else if( algo == 7 && opt.expert ) {
 	    if (cpr_get_answer_is_yes ("keygen.algo.rsa_se",_(
 		"The use of this algorithm is deprecated - create anyway? "))){
               algo = PUBKEY_ALGO_RSA;
               *r_usage = PUBKEY_USAGE_ENC | PUBKEY_USAGE_SIG;
@@ -1005,11 +1088,11 @@ static unsigned
 ask_keysize( int algo )
 {
     char *answer;
     unsigned nbits;
 
-    if (algo != PUBKEY_ALGO_DSA && algo != PUBKEY_ALGO_RSA) {
+    if (algo != PUBKEY_ALGO_DSA && algo != PUBKEY_ALGO_RSA && algo != PUBKEY_ALGO_LANS) {
         tty_printf (_("About to generate a new %s keypair.\n"
                       "              minimum keysize is  768 bits\n"
                       "              default keysize is 1024 bits\n"
                       "    highest suggested keysize is 2048 bits\n"),
                     pubkey_algo_to_string(algo) );
@@ -1024,10 +1107,12 @@ ask_keysize( int algo )
 	if( algo == PUBKEY_ALGO_DSA && (nbits < 512 || nbits > 1024) )
 	    tty_printf(_("DSA only allows keysizes from 512 to 1024\n"));
 	else if( algo == PUBKEY_ALGO_RSA && nbits < 1024 )
 	    tty_printf(_("keysize too small;"
 			 " 1024 is smallest value allowed for RSA.\n"));
+	else if( algo == PUBKEY_ALGO_LANS && nbits != 1024 )
+	    tty_printf(_("LANS only allows keysizes of 1024 bits\n"));
 	else if( nbits < 768 )
 	    tty_printf(_("keysize too small;"
 			 " 768 is smallest value allowed.\n"));
 	else if( nbits > 4096 ) {
 	    /* It is ridiculous and an annoyance to use larger key sizes!
@@ -1427,10 +1512,12 @@ do_create( int algo, unsigned int nbits,
 	rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k, sk, expiredate);
     else if( algo == PUBKEY_ALGO_DSA )
 	rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, sk, expiredate);
     else if( algo == PUBKEY_ALGO_RSA )
 	rc = gen_rsa(algo, nbits, pub_root, sec_root, dek, s2k, sk, expiredate);
+    else if( algo == PUBKEY_ALGO_LANS )
+	   rc = gen_lans(nbits, pub_root, sec_root, dek, s2k, sk, expiredate);
     else
 	BUG();
 
   #ifdef ENABLE_COMMENT_PACKETS
     if( !rc ) {
diff -u5prk.orig gnupg-1.2.1.orig/g10/keyid.c gnupg-1.2.1/g10/keyid.c
--- gnupg-1.2.1.orig/g10/keyid.c	2002-06-29 17:46:34 +0400
+++ gnupg-1.2.1/g10/keyid.c	2002-12-20 17:33:42 +0300
@@ -42,10 +42,11 @@ pubkey_letter( int algo )
       case PUBKEY_ALGO_RSA_E:	return 'r' ;
       case PUBKEY_ALGO_RSA_S:	return 's' ;
       case PUBKEY_ALGO_ELGAMAL_E: return 'g';
       case PUBKEY_ALGO_ELGAMAL: return 'G' ;
       case PUBKEY_ALGO_DSA:	return 'D' ;
+      case PUBKEY_ALGO_LANS:	return 'L' ;
       default: return '?';
     }
 }
 
 static MD_HANDLE
diff -u5prk.orig gnupg-1.2.1.orig/g10/mainproc.c gnupg-1.2.1/g10/mainproc.c
--- gnupg-1.2.1.orig/g10/mainproc.c	2002-10-12 15:39:35 +0400
+++ gnupg-1.2.1/g10/mainproc.c	2002-12-20 17:33:42 +0300
@@ -334,10 +334,11 @@ proc_pubkey_enc( CTX c, PACKET *pkt )
 	    m_free(c->dek); c->dek = NULL;
 	}
     }
     else if( is_ELGAMAL(enc->pubkey_algo)
 	|| enc->pubkey_algo == PUBKEY_ALGO_DSA
+	|| enc->pubkey_algo == PUBKEY_ALGO_LANS
 	|| is_RSA(enc->pubkey_algo)  ) {
 	if ( !c->dek && ((!enc->keyid[0] && !enc->keyid[1])
                           || opt.try_all_secrets
 			  || !seckey_available( enc->keyid )) ) {
 	    if( opt.list_only )
@@ -1594,11 +1595,11 @@ proc_tree( CTX c, KBNODE node )
 		     && is_RSA( sig->pubkey_algo ) ) {
 		/* enable a workaround for a pgp2 bug */
 		c->mfx.md2 = md_open( DIGEST_ALGO_MD5, 0 );
 	    }
 	    else if( sig->digest_algo == DIGEST_ALGO_SHA1
-		     && sig->pubkey_algo == PUBKEY_ALGO_DSA
+		     && ( sig->pubkey_algo == PUBKEY_ALGO_DSA || sig->pubkey_algo == PUBKEY_ALGO_LANS )
 		     && sig->sig_class == 0x01 ) {
 		/* enable the workaround also for pgp5 when the detached
 		 * signature has been created in textmode */
 		c->mfx.md2 = md_open( sig->digest_algo, 0 );
 	    }
diff -u5prk.orig gnupg-1.2.1.orig/g10/misc.c gnupg-1.2.1/g10/misc.c
--- gnupg-1.2.1.orig/g10/misc.c	2002-09-11 11:27:54 +0400
+++ gnupg-1.2.1/g10/misc.c	2002-12-20 17:33:42 +0300
@@ -180,10 +180,14 @@ print_cipher_algo_note( int algo )
 	     || algo == CIPHER_ALGO_BLOWFISH
 	     || algo == CIPHER_ALGO_TWOFISH
 	     || algo == CIPHER_ALGO_RIJNDAEL
 	     || algo == CIPHER_ALGO_RIJNDAEL192
 	     || algo == CIPHER_ALGO_RIJNDAEL256
+	     || algo == CIPHER_ALGO_WICKER
+	     || algo == CIPHER_ALGO_NUSH256
+	     || algo == CIPHER_ALGO_NUSH192
+	     || algo == CIPHER_ALGO_NUSH128
 	   )
 	;
     else {
 	static int did_note = 0;
 
@@ -273,10 +277,13 @@ openpgp_pk_algo_usage ( int algo )
           use = PUBKEY_USAGE_SIG;
           break;
       case PUBKEY_ALGO_ELGAMAL:
           use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC;
           break;
+      case PUBKEY_ALGO_LANS:  
+          use = PUBKEY_USAGE_SIG;
+          break;
       default:
           break;
     }
     return use;
 }
diff -u5prk.orig gnupg-1.2.1.orig/g10/seskey.c gnupg-1.2.1/g10/seskey.c
--- gnupg-1.2.1.orig/g10/seskey.c	2002-06-29 17:46:34 +0400
+++ gnupg-1.2.1/g10/seskey.c	2002-12-20 17:33:42 +0300
@@ -198,11 +198,13 @@ encode_md_value( int pubkey_algo, MD_HAN
         mdlen = md_digest_length (hash_algo);
         if (mdlen != 20) {
             log_error (_("DSA requires the use of a 160 bit hash algorithm\n"));
             return NULL;
         }
+    }
 
+    if( pubkey_algo == PUBKEY_ALGO_DSA || pubkey_algo == PUBKEY_ALGO_LANS ) {
 	frame = md_is_secure(md)? mpi_alloc_secure((md_digest_length(hash_algo)
 				 +BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB )
 				: mpi_alloc((md_digest_length(hash_algo)
 				 +BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB );
 	mpi_set_buffer( frame, md_read(md, hash_algo),
diff -u5prk.orig gnupg-1.2.1.orig/g10/sign.c gnupg-1.2.1/g10/sign.c
--- gnupg-1.2.1.orig/g10/sign.c	2002-08-20 16:45:57 +0400
+++ gnupg-1.2.1/g10/sign.c	2002-12-20 17:33:42 +0300
@@ -334,11 +334,11 @@ hash_for(int pubkey_algo, int packet_ver
 {
     if( opt.def_digest_algo )
 	return opt.def_digest_algo;
     if( recipient_digest_algo )
         return recipient_digest_algo;
-    if( pubkey_algo == PUBKEY_ALGO_DSA )
+    if( pubkey_algo == PUBKEY_ALGO_DSA || pubkey_algo == PUBKEY_ALGO_LANS )
 	return DIGEST_ALGO_SHA1;
     if( pubkey_algo == PUBKEY_ALGO_RSA && packet_version < 4 )
 	return DIGEST_ALGO_MD5;
     return DEFAULT_DIGEST_ALGO;
 }
diff -u5prk.orig gnupg-1.2.1.orig/include/cipher.h gnupg-1.2.1/include/cipher.h
--- gnupg-1.2.1.orig/include/cipher.h	2002-08-13 22:44:25 +0400
+++ gnupg-1.2.1/include/cipher.h	2002-12-20 17:33:42 +0300
@@ -40,27 +40,33 @@
 #define CIPHER_ALGO_RIJNDAEL192  CIPHER_ALGO_AES192
 #define CIPHER_ALGO_RIJNDAEL256  CIPHER_ALGO_AES256
 #define CIPHER_ALGO_TWOFISH	10  /* twofish 256 bit */
 #define CIPHER_ALGO_SKIPJACK   101  /* experimental: skipjack */
 #define CIPHER_ALGO_TWOFISH_OLD 102 /* experimental: twofish 128 bit */
+#define CIPHER_ALGO_WICKER      103   /* LAN Crypto WICKER */
+#define CIPHER_ALGO_NUSH128     104   /* LAN Crypto NUSH128 */
+#define CIPHER_ALGO_NUSH192     105   /* LAN Crypto NUSH192 */
+#define CIPHER_ALGO_NUSH256     106   /* LAN Crypto NUSH256 */
 #define CIPHER_ALGO_DUMMY      110  /* no encryption at all */
 
 #define PUBKEY_ALGO_RSA        1
 #define PUBKEY_ALGO_RSA_E      2     /* RSA encrypt only */
 #define PUBKEY_ALGO_RSA_S      3     /* RSA sign only */
 #define PUBKEY_ALGO_ELGAMAL_E 16     /* encrypt only ElGamal (but not for v3)*/
 #define PUBKEY_ALGO_DSA       17
 #define PUBKEY_ALGO_ELGAMAL   20     /* sign and encrypt elgamal */
+#define PUBKEY_ALGO_LANS      101    /* LAN Crypto LANS */
 
 #define PUBKEY_USAGE_SIG     1	    /* key is good for signatures */
 #define PUBKEY_USAGE_ENC     2	    /* key is good for encryption */
 #define PUBKEY_USAGE_CERT    4      /* key is also good to certify other keys*/
 
 #define DIGEST_ALGO_MD5       1
 #define DIGEST_ALGO_SHA1      2
 #define DIGEST_ALGO_RMD160    3
 #define DIGEST_ALGO_TIGER     6
+#define DIGEST_ALGO_GAS48     101		/* LAN Crypto GAS48 */
 
 #define is_RSA(a)     ((a)==PUBKEY_ALGO_RSA || (a)==PUBKEY_ALGO_RSA_E \
 		       || (a)==PUBKEY_ALGO_RSA_S )
 #define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL || (a)==PUBKEY_ALGO_ELGAMAL_E)
 
