/
SHA256Generator.java
95 lines (84 loc) · 2.7 KB
/
SHA256Generator.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package net.i2p.crypto;
import java.security.DigestException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.LinkedBlockingQueue;
import net.i2p.I2PAppContext;
import net.i2p.data.Hash;
/**
* Defines a wrapper for SHA-256 operation.
*
* As of release 0.8.7, uses java.security.MessageDigest by default.
* As of release 0.9.25, uses only MessageDigest.
* GNU-Crypto gnu.crypto.hash.Sha256Standalone
* is removed as of 0.9.28.
*/
public final class SHA256Generator {
private final LinkedBlockingQueue<MessageDigest> _digests;
/**
* @param context unused
*/
public SHA256Generator(I2PAppContext context) {
_digests = new LinkedBlockingQueue<MessageDigest>(32);
}
public static final SHA256Generator getInstance() {
return I2PAppContext.getGlobalContext().sha();
}
/**
* Calculate the SHA-256 hash of the source and cache the result.
* @param source what to hash
* @return hash of the source
*/
public final Hash calculateHash(byte[] source) {
return calculateHash(source, 0, source.length);
}
/**
* Calculate the hash and cache the result.
* @param source what to hash
*/
public final Hash calculateHash(byte[] source, int start, int len) {
MessageDigest digest = acquire();
digest.update(source, start, len);
byte rv[] = digest.digest();
release(digest);
return Hash.create(rv);
}
/**
* Use this if you only need the data, not a Hash object.
* Does not cache.
* @param out needs 32 bytes starting at outOffset
*/
public final void calculateHash(byte[] source, int start, int len, byte out[], int outOffset) {
MessageDigest digest = acquire();
digest.update(source, start, len);
try {
digest.digest(out, outOffset, Hash.HASH_LENGTH);
} catch (DigestException e) {
throw new RuntimeException(e);
} finally {
release(digest);
}
}
private MessageDigest acquire() {
MessageDigest rv = _digests.poll();
if (rv != null)
rv.reset();
else
rv = getDigestInstance();
return rv;
}
private void release(MessageDigest digest) {
_digests.offer(digest);
}
/**
* Return a new MessageDigest from the system libs.
* @since 0.8.7, public since 0.8.8 for FortunaStandalone
*/
public static MessageDigest getDigestInstance() {
try {
return MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}