public static void initializeSession(SessionState sessionState, BobSignalProtocolParameters parameters) { try { sessionState.setSessionVersion(CiphertextMessage.CURRENT_VERSION); sessionState.setRemoteIdentityKey(parameters.getTheirIdentityKey()); sessionState.setLocalIdentityKey(parameters.getOurIdentityKey().getPublicKey()); MemoryStream secrets = new MemoryStream(); byte[] discontinuityBytes = getDiscontinuityBytes(); secrets.Write(discontinuityBytes, 0, discontinuityBytes.Length); byte[] agree1 = Curve.calculateAgreement(parameters.getTheirIdentityKey().getPublicKey(), parameters.getOurSignedPreKey().getPrivateKey()); byte[] agree2 = Curve.calculateAgreement(parameters.getTheirBaseKey(), parameters.getOurIdentityKey().getPrivateKey()); byte[] agree3 = Curve.calculateAgreement(parameters.getTheirBaseKey(), parameters.getOurSignedPreKey().getPrivateKey()); secrets.Write(agree1, 0, agree1.Length); secrets.Write(agree2, 0, agree2.Length); secrets.Write(agree3, 0, agree3.Length); if (parameters.getOurOneTimePreKey().HasValue) { byte[] otAgree = Curve.calculateAgreement(parameters.getTheirBaseKey(), parameters.getOurOneTimePreKey().ForceGetValue().getPrivateKey()); secrets.Write(otAgree, 0, otAgree.Length); } DerivedKeys derivedKeys = calculateDerivedKeys(secrets.ToArray()); sessionState.setSenderChain(parameters.getOurRatchetKey(), derivedKeys.getChainKey()); sessionState.setRootKey(derivedKeys.getRootKey()); } catch (IOException e) { throw new Exception(e.Message); } }