KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > crypto > digest > SHAReverseInterleave


1 /*
2 * JBoss, the OpenSource J2EE webOS
3 *
4 * Distributable under LGPL license.
5 * See terms of license at gnu.org.
6 */

7 package org.jboss.crypto.digest;
8
9 import java.io.ByteArrayOutputStream JavaDoc;
10 import java.security.MessageDigest JavaDoc;
11 import java.security.MessageDigestSpi JavaDoc;
12 import java.security.NoSuchAlgorithmException JavaDoc;
13 import java.security.ProviderException JavaDoc;
14 import java.util.Arrays JavaDoc;
15
16 /** An alternate SHA Interleave algorithm as implemented in the SRP
17  distribution. This version reverses the even and odd byte streams before
18  performing the SHA digest.
19
20  This product includes software developed by Tom Wu and Eugene
21  Jhong for the SRP Distribution (http://srp.stanford.edu/srp/).
22
23 @author Scott.Stark@jboss.org
24 @version $Revision: 1.3.6.1 $
25 */

26 public class SHAReverseInterleave extends MessageDigestSpi JavaDoc
27 {
28    private static final int SHA_HASH_LEN = 20;
29
30    private ByteArrayOutputStream JavaDoc evenBytes;
31    private ByteArrayOutputStream JavaDoc oddBytes;
32    private int count;
33    private boolean skipLeadingZeros;
34    private MessageDigest JavaDoc sha;
35
36    /** Creates a new instance of SHAReverseInterleave
37     @exception ProviderException thrown if MessageDigest.getInstance("SHA")
38     throws a NoSuchAlgorithmException.
39     */

40    public SHAReverseInterleave()
41    {
42       try
43       {
44          sha = MessageDigest.getInstance("SHA");
45       }
46       catch(NoSuchAlgorithmException JavaDoc e)
47       {
48          throw new ProviderException JavaDoc("Failed to obtain SHA MessageDigest");
49       }
50       evenBytes = new ByteArrayOutputStream JavaDoc();
51       oddBytes = new ByteArrayOutputStream JavaDoc();
52       engineReset();
53    }
54
55    protected int engineGetDigestLength()
56    {
57       return 2 * SHA_HASH_LEN;
58    }
59
60    /**
61     * Completes the digest computation by performing final
62     * operations such as padding. Once <code>engineDigest</code> has
63     * been called, the engine should be reset (see
64     * {@link #engineReset() engineReset}).
65     * Resetting is the responsibility of the
66     * engine implementor.
67     *
68     * @return the array of bytes for the resulting digest value.
69     */

70    protected byte[] engineDigest()
71    {
72       byte[] E = evenBytes.toByteArray();
73       // If the count is odd, drop the first byte
74
int length = E.length;
75       if( count % 2 == 1 )
76          length --;
77       // Reverse the order of the even bytes
78
byte[] tmp = new byte[length];
79       for(int i = 0; i < length; i ++)
80       {
81          tmp[i] = E[E.length - i - 1];
82          System.out.println("E["+i+"] = "+tmp[i]);
83       }
84       E = tmp;
85       byte[] G = sha.digest(E);
86
87       byte[] F = oddBytes.toByteArray();
88       // Reverse the order of the even bytes
89
tmp = new byte[F.length];
90       for(int i = 0; i < F.length; i ++)
91       {
92          tmp[i] = F[F.length - i - 1];
93          System.out.println("F["+i+"] = "+tmp[i]);
94       }
95       F = tmp;
96       sha.reset();
97       byte[] H = sha.digest(F);
98       length = G.length + H.length;
99       byte[] digest = new byte[length];
100       for(int i = 0; i < G.length; ++i)
101          digest[2 * i] = G[i];
102       for(int i = 0; i < H.length; ++i)
103          digest[2 * i + 1] = H[i];
104       engineReset();
105       return digest;
106    }
107
108    /**
109     * Resets the digest for further use.
110     */

111    protected void engineReset()
112    {
113       skipLeadingZeros = true;
114       count = 0;
115       evenBytes.reset();
116       oddBytes.reset();
117       sha.reset();
118    }
119
120    /**
121     * Updates the digest using the specified byte.
122     *
123     * @param input the byte to use for the update.
124     */

125    protected void engineUpdate(byte input)
126    {
127       if( skipLeadingZeros == true && input == 0 )
128          return;
129       skipLeadingZeros = false;
130       if( count % 2 == 0 )
131          evenBytes.write(input);
132       else
133          oddBytes.write(input);
134       count ++;
135    }
136
137    /**
138     * Updates the digest using the specified array of bytes,
139     * starting at the specified offset.
140     *
141     * @param input the array of bytes to use for the update.
142     * @param offset the offset to start from in the array of bytes.
143     * @param len the input of bytes to use, starting at
144     * <code>offset</code>.
145     */

146    protected void engineUpdate(byte[] input, int offset, int len)
147    {
148       for(int i = offset; i < offset+len; i ++)
149          engineUpdate(input[i]);
150    }
151
152 }
153
Popular Tags