TEA.java
上传用户:huihesys
上传日期:2007-01-04
资源大小:3877k
文件大小:14k
源码类别:

WEB邮件程序

开发平台:

C/C++

  1. /* CVS ID: $Id: TEA.java,v 1.2 2000/04/06 08:02:02 wastl Exp $ */
  2. package net.wastl.webmail.misc;
  3. import java.math.*;
  4. /**
  5. * Tiny Encryption Algorithm.
  6. * <P>
  7. * (The following description is from the web page for the C and Assembler source
  8. * code at <A HREF="http://vader.brad.ac.uk/tea/tea.shtml"> University of Bradford
  9. * Yorkshire, England - The Cryptography & Computer Communications Security
  10. * Group</A>) The description is used with the permission of the authors,
  11. * Dr S J Shepherd and D A G Gillies.
  12. * <P>
  13. * The Tiny Encryption Algorithm is one of the fastest and most efficient
  14. * cryptographic algorithms in existence. It was developed by David
  15. * Wheeler and Roger Needham at the Computer Laboratory of Cambridge
  16. * University. It is a Feistel cipher which uses operations from mixed
  17. * (orthogonal) algebraic groups - XORs and additions in this case. It
  18. * encrypts 64 data bits at a time using a 128-bit key. It seems highly
  19. * resistant to differential cryptanalysis, and achieves complete
  20. * diffusion (where a one bit difference in the plaintext will cause
  21. * approximately 32 bit differences in the ciphertext) after only six
  22. * rounds. Performance on a modern desktop computer or workstation is
  23. * very impressive. 
  24. * <P>
  25. * TEA takes 64 bits of data in v[0] and v[1], and 128 bits of key in
  26. * k[0] - k[3]. The result is returned in w[0] and w[1]. Returning the
  27. * result separately makes implementation of cipher modes other than
  28. * Electronic Code Book a little bit easier.
  29. * <P>
  30. * TEA can be operated in any of the modes of DES.
  31. * <P>
  32. * n is the number of iterations. 32 is ample, 16 is sufficient, as few
  33. * as eight should be OK for most applications, especially ones where
  34. * the data age quickly (real-time video, for example). The algorithm
  35. * achieves good dispersion after six iterations. The iteration count
  36. * can be made variable if required.
  37. * <P>
  38. * Note this algorithm is optimised for 32-bit CPUs with fast shift
  39. * capabilities. It can very easily be ported to assembly language on
  40. * most CPUs.
  41. * <P>
  42. * delta is chosen to be the Golden ratio ((5/4)1/2 - 1/2 ~ 0.618034)
  43. * multiplied by 232. On entry to decipher(), sum is set to be delta *
  44. * n. Which way round you call the functions is arbitrary: DK(EK(P)) =
  45. * EK(DK(P)) where EK and DK are encryption and decryption under key K
  46. * respectively. 
  47. * <P>
  48. * Translator's notes:
  49. * <UL>
  50. * <LI> Although the <I>this algorithm is optimised for
  51. * 32-bit CPUs with fast shift capabilities</I> Java manages to throw
  52. * it all away by not providing unsigned values resulting in the excessive
  53. * use of AND's to prevent sign extension on promotion of a byte 
  54. * to an integer.
  55. * </LI>
  56. * <P>
  57. * <LI>
  58. * The following description is taken from the
  59. * Mach5 Software cryptography archives at
  60. * <A HREF="http://www.mach5.com/crypto/">www.mach5.com/crypto</A>.
  61. * <p><font face="Arial" size="4">Tiny Encryption Algorithm (TEA)</font><br>
  62. * <font size="3" face="Arial">TEA is a cryptographic algorithm designed to minimize memory
  63. * footprint, and maximize speed. However, the cryptographers from <a
  64. *
  65. * href="http://www.counterpane.com">Counterpane Systems</a> have <a
  66. *
  67. * href="http://www.cs.berkeley.edu/~daw/keysched-crypto96.ps">discovered three related-key
  68. * attacks </a>on TEA, the best of which requires only 223 chosen plaintexts and one related
  69. * key query. The problems arise from the overly simple key schedule. Each TEA key can be
  70. * found to have three other equivalent keys, as described in <a
  71. *
  72. * href="http://www.cs.berkeley.edu/~daw/keysched-icics97.ps">a paper</a> by <a
  73. *
  74. * href="http://www.cs.berkeley.edu/~daw/">David Wagner</a>, John Kelsey, and <a
  75. *
  76. * href="http://www.counterpane.com/schneier.html">Bruce Schneier</a>. This precludes the
  77. * possibility of using TEA as a hash function. Roger Needham and David Wheeler have proposed
  78. * <a href="http://www.cl.cam.ac.uk/ftp/users/djw3/xtea.ps">extensions to TEA</a> that
  79. * counters the above attacks.</font></p>
  80. * </LI>
  81. * </UL>
  82. *
  83. * <P> Example of use:
  84. * <PRE>
  85. * byte key[] = new BigInteger("39e858f86df9b909a8c87cb8d9ad599", 16).toByteArray();
  86. * TEA t = new TEA(key);
  87. * <BR>
  88. * String src = "hello world!";
  89. * System.out.println("input = " + src);
  90. * byte plainSource[] = src.getBytes();
  91. * int enc[] = t.encode(plainSource, plainSource.length);
  92. * System.out.println(t.padding() + " bytes added as padding.");
  93. * byte dec[] = t.decode(enc);
  94. * System.out.println("output = " + new String(dec));
  95. * </PRE>
  96. *
  97. * @author Translated by Michael Lecuyer (mjl@theorem.com) from the C Language.
  98. * @version 1.0 Sep 8, 1998
  99. * @since JDK1.1
  100. */
  101. public class TEA
  102. {
  103.    private int _key[];  // The 128 bit key.
  104.    private byte _keyBytes[];  // original key as found
  105.    private int _padding;      // amount of padding added in byte --> integer conversion.
  106.    /**
  107.    * Encodes and decodes "Hello world!" for your personal pleasure.
  108.    */
  109.    public static void main(String args[])
  110.    {
  111.       // A simple test of TEA.
  112.       byte key[] = new BigInteger("39e858f86df9b909a8c87cb8d9ad599", 16).toByteArray();
  113.       TEA t = new TEA(key);
  114.       String src = "hello world!";
  115.       System.out.println("input = " + src);
  116.       byte plainSource[] = src.getBytes();
  117.       int enc[] = t.encode(plainSource, plainSource.length);
  118.       System.out.println(t.padding() + " bytes added as padding.");
  119.       byte dec[] = t.decode(enc);
  120.       System.out.println("output = " + new String(dec));
  121.    }
  122.    /**
  123.    * Accepts key for enciphering/deciphering.
  124.    *
  125.    * @throws ArrayIndexOutOfBoundsException if the key isn't the correct length.
  126.    *
  127.    * @param key 128 bit (16 byte) key.
  128.    */
  129.    public TEA(byte key[])
  130.    {
  131.       int klen = key.length;
  132.       _key = new int[4];
  133.       
  134.       // Incorrect key length throws exception.
  135.       if (klen != 16)
  136.          throw new ArrayIndexOutOfBoundsException(this.getClass().getName() + ": Key is not 16 bytes");
  137.       int j, i;
  138.       for (i = 0, j = 0; j < klen; j += 4, i++)
  139.          _key[i] = (key[j] << 24 ) | (((key[j+1])&0xff) << 16) | (((key[j+2])&0xff) << 8) | ((key[j+3])&0xff);
  140.       _keyBytes = key;  // save for toString.
  141.    }
  142.    /**
  143.    * Representation of TEA class
  144.    */
  145.    public String toString()
  146.    {
  147.       String tea = this.getClass().getName();
  148.       tea +=  ": Tiny Encryption Algorithm (TEA)  key: " + dumpBytes(_keyBytes);
  149.       return tea;
  150.    }
  151.    /**
  152.    * Encipher two <code>int</code>s.
  153.    * Replaces the original contents of the parameters with the results.
  154.    * The integers are usually created from 8 bytes.
  155.    * The usual way to collect bytes to the int array is:
  156.    * <PRE>
  157.    * byte ba[] = { .... };
  158.    * int v[] = new int[2];
  159.    * v[0] = (ba[j] << 24 ) | (((ba[j+1])&0xff) << 16) | (((ba[j+2])&0xff) << 8) | ((ba[j+3])&0xff);
  160.    * v[1] = (ba[j+4] << 24 ) | (((ba[j+5])&0xff) << 16) | (((ba[j+6])&0xff) << 8) | ((ba[j+7])&0xff);
  161.    * v = encipher(v);
  162.    * </PRE>
  163.    *
  164.    * @param v two <code>int</code> array as input. 
  165.    *
  166.    * @return array of two <code>int</code>s, enciphered.
  167.    */
  168.    public int [] encipher(int v[])
  169.    {
  170.       int y=v[0];
  171.       int z=v[1];
  172.       int sum=0;
  173.       int delta=0x9E3779B9;
  174.       int a=_key[0];
  175.       int b=_key[1];
  176.       int c=_key[2];
  177.       int d=_key[3];
  178.       int n=32;
  179.       while(n-->0)
  180.       {
  181.          sum += delta;
  182.          y += (z << 4)+a ^ z+sum ^ (z >> 5)+b;
  183.          z += (y << 4)+c ^ y+sum ^ (y >> 5)+d;
  184.       }
  185.       v[0] = y;
  186.       v[1] = z;
  187.       return v;
  188.    }
  189.    /**
  190.    * Decipher two <code>int</code>s.
  191.    * Replaces the original contents of the parameters with the results.
  192.    * The integers are usually decocted to 8 bytes.
  193.    * The decoction of the <code>int</code>s to bytes can be done
  194.    * this way.
  195.    * <PRE>
  196.    * int x[] = decipher(ins);
  197.    * outb[j]   = (byte)(x[0] >>> 24);
  198.    * outb[j+1] = (byte)(x[0] >>> 16);
  199.    * outb[j+2] = (byte)(x[0] >>> 8);
  200.    * outb[j+3] = (byte)(x[0]);
  201.    * outb[j+4] = (byte)(x[1] >>> 24);
  202.    * outb[j+5] = (byte)(x[1] >>> 16);
  203.    * outb[j+6] = (byte)(x[1] >>> 8);
  204.    * outb[j+7] = (byte)(x[1]);
  205.    * </PRE>
  206.    *
  207.    * @param v <code>int</code> array of 2
  208.    *
  209.    * @return deciphered <code>int</code> array of 2
  210.    */
  211.    public int [] decipher(int v[])
  212.    {
  213.       int y=v[0];
  214.       int z=v[1];
  215.       int sum=0xC6EF3720;
  216.       int delta=0x9E3779B9;
  217.       int a=_key[0];
  218.       int b=_key[1];
  219.       int c=_key[2];
  220.       int d=_key[3];
  221.       int n=32;
  222.       // sum = delta<<5, in general sum = delta * n 
  223.       while(n-->0)
  224.       {
  225.          z -= (y << 4)+c ^ y+sum ^ (y >> 5) + d;
  226.          y -= (z << 4)+a ^ z+sum ^ (z >> 5) + b;
  227.          sum -= delta;
  228.       }
  229.       v[0] = y;
  230.       v[1] = z;
  231.       return v;
  232.    }
  233.    /**
  234.    * Encipher two <code>bytes</code>s.
  235.    *
  236.    * @param v <code>byte</code> array of 2
  237.    *
  238.    * @return enciphered <code>byte</code> array of 2
  239.    */
  240.    public byte [] encipher(byte v[])
  241.    {
  242.       byte y=v[0];
  243.       byte z=v[1];
  244.       int sum=0;
  245.       int delta=0x9E3779B9;
  246.       int a=_key[0];
  247.       int b=_key[1];
  248.       int c=_key[2];
  249.       int d=_key[3];
  250.       int n=32;
  251.       while(n-->0)
  252.       {
  253.          sum += delta;
  254.          y += (z << 4)+a ^ z+sum ^ (z >> 5)+b;
  255.          z += (y << 4)+c ^ y+sum ^ (y >> 5)+d;
  256.       }
  257.       v[0] = y;
  258.       v[1] = z;
  259.       return v;
  260.    }
  261.    /**
  262.    * Decipher two <code>bytes</code>s.
  263.    *
  264.    * @param v <code>byte</code> array of 2
  265.    *
  266.    * @return decipherd <code>byte</code> array of 2
  267.    */
  268.    public byte [] decipher(byte v[])
  269.    {
  270.       byte y=v[0];
  271.       byte z=v[1];
  272.       int sum=0xC6EF3720;
  273.       int delta=0x9E3779B9;
  274.       int a=_key[0];
  275.       int b=_key[1];
  276.       int c=_key[2];
  277.       int d=_key[3];
  278.       int n=32;
  279.       // sum = delta<<5, in general sum = delta * n 
  280.       while(n-->0)
  281.       {
  282.          z -= (y << 4)+c ^ y+sum ^ (y >> 5)+d;
  283.          y -= (z << 4)+a ^ z+sum ^ (z >> 5)+b;
  284.          sum -= delta;
  285.       }
  286.       v[0] = y;
  287.       v[1] = z;
  288.       return v;
  289.    }
  290.    /**
  291.    * Byte wrapper for encoding.
  292.    * Converts bytes to ints.
  293.    * Padding will be added if required.
  294.    *
  295.    * @param b incoming <code>byte</code> array
  296.    *
  297.    * @param byte count
  298.    *
  299.    * @return integer conversion array, possibly with padding.
  300.    *
  301.    * @see #padding
  302.    */
  303.    int [] encode(byte b[], int count)
  304.    {
  305.       int j ,i;
  306.       int bLen = count;
  307.       byte bp[] = b;
  308.       _padding = bLen % 8;
  309.       if (_padding != 0)   // Add some padding, if necessary.
  310.       {
  311.          _padding = 8 - (bLen % 8);
  312.          bp = new byte[bLen + _padding];
  313.          System.arraycopy(b, 0, bp, 0, bLen);
  314.          bLen = bp.length;
  315.       }
  316.       int intCount = bLen / 4;
  317.       int r[] = new int[2];
  318.       int out[] = new int[intCount];
  319.       for (i = 0, j = 0; j < bLen; j += 8, i += 2)
  320.       {
  321.          // Java's unforgivable lack of unsigneds causes more bit
  322.          // twiddling than this language really needs.
  323.          r[0] = (bp[j] << 24 ) | (((bp[j+1])&0xff) << 16) | (((bp[j+2])&0xff) << 8) | ((bp[j+3])&0xff);
  324.          r[1] = (bp[j+4] << 24 ) | (((bp[j+5])&0xff) << 16) | (((bp[j+6])&0xff) << 8) | ((bp[j+7])&0xff);
  325.          encipher(r);
  326.          out[i] = r[0];
  327.          out[i+1] = r[1];
  328.       }
  329.       return out;
  330.    }
  331.    /**
  332.    * Report how much padding was done in the last encode.
  333.    *
  334.    * @return bytes of padding added
  335.    *
  336.    * @see #encode
  337.    */
  338.    public int padding()
  339.    {
  340.       return _padding;
  341.    }
  342.    /**
  343.    * Convert a byte array to ints and then decode.
  344.    * There may be some padding at the end of the byte array from
  345.    * the previous encode operation.
  346.    *
  347.    * @param b bytes to decode
  348.    * @param count number of bytes in the array to decode
  349.    *
  350.    * @return <code>byte</code> array of decoded bytes.
  351.    */
  352.    public byte [] decode(byte b[], int count)
  353.    {
  354.       int i, j;
  355.       int intCount = count / 4;
  356.       int ini[] = new int[intCount];
  357.       for (i = 0, j = 0; i < intCount; i += 2, j += 8)
  358.       {
  359.          ini[i] = (b[j] << 24 ) | (((b[j+1])&0xff) << 16) | (((b[j+2])&0xff) << 8) | ((b[j+3])&0xff);
  360.          ini[i+1] = (b[j+4] << 24 ) | (((b[j+5])&0xff) << 16) | (((b[j+6])&0xff) << 8) | ((b[j+7])&0xff);
  361.       }
  362.       return decode(ini);
  363.    }
  364.    /**
  365.    * Decode an integer array.
  366.    * There may be some padding at the end of the byte array from
  367.    * the previous encode operation.
  368.    *
  369.    * @param b bytes to decode
  370.    * @param count number of bytes in the array to decode
  371.    *
  372.    * @return <code>byte</code> array of decoded bytes.
  373.    */
  374.    public byte [] decode(int b[])
  375.    {
  376.       // create the large number and start stripping ints out, two at a time.
  377.       int intCount = b.length;
  378.       byte outb[] = new byte[intCount * 4];
  379.       int tmp[] = new int[2];
  380.       // decipher all the ints.
  381.       int i, j;
  382.       for (j = 0, i = 0; i < intCount; i += 2, j += 8)
  383.       {
  384.          tmp[0] = b[i];
  385.          tmp[1] = b[i+1];
  386.          decipher(tmp);
  387.          outb[j]   = (byte)(tmp[0] >>> 24);
  388.          outb[j+1] = (byte)(tmp[0] >>> 16);
  389.          outb[j+2] = (byte)(tmp[0] >>> 8);
  390.          outb[j+3] = (byte)(tmp[0]);
  391.          outb[j+4] = (byte)(tmp[1] >>> 24);
  392.          outb[j+5] = (byte)(tmp[1] >>> 16);
  393.          outb[j+6] = (byte)(tmp[1] >>> 8);
  394.          outb[j+7] = (byte)(tmp[1]);
  395.       }
  396.       return outb;
  397.    }
  398.    // Display some bytes in HEX.
  399.    //
  400.    private String dumpBytes(byte b[])
  401.    {
  402.       StringBuffer r = new StringBuffer();
  403.       final String hex = "0123456789ABCDEF";
  404.       for (int i = 0; i < b.length; i++)
  405.       {
  406.          int c = ((b[i]) >>> 4) & 0xf;
  407.          r.append(hex.charAt(c));
  408.          c = ((int)b[i] & 0xf);
  409.          r.append(hex.charAt(c));
  410.       }
  411.       return r.toString();
  412.    }
  413. }