Example #1
0
        public EcKeyPair GetSenderRatchetKeyPair()
        {
            IEcPublicKey  publicKey  = GetSenderRatchetKey();
            IEcPrivateKey privateKey = Curve.DecodePrivatePoint(_sessionStructure.SenderChain
                                                                .SenderRatchetKeyPrivate
                                                                .ToByteArray());

            return(new EcKeyPair(publicKey, privateKey));
        }
Example #2
0
        public IdentityKeyPair GetPendingKeyExchangeIdentityKey()
        {
            IdentityKey publicKey = new IdentityKey(_sessionStructure.PendingKeyExchange
                                                    .LocalIdentityKey.ToByteArray(), 0);

            IEcPrivateKey privateKey = Curve.DecodePrivatePoint(_sessionStructure.PendingKeyExchange
                                                                .LocalIdentityKeyPrivate
                                                                .ToByteArray());

            return(new IdentityKeyPair(publicKey, privateKey));
        }
Example #3
0
        public EcKeyPair GetPendingKeyExchangeRatchetKey()
        {
            IEcPublicKey publicKey = Curve.DecodePoint(_sessionStructure.PendingKeyExchange
                                                       .LocalRatchetKey.ToByteArray(), 0);

            IEcPrivateKey privateKey = Curve.DecodePrivatePoint(_sessionStructure.PendingKeyExchange
                                                                .LocalRatchetKeyPrivate
                                                                .ToByteArray());

            return(new EcKeyPair(publicKey, privateKey));
        }
 private byte[] GetSignature(IEcPrivateKey signatureKey, byte[] serialized)
 {
     try
     {
         return(Curve.CalculateSignature(signatureKey, serialized));
     }
     catch (InvalidKeyException e)
     {
         throw new Exception(e.Message);
     }
 }
 public static byte[] CalculateSignature(IEcPrivateKey signingKey, byte[] message)
 {
     if (signingKey.GetKeyType() == DjbType)
     {
         return(Curve25519.GetInstance(Curve25519ProviderType.Best)
                .CalculateSignature(((DjbEcPrivateKey)signingKey).GetPrivateKey(), message));
     }
     else
     {
         throw new InvalidKeyException("Unknown type: " + signingKey.GetKeyType());
     }
 }
Example #6
0
 public IdentityKeyPair(byte[] serialized)
 {
     try
     {
         StorageProtos.IdentityKeyPairStructure structure = StorageProtos.IdentityKeyPairStructure.ParseFrom(serialized);
         _publicKey  = new IdentityKey(structure.PublicKey.ToByteArray(), 0);
         _privateKey = Curve.DecodePrivatePoint(structure.PrivateKey.ToByteArray());
     }
     catch (InvalidProtocolBufferException e)
     {
         throw new InvalidKeyException(e);
     }
 }
        public EcKeyPair GetKeyPair()
        {
            try
            {
                IEcPublicKey  publicKey  = Curve.DecodePoint(_structure.PublicKey.ToByteArray(), 0);
                IEcPrivateKey privateKey = Curve.DecodePrivatePoint(_structure.PrivateKey.ToByteArray());

                return(new EcKeyPair(publicKey, privateKey));
            }
            catch (InvalidKeyException e)
            {
                throw new Exception(e.Message);
            }
        }
        public SenderKeyMessage(uint keyId, uint iteration, byte[] ciphertext, IEcPrivateKey signatureKey)
        {
            byte[] version = { ByteUtil.IntsToByteHighAndLow((int)CurrentVersion, (int)CurrentVersion) };
            byte[] message = WhisperProtos.SenderKeyMessage.CreateBuilder()
                             .SetId(keyId)
                             .SetIteration(iteration)
                             .SetCiphertext(ByteString.CopyFrom(ciphertext))
                             .Build().ToByteArray();

            byte[] signature = GetSignature(signatureKey, ByteUtil.Combine(version, message));

            _serialized     = ByteUtil.Combine(version, message, signature);
            _messageVersion = CurrentVersion;
            _keyId          = keyId;
            _iteration      = iteration;
            _ciphertext     = ciphertext;
        }
        public static byte[] CalculateAgreement(IEcPublicKey publicKey, IEcPrivateKey privateKey)
        {
            if (publicKey.GetKeyType() != privateKey.GetKeyType())
            {
                throw new InvalidKeyException("Public and private keys must be of the same type!");
            }

            if (publicKey.GetKeyType() == DjbType)
            {
                return(Curve25519.GetInstance(Curve25519ProviderType.Best)
                       .CalculateAgreement(((DjbEcPublicKey)publicKey).GetPublicKey(),
                                           ((DjbEcPrivateKey)privateKey).GetPrivateKey()));
            }
            else
            {
                throw new InvalidKeyException("Unknown type: " + publicKey.GetKeyType());
            }
        }
        public SenderKeyMessage(uint keyId, uint iteration, byte[] ciphertext, IEcPrivateKey signatureKey)
        {
            byte[] version = { ByteUtil.IntsToByteHighAndLow((int)CurrentVersion, (int)CurrentVersion) };
            byte[] message = new SenderKeyMessage
            {
                Id         = keyId,
                Iteration  = iteration,
                Ciphertext = ByteString.CopyFrom(ciphertext),
            }.ToByteArray();

            byte[] signature = GetSignature(signatureKey, ByteUtil.Combine(version, message));

            _serialized     = ByteUtil.Combine(version, message, signature);
            _messageVersion = CurrentVersion;
            _keyId          = keyId;
            _iteration      = iteration;
            _ciphertext     = ciphertext;
        }
