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); } } }