Cryptography-Digest Digest #815, Volume #11      Thu, 18 May 00 20:13:01 EDT

Contents:
  Re: Skipjack implementation in C (this one works) ("Douglas A. Gwyn")
  Re: Matching substrings in a signature (Paul Rubin)
  Re: random.org? (Tim Tyler)
  Re: Open source cryptography library: BeeCrypt (Paul Rubin)
  Re: Unbreakable encryption. (Tim Tyler)

----------------------------------------------------------------------------

From: "Douglas A. Gwyn" <[EMAIL PROTECTED]>
Subject: Re: Skipjack implementation in C (this one works)
Date: Thu, 18 May 2000 23:09:24 GMT

/*
        SKIPJACK implementation in Standard C

        last edit:      25-Jan-1999     [EMAIL PROTECTED]

        This is a C89 implementation of the SKIPJACK block cipher algorithm
        described in version 2.0 of NSA's SKIPJACK specification dated
        29 May 1998 <http://csrc.nist.gov/encryption/skipjack-kea.htm>.
*/
#ifdef DEBUG
#include        <stdio.h>
#endif

/*
        Interface specification:
*/
#define SJ_Keysize      10      /* (80 bits) */

/* Encryption/decryption is performed for a single 64-bit block. */

void    SJ_Encrypt ( const unsigned char *Key, const unsigned char
*Plaintext,
                     unsigned char *Ciphertext
                   );

void    SJ_Decrypt ( const unsigned char *Key, const unsigned char
*Ciphertext,
                     unsigned char *Plaintext
                   );

int     SJ_Selftest ( void );   /* returns nonzero iff passed test */

/*
        Implementation:
*/

static const unsigned char F[256] =
        {
        0xA3, 0xD7, 0x09, 0x83, 0xF8, 0x48, 0xF6, 0xF4,
        0xB3, 0x21, 0x15, 0x78, 0x99, 0xB1, 0xAF, 0xF9,
        0xE7, 0x2D, 0x4D, 0x8A, 0xCE, 0x4C, 0xCA, 0x2E,
        0x52, 0x95, 0xD9, 0x1E, 0x4E, 0x38, 0x44, 0x28,
        0x0A, 0xDF, 0x02, 0xA0, 0x17, 0xF1, 0x60, 0x68,
        0x12, 0xB7, 0x7A, 0xC3, 0xE9, 0xFA, 0x3D, 0x53,
        0x96, 0x84, 0x6B, 0xBA, 0xF2, 0x63, 0x9A, 0x19,
        0x7C, 0xAE, 0xE5, 0xF5, 0xF7, 0x16, 0x6A, 0xA2,
        0x39, 0xB6, 0x7B, 0x0F, 0xC1, 0x93, 0x81, 0x1B,
        0xEE, 0xB4, 0x1A, 0xEA, 0xD0, 0x91, 0x2F, 0xB8,
        0x55, 0xB9, 0xDA, 0x85, 0x3F, 0x41, 0xBF, 0xE0,
        0x5A, 0x58, 0x80, 0x5F, 0x66, 0x0B, 0xD8, 0x90,
        0x35, 0xD5, 0xC0, 0xA7, 0x33, 0x06, 0x65, 0x69,
        0x45, 0x00, 0x94, 0x56, 0x6D, 0x98, 0x9B, 0x76,
        0x97, 0xFC, 0xB2, 0xC2, 0xB0, 0xFE, 0xDB, 0x20,
        0xE1, 0xEB, 0xD6, 0xE4, 0xDD, 0x47, 0x4A, 0x1D,
        0x42, 0xED, 0x9E, 0x6E, 0x49, 0x3C, 0xCD, 0x43,
        0x27, 0xD2, 0x07, 0xD4, 0xDE, 0xC7, 0x67, 0x18,
        0x89, 0xCB, 0x30, 0x1F, 0x8D, 0xC6, 0x8F, 0xAA,
        0xC8, 0x74, 0xDC, 0xC9, 0x5D, 0x5C, 0x31, 0xA4,
        0x70, 0x88, 0x61, 0x2C, 0x9F, 0x0D, 0x2B, 0x87,
        0x50, 0x82, 0x54, 0x64, 0x26, 0x7D, 0x03, 0x40,
        0x34, 0x4B, 0x1C, 0x73, 0xD1, 0xC4, 0xFD, 0x3B,
        0xCC, 0xFB, 0x7F, 0xAB, 0xE6, 0x3E, 0x5B, 0xA5,
        0xAD, 0x04, 0x23, 0x9C, 0x14, 0x51, 0x22, 0xF0,
        0x29, 0x79, 0x71, 0x7E, 0xFF, 0x8C, 0x0E, 0xE2,
        0x0C, 0xEF, 0xBC, 0x72, 0x75, 0x6F, 0x37, 0xA1,
        0xEC, 0xD3, 0x8E, 0x62, 0x8B, 0x86, 0x10, 0xE8,
        0x08, 0x77, 0x11, 0xBE, 0x92, 0x4F, 0x24, 0xC5,
        0x32, 0x36, 0x9D, 0xCF, 0xF3, 0xA6, 0xBB, 0xAC,
        0x5E, 0x6C, 0xA9, 0x13, 0x57, 0x25, 0xB5, 0xE3,
        0xBD, 0xA8, 0x3A, 0x01, 0x05, 0x59, 0x2A, 0x46
        };

