Cryptography-Digest Digest #667, Volume #9        Sat, 5 Jun 99 23:13:02 EDT

Contents:
  IDEA in Java (Dominik Werder)
  SCOTT19U pass in nut shell (SCOTT19U.ZIP_GUY)
  Re: Challenge to SCOTT19U.ZIP_GUY ([EMAIL PROTECTED])
  Re: OTP Problems (Patrick Juola)
  Re: The BRUCE SCHNEIER  Tirade (Patrick Juola)
  Scottu: I actually saw something usefull ([EMAIL PROTECTED])
  Re: Another source of random numbers (Barney Wol)
  Re: evolving round keys
  Re: "Cipher Systems", Beker & Piper?

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

From: Dominik Werder <[EMAIL PROTECTED]>
Subject: IDEA in Java
Date: Sun, 06 Jun 1999 00:14:28 +0200

Dies ist eine mehrteilige Nachricht im MIME-Format.
==============C17B702688FF3EA9E94363A0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi!

I try to implement IDEA in Java, but the code dont pass the test vectors
sb. posted me here.
Perhaps has sb the time to take a look at the code, i included it as
attachment.
thx

Dom.
==============C17B702688FF3EA9E94363A0
Content-Type: text/plain; charset=us-ascii;
 name="IDEA.java"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="IDEA.java"


// IDEA Modul (C) by Dominik Werder 1999

// daten input und output immer auf byte[] basis
// ECB
// CBC

class IDEA {

  static private int[] encryptKeys = new int[52];
  static private int[] decryptKeys = new int[52];



  public static void setKey(int[] key) {     // generiert die ganzen subkeys usw....
    int k1, k2, j;
    int t1, t2, t3;

    // Encryption keys.  The first 8 key values come from the 16
    // user-supplied key bytes.
    k1 = 0;
    while (k1 <= 7) {
      encryptKeys[k1] = ((key[2 * k1] & 0xff) << 8) | (key[2 * k1 + 1] & 0xff);
      k1++;
    }

    // Subsequent key values are the previous values rotated to the
    // left by 25 bits.

    while (k1 <= 51) {
      encryptKeys[k1] = ((encryptKeys[k1 - 8] << 9) | (encryptKeys[k1 - 7] >>> 7)) & 
0xffff;
      k1++;
    }


    // Decryption keys.  These are the encryption keys, inverted and
    // in reverse order.
    k1 = 0;
    k2 = 51;
    t1 = mulinv( encryptKeys[k1++] );
    t2 = -encryptKeys[k1++];
    t3 = -encryptKeys[k1++];
    decryptKeys[k2--] = mulinv( encryptKeys[k1++] );
    decryptKeys[k2--] = t3;
    decryptKeys[k2--] = t2;
    decryptKeys[k2--] = t1;
    j = 1;
    while (j < 8) {
      t1 = encryptKeys[k1++];
      decryptKeys[k2--] = encryptKeys[k1++];
      decryptKeys[k2--] = t1;
      t1 = mulinv( encryptKeys[k1++] );
      t2 = -encryptKeys[k1++];
      t3 = -encryptKeys[k1++];
      decryptKeys[k2--] = mulinv( encryptKeys[k1++] );
      decryptKeys[k2--] = t2;
      decryptKeys[k2--] = t3;
      decryptKeys[k2--] = t1;
      j++;
    }
    t1 = encryptKeys[k1++];
    decryptKeys[k2--] = encryptKeys[k1++];
    decryptKeys[k2--] = t1;
    t1 = mulinv( encryptKeys[k1++] );
    t2 = -encryptKeys[k1++];
    t3 = -encryptKeys[k1++];
    decryptKeys[k2--] = mulinv( encryptKeys[k1++] );
    decryptKeys[k2--] = t3;
    decryptKeys[k2--] = t2;
    decryptKeys[k2--] = t1;

    k1 = 0;
    while (k1 <= 51) {
      //encryptKeys[k1] = (encryptKeys[k1] & 0xffff);
      //decryptKeys[k1] = (decryptKeys[k1] & 0xffff);
      //encryptKeys[k1] = (encryptKeys[k1] ^ 0x0dae);     // I read one can avoid weak 
keys by xoring every subkey with "0dae", but it doesnt work
      //decryptKeys[k1] = (decryptKeys[k1] ^ 0x0dae);
      //encryptKeys[k1] = (encryptKeys[k1] ^ 0x0dae) & 0xffff;
      //decryptKeys[k1] = (decryptKeys[k1] ^ 0x0dae) & 0xffff;
      k1++;
    }
  }



