KickJava   Java API By Example, From Geeks To Geeks.

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


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
15 /** The SHA_Interleave algorithm as described in section 3.1 of RFC2945. This
16  needs an SHA MessageDigest provider to function.
17
18 @author Scott.Stark@jboss.org
19 @version $Revision: 1.1.28.1 $
20 */

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

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

65    protected byte[] engineDigest()
66    {
67       byte[] E = evenBytes.toByteArray();
68       byte[] G = sha.digest(E);
69       // If the count is odd, drop the first byte
70
byte[] F = oddBytes.toByteArray();
71       int offset = 0;
72       if( count % 2 == 1 )
73          offset = 1;
74       sha.reset();
75       sha.update(F, offset, F.length-offset);
76       byte[] H = sha.digest();
77       int length = G.length + H.length;
78       byte[] digest = new byte[length];
79       for(int i = 0; i < G.length; ++i)
80          digest[2 * i] = G[i];
81       for(int i = 0; i < H.length; ++i)
82          digest[2 * i + 1] = H[i];
83       engineReset();
84       return digest;
85    }
86
87    /**
88     * Resets the digest for further use.
89     */

90    protected void engineReset()
91    {
92       skipLeadingZeros = true;
93       count = 0;
94       evenBytes.reset();
95       oddBytes.reset();
96       sha.reset();
97    }
98
99    /**
100     * Updates the digest using the specified byte.
101     *
102     * @param input the byte to use for the update.
103     */

104    protected void engineUpdate(byte input)
105    {
106       if( skipLeadingZeros == true && input == 0 )
107          return;
108       skipLeadingZeros = false;
109       if( count % 2 == 0 )
110          evenBytes.write(input);
111       else
112          oddBytes.write(input);
113       count ++;
114    }
115
116    /**
117     * Updates the digest using the specified array of bytes,
118     * starting at the specified offset.
119     *
120     * @param input the array of bytes to use for the update.
121     * @param offset the offset to start from in the array of bytes.
122     * @param len the input of bytes to use, starting at
123     * <code>offset</code>.
124     */

125    protected void engineUpdate(byte[] input, int offset, int len)
126    {
127       for(int i = offset; i < offset+len; i ++)
128          engineUpdate(input[i]);
129    }
130
131 }
132
Popular Tags