/** * Copyright (C) 2014 Open Whisper Systems * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package org.whispersystems.libaxolotl.ratchet; import org.whispersystems.libaxolotl.InvalidKeyException; import org.whispersystems.libaxolotl.ecc.Curve; import org.whispersystems.libaxolotl.ecc.ECKeyPair; import org.whispersystems.libaxolotl.ecc.ECPublicKey; import org.whispersystems.libaxolotl.kdf.DerivedRootSecrets; import org.whispersystems.libaxolotl.kdf.HKDF; import org.whispersystems.libaxolotl.util.ByteUtil; import org.whispersystems.libaxolotl.util.Pair; public class RootKey { private final HKDF kdf; private final byte[] key; public RootKey(HKDF kdf, byte[] key) { this.kdf = kdf; this.key = key; } public byte[] getKeyBytes() { return key; } public Pair createChain(ECPublicKey theirRatchetKey, ECKeyPair ourRatchetKey) throws InvalidKeyException { byte[] sharedSecret = Curve.calculateAgreement(theirRatchetKey, ourRatchetKey.getPrivateKey()); byte[] derivedSecretBytes = kdf.deriveSecrets(sharedSecret, key, "WhisperRatchet".getBytes(), DerivedRootSecrets.SIZE); DerivedRootSecrets derivedSecrets = new DerivedRootSecrets(derivedSecretBytes); RootKey newRootKey = new RootKey(kdf, derivedSecrets.getRootKey()); ChainKey newChainKey = new ChainKey(kdf, derivedSecrets.getChainKey(), 0); return new Pair<>(newRootKey, newChainKey); } }