Skip to content

Commit f07ed6e

Browse files
- removed misleading statements about the key lifecycle from the javadoc
- incremented version number - added benchmark test
1 parent 3947c0b commit f07ed6e

File tree

6 files changed

+137
-10
lines changed

6 files changed

+137
-10
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public void encryptWithAdditionalData() {
3737
<dependency>
3838
<groupId>org.cryptomator</groupId>
3939
<artifactId>siv-mode</artifactId>
40-
<version>1.0.7</version>
40+
<version>1.1.0</version>
4141
</dependency>
4242
</dependencies>
4343
```

pom.xml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<modelVersion>4.0.0</modelVersion>
44
<groupId>org.cryptomator</groupId>
55
<artifactId>siv-mode</artifactId>
6-
<version>1.0.9-SNAPSHOT</version>
6+
<version>1.1.0</version>
77

88
<name>SIV Mode</name>
99
<description>RFC 5297 SIV mode: deterministic authenticated encryption</description>
@@ -59,6 +59,18 @@
5959
<version>1.10.19</version>
6060
<scope>test</scope>
6161
</dependency>
62+
<dependency>
63+
<groupId>org.openjdk.jmh</groupId>
64+
<artifactId>jmh-core</artifactId>
65+
<version>1.12</version>
66+
<scope>test</scope>
67+
</dependency>
68+
<dependency>
69+
<groupId>org.openjdk.jmh</groupId>
70+
<artifactId>jmh-generator-annprocess</artifactId>
71+
<version>1.12</version>
72+
<scope>test</scope>
73+
</dependency>
6274
</dependencies>
6375

6476
<build>

src/main/java/org/cryptomator/siv/JceAesBlockCipher.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
* Sebastian Stenzel - initial API and implementation
99
******************************************************************************/
1010

11-
import java.nio.ByteBuffer;
1211
import java.security.InvalidKeyException;
1312
import java.security.Key;
1413
import java.security.NoSuchAlgorithmException;
@@ -78,10 +77,8 @@ public int processBlock(byte[] in, int inOff, byte[] out, int outOff) throws Dat
7877
if (in.length - inOff < getBlockSize()) {
7978
throw new DataLengthException("Insufficient data in 'in'.");
8079
}
81-
ByteBuffer inBuf = ByteBuffer.wrap(in, inOff, getBlockSize());
82-
ByteBuffer outBuf = ByteBuffer.wrap(out, outOff, out.length - outOff);
8380
try {
84-
return cipher.update(inBuf, outBuf);
81+
return cipher.update(in, inOff, getBlockSize(), out, outOff);
8582
} catch (ShortBufferException e) {
8683
throw new DataLengthException("Insufficient space in 'out'.");
8784
}

src/main/java/org/cryptomator/siv/SivMode.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ public static interface BlockCipherFactory {
7575

7676
/**
7777
* Convenience method, if you are using the javax.crypto API. This is just a wrapper for {@link #encrypt(byte[], byte[], byte[], byte[]...)}.
78-
* This method accesses key bytes directly and destroys these bytes when finished. However the two given keys will remain untouched.
7978
*
8079
* @param ctrKey SIV mode requires two separate keys. You can use one long key, which is splitted in half. See https://tools.ietf.org/html/rfc5297#section-2.2
8180
* @param macKey SIV mode requires two separate keys. You can use one long key, which is splitted in half. See https://tools.ietf.org/html/rfc5297#section-2.2
@@ -100,7 +99,6 @@ public byte[] encrypt(SecretKey ctrKey, SecretKey macKey, byte[] plaintext, byte
10099

101100
/**
102101
* Encrypts plaintext using SIV mode. A block cipher defined by the constructor is being used.<br>
103-
* This method leaves the two given keys untouched, the calling function needs to makes sure, key bytes are destroyed when finished.
104102
*
105103
* @param ctrKey SIV mode requires two separate keys. You can use one long key, which is splitted in half. See https://tools.ietf.org/html/rfc5297#section-2.2
106104
* @param macKey SIV mode requires two separate keys. You can use one long key, which is splitted in half. See https://tools.ietf.org/html/rfc5297#section-2.2
@@ -147,7 +145,6 @@ public byte[] encrypt(byte[] ctrKey, byte[] macKey, byte[] plaintext, byte[]...
147145

148146
/**
149147
* Convenience method, if you are using the javax.crypto API. This is just a wrapper for {@link #decrypt(byte[], byte[], byte[], byte[]...)}.
150-
* This method accesses key bytes directly and destroys these bytes when finished. However the two given keys will remain untouched.
151148
*
152149
* @param ctrKey SIV mode requires two separate keys. You can use one long key, which is splitted in half. See https://tools.ietf.org/html/rfc5297#section-2.2
153150
* @param macKey SIV mode requires two separate keys. You can use one long key, which is splitted in half. See https://tools.ietf.org/html/rfc5297#section-2.2
@@ -174,7 +171,6 @@ public byte[] decrypt(SecretKey ctrKey, SecretKey macKey, byte[] ciphertext, byt
174171

175172
/**
176173
* Decrypts ciphertext using SIV mode. A block cipher defined by the constructor is being used.<br>
177-
* This method leaves the two given keys untouched, the calling function needs to makes sure, key bytes are destroyed when finished.
178174
*
179175
* @param ctrKey SIV mode requires two separate keys. You can use one long key, which is splitted in half. See https://tools.ietf.org/html/rfc5297#section-2.2
180176
* @param macKey SIV mode requires two separate keys. You can use one long key, which is splitted in half. See https://tools.ietf.org/html/rfc5297#section-2.2
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2016 Sebastian Stenzel
3+
* This file is licensed under the terms of the MIT license.
4+
* See the LICENSE.txt file for more info.
5+
*
6+
* Contributors:
7+
* Sebastian Stenzel - initial API and implementation
8+
******************************************************************************/
9+
package org.cryptomator.siv;
10+
11+
import org.junit.Test;
12+
import org.openjdk.jmh.runner.Runner;
13+
import org.openjdk.jmh.runner.RunnerException;
14+
import org.openjdk.jmh.runner.options.Options;
15+
import org.openjdk.jmh.runner.options.OptionsBuilder;
16+
17+
public class BenchmarkTest {
18+
19+
@Test
20+
public void runBenchmarks() throws RunnerException {
21+
// Taken from http://stackoverflow.com/a/30486197/4014509:
22+
Options opt = new OptionsBuilder()
23+
// Specify which benchmarks to run
24+
.include(getClass().getPackage().getName() + ".*Benchmark.*")
25+
// Set the following options as needed
26+
.threads(2).forks(1) //
27+
.shouldFailOnError(true).shouldDoGC(true)
28+
// .jvmArgs("-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining")
29+
// .addProfiler(WinPerfAsmProfiler.class)
30+
.build();
31+
32+
new Runner(opt).run();
33+
}
34+
35+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2016 Sebastian Stenzel
3+
* This file is licensed under the terms of the MIT license.
4+
* See the LICENSE.txt file for more info.
5+
*
6+
* Contributors:
7+
* Sebastian Stenzel - initial API and implementation
8+
******************************************************************************/
9+
package org.cryptomator.siv;
10+
11+
import java.util.Arrays;
12+
import java.util.concurrent.TimeUnit;
13+
14+
import org.bouncycastle.crypto.BlockCipher;
15+
import org.bouncycastle.crypto.engines.AESFastEngine;
16+
import org.bouncycastle.crypto.engines.AESLightEngine;
17+
import org.cryptomator.siv.SivMode.BlockCipherFactory;
18+
import org.openjdk.jmh.annotations.Benchmark;
19+
import org.openjdk.jmh.annotations.BenchmarkMode;
20+
import org.openjdk.jmh.annotations.Level;
21+
import org.openjdk.jmh.annotations.Measurement;
22+
import org.openjdk.jmh.annotations.Mode;
23+
import org.openjdk.jmh.annotations.OutputTimeUnit;
24+
import org.openjdk.jmh.annotations.Scope;
25+
import org.openjdk.jmh.annotations.Setup;
26+
import org.openjdk.jmh.annotations.State;
27+
import org.openjdk.jmh.annotations.Warmup;
28+
29+
/**
30+
* Needs to be compiled via maven as the JMH annotation processor needs to do stuff...
31+
*/
32+
@State(Scope.Thread)
33+
@Warmup(iterations = 2, time = 500, timeUnit = TimeUnit.MILLISECONDS)
34+
@Measurement(iterations = 2, time = 500, timeUnit = TimeUnit.MILLISECONDS)
35+
@BenchmarkMode(value = {Mode.AverageTime})
36+
@OutputTimeUnit(TimeUnit.MICROSECONDS)
37+
public class SivModeBenchmark {
38+
39+
private int run;
40+
private final byte[] encKeyBuf = new byte[16];
41+
private final byte[] macKeyBuf = new byte[16];
42+
private final byte[] testData = new byte[8 * 1024];
43+
private final byte[] adData = new byte[1024];
44+
45+
private final SivMode jceSivMode = new SivMode();
46+
private final SivMode bcFastSivMode = new SivMode(new BlockCipherFactory() {
47+
48+
@Override
49+
public BlockCipher create() {
50+
return new AESFastEngine();
51+
}
52+
53+
});
54+
private final SivMode bcLightSivMode = new SivMode(new BlockCipherFactory() {
55+
56+
@Override
57+
public BlockCipher create() {
58+
return new AESLightEngine();
59+
}
60+
61+
});
62+
63+
@Setup(Level.Trial)
64+
public void shuffleData() {
65+
run++;
66+
Arrays.fill(encKeyBuf, (byte) (run & 0xFF));
67+
Arrays.fill(macKeyBuf, (byte) (run & 0xFF));
68+
Arrays.fill(testData, (byte) (run & 0xFF));
69+
Arrays.fill(adData, (byte) (run & 0xFF));
70+
}
71+
72+
@Benchmark
73+
public void benchmarkJce() {
74+
jceSivMode.encrypt(encKeyBuf, macKeyBuf, testData, adData);
75+
}
76+
77+
@Benchmark
78+
public void benchmarkBcFast() {
79+
bcFastSivMode.encrypt(encKeyBuf, macKeyBuf, testData, adData);
80+
}
81+
82+
@Benchmark
83+
public void benchmarkBcLight() {
84+
bcLightSivMode.encrypt(encKeyBuf, macKeyBuf, testData, adData);
85+
}
86+
87+
}

0 commit comments

Comments
 (0)