private ChainKey getOrCreateChainKey(SessionState sessionState, ECPublicKey theirEphemeral) { try { if (sessionState.hasReceiverChain(theirEphemeral)) { return sessionState.getReceiverChainKey(theirEphemeral); } else { RootKey rootKey = sessionState.getRootKey(); ECKeyPair ourEphemeral = sessionState.getSenderRatchetKeyPair(); Pair<RootKey, ChainKey> receiverChain = rootKey.createChain(theirEphemeral, ourEphemeral); ECKeyPair ourNewEphemeral = Curve.generateKeyPair(); Pair<RootKey, ChainKey> senderChain = receiverChain.first().createChain(theirEphemeral, ourNewEphemeral); sessionState.setRootKey(senderChain.first()); sessionState.addReceiverChain(theirEphemeral, receiverChain.second()); sessionState.setPreviousCounter(Math.Max(sessionState.getSenderChainKey().getIndex() - 1, 0)); sessionState.setSenderChain(ourNewEphemeral, senderChain.second()); return receiverChain.second(); } } catch (InvalidKeyException e) { throw new InvalidMessageException(e); } }