Example #11
0
 public IdentityKeyPair(IdentityKey publicKey, IEcPrivateKey privateKey)
 {
     _publicKey  = publicKey;
     _privateKey = privateKey;
 }
Example #12
0
        public void TestRootKeyDerivationV2()
        {
            byte[] rootKeySeed =
            {
                0x7b, 0xa6, 0xde, 0xbc, 0x2b,
                0xc1, 0xbb, 0xf9, 0x1a, 0xbb,
                0xc1, 0x36, 0x74, 0x04, 0x17,
                0x6c, 0xa6, 0x23, 0x09, 0x5b,
                0x7e, 0xc6, 0x6b, 0x45, 0xf6,
                0x02, 0xd9, 0x35, 0x38, 0x94,
                0x2d, 0xcc
            };

            byte[] alicePublic =
            {
                0x05, 0xee, 0x4f, 0xa6, 0xcd,
                0xc0, 0x30, 0xdf, 0x49, 0xec,
                0xd0, 0xba, 0x6c, 0xfc, 0xff,
                0xb2, 0x33, 0xd3, 0x65, 0xa2,
                0x7f, 0xad, 0xbe, 0xff, 0x77,
                0xe9, 0x63, 0xfc, 0xb1, 0x62,
                0x22, 0xe1, 0x3a
            };

            byte[] alicePrivate =
            {
                0x21, 0x68, 0x22, 0xec, 0x67,
                0xeb, 0x38, 0x04, 0x9e, 0xba,
                0xe7, 0xb9, 0x39, 0xba, 0xea,
                0xeb, 0xb1, 0x51, 0xbb, 0xb3,
                0x2d, 0xb8, 0x0f, 0xd3, 0x89,
                0x24, 0x5a, 0xc3, 0x7a, 0x94,
                0x8e, 0x50
            };

            byte[] bobPublic =
            {
                0x05, 0xab, 0xb8, 0xeb, 0x29,
                0xcc, 0x80, 0xb4, 0x71, 0x09,
                0xa2, 0x26, 0x5a, 0xbe, 0x97,
                0x98, 0x48, 0x54, 0x06, 0xe3,
                0x2d, 0xa2, 0x68, 0x93, 0x4a,
                0x95, 0x55, 0xe8, 0x47, 0x57,
                0x70, 0x8a, 0x30
            };

            byte[] nextRoot =
            {
                0xb1, 0x14, 0xf5, 0xde, 0x28,
                0x01, 0x19, 0x85, 0xe6, 0xeb,
                0xa2, 0x5d, 0x50, 0xe7, 0xec,
                0x41, 0xa9, 0xb0, 0x2f, 0x56,
                0x93, 0xc5, 0xc7, 0x88, 0xa6,
                0x3a, 0x06, 0xd2, 0x12, 0xa2,
                0xf7, 0x31
            };

            byte[] nextChain =
            {
                0x9d, 0x7d, 0x24, 0x69, 0xbc,
                0x9a, 0xe5, 0x3e, 0xe9, 0x80,
                0x5a, 0xa3, 0x26, 0x4d, 0x24,
                0x99, 0xa3, 0xac, 0xe8, 0x0f,
                0x4c, 0xca, 0xe2, 0xda, 0x13,
                0x43, 0x0c, 0x5c, 0x55, 0xb5,
                0xca, 0x5f
            };

            IEcPublicKey  alicePublicKey  = Curve.DecodePoint(alicePublic, 0);
            IEcPrivateKey alicePrivateKey = Curve.DecodePrivatePoint(alicePrivate);
            EcKeyPair     aliceKeyPair    = new EcKeyPair(alicePublicKey, alicePrivateKey);

            IEcPublicKey bobPublicKey = Curve.DecodePoint(bobPublic, 0);
            RootKey      rootKey      = new RootKey(Hkdf.CreateFor(2), rootKeySeed);

            Pair <RootKey, ChainKey> rootKeyChainKeyPair = rootKey.CreateChain(bobPublicKey, aliceKeyPair);
            RootKey  nextRootKey  = rootKeyChainKeyPair.First();
            ChainKey nextChainKey = rootKeyChainKeyPair.Second();

            CollectionAssert.AreEqual(rootKey.GetKeyBytes(), rootKeySeed);
            CollectionAssert.AreEqual(nextRootKey.GetKeyBytes(), nextRoot);
            CollectionAssert.AreEqual(nextChainKey.GetKey(), nextChain);
        }
