aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/org/whispersystems/libaxolotl/groups/ratchet/SenderChainKey.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/org/whispersystems/libaxolotl/groups/ratchet/SenderChainKey.java')
-rw-r--r--src/main/java/org/whispersystems/libaxolotl/groups/ratchet/SenderChainKey.java49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/main/java/org/whispersystems/libaxolotl/groups/ratchet/SenderChainKey.java b/src/main/java/org/whispersystems/libaxolotl/groups/ratchet/SenderChainKey.java
new file mode 100644
index 00000000..71375923
--- /dev/null
+++ b/src/main/java/org/whispersystems/libaxolotl/groups/ratchet/SenderChainKey.java
@@ -0,0 +1,49 @@
+package org.whispersystems.libaxolotl.groups.ratchet;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+public class SenderChainKey {
+
+ private static final byte[] MESSAGE_KEY_SEED = {0x01};
+ private static final byte[] CHAIN_KEY_SEED = {0x02};
+
+ private final int iteration;
+ private final byte[] chainKey;
+
+ public SenderChainKey(int iteration, byte[] chainKey) {
+ this.iteration = iteration;
+ this.chainKey = chainKey;
+ }
+
+ public int getIteration() {
+ return iteration;
+ }
+
+ public SenderMessageKey getSenderMessageKey() {
+ return new SenderMessageKey(iteration, getDerivative(MESSAGE_KEY_SEED, chainKey));
+ }
+
+ public SenderChainKey getNext() {
+ return new SenderChainKey(iteration + 1, getDerivative(CHAIN_KEY_SEED, chainKey));
+ }
+
+ public byte[] getSeed() {
+ return chainKey;
+ }
+
+ private byte[] getDerivative(byte[] seed, byte[] key) {
+ try {
+ Mac mac = Mac.getInstance("HmacSHA256");
+ mac.init(new SecretKeySpec(key, "HmacSHA256"));
+
+ return mac.doFinal(seed);
+ } catch (NoSuchAlgorithmException | InvalidKeyException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+}