void
SJ_Encrypt ( const unsigned char *K, const unsigned char *P, unsigned
char *C )
        {
        register int    i, k;   /* could be unsigned char */
        unsigned char   counter = 0;
        unsigned char   temp[2];

        for ( i = 0; i < 8; ++i )
                C[i] = P[i];

#ifdef DEBUG
        printf( "%2d", counter );
        for ( i = 0; i < 8; ++i )
                printf( " %2.2x", C[i] );
        printf( "\n" );
#endif

        k = 0;

        do      {
                ++counter;
                temp[0] = C[6];
                temp[1] = C[7];
                C[6] = C[4];
                C[7] = C[5];
                C[4] = C[2];
                C[5] = C[3];
                C[2] = C[0];
                C[3] = C[1];
                C[2] ^= F[C[3] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[3] ^= F[C[2] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[2] ^= F[C[3] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[3] ^= F[C[2] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[0] = temp[0] ^ C[2];
                C[1] = temp[1] ^ C[3] ^ counter;
#ifdef DEBUG
                printf( "%2d", counter );
                for ( i = 0; i < 8; ++i )
                        printf( " %2.2x", C[i] );
                printf( "\n" );
#endif
                }
        while ( counter < 8 );
        do      {
                ++counter;
                temp[0] = C[6];
                temp[1] = C[7];
                C[6] = C[4];
                C[7] = C[5];
                C[4] = C[2];
                C[5] = C[3];
                C[2] = C[0];
                C[3] = C[1];
                C[4] ^= C[0];
                C[5] ^= C[1] ^ counter;
                C[2] ^= F[C[3] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[3] ^= F[C[2] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[2] ^= F[C[3] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[3] ^= F[C[2] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[0] = temp[0];
                C[1] = temp[1];
#ifdef DEBUG
                printf( "%2d", counter );
                for ( i = 0; i < 8; ++i )
                        printf( " %2.2x", C[i] );
                printf( "\n" );
#endif
                }
        while ( counter < 16 );
        do      {
                ++counter;
                temp[0] = C[6];
                temp[1] = C[7];
                C[6] = C[4];
                C[7] = C[5];
                C[4] = C[2];
                C[5] = C[3];
                C[2] = C[0];
                C[3] = C[1];
                C[2] ^= F[C[3] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[3] ^= F[C[2] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[2] ^= F[C[3] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[3] ^= F[C[2] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[0] = temp[0] ^ C[2];
                C[1] = temp[1] ^ C[3] ^ counter;
#ifdef DEBUG
                printf( "%2d", counter );
                for ( i = 0; i < 8; ++i )
                        printf( " %2.2x", C[i] );
                printf( "\n" );
#endif
                }
        while ( counter < 24 );
        do      {
                ++counter;
                temp[0] = C[6];
                temp[1] = C[7];
                C[6] = C[4];
                C[7] = C[5];
                C[4] = C[2];
                C[5] = C[3];
                C[2] = C[0];
                C[3] = C[1];
                C[4] ^= C[0];
                C[5] ^= C[1] ^ counter;
                C[2] ^= F[C[3] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[3] ^= F[C[2] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[2] ^= F[C[3] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[3] ^= F[C[2] ^ K[k]];
                if ( ++k >= SJ_Keysize )
                        k = 0;
                C[0] = temp[0];
                C[1] = temp[1];
#ifdef DEBUG
                printf( "%2d", counter );
                for ( i = 0; i < 8; ++i )
                        printf( " %2.2x", C[i] );
                printf( "\n" );
#endif
                }
        while ( counter < 32 );
        }

void
SJ_Decrypt ( const unsigned char *K, const unsigned char *C, unsigned
char *P )
        {
        register int    i, k;   /* could be unsigned char */
        unsigned char   counter = 32;
        unsigned char   temp[2];

        for ( i = 0; i < 8; ++i )
                P[i] = C[i];

        k = 127 % SJ_Keysize /* + 1 */;

        do      {
#ifdef DEBUG
                printf( "%2d", counter );
                for ( i = 0; i < 8; ++i )
                        printf( " %2.2x", P[i] );
                printf( "\n" );
#endif
                temp[0] = P[0];
                temp[1] = P[1];
                P[0] = P[2];
                P[1] = P[3];
                P[2] = P[4];
                P[3] = P[5];
                P[4] = P[6];
                P[5] = P[7];
                P[1] ^= F[P[0] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[0] ^= F[P[1] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[1] ^= F[P[0] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[0] ^= F[P[1] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[2] ^= P[0];
                P[3] ^= P[1] ^ counter;
                P[6] = temp[0];
                P[7] = temp[1];
                --counter;
                }
        while ( counter > 24 );
        do      {
#ifdef DEBUG
                printf( "%2d", counter );
                for ( i = 0; i < 8; ++i )
                        printf( " %2.2x", P[i] );
                printf( "\n" );
#endif
                temp[0] = P[0] ^ P[2];
                temp[1] = P[1] ^ P[3] ^ counter;
                P[0] = P[2];
                P[1] = P[3];
                P[2] = P[4];
                P[3] = P[5];
                P[4] = P[6];
                P[5] = P[7];
                P[1] ^= F[P[0] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[0] ^= F[P[1] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[1] ^= F[P[0] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[0] ^= F[P[1] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[6] = temp[0];
                P[7] = temp[1];
                --counter;
                }
        while ( counter > 16 );
        do      {
#ifdef DEBUG
                printf( "%2d", counter );
                for ( i = 0; i < 8; ++i )
                        printf( " %2.2x", P[i] );
                printf( "\n" );
#endif
                temp[0] = P[0];
                temp[1] = P[1];
                P[0] = P[2];
                P[1] = P[3];
                P[2] = P[4];
                P[3] = P[5];
                P[4] = P[6];
                P[5] = P[7];
                P[1] ^= F[P[0] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[0] ^= F[P[1] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[1] ^= F[P[0] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[0] ^= F[P[1] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[2] ^= P[0];
                P[3] ^= P[1] ^ counter;
                P[6] = temp[0];
                P[7] = temp[1];
                --counter;
                }
        while ( counter > 8 );
        do      {
#ifdef DEBUG
                printf( "%2d", counter );
                for ( i = 0; i < 8; ++i )
                        printf( " %2.2x", P[i] );
                printf( "\n" );
#endif
                temp[0] = P[0] ^ P[2];
                temp[1] = P[1] ^ P[3] ^ counter;
                P[0] = P[2];
                P[1] = P[3];
                P[2] = P[4];
                P[3] = P[5];
                P[4] = P[6];
                P[5] = P[7];
                P[1] ^= F[P[0] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[0] ^= F[P[1] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[1] ^= F[P[0] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[0] ^= F[P[1] ^ K[k]];
                if ( --k < 0 )
                        k = SJ_Keysize - 1;
                P[6] = temp[0];
                P[7] = temp[1];
                --counter;
                }
        while ( counter > 0 );

#ifdef DEBUG
        printf( "%2d", counter );
        for ( i = 0; i < 8; ++i )
                printf( " %2.2x", P[i] );
        printf( "\n" );
#endif
        }

int
SJ_Selftest( void )
        {
        register int            i;
        const unsigned char     K[10] =
                {
                        0x00, 0x99, 0x88, 0x77, 0x66,
                        0x55, 0x44, 0x33, 0x22, 0x11
                };
        const unsigned char     P[8] =
                {
                        0x33, 0x22, 0x11, 0x00,
                        0xDD, 0xCC, 0xBB, 0xAA
                };
        unsigned char           C[8], P2[8];
        const unsigned char     Cexp[8] =
                {
                        0x25, 0x87, 0xCA, 0xE2,
                        0x7A, 0x12, 0xD3, 0x00
                };

#ifdef DEBUG
        printf( "K:" );
        for ( i = 0; i < 10; ++i )
                printf( " %2.2x", K[i] );
        printf( "\n" );
        printf( "P:" );
        for ( i = 0; i < 8; ++i )
                printf( " %2.2x", P[i] );
        printf( "\n" );
#endif

        SJ_Encrypt( K, P, C );

#ifdef DEBUG
        printf( "C:" );
        for ( i = 0; i < 8; ++i )
                printf( " %2.2x", C[i] );
        printf( "\n" );
        printf( "E:" );
        for ( i = 0; i < 8; ++i )
                printf( " %2.2x", Cexp[i] );
        printf( "\n" );
        for ( i = 0; i < 8; ++i )
                C[i] = Cexp[i];
#endif

        SJ_Decrypt( K, C, P2 );

#ifdef DEBUG
        printf( "R:" );
        for ( i = 0; i < 8; ++i )
                printf( " %2.2x", P2[i] );
        printf( "\n" );
#endif

        for ( i = 0; i < 8; ++i )
                if ( C[i] != Cexp[i] || P2[i] != P[i] )
                        return 0;

        return 1;
        }

#ifdef TEST
/*
        SKIPJACK test in Standard C

        last edit:      25-Jan-1999     [EMAIL PROTECTED]
*/

#include        <stdio.h>
#include        <stdlib.h>

/*
        SKIPJACK library Interface specification:
*/
#define SJ_Keysize      10      /* (80 bits) */

/* Encryption/decryption is performed for a single 64-bit block. */

void    SJ_Encrypt ( const unsigned char *Key, const unsigned char
*Plaintext,
                     unsigned char *Ciphertext
                   );

void    SJ_Decrypt ( const unsigned char *Key, const unsigned char
*Ciphertext,
                     unsigned char *Plaintext
                   );

int     SJ_Selftest ( void );   /* returns nonzero iff passed test */

/*
        Test program:
*/

int
main( int argc, char **argv )
        {
        static char     *mess[2] = { "Failed", "Succeeded" };
        register int    ok = SJ_Selftest();

        printf( "SKIPJACK TEST: %s.\n", mess[ok] );

        return ok ? EXIT_SUCCESS : EXIT_FAILURE;
        }
#endif

------------------------------

From: [EMAIL PROTECTED] (Paul Rubin)
Subject: Re: Matching substrings in a signature
Date: 18 May 2000 23:23:57 GMT

In article <8g1hbk$c38$[EMAIL PROTECTED]>,
Ken Christensen <[EMAIL PROTECTED]> wrote:
>Hello all, cryptography is not my area. so my apologies if this is a stupid
>or inappropriate question.  Is there a method of encoding or hashing that
>would allow one to determine if a substring is contained within a signature
>of a string?  That is, if "abcdefghij" encrypts to a signature "xyz" (where
>"xyz" is much smaller than "abcdefghij"), can I determine if "def" is
>contained within "xyz"?  The intended application is to take a list of names
>and compress them into a signature.  Then, with high probability (100%
>certainty is not needed!) determine if, say, "John Doe" is contained in the
>list given only knowledge of the signature.  False hits are perfectly OK,
>false misses are not OK, but can be dealt with if necessary.  Yes, I do know
>about Bloom filters. I am looking for other methods.  Efficiency in both
>processing and memory are important.

Look in "Programming Pearls" by Jon Bentley, for his description of
M. D. McIlroy's implementation of the original Unix spelling checker
program on the PDP-11.  It used a bit map where each bit position
corresponded to the hash of an English word from a dictionary.  If you
wanted to know whether a word was in the dictionary, you'd hash it and
look in the bit map.  There were a bunch of other tricks for handling
exceptions, common prefixes and suffixes, etc.

I think the Apple Hypercard program also did something like that.

------------------------------

From: Tim Tyler <[EMAIL PROTECTED]>
Subject: Re: random.org?
Reply-To: [EMAIL PROTECTED]
Date: Thu, 18 May 2000 23:05:47 GMT

RecilS <[EMAIL PROTECTED]> wrote:

: Does anyone know the quality level of random.org? [...]

The conventional web interface fails to use SSL - so eavsdroppers can see
your random numbers as they come to you - so they can't be subsequently
assumed to be secure for cryptographic purposes.

Beyond that, I can't say.
-- 
__________  Lotus Artificial Life  http://alife.co.uk/  [EMAIL PROTECTED]
 |im |yler  The Mandala Centre   http://mandala.co.uk/  Breast is best.

------------------------------

From: [EMAIL PROTECTED] (Paul Rubin)
Subject: Re: Open source cryptography library: BeeCrypt
Date: 18 May 2000 23:47:56 GMT

In article <[EMAIL PROTECTED]>,
Bob Deblier  <[EMAIL PROTECTED]> wrote:
>My employer, Virtual Unlimited B.V., has graciously given permission to
>release the cryptography library I have developed as open source under
>the GNU Lesser General Public License. Virtual Unlimited feels that it
>is essential that the cryptographic routines used by our products be
>open for inspection, and that strong cryptography should be available to
>everyone for protecting your privacy.

What does this library do that the OpenSSL library doesn't?  And if
you don't release source to your application that uses the library,
how can users check whether the application has its own security bugs?

Thanks.

------------------------------

From: Tim Tyler <[EMAIL PROTECTED]>
Subject: Re: Unbreakable encryption.
Reply-To: [EMAIL PROTECTED]
Date: Thu, 18 May 2000 23:30:16 GMT

[EMAIL PROTECTED] wrote:

: I would welcome any comments on weaknesses in Base Encryption. [...]

Your method (as described in your examples) applies a base change, a
linear transformation, and then a base change - and that's it.

Try encrypting a file consisting of all zero bytes using this technique
to see how useless it is.
-- 
__________  Lotus Artificial Life  http://alife.co.uk/  [EMAIL PROTECTED]
 |im |yler  The Mandala Centre   http://mandala.co.uk/  This tagline no verb.

------------------------------


** FOR YOUR REFERENCE **

The service address, to which questions about the list itself and requests
to be added to or deleted from it should be directed, is:

    Internet: [EMAIL PROTECTED]

You can send mail to the entire list (and sci.crypt) via:

    Internet: [EMAIL PROTECTED]

End of Cryptography-Digest Digest
******************************

Reply via email to