Example #13
0
 public EcKeyPair(IEcPublicKey publicKey, IEcPrivateKey privateKey)
 {
     _publicKey  = publicKey;
     _privateKey = privateKey;
 }
        public void TestAgreement()
        {
            byte[] alicePublic =
            {
                0x05, 0x1b, 0xb7, 0x59, 0x66,
                0xf2, 0xe9, 0x3a, 0x36, 0x91,
                0xdf, 0xff, 0x94, 0x2b, 0xb2,
                0xa4, 0x66, 0xa1, 0xc0, 0x8b,
                0x8d, 0x78, 0xca, 0x3f, 0x4d,
                0x6d, 0xf8, 0xb8, 0xbf, 0xa2,
                0xe4, 0xee, 0x28
            };

            byte[] alicePrivate =
            {
                0xc8, 0x06, 0x43, 0x9d, 0xc9,
                0xd2, 0xc4, 0x76, 0xff, 0xed,
                0x8f, 0x25, 0x80, 0xc0, 0x88,
                0x8d, 0x58, 0xab, 0x40, 0x6b,
                0xf7, 0xae, 0x36, 0x98, 0x87,
                0x90, 0x21, 0xb9, 0x6b, 0xb4,
                0xbf, 0x59
            };

            byte[] bobPublic =
            {
                0x05, 0x65, 0x36, 0x14, 0x99,
                0x3d, 0x2b, 0x15, 0xee, 0x9e,
                0x5f, 0xd3, 0xd8, 0x6c, 0xe7,
                0x19, 0xef, 0x4e, 0xc1, 0xda,
                0xae, 0x18, 0x86, 0xa8, 0x7b,
                0x3f, 0x5f, 0xa9, 0x56, 0x5a,
                0x27, 0xa2, 0x2f
            };

            byte[] bobPrivate =
            {
                0xb0, 0x3b, 0x34, 0xc3, 0x3a,
                0x1c, 0x44, 0xf2, 0x25, 0xb6,
                0x62, 0xd2, 0xbf, 0x48, 0x59,
                0xb8, 0x13, 0x54, 0x11, 0xfa,
                0x7b, 0x03, 0x86, 0xd4, 0x5f,
                0xb7, 0x5d, 0xc5, 0xb9, 0x1b,
                0x44, 0x66
            };

            byte[] shared =
            {
                0x32, 0x5f, 0x23, 0x93, 0x28,
                0x94, 0x1c, 0xed, 0x6e, 0x67,
                0x3b, 0x86, 0xba, 0x41, 0x01,
                0x74, 0x48, 0xe9, 0x9b, 0x64,
                0x9a, 0x9c, 0x38, 0x06, 0xc1,
                0xdd, 0x7c, 0xa4, 0xc4, 0x77,
                0xe6, 0x29
            };

            IEcPublicKey  alicePublicKey  = Curve.DecodePoint(alicePublic, 0);
            IEcPrivateKey alicePrivateKey = Curve.DecodePrivatePoint(alicePrivate);

            IEcPublicKey  bobPublicKey  = Curve.DecodePoint(bobPublic, 0);
            IEcPrivateKey bobPrivateKey = Curve.DecodePrivatePoint(bobPrivate);

            byte[] sharedOne = Curve.CalculateAgreement(alicePublicKey, bobPrivateKey);
            byte[] sharedTwo = Curve.CalculateAgreement(bobPublicKey, alicePrivateKey);

            CollectionAssert.AreEqual(sharedOne, shared);
            CollectionAssert.AreEqual(sharedTwo, shared);
        }
        public void TestSignature()
        {
            byte[] aliceIdentityPrivate =
            {
                0xc0, 0x97, 0x24, 0x84, 0x12,
                0xe5, 0x8b, 0xf0, 0x5d, 0xf4,
                0x87, 0x96, 0x82, 0x05, 0x13,
                0x27, 0x94, 0x17, 0x8e, 0x36,
                0x76, 0x37, 0xf5, 0x81, 0x8f,
                0x81, 0xe0, 0xe6, 0xce, 0x73,
                0xe8, 0x65
            };

            byte[] aliceIdentityPublic =
            {
                0x05, 0xab, 0x7e, 0x71, 0x7d,
                0x4a, 0x16, 0x3b, 0x7d, 0x9a,
                0x1d, 0x80, 0x71, 0xdf, 0xe9,
                0xdc, 0xf8, 0xcd, 0xcd, 0x1c,
                0xea, 0x33, 0x39, 0xb6, 0x35,
                0x6b, 0xe8, 0x4d, 0x88, 0x7e,
                0x32, 0x2c, 0x64
            };

            byte[] aliceEphemeralPublic =
            {
                0x05, 0xed, 0xce, 0x9d, 0x9c,
                0x41, 0x5c, 0xa7, 0x8c, 0xb7,
                0x25, 0x2e, 0x72, 0xc2, 0xc4,
                0xa5, 0x54, 0xd3, 0xeb, 0x29,
                0x48, 0x5a, 0x0e, 0x1d, 0x50,
                0x31, 0x18, 0xd1, 0xa8, 0x2d,
                0x99, 0xfb, 0x4a
            };

            byte[] aliceSignature =
            {
                0x5d, 0xe8, 0x8c, 0xa9, 0xa8,
                0x9b, 0x4a, 0x11, 0x5d, 0xa7,
                0x91, 0x09, 0xc6, 0x7c, 0x9c,
                0x74, 0x64, 0xa3, 0xe4, 0x18,
                0x02, 0x74, 0xf1, 0xcb, 0x8c,
                0x63, 0xc2, 0x98, 0x4e, 0x28,
                0x6d, 0xfb, 0xed, 0xe8, 0x2d,
                0xeb, 0x9d, 0xcd, 0x9f, 0xae,
                0x0b, 0xfb, 0xb8, 0x21, 0x56,
                0x9b, 0x3d, 0x90, 0x01, 0xbd,
                0x81, 0x30, 0xcd, 0x11, 0xd4,
                0x86, 0xce, 0xf0, 0x47, 0xbd,
                0x60, 0xb8, 0x6e, 0x88
            };

            IEcPrivateKey alicePrivateKey = Curve.DecodePrivatePoint(aliceIdentityPrivate);
            IEcPublicKey  alicePublicKey  = Curve.DecodePoint(aliceIdentityPublic, 0);
            IEcPublicKey  aliceEphemeral  = Curve.DecodePoint(aliceEphemeralPublic, 0);

            if (!Curve.VerifySignature(alicePublicKey, aliceEphemeral.Serialize(), aliceSignature))
            {
                Assert.Fail("Sig verification failed!");
            }

            for (int i = 0; i < aliceSignature.Length; i++)
            {
                byte[] modifiedSignature = new byte[aliceSignature.Length];
                System.Buffer.BlockCopy(aliceSignature, 0, modifiedSignature, 0, modifiedSignature.Length);

                modifiedSignature[i] ^= 0x01;

                if (Curve.VerifySignature(alicePublicKey, aliceEphemeral.Serialize(), modifiedSignature))
                {
                    Assert.Fail("Sig verification succeeded!");
                }
            }
        }
        public void TestRatchetingSessionAsBob()
        {
            byte[] bobPublic = { (byte)0x05, (byte)0x2c, (byte)0xb4, (byte)0x97,
                                 (byte)0x76, (byte)0xb8, (byte)0x77, (byte)0x02,
                                 (byte)0x05, (byte)0x74, (byte)0x5a, (byte)0x3a,
                                 (byte)0x6e, (byte)0x24, (byte)0xf5, (byte)0x79,
                                 (byte)0xcd, (byte)0xb4, (byte)0xba, (byte)0x7a,
                                 (byte)0x89, (byte)0x04, (byte)0x10, (byte)0x05,
                                 (byte)0x92, (byte)0x8e, (byte)0xbb, (byte)0xad,
                                 (byte)0xc9, (byte)0xc0, (byte)0x5a, (byte)0xd4,
                                 (byte)0x58 };

            byte[] bobPrivate = { (byte)0xa1, (byte)0xca, (byte)0xb4, (byte)0x8f,
                                  (byte)0x7c, (byte)0x89, (byte)0x3f, (byte)0xaf,
                                  (byte)0xa9, (byte)0x88, (byte)0x0a, (byte)0x28,
                                  (byte)0xc3, (byte)0xb4, (byte)0x99, (byte)0x9d,
                                  (byte)0x28, (byte)0xd6, (byte)0x32, (byte)0x95,
                                  (byte)0x62, (byte)0xd2, (byte)0x7a, (byte)0x4e,
                                  (byte)0xa4, (byte)0xe2, (byte)0x2e, (byte)0x9f,
                                  (byte)0xf1, (byte)0xbd, (byte)0xd6, (byte)0x5a };

            byte[] bobIdentityPublic = { (byte)0x05, (byte)0xf1, (byte)0xf4, (byte)0x38,
                                         (byte)0x74, (byte)0xf6, (byte)0x96, (byte)0x69,
                                         (byte)0x56, (byte)0xc2, (byte)0xdd, (byte)0x47,
                                         (byte)0x3f, (byte)0x8f, (byte)0xa1, (byte)0x5a,
                                         (byte)0xde, (byte)0xb7, (byte)0x1d, (byte)0x1c,
                                         (byte)0xb9, (byte)0x91, (byte)0xb2, (byte)0x34,
                                         (byte)0x16, (byte)0x92, (byte)0x32, (byte)0x4c,
                                         (byte)0xef, (byte)0xb1, (byte)0xc5, (byte)0xe6,
                                         (byte)0x26 };

            byte[] bobIdentityPrivate = { (byte)0x48, (byte)0x75, (byte)0xcc, (byte)0x69,
                                          (byte)0xdd, (byte)0xf8, (byte)0xea, (byte)0x07,
                                          (byte)0x19, (byte)0xec, (byte)0x94, (byte)0x7d,
                                          (byte)0x61, (byte)0x08, (byte)0x11, (byte)0x35,
                                          (byte)0x86, (byte)0x8d, (byte)0x5f, (byte)0xd8,
                                          (byte)0x01, (byte)0xf0, (byte)0x2c, (byte)0x02,
                                          (byte)0x25, (byte)0xe5, (byte)0x16, (byte)0xdf,
                                          (byte)0x21, (byte)0x56, (byte)0x60, (byte)0x5e };

            byte[] aliceBasePublic = { (byte)0x05, (byte)0x47, (byte)0x2d, (byte)0x1f,
                                       (byte)0xb1, (byte)0xa9, (byte)0x86, (byte)0x2c,
                                       (byte)0x3a, (byte)0xf6, (byte)0xbe, (byte)0xac,
                                       (byte)0xa8, (byte)0x92, (byte)0x02, (byte)0x77,
                                       (byte)0xe2, (byte)0xb2, (byte)0x6f, (byte)0x4a,
                                       (byte)0x79, (byte)0x21, (byte)0x3e, (byte)0xc7,
                                       (byte)0xc9, (byte)0x06, (byte)0xae, (byte)0xb3,
                                       (byte)0x5e, (byte)0x03, (byte)0xcf, (byte)0x89,
                                       (byte)0x50 };

            byte[] aliceEphemeralPublic = { (byte)0x05, (byte)0x6c, (byte)0x3e, (byte)0x0d,
                                            (byte)0x1f, (byte)0x52, (byte)0x02, (byte)0x83,
                                            (byte)0xef, (byte)0xcc, (byte)0x55, (byte)0xfc,
                                            (byte)0xa5, (byte)0xe6, (byte)0x70, (byte)0x75,
                                            (byte)0xb9, (byte)0x04, (byte)0x00, (byte)0x7f,
                                            (byte)0x18, (byte)0x81, (byte)0xd1, (byte)0x51,
                                            (byte)0xaf, (byte)0x76, (byte)0xdf, (byte)0x18,
                                            (byte)0xc5, (byte)0x1d, (byte)0x29, (byte)0xd3,
                                            (byte)0x4b };

            byte[] aliceIdentityPublic = { (byte)0x05, (byte)0xb4, (byte)0xa8, (byte)0x45,
                                           (byte)0x56, (byte)0x60, (byte)0xad, (byte)0xa6,
                                           (byte)0x5b, (byte)0x40, (byte)0x10, (byte)0x07,
                                           (byte)0xf6, (byte)0x15, (byte)0xe6, (byte)0x54,
                                           (byte)0x04, (byte)0x17, (byte)0x46, (byte)0x43,
                                           (byte)0x2e, (byte)0x33, (byte)0x39, (byte)0xc6,
                                           (byte)0x87, (byte)0x51, (byte)0x49, (byte)0xbc,
                                           (byte)0xee, (byte)0xfc, (byte)0xb4, (byte)0x2b,
                                           (byte)0x4a };

            byte[] bobSignedPreKeyPublic = { (byte)0x05, (byte)0xac, (byte)0x24, (byte)0x8a, (byte)0x8f,
                                             (byte)0x26, (byte)0x3b, (byte)0xe6, (byte)0x86, (byte)0x35,
                                             (byte)0x76, (byte)0xeb, (byte)0x03, (byte)0x62, (byte)0xe2,
                                             (byte)0x8c, (byte)0x82, (byte)0x8f, (byte)0x01, (byte)0x07,
                                             (byte)0xa3, (byte)0x37, (byte)0x9d, (byte)0x34, (byte)0xba,
                                             (byte)0xb1, (byte)0x58, (byte)0x6b, (byte)0xf8, (byte)0xc7,
                                             (byte)0x70, (byte)0xcd, (byte)0x67 };

            byte[] bobSignedPreKeyPrivate = { (byte)0x58, (byte)0x39, (byte)0x00, (byte)0x13, (byte)0x1f,
                                              (byte)0xb7, (byte)0x27, (byte)0x99, (byte)0x8b, (byte)0x78,
                                              (byte)0x03, (byte)0xfe, (byte)0x6a, (byte)0xc2, (byte)0x2c,
                                              (byte)0xc5, (byte)0x91, (byte)0xf3, (byte)0x42, (byte)0xe4,
                                              (byte)0xe4, (byte)0x2a, (byte)0x8c, (byte)0x8d, (byte)0x5d,
                                              (byte)0x78, (byte)0x19, (byte)0x42, (byte)0x09, (byte)0xb8,
                                              (byte)0xd2, (byte)0x53 };

            byte[] senderChain = { (byte)0x97, (byte)0x97, (byte)0xca, (byte)0xca, (byte)0x53,
                                   (byte)0xc9, (byte)0x89, (byte)0xbb, (byte)0xe2, (byte)0x29,
                                   (byte)0xa4, (byte)0x0c, (byte)0xa7, (byte)0x72, (byte)0x70,
                                   (byte)0x10, (byte)0xeb, (byte)0x26, (byte)0x04, (byte)0xfc,
                                   (byte)0x14, (byte)0x94, (byte)0x5d, (byte)0x77, (byte)0x95,
                                   (byte)0x8a, (byte)0x0a, (byte)0xed, (byte)0xa0, (byte)0x88,
                                   (byte)0xb4, (byte)0x4d };

            IdentityKey     bobIdentityKeyPublic   = new IdentityKey(bobIdentityPublic, 0);
            IEcPrivateKey   bobIdentityKeyPrivate  = Curve.DecodePrivatePoint(bobIdentityPrivate);
            IdentityKeyPair bobIdentityKey         = new IdentityKeyPair(bobIdentityKeyPublic, bobIdentityKeyPrivate);
            IEcPublicKey    bobEphemeralPublicKey  = Curve.DecodePoint(bobPublic, 0);
            IEcPrivateKey   bobEphemeralPrivateKey = Curve.DecodePrivatePoint(bobPrivate);
            EcKeyPair       bobEphemeralKey        = new EcKeyPair(bobEphemeralPublicKey, bobEphemeralPrivateKey);
            EcKeyPair       bobBaseKey             = bobEphemeralKey;
            EcKeyPair       bobSignedPreKey        = new EcKeyPair(Curve.DecodePoint(bobSignedPreKeyPublic, 0), Curve.DecodePrivatePoint(bobSignedPreKeyPrivate));

            IEcPublicKey aliceBasePublicKey      = Curve.DecodePoint(aliceBasePublic, 0);
            IEcPublicKey aliceEphemeralPublicKey = Curve.DecodePoint(aliceEphemeralPublic, 0);
            IdentityKey  aliceIdentityPublicKey  = new IdentityKey(aliceIdentityPublic, 0);

            BobSignalProtocolParameters parameters = BobSignalProtocolParameters.NewBuilder()
                                                     .SetOurIdentityKey(bobIdentityKey)
                                                     .SetOurSignedPreKey(bobSignedPreKey)
                                                     .SetOurRatchetKey(bobEphemeralKey)
                                                     .SetOurOneTimePreKey(May <EcKeyPair> .NoValue)
                                                     .SetTheirIdentityKey(aliceIdentityPublicKey)
                                                     .SetTheirBaseKey(aliceBasePublicKey)
                                                     .Create();

            SessionState session = new SessionState();

            RatchetingSession.InitializeSession(session, parameters);

            Assert.AreEqual <IdentityKey>(session.GetLocalIdentityKey(), bobIdentityKey.GetPublicKey());
            Assert.AreEqual <IdentityKey>(session.GetRemoteIdentityKey(), aliceIdentityPublicKey);
            CollectionAssert.AreEqual(session.GetSenderChainKey().GetKey(), senderChain);
        }