Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/agc-netpgp-standalone]: src/crypto/external/bsd/netpgp Now that idea is ...
details: https://anonhg.NetBSD.org/src/rev/8e954c7c32b0
branches: agc-netpgp-standalone
changeset: 777810:8e954c7c32b0
user: agc <agc%NetBSD.org@localhost>
date: Sat Oct 20 04:42:42 2012 +0000
description:
Now that idea is out of jail, add it as a cipher - requested by christos.
For all intents and purposes, AES will be used these days, but idea may
be used in legacy things, so mainly for completeness.
diffstat:
crypto/external/bsd/netpgp/dist/src/libcipher/idea.c | 529 +++++++++++++++++++
crypto/external/bsd/netpgp/dist/src/libcipher/idea.h | 59 ++
crypto/external/bsd/netpgp/lib/cipher/Makefile | 3 +-
3 files changed, 590 insertions(+), 1 deletions(-)
diffs (truncated from 617 to 300 lines):
diff -r 209a48e53948 -r 8e954c7c32b0 crypto/external/bsd/netpgp/dist/src/libcipher/idea.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crypto/external/bsd/netpgp/dist/src/libcipher/idea.c Sat Oct 20 04:42:42 2012 +0000
@@ -0,0 +1,529 @@
+/* Paulo Barreto <pbarreto%unisys.com.br@localhost> 1996.01.17 */
+/*
+ * idea.c - C source code for IDEA block cipher.
+ * IDEA (International Data Encryption Algorithm), formerly known as
+ * IPES (Improved Proposed Encryption Standard).
+ * Algorithm developed by Xuejia Lai and James L. Massey, of ETH Zurich.
+ * This implementation modified and derived from original C code
+ * developed by Xuejia Lai.
+ * Zero-based indexing added, names changed from IPES to IDEA.
+ * CFB functions added. Random number routines added.
+ *
+ * Extensively optimized and restructured by Colin Plumb.
+ *
+ * The IDEA(tm) block cipher is covered by patents held by ETH and a
+ * Swiss company called Ascom-Tech AG. The Swiss patent number is
+ * PCT/CH91/00117, the European patent number is EP 0 482 154 B1, and
+ * the U.S. patent number is US005214703. IDEA(tm) is a trademark of
+ * Ascom-Tech AG. There is no license fee required for noncommercial
+ * use. Commercial users may obtain licensing details from Dieter
+ * Profos, Ascom Tech AG, Solothurn Lab, Postfach 151, 4502 Solothurn,
+ * Switzerland, Tel +41 65 242885, Fax +41 65 235761.
+ *
+ * The IDEA block cipher uses a 64-bit block size, and a 128-bit key
+ * size. It breaks the 64-bit cipher block into four 16-bit words
+ * because all of the primitive inner operations are done with 16-bit
+ * arithmetic. It likewise breaks the 128-bit cipher key into eight
+ * 16-bit words.
+ *
+ * For further information on the IDEA cipher, see the book:
+ * Xuejia Lai, "On the Design and Security of Block Ciphers",
+ * ETH Series on Information Processing (ed. J.L. Massey) Vol 1,
+ * Hartung-Gorre Verlag, Konstanz, Switzerland, 1992. ISBN
+ * 3-89191-573-X.
+ *
+ * This code runs on arrays of bytes by taking pairs in big-endian
+ * order to make the 16-bit words that IDEA uses internally. This
+ * produces the same result regardless of the byte order of the
+ * native CPU.
+ */
+#include <inttypes.h>
+#include <string.h>
+
+#include "idea.h"
+
+#define OPTIMIZE
+
+#define LOW16(x) ((x) & 0xFFFF)
+
+/*
+ * Compute the multiplicative inverse of x, modulo 65537, using Euclid's
+ * algorithm. It is unrolled twice to avoid swapping the registers each
+ * iteration, and some subtracts of t have been changed to adds.
+ */
+static __inline uint16_t
+mulInv(uint16_t x)
+{
+ uint16_t t0, t1;
+ uint16_t q, y;
+
+ if (x <= 1)
+ return x; /* 0 and 1 are self-inverse */
+ t1 = 0x10001 / x; /* Since x >= 2, this fits into 16 bits */
+ y = 0x10001 % x;
+ if (y == 1)
+ return ( uint16_t ) LOW16(1-t1);
+ t0 = 1;
+ do {
+ q = x / y;
+ x = x % y;
+ t0 += q * t1;
+ if (x == 1)
+ return t0;
+ q = y / x;
+ y = y % x;
+ t1 += q * t0;
+ } while (y != 1);
+ return ( uint16_t ) LOW16(1-t1);
+}
+
+/*
+ * Expand a 128-bit user key to a working encryption key EK
+ */
+static void
+ideaExpandKey(const uint8_t *userkey, uint16_t *EK)
+{
+ unsigned i,j;
+
+ for (j=0; j<8; j++) {
+ EK[j] = (userkey[0]<<8) + userkey[1];
+ userkey += 2;
+ }
+ for (i=0; j < IDEA_KEYLEN; j++) {
+ i++;
+ EK[i+7] = (EK[i & 7] << 9) | (EK[(i + 1) & 7] >> 7);
+ EK += i & 8;
+ i &= 7;
+ }
+}
+
+#define NEG(x) (- (int) (x))
+
+/*
+ * Compute IDEA decryption key DK from an expanded IDEA encryption key EK
+ * Note that the input and output may be the same. Thus, the key is
+ * inverted into an internal buffer, and then copied to the output.
+ */
+static void
+ideaInvertKey(const uint16_t *EK, uint16_t DK[IDEA_KEYLEN])
+{
+ uint16_t temp[IDEA_KEYLEN];
+#ifdef OPTIMIZE
+ register int k, p, r;
+
+ p = IDEA_KEYLEN;
+ temp [p-1] = mulInv (EK [3]);
+ temp [p-2] = NEG (EK [2]);
+ temp [p-3] = NEG (EK [1]);
+ temp [p-4] = mulInv (EK [0]);
+
+ k = 4; p -= 4;
+ for (r = IDEA_ROUNDS - 1; r > 0; r--) {
+ temp [p-1] = EK [k+1];
+ temp [p-2] = EK [k];
+ temp [p-3] = mulInv (EK [k+5]);
+ temp [p-4] = NEG (EK [k+3]);
+ temp [p-5] = NEG (EK [k+4]);
+ temp [p-6] = mulInv (EK [k+2]);
+ k += 6; p -= 6;
+ }
+ temp [p-1] = EK [k+1];
+ temp [p-2] = EK [k];
+ temp [p-3] = mulInv (EK [k+5]);
+ temp [p-4] = NEG (EK [k+4]);
+ temp [p-5] = NEG (EK [k+3]);
+ temp [p-6] = mulInv (EK [k+2]);
+#else /* !OPTIMIZE */
+ int i;
+ uint16_t t1, t2, t3;
+ uint16_t *p = temp + IDEA_KEYLEN;
+
+ t1 = mulInv(*EK++);
+ t2 = - ( int ) *EK++;
+ t3 = - ( int ) *EK++;
+ *--p = mulInv(*EK++);
+ *--p = t3;
+ *--p = t2;
+ *--p = t1;
+
+ for (i = 0; i < IDEA_ROUNDS-1; i++) {
+ t1 = *EK++;
+ *--p = *EK++;
+ *--p = t1;
+
+ t1 = mulInv(*EK++);
+ t2 = - ( int ) *EK++;
+ t3 = - ( int ) *EK++;
+ *--p = mulInv(*EK++);
+ *--p = t2;
+ *--p = t3;
+ *--p = t1;
+ }
+ t1 = *EK++;
+ *--p = *EK++;
+ *--p = t1;
+
+ t1 = mulInv(*EK++);
+ t2 = - ( int ) *EK++;
+ t3 = - ( int ) *EK++;
+ *--p = mulInv(*EK++);
+ *--p = t3;
+ *--p = t2;
+ *--p = t1;
+#endif /* ?OPTIMIZE */
+/* Copy and destroy temp copy */
+ memcpy(DK, temp, sizeof(temp));
+ memset(temp, 0x0, sizeof(temp));
+}
+
+/*
+ * MUL(x,y) computes x = x*y, modulo 0x10001. Requires two temps,
+ * t16 and t32. x is modified, and must me a side-effect-free lvalue.
+ * y may be anything, but unlike x, must be strictly 16 bits even if
+ * LOW16() is #defined.
+ * All of these are equivalent - see which is faster on your machine
+ */
+#define MUL(x,y) \
+ ((t16 = (y)) ? \
+ (x=LOW16(x)) ? \
+ t32 = (uint32_t)x*t16, \
+ x = LOW16(t32), \
+ t16 = t32>>16, \
+ x = (x-t16)+(x<t16) \
+ : \
+ (x = 1-t16) \
+ : \
+ (x = 1-x))
+
+/* IDEA encryption/decryption algorithm */
+/* Note that in and out can be the same buffer */
+static void
+ideaCipher(const uint8_t inbuf[8], uint8_t outbuf[8], const uint16_t *key)
+{
+ register uint16_t x1, x2, x3, x4, s2, s3;
+ const uint16_t *in;
+ uint16_t *out;
+ register uint16_t t16; /* Temporaries needed by MUL macro */
+ register uint32_t t32;
+#ifndef OPTIMIZE
+ int r = IDEA_ROUNDS;
+#endif /* ?OPTIMIZE */
+ int indian = 1;
+
+ in = (const uint16_t *)(const void *)inbuf;
+#ifdef OPTIMIZE
+ x1 = in[0]; x2 = in[1];
+ x3 = in[2]; x4 = in[3];
+#else /* !OPTIMIZE */
+ x1 = *in++; x2 = *in++;
+ x3 = *in++; x4 = *in;
+#endif /* ?OPTIMIZE */
+ if (*(char *)(void *)&indian) {
+ /* little endian */
+ x1 = (x1>>8) | (x1<<8);
+ x2 = (x2>>8) | (x2<<8);
+ x3 = (x3>>8) | (x3<<8);
+ x4 = (x4>>8) | (x4<<8);
+ }
+
+#ifdef OPTIMIZE
+ /* round 1: */
+ MUL(x1,key[0]);
+ x2 += key[1];
+ x3 += key[2];
+ MUL(x4, key[3]);
+
+ s3 = x3;
+ x3 ^= x1;
+ MUL(x3, key[4]);
+ s2 = x2;
+ x2 ^= x4;
+ x2 += x3;
+ MUL(x2, key[5]);
+ x3 += x2;
+
+ x1 ^= x2; x4 ^= x3;
+ x2 ^= s3; x3 ^= s2;
+
+ /* round 2: */
+ MUL(x1,key[6]);
+ x2 += key[7];
+ x3 += key[8];
+ MUL(x4, key[9]);
+
+ s3 = x3;
+ x3 ^= x1;
+ MUL(x3, key[10]);
+ s2 = x2;
+ x2 ^= x4;
+ x2 += x3;
+ MUL(x2, key[11]);
+ x3 += x2;
+
+ x1 ^= x2; x4 ^= x3;
+ x2 ^= s3; x3 ^= s2;
+
+ /* round 3: */
+ MUL(x1,key[12]);
+ x2 += key[13];
+ x3 += key[14];
+ MUL(x4, key[15]);
+
+ s3 = x3;
+ x3 ^= x1;
+ MUL(x3, key[16]);
+ s2 = x2;
+ x2 ^= x4;
+ x2 += x3;
+ MUL(x2, key[17]);
+ x3 += x2;
+
+ x1 ^= x2; x4 ^= x3;
+ x2 ^= s3; x3 ^= s2;
+
+ /* round 4: */
+ MUL(x1,key[18]);
+ x2 += key[19];
+ x3 += key[20];
+ MUL(x4, key[21]);
+
+ s3 = x3;
+ x3 ^= x1;
+ MUL(x3, key[22]);
+ s2 = x2;
+ x2 ^= x4;
+ x2 += x3;
+ MUL(x2, key[23]);
Home |
Main Index |
Thread Index |
Old Index