public static void InitializeSession(SessionState sessionState,
                                             SymmetricSignalProtocolParameters parameters)
        {
            if (IsAlice(parameters.GetOurBaseKey().GetPublicKey(), parameters.GetTheirBaseKey()))
            {
                AliceSignalProtocolParameters.Builder aliceParameters = AliceSignalProtocolParameters.NewBuilder();

                aliceParameters.SetOurBaseKey(parameters.GetOurBaseKey())
                .SetOurIdentityKey(parameters.GetOurIdentityKey())
                .SetTheirRatchetKey(parameters.GetTheirRatchetKey())
                .SetTheirIdentityKey(parameters.GetTheirIdentityKey())
                .SetTheirSignedPreKey(parameters.GetTheirBaseKey())
                .SetTheirOneTimePreKey(May <IEcPublicKey> .NoValue);

                InitializeSession(sessionState, aliceParameters.Create());
            }
            else
            {
                BobSignalProtocolParameters.Builder bobParameters = BobSignalProtocolParameters.NewBuilder();

                bobParameters.SetOurIdentityKey(parameters.GetOurIdentityKey())
                .SetOurRatchetKey(parameters.GetOurRatchetKey())
                .SetOurSignedPreKey(parameters.GetOurBaseKey())
                .SetOurOneTimePreKey(May <EcKeyPair> .NoValue)
                .SetTheirBaseKey(parameters.GetTheirBaseKey())
                .SetTheirIdentityKey(parameters.GetTheirIdentityKey());

                InitializeSession(sessionState, bobParameters.Create());
            }
        }
        public static void InitializeSession(SessionState sessionState, AliceSignalProtocolParameters parameters)

        {
            try
            {
                sessionState.SetSessionVersion(CiphertextMessage.CurrentVersion);
                sessionState.SetRemoteIdentityKey(parameters.GetTheirIdentityKey());
                sessionState.SetLocalIdentityKey(parameters.GetOurIdentityKey().GetPublicKey());

                EcKeyPair    sendingRatchetKey = Curve.GenerateKeyPair();
                MemoryStream secrets           = new MemoryStream();

                byte[] discontinuityBytes = GetDiscontinuityBytes();
                secrets.Write(discontinuityBytes, 0, discontinuityBytes.Length);

                byte[] agree1 = Curve.CalculateAgreement(parameters.GetTheirSignedPreKey(),
                                                         parameters.GetOurIdentityKey().GetPrivateKey());
                byte[] agree2 = Curve.CalculateAgreement(parameters.GetTheirIdentityKey().GetPublicKey(),
                                                         parameters.GetOurBaseKey().GetPrivateKey());
                byte[] agree3 = Curve.CalculateAgreement(parameters.GetTheirSignedPreKey(),
                                                         parameters.GetOurBaseKey().GetPrivateKey());

                secrets.Write(agree1, 0, agree1.Length);
                secrets.Write(agree2, 0, agree2.Length);
                secrets.Write(agree3, 0, agree3.Length);

                if (parameters.GetTheirOneTimePreKey().HasValue)
                {
                    byte[] otAgree = Curve.CalculateAgreement(parameters.GetTheirOneTimePreKey().ForceGetValue(),
                                                              parameters.GetOurBaseKey().GetPrivateKey());
                    secrets.Write(otAgree, 0, otAgree.Length);
                }

                DerivedKeys derivedKeys = CalculateDerivedKeys(secrets.ToArray());
                Pair <RootKey, ChainKey> sendingChain = derivedKeys.GetRootKey().CreateChain(parameters.GetTheirRatchetKey(), sendingRatchetKey);

                sessionState.AddReceiverChain(parameters.GetTheirRatchetKey(), derivedKeys.GetChainKey());
                sessionState.SetSenderChain(sendingRatchetKey, sendingChain.Second());
                sessionState.SetRootKey(sendingChain.First());
            }
            catch (IOException e)
            {
                throw new Exception(e.Message);
            }
        }