  // Run IDEA on one block
  // t1..t14 are temp variables for the inner rounds
  // k counts the key-index
  private static void ideacore(int[] in, int[] out, int[] keys) {
    int x1, x2, x3, x4, k, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, 
t14, round;

    x1 = in[0] & 0xffff;  // taking only the lowest 16 bit of the 32 bit integer
    x2 = in[1] & 0xffff;
    x3 = in[2] & 0xffff;
    x4 = in[3] & 0xffff;
    k = 0;
    round = 0;
    while (round <= 7) {
      t1 = (mul(x1, keys[k])) & 0xffff; k++;
      t2 = ((x2 + keys[k]) % 0x10000) & 0xffff; k++;
      t3 = ((x3 + keys[k]) % 0x10000) & 0xffff; k++;
      t4 = (mul(x4, keys[k])) & 0xffff; k++;

      t5 = (t1 ^ t3) & 0xffff;
      t6 = (t2 ^ t4) & 0xffff;
      t7 = (mul(t5, keys[k])) & 0xffff; k++;
      t8 = ((t6 + t7) % 0x10000) & 0xffff;
      t9 = (mul(t8, keys[k])) & 0xffff; k++;
      t10 = ((t7 + t9) % 0x10000) & 0xffff;

      t11 = (t1 ^ t9) & 0xffff;
      t12 = (t3 ^ t9) & 0xffff;
      t13 = (t2 ^ t10) & 0xffff;
      t14 = (t4 ^ t10) & 0xffff;

      x1 = t11;
      x2 = t12;  // swap two inner blocks
      x3 = t13;
      x4 = t14;

      round++;
    }
    // output transformation
    out[0] = mul( x1, keys[k] ) & 0xffff; k++;
    out[1] = (( x3 + keys[k] ) % 0x10000) & 0xffff; k++;
    out[2] = (( x2 + keys[k] ) % 0x10000) & 0xffff; k++;
    out[3] = mul( x4, keys[k] ) & 0xffff; k++;
  }

  // Multiplication modulo 65537.
  private static int mul( int a, int b ) {
    int ab = a * b;
    if ( ab != 0 ) {
      int lo = ab & 0xffff;
      int hi = ab >>> 16;
      return ( ( lo - hi ) + ( lo < hi ? 1 : 0 ) ) & 0xffff;
    }
    if ( a != 0 ) return ( 1 - a ) & 0xffff;
    return ( 1 - b ) & 0xffff;
  }

  // The multiplicative inverse of x, modulo 65537. Uses Euclid's
  // GCD algorithm.  It is unrolled twice to avoid swapping the
  // meaning of the registers each iteration, and some subtracts
  // of t have been changed to adds.
  private static int mulinv( int x ) {
    int t0, t1, q, y;
    if ( x <= 1 ) return x;   // 0 and 1 are self-inverse
    t0 = 1;
    t1 = 0x10001 / x; // since x >= 2, this fits into 16 bits
    y = ( 0x10001 % x ) & 0xffff;
    for (;;) {
      if ( y == 1 )
        return ( 1 - t1 ) & 0xffff;
      q = x / y;
      x = x % y;
      t0 = ( t0 + q * t1 ) & 0xffff;
      if ( x == 1 )
        return t0;
      q = y / x;
      y = y % x;
      t1 = ( t1 + q * t0 ) & 0xffff;
    }
  }






  public static void main(String[] args) {
    byte[] data = { (byte)0x00, (byte)0x00, (byte)0x45, (byte)0x67,
                    (byte)0x89, (byte)0xab, (byte)0xcd, (byte)0xef};

    System.out.println("data 0 normal:      " + Long.toHexString(data[0]));
    System.out.println("data 0 normal:      " + data[0]);
    System.out.println("data 56 nach links: " + Long.toHexString((long)(data[0]) << 
56));
    System.out.println("data 56 nach links: " + ((long)(data[0]) << 56));
    System.out.println("-----");

    long a = 0x0000000000000000L;
    System.out.println("a: " + a);
    a = ((((long)data[7]) | (long)0xFFFFFFFFFFFFFF00L) & (((((long)data[6]) << 8) | 
(long)0xFFFFFFFFFFFF00FFL) & (((((long)data[5]) << 16) | (long)0xFFFFFFFFFF00FFFFL) & 
(((((long)data[4]) << 24) | (long)0xFFFFFFFF00FFFFFFL) & (((((long)data[3]) << 32) | 
(long)0xFFFFFF00FFFFFFFFL) & (((((long)data[2]) << 40) | (long)0xFFFF00FFFFFFFFFFL) & 
(((((long)data[1]) << 48) | (long)0xFF00FFFFFFFFFFFFL) & (((((long)data[0]) << 56) | 
(long)0x00FFFFFFFFFFFFFFL)))))))));

    System.out.println("A: " + Long.toHexString(a));

    for (int aa = 0; aa < 65536; ++aa) {
      int bb = mulinv(aa);
      int cc = mul(aa, bb);
      if (cc != 1) System.err.println("mul/mulinv flaw: " + aa + " * " + bb + " = " + 
cc);
    }

    int[] plain = { 0x0808, 0x0808, 0x0808, 0x0808 };
    int[] crypt = new int[4];
    int[] decrypt = new int[4];
    int[] key =  { 0x9D, 0x40, 0x75, 0xC1,
                   0x03, 0xBC, 0x32, 0x2A,
                   0xFB, 0x03, 0xE7, 0xBE,
                   0x6A, 0xB3, 0x00, 0x06};


    System.out.print("Plain: ");
    int i = 0;
    while (i < 4) {
      System.out.println(Integer.toHexString(plain[i]));
      i++;
    }
    System.out.println();

    setKey(key);
    ideacore(plain, crypt, encryptKeys);
    System.out.print("crypt: ");
    i = 0;
    while (i < 4) {
      System.out.println(Integer.toHexString(crypt[i]));
      i++;
    }
    System.out.println();

    ideacore(crypt, decrypt, decryptKeys);

    System.out.print("decrypt: ");
    i = 0;
    while (i < 4) {
      System.out.println(Integer.toHexString(decrypt[i]));
      i++;
    }
    System.out.println();

    System.out.println("Done");
  }
}
==============C17B702688FF3EA9E94363A0==


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

From: [EMAIL PROTECTED] (SCOTT19U.ZIP_GUY)
Subject: SCOTT19U pass in nut shell
Date: Sun, 06 Jun 1999 00:34:55 GMT


This describles one of the many passes that is
used over and over in doEnc of my code.

think of the file as bunch of bits instead of bytes

lay out a structures on top of the bits let P0 represent the first one
lay another sturcture on top but shift 9 bits back call this structure
C and C0 is the first such sturcture. know one needs a C-1 field
use the last 19 bits of the file.

 then apply the following formula

Cn= E{ ( Cn-1 xor Pn) + Pn+1}  

where E{ } is any possible 19 bit single cycle look up table.

n goes from 0 to  as far as possible so that the the Clast is just inside
the file.

you already knoe when n = 0  you need C-1  like I said that is the last 19 
bits. As you do the first few C0 C1 and etc you add them to botton of
file so that you have stuff to work with at the bottom.

after you make a pass of this note part of C0 the top 9 bits which you also
add to the bottom of file is not used in the output at top. The actuall finial 
output of the pass has not moved in memory one bit. But the effect is the
file is rotated 9 bits 

That is one pass in a nutshell it really is straight forward is it not.


David A. Scott
--
                    SCOTT19U.ZIP NOW AVAILABLE WORLD WIDE
                    http://www.jim.com/jamesd/Kong/scott19u.zip
                    http://members.xoom.com/ecil/index.htm
                    NOTE EMAIL address is for SPAMERS

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

From: [EMAIL PROTECTED]
Subject: Re: Challenge to SCOTT19U.ZIP_GUY
Date: Sat, 05 Jun 1999 23:01:08 GMT



>   Tom if your really a 17 year old kid and know C. Why don't you look
it
> at. The guide lines are there in the code.

What does my age have anything to do with this?  I am merely making
suggestions.  To me the first thing you could do is use 32/16 bit
words.  You could perform variable key- or data- dependant rotations on
the words or the entire array.  You could use a 19x32 sbox instead of a
19x19 sbox.

My main concern (or beef, whatever) is the memory required and word
size.  You could perform the same quadratic as RC6 on 19 bit words, but
be werely that using only the quad. is subseptable to differential
analysis (consider flipping the top bits of '2x^2 + x').  This could
reduce the memory by a bunch.  You could use a function like

unsigned long sbox(unsigned long a, unsigned long b)
{
 return ((a+b) * ((a+a+b+b)+1)) & ((1<<19)-1);
}

Where a is the data input, and b is a round/sub key.  You will still
have to perform sub form of permutation to avoid diff. analysis.  RC6
uses the data-dependant rotation.  You could up this to the entire
message?  But that would require log2(M) bits per rotation.

That's my 2cents.

Tom
--
PGP public keys.  SPARE key is for daily work, WORK key is for
published work.  The spare is at
'http://members.tripod.com/~tomstdenis/key_s.pgp'.  Work key is at
'http://members.tripod.com/~tomstdenis/key.pgp'.  Try SPARE first!


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

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

From: [EMAIL PROTECTED] (Patrick Juola)
Subject: Re: OTP Problems
Date: 31 May 1999 08:51:57 -0400

In article <[EMAIL PROTECTED]>,  <[EMAIL PROTECTED]> wrote:
>Dan wrote:
>> 
>> >Wait for the next shipment of key material, or switch to another cipher,
>> >or reuse portions of the key material in some way (and sacrifice
>> >unconditional secrecy in the process, if acceptable).
>> 
>> [snip]
>> 
>> >This problem can be solved quite easily.  (Re)synchronization can be
>> >achieved by transmitting in the clear the offset of key bits in the
>> >one-time pad.
>> 
>> Assuming the following scenario:
>> 
>> Bob meets Alice once a month and delivers to her a CD-ROM containing
>> 650MB of randomly generated data.  Each time Alice and Bob communicate,
>> the message of length n is sent, and is prefixed with offset y.  Starting
>> at offset y, using n bytes, the message is decrypted.
>> 
>> The problems with this are obvious:
>> 
>> i) Anyone duplicating the CD can read messages
>
>Let's see if I understand your point. You are critizing the OTP system
>because anyone with the proper key can read the messages?  Can you
>describe what is bad about this property?

The fact that the CD is physically persistant; if I can get a copy
of your CD, I can read everything that has ever been encrypted with
that CD.  So the key-security issue becomes one of physical security
as well as information security -- not only do you need to transmit
the key securely, but you need to store it securely for a potentially
unbounded length of time.

        -kitten

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

From: [EMAIL PROTECTED] (Patrick Juola)
Crossposted-To: talk.politics.crypto,alt.privacy
Subject: Re: The BRUCE SCHNEIER  Tirade
Date: 31 May 1999 08:47:44 -0400

In article <[EMAIL PROTECTED]>,
John Kennedy <[EMAIL PROTECTED]> wrote:
>On 28 May 1999 08:56:31 -0400, [EMAIL PROTECTED] (Patrick Juola)
>wrote:
>
>>In article <[EMAIL PROTECTED]>,
>>John Kennedy <[EMAIL PROTECTED]> wrote:
>>>On Thu, 27 May 1999 22:49:34 -0400, "Brian Hetrick"
>>><[EMAIL PROTECTED]> wrote:
>>>
>>>>Well, I'm not Bruce Schneier, but OTP systems are unusable in practice
>>>>because the key size must be the same as the message size -- otherwise
>>>>it's not an OTP -- and distributing the key requires a secure channel.
>>>>Since you can securely distribute the key, it makes sense to use the
>>>>same channel to securely distribute the message, and not bother with a
>>>>key.  (Actually, there is a time dependency in there.  It is possible
>>>>that the secure channel existed in the past, but not right at the
>>>>moment; in that case, and in that case _alone_, it makes sense to use
>>>>an OTP.)
>>>>
>>>
>>>
>>>Which is why one time pads have been, and presumably still are used.
>>>
>>>Which is why I was puzzled by the comment attributed to Schneier that
>>>they are unusable.
>>>
>>>Yes, I understand that they are no replacement for public key
>>>cryptography, but in the right situation they are possibly superior if
>>>provably secure.
>>
>>
>>But said right situation appears so infrequently as to be a practical
>>definition of useless.  I'm more likely to need a triphibious automobile
>>than an OTP.
>
>A provably secure code could be very useful for a spy. 

So would a triphibious automobile.  In fact, some of the few
publicly-known uses have been for communication with deep-cover
spies (the keyword you are probably looking for is VENONA).

But this still more or les proves the Mr. Schneier's point.  If
this is the only situation you can think of where an OTP is
useful, then this provides a practical definition of useless.
How many spies do you meet in a given week?

        -kitten






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

From: [EMAIL PROTECTED]
Subject: Scottu: I actually saw something usefull
Date: Sun, 06 Jun 1999 00:12:03 GMT

On his page there is a brief description of the algorithm. I found this

Cn = S{ (((Cn-1) XOR (Pn)) + (Pn+1))mod 2^W }

Which happens to be the round function, where

Cn    is the ciphertext at n
S     is the large S-box
Pn    is the plaintext at n

Now I know little of actually starting an attack, but from what I
briefly saw, he runs from 0-n 25 times.  Errors in the ciphertext
propagate forwards only though (note Cn-1 usage).  If he ran this
forwards and backwards this might help (note: would have to use Cn+1
which I did not see on his page).

Which leads me to think that the first set of n-25 words leaks info
about the s-boxes.  The key schedule does not look too proper though..


---snip----

Step 1: Create a memory array of 64K words (FFFF words in hexadecimal
terminology). Call this array List1[i]. These words will have addresses
i from 0 to FFFF hex. The values initially stored in these locations
are simply 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, 10, 11,
12, ... etc. up to FFFF hex. Each of these values will be selected only
once by the algorithm, and the value will be put in a location of the S-
Box memory array that is chosen by Rules defined below. After a value
from location i is put in the S-Box, location i is written with a new
value, according to the Rules defined below.

Step 2: Use the keyraw.key file with location pointed to by j. This
keyraw.key file may have less than 64K words. Call each word key[j].
Start at location j=0 and use the value at that location according to
the Rules defined below to make an entry in the S-Box. Then j will be
incremented through the whole keyraw.key file, and j will wrap around
as many times as needed to finish making the S-Box.

Step 3: Set x=1. Take the key value at j=0, add 1 to it, mod ((2^16)-1-
x) and put that number in S-Box location 0. Place key[j]+1 in List1[S-
Box[j]].

Step 4: Set x=2. Take the key value at j=1, add 1+j to it, mod ((2^16)-
1-x) , and place that value in S-Box[S-Box[j-1]]. Place key[j]+1 in
List1[S-Box[j]].

Step 5: Set x=3. Take the key value at j=2, add 1+j to it, mod ((2^16)-
1-x) , and place that value in S-Box[S-Box[j-1]]. Place key[j]+1 in
List1[S-Box[j]].
. 
. 
. 
Step Y: Increment x and j. Take key[j], add 1+j to it, mod ((2^16)-1-
x), and place that value in S-Box[S-Box[j-1]]. Place key[j]+1 in List1
[S-Box[j]].

Simple, yet oh so powerful! Right? Get it? Huh? No? Well, tough. Learn
it, love it, live it.
---snip----

Looks to complicated.  I would love to see a pro hack at it.  Why
doesn't he just use a key schedule like RC4?  RC4 is really simple
(that's why I like it) to implement and avoids implementation errors.

I will have to read more of the page:
   http://members.xoom.com/ecil/page2.htm

Basically it's a codebook cipher using the previous/next cipher/plain
text as entries into the table.  I think it's a little too simple
(the 'round function') to be sure.

Tom
--
PGP public keys.  SPARE key is for daily work, WORK key is for
published work.  The spare is at
'http://members.tripod.com/~tomstdenis/key_s.pgp'.  Work key is at
'http://members.tripod.com/~tomstdenis/key.pgp'.  Try SPARE first!


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

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

From: Barney Wol <[EMAIL PROTECTED]>
Subject: Re: Another source of random numbers
Date: Sun, 06 Jun 1999 01:09:50 GMT

Gentlemen,

        Thank you all for your comments.

                Barney



Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.

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

From: [EMAIL PROTECTED] ()
Subject: Re: evolving round keys
Date: 6 Jun 99 02:24:07 GMT

[EMAIL PROTECTED] wrote:
: David Wagner (he is a cool guy) helped me realized that this would not
: hinder a differential or linear attack except to make it harder to
: implement.

Yes, David Wagner has sent me some very helpful comments via E-mail as
well.

If the subkeys recur in a regular sequence, that might be true, but if the
subkeys are varied in a sophisticated fashion, so that it's not easy to
tell when the same subkey is ever used again, though, I would think that
differential and linear attacks would be hindered - greatly. (Of course, I
suppose D.W. could get picky, and note that one could do a birthday attack
on the IV...)

: What about s-boxes/tables that get swapped like in RC4?

If you swap the s-box entries that are _used_ in a block encipherment, you
would be using a patented technique: Terry Ritter's Dynamic Substitution.
But yes, it _is_ a good idea.

John Savard

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

From: [EMAIL PROTECTED] ()
Subject: Re: "Cipher Systems", Beker & Piper?
Date: 6 Jun 99 02:39:31 GMT

[EMAIL PROTECTED] wrote:
: However, it's not one I've heard of.

A web search has turned up the fact that it was published by John Wiley
and Sons (and by Northwood, presumably in the U.K.), so it's probably
pricey along the lines of Konheim...but it appears to be an excellent
book, as it is used as a reference in many courses, and the authors later
wrote a book on secure speech communication.

John Savard

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


** 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