Skip to content

Commit 6864c71

Browse files
committed
Store a local Mac instead of regenerating one every time.
1 parent 7341c85 commit 6864c71

File tree

3 files changed

+10
-22
lines changed

3 files changed

+10
-22
lines changed

src/benchmark/java/com/eatthepath/otp/HmacOneTimePasswordGeneratorBenchmark.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import java.security.Key;
1111
import java.security.NoSuchAlgorithmException;
1212

13-
@State(Scope.Thread)
13+
@State(Scope.Benchmark)
1414
public class HmacOneTimePasswordGeneratorBenchmark {
1515

1616
private HmacOneTimePasswordGenerator hotp;

src/main/java/com/eatthepath/otp/HmacOneTimePasswordGenerator.java

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,12 @@
3131
* <p>Generates HMAC-based one-time passwords (HOTP) as specified in
3232
* <a href="https://tools.ietf.org/html/rfc4226">RFC&nbsp;4226</a>.</p>
3333
*
34-
* <p>{@code HmacOneTimePasswordGenerator} instances are thread-safe and may be shared and re-used across multiple
35-
* threads.</p>
34+
* <p>{@code HmacOneTimePasswordGenerator} instances are thread-safe and may be shared between threads.</p>
3635
*
3736
* @author <a href="https://github.com/jchambers">Jon Chambers</a>
3837
*/
3938
public class HmacOneTimePasswordGenerator {
40-
private final String algorithm;
39+
private final Mac mac;
4140
private final int passwordLength;
4241

4342
private final int modDivisor;
@@ -92,6 +91,8 @@ public HmacOneTimePasswordGenerator(final int passwordLength) throws NoSuchAlgor
9291
* @throws NoSuchAlgorithmException if the given algorithm is not supported by the underlying JRE
9392
*/
9493
protected HmacOneTimePasswordGenerator(final int passwordLength, final String algorithm) throws NoSuchAlgorithmException {
94+
this.mac = Mac.getInstance(algorithm);
95+
9596
switch (passwordLength) {
9697
case 6: {
9798
this.modDivisor = 1_000_000;
@@ -114,10 +115,6 @@ protected HmacOneTimePasswordGenerator(final int passwordLength, final String al
114115
}
115116

116117
this.passwordLength = passwordLength;
117-
118-
// Our purpose here is just to throw an exception immediately if the algorithm is bogus.
119-
Mac.getInstance(algorithm);
120-
this.algorithm = algorithm;
121118
}
122119

123120
/**
@@ -131,21 +128,13 @@ protected HmacOneTimePasswordGenerator(final int passwordLength, final String al
131128
*
132129
* @throws InvalidKeyException if the given key is inappropriate for initializing the {@link Mac} for this generator
133130
*/
134-
public int generateOneTimePassword(final Key key, final long counter) throws InvalidKeyException {
135-
final Mac mac;
136-
137-
try {
138-
mac = Mac.getInstance(this.algorithm);
139-
mac.init(key);
140-
} catch (final NoSuchAlgorithmException e) {
141-
// This should never happen since we verify that the algorithm is legit in the constructor.
142-
throw new RuntimeException(e);
143-
}
131+
public synchronized int generateOneTimePassword(final Key key, final long counter) throws InvalidKeyException {
132+
this.mac.init(key);
144133

145134
final ByteBuffer buffer = ByteBuffer.allocate(8);
146135
buffer.putLong(0, counter);
147136

148-
final byte[] hmac = mac.doFinal(buffer.array());
137+
final byte[] hmac = this.mac.doFinal(buffer.array());
149138
final int offset = hmac[hmac.length - 1] & 0x0f;
150139

151140
for (int i = 0; i < 4; i++) {
@@ -174,6 +163,6 @@ public int getPasswordLength() {
174163
* @return the name of the HMAC algorithm used by this generator
175164
*/
176165
public String getAlgorithm() {
177-
return this.algorithm;
166+
return this.mac.getAlgorithm();
178167
}
179168
}

src/main/java/com/eatthepath/otp/TimeBasedOneTimePasswordGenerator.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@
3131
* <p>Generates time-based one-time passwords (TOTP) as specified in
3232
* <a href="https://tools.ietf.org/html/rfc6238">RFC&nbsp;6238</a>.</p>
3333
*
34-
* <p>{@code TimeBasedOneTimePasswordGenerator} instances are thread-safe and may be shared and re-used across multiple
35-
* threads.</p>
34+
* <p>{@code TimeBasedOneTimePasswordGenerator} instances are thread-safe and may be shared between threads.</p>
3635
*
3736
* @author <a href="https://github.com/jchambers">Jon Chambers</a>
3837
*/

0 commit comments

Comments
 (0)