01: package org.bouncycastle.crypto.digests;
02:
03: import org.bouncycastle.crypto.ExtendedDigest;
04:
05: /**
06: * Wrapper class that reduces the output length of a particular digest to
07: * only the first n bytes of the digest function.
08: */
09: public class ShortenedDigest implements ExtendedDigest {
10: private ExtendedDigest baseDigest;
11: private int length;
12:
13: /**
14: * Base constructor.
15: *
16: * @param baseDigest underlying digest to use.
17: * @param length length in bytes of the output of doFinal.
18: * @exception IllegalArgumentException if baseDigest is null, or length is greater than baseDigest.getDigestSize().
19: */
20: public ShortenedDigest(ExtendedDigest baseDigest, int length) {
21: if (baseDigest == null) {
22: throw new IllegalArgumentException(
23: "baseDigest must not be null");
24: }
25:
26: if (length > baseDigest.getDigestSize()) {
27: throw new IllegalArgumentException(
28: "baseDigest output not large enough to support length");
29: }
30:
31: this .baseDigest = baseDigest;
32: this .length = length;
33: }
34:
35: public String getAlgorithmName() {
36: return baseDigest.getAlgorithmName() + "(" + length * 8 + ")";
37: }
38:
39: public int getDigestSize() {
40: return length;
41: }
42:
43: public void update(byte in) {
44: baseDigest.update(in);
45: }
46:
47: public void update(byte[] in, int inOff, int len) {
48: baseDigest.update(in, inOff, len);
49: }
50:
51: public int doFinal(byte[] out, int outOff) {
52: byte[] tmp = new byte[baseDigest.getDigestSize()];
53:
54: baseDigest.doFinal(tmp, 0);
55:
56: System.arraycopy(tmp, 0, out, outOff, length);
57:
58: return length;
59: }
60:
61: public void reset() {
62: baseDigest.reset();
63: }
64:
65: public int getByteLength() {
66: return baseDigest.getByteLength();
67: }
68: }
|