public KeyExchangeMessage(UInt32 messageVersion, UInt32 sequence, UInt32 flags,
		                           ECPublicKey baseKey, byte[] baseKeySignature,
		                           ECPublicKey ratchetKey,
		                           IdentityKey identityKey)
        {
            MaxVersion = CiphertextMessage.CURRENT_VERSION;
            Version = messageVersion;
            Sequence = sequence;
            Flags = flags;
            BaseKey = baseKey;
            BaseKeySignature = baseKeySignature;
            RatchetKey = ratchetKey;
            IdentityKey = identityKey;

            byte[] version = { ByteUtil.IntsToByteHighAndLow(Version, MaxVersion) };
            var keyExchangeMsg = new WhisperProtos.KeyExchangeMessage {
                id = (Sequence << 5) | Flags,
                baseKey = BaseKey.Serialize(),
                ratchetKey = RatchetKey.Serialize(),
                identityKey = IdentityKey.Serialize()
            };

            if(Version >= 3)
            {
                keyExchangeMsg.baseKeySignature = BaseKeySignature;
            }

            byte[] bytes;
            using(var stream = new MemoryStream())
            {
                Serializer.Serialize(stream, keyExchangeMsg);
                bytes = stream.ToArray();
            }
            _serialized = ByteUtil.Combine(version, bytes);
        }
        public PreKeyWhisperMessage(UInt32 messageVersion, UInt32 registrationId, Maybe<UInt32> preKeyId,
		                            UInt32 signedPreKeyId, ECPublicKey baseKey, IdentityKey identityKey,
		                            WhisperMessage message)
        {
            MessageVersion = messageVersion;
            RegistrationId = registrationId;
            PreKeyId = preKeyId;
            SignedPreKeyId = signedPreKeyId;
            BaseKey = baseKey;
            IdentityKey = identityKey;
            Message = message;

            var preKeyMessage = new WhisperProtos.PreKeyWhisperMessage {
                signedPreKeyId = SignedPreKeyId,
                baseKey = BaseKey.Serialize(),
                identityKey = IdentityKey.Serialize(),
                message = Message.Serialize(),
                registrationId = registrationId
            };

            preKeyId.Do(pKid => preKeyMessage.preKeyId = pKid);

            byte[] versionBytes = { ByteUtil.IntsToByteHighAndLow(MessageVersion, CURRENT_VERSION) };

            byte[] messageBytes;
            using(var stream = new MemoryStream())
            {
                Serializer.Serialize(stream, preKeyMessage);
                messageBytes = stream.ToArray();
            }

            _serialized = ByteUtil.Combine(versionBytes, messageBytes);
        }
Example #3
0
        public WhisperMessage(UInt32 messageVersion, byte[] macKey, ECPublicKey senderRatchetKey,
		                      UInt32 counter, UInt32 previousCounter, byte[] ciphertext,
		                      IdentityKey senderIdentityKey,
		                      IdentityKey receiverIdentityKey)
        {
            byte[] version = { ByteUtil.IntsToByteHighAndLow(messageVersion, CURRENT_VERSION) };

            var messageObj = new WhisperProtos.WhisperMessage {
                RatchetKey = senderRatchetKey.Serialize(),
                Counter = counter,
                PreviousCounter = previousCounter,
                Ciphertext = ciphertext
            };

            byte[] message;

            using(var stream = new MemoryStream())
            {
                Serializer.Serialize<WhisperProtos.WhisperMessage>(stream, messageObj);
                message = stream.ToArray();
            }

            byte[] mac = GetMac(messageVersion, senderIdentityKey, receiverIdentityKey, macKey,
                             ByteUtil.Combine(version, message));

            _serialized = ByteUtil.Combine(version, message, mac);
            SenderRatchetKey = senderRatchetKey;
            Counter = counter;
            PreviousCounter = previousCounter;
            Body = ciphertext;
            MessageVersion = messageVersion;
        }
Example #4
0
 public static bool VerifySignature(ECPublicKey signingKey, byte[] message, byte[] signature)
 {
     if (signingKey.GetKeyType () == DJB_TYPE) {
         return Sodium.OneTimeAuth.Verify (message, signature, signingKey.Serialize ());
     } else {
         throw new Exception ("Unknown type");
     }
 }
Example #5
0
        public Tuple<RootKey, ChainKey> CreateChain(ECPublicKey theirRatchetKey, ECKeyPair ourRatchetKey)
        {
            byte[] sharedSecret = Curve.CalculateAgreement (theirRatchetKey, ourRatchetKey.PrivateKey);
            byte[] derivedSecretBytes = _kdf.DeriveSecrets (sharedSecret, Key, Encoding.UTF8.GetBytes ("WhisperRatchet"), DerivedRootSecrets.SIZE);
            var derivedSecrets = new DerivedRootSecrets (derivedSecretBytes);

            RootKey newRootKey = new RootKey (_kdf, derivedSecrets.RootKey);
            ChainKey newChainKey = new ChainKey (_kdf, derivedSecrets.ChainKey, 0);

            return new Tuple<RootKey, ChainKey> (newRootKey, newChainKey);
        }
Example #6
0
        public PreKeyBundle(UInt32 registrationId, UInt32 deviceId, UInt32 preKeyId, ECPublicKey preKeyPublic,
		                     UInt32 signedPreKeyId, ECPublicKey signedPreKeyPublic, byte[] signedPreKeySignature,
		                     IdentityKey identityKey)
        {
            RegistrationID = registrationId;
            DeviceID = deviceId;
            PreKeyId = preKeyId;
            PreKeyPublic = preKeyPublic;
            SignedPreKeyID = signedPreKeyId;
            SignedPreKeyPublic = signedPreKeyPublic;
            SignedPreKeySignature = signedPreKeySignature;
            IdentityKey = identityKey;
        }
        public SymmetricAxolotlParameters(ECKeyPair ourBaseKey, ECKeyPair ourRatchetKey, 
		                                   IdentityKeyPair ourIdentityKey, ECPublicKey theirBaseKey, 
		                                   ECPublicKey theirRatchetKey, IdentityKey theirIdentityKey)
        {
            OurBaseKey = ourBaseKey;
            OurRatchetKey = ourRatchetKey;
            OurIdentityKey = ourIdentityKey;
            TheirBaseKey = theirBaseKey;
            TheirRatchetKey = theirRatchetKey;
            TheirIdentityKey = theirIdentityKey;

            if (ourBaseKey == null || ourRatchetKey == null || ourIdentityKey == null ||
                theirBaseKey == null || theirRatchetKey == null || theirIdentityKey == null)
            {
                throw new Exception("Null values!");
            }
        }
        public BobAxolotlParameters(IdentityKeyPair ourIdentityKey, ECKeyPair ourSignedPreKey,
		                             ECKeyPair ourRatchetKey, Maybe<ECKeyPair> ourOneTimePreKey,
		                             IdentityKey theirIdentityKey, ECPublicKey theirBaseKey)
        {
            OurIdentityKey = ourIdentityKey;
            OurSignedPreKey = ourSignedPreKey;
            OurOneTimePreKey = ourOneTimePreKey;
            OurRatchetKey = ourRatchetKey;
            TheirIdentityKey = theirIdentityKey;
            TheirBaseKey = theirBaseKey;

            if (ourIdentityKey == null || ourSignedPreKey == null || ourRatchetKey == null ||
                theirIdentityKey == null || theirBaseKey == null)
            {
                throw new Exception("Null value!");
            }
        }
Example #9
0
        public static byte[] CalculateAgreement(ECPublicKey publicKey, ECPrivateKey privateKey)
        {
            if (publicKey.GetKeyType () != privateKey.GetKeyType ()) {
                throw new Exception ("Public and private keys must be of the same type!");
            }

            if (publicKey.GetKeyType () == DJB_TYPE) {
                var sK = privateKey.Serialize ();
                var typedPK = publicKey.Serialize ();

                var pK = new byte[typedPK.Length - 1];
                for (int i = 1; i < typedPK.Length; i++) {
                    pK [i - 1] = typedPK [i];
                }

                var shared = Sodium.ScalarMult.Mult (sK, pK);
                return shared;
            } else {
                throw new Exception ("Unknown type");
            }
        }
Example #10
0
        private SenderKeyState(UInt32 id, UInt32 iteration, byte[] chainKey,
		                       ECPublicKey signatureKeyPublic,
		                       Maybe<ECPrivateKey> signatureKeyPrivate)
        {
            var senderChainKeyStructure = new SenderKeyStateStructure.SenderChainKey {
                Iteration = (uint)iteration,
                Seed = chainKey
            };

            var signingKeyStructure = new SenderKeyStateStructure.SenderSigningKey {
                PublicKey = signatureKeyPublic.Serialize()
            };

            signatureKeyPrivate.Do (SKp => {
                signingKeyStructure.PrivateKey = SKp.Serialize();
            });

            Structure = new SenderKeyStateStructure {
                SenderKeyId = (uint)id,
                senderChainKey = senderChainKeyStructure,
                senderSigningKey = signingKeyStructure
            };
        }
        public SenderKeyDistributionMessage(UInt32 id, UInt32 iteration, byte[] chainKey, ECPublicKey signatureKey)
        {
            byte[] version = { ByteUtil.IntsToByteHighAndLow(CURRENT_VERSION, CURRENT_VERSION) };

            var protobufObject = new WhisperProtos.SenderKeyDistributionMessage {
                id = id,
                iteration = iteration,
                chainKey = chainKey,
                signingKey = signatureKey.Serialize()
            };

            byte[] protobuf;
            using(var stream = new MemoryStream())
            {
                Serializer.Serialize<WhisperProtos.SenderKeyDistributionMessage>(stream, protobufObject);
                protobuf = stream.ToArray();
            }

            Id = id;
            Iteration = iteration;
            ChainKey = chainKey;
            SignatureKey = signatureKey;
            _serialized = ByteUtil.Combine(version, protobuf);
        }
Example #12
0
        public ChainKey GetReceiverChainKey(ECPublicKey senderEphemeral)
        {
            Tuple<Chain, UInt32> ReceiverChainAndIndex = GetReceiverChain(senderEphemeral);
            var ReceiverChain = ReceiverChainAndIndex.Item1;

            if(ReceiverChain == null)
            {
                return null;
            }
            else
            {
                return new ChainKey(HKDF.CreateFor(GetSessionVersion()),
                    ReceiverChain.chainKey.key,
                    ReceiverChain.chainKey.index);
            }
        }
Example #13
0
 public abstract int CompareTo(ECPublicKey another);
Example #14
0
            public UnacknowledgedPreKeyMessageItems(Maybe<UInt32> preKeyId,
			                                        UInt32 signedPreKeyId,
			                                        ECPublicKey baseKey)
            {
                PreKeyId = preKeyId;
                SignedPreKeyId = signedPreKeyId;
                BaseKey = baseKey;
            }
Example #15
0
        private Tuple<Chain, UInt32> GetReceiverChain(ECPublicKey senderEphemeral)
        {
            List<Chain> ReceiverChains = Structure.ReceiverChains;
            UInt32 index = 0;

            foreach(var chain in ReceiverChains)
            {
                try
                {
                    ECPublicKey chainSenderRatchetKey = Curve.DecodePoint(chain.SenderRatchetKey, 0);

                    if(chainSenderRatchetKey.Equals(senderEphemeral))
                        return new Tuple<Chain, UInt32>(chain, index);

                    index++;
                }
                catch(InvalidKeyException e)
                {
                    Logger.w("SessionRecordV2", e);
                }
            }

            return null;
        }
Example #16
0
        public void SetUnacknowledgedPreKeyMessage(Maybe<UInt32> preKeyId, UInt32 signedPreKeyId, ECPublicKey baseKey)
        {
            // TODO: check~
            var pending = new PendingPreKey {
                signedPreKeyId = signedPreKeyId,
                baseKey = baseKey.Serialize()
            };
            preKeyId.Do(pKid => pending.preKeyId = pKid);

            Structure.PendPreKey = pending;
        }
Example #17
0
 public void SetReceiverChainKey(ECPublicKey senderEphemeral, ChainKey chainKey)
 {
     var chainAndIndex = GetReceiverChain(senderEphemeral);
     var chain = chainAndIndex.Item1;
     var chainKeyStructure = new Chain.ChainKey {
         key = chainKey.Key,
         index = (UInt32)chainKey.Index
     };
     chain.chainKey = chainKeyStructure;
 }
Example #18
0
 public void SetMessageKeys(ECPublicKey senderEphemeral, MessageKeys messageKeys)
 {
     var chainAndIndex = GetReceiverChain(senderEphemeral);
     var chain = chainAndIndex.Item1;
     var messageKeyStructure = new Chain.MessageKey {
         cipherKey = messageKeys.CipherKey,
         macKey = messageKeys.MacKey,
         index = messageKeys.Counter,
         iv = messageKeys.Iv
     };
     chain.messageKeys.Add(messageKeyStructure);
 }
Example #19
0
 public IdentityKey(ECPublicKey publicKey)
 {
     PublicKey = publicKey;
 }
Example #20
0
 public override int CompareTo(ECPublicKey another)
 {
     return (int)new BigInteger (PublicKey).Compare (new BigInteger (((DjbECPublicKey)another).PublicKey));
 }
 public Builder SetTheirBaseKey(ECPublicKey theirBaseKey)
 {
     _theirBaseKey = theirBaseKey;
     return this;
 }
Example #22
0
        public void AddReceiverChain(ECPublicKey senderRatchetKey, ChainKey chainKey)
        {
            var chainKeyStructure = new Chain.ChainKey {
                key = chainKey.Key,
                index = (UInt32)chainKey.Index
            };

            var chain = new Chain {
                chainKey = chainKeyStructure,
                SenderRatchetKey = senderRatchetKey.Serialize()
            };

            Structure.ReceiverChains.Add(chain);

            if(Structure.ReceiverChains.Count > 5)
            {
                Structure.ReceiverChains.RemoveAt(0);
            }
        }
 private static bool IsAlice(ECPublicKey ourKey, ECPublicKey theirKey)
 {
     return ourKey.CompareTo(theirKey) < 0;
 }
Example #24
0
 public void AddSenderKeyState(UInt32 id, UInt32 iteration, byte[] chainKey, ECPublicKey signatureKey)
 {
     _senderKeyStates.Add(new SenderKeyState(id, iteration, chainKey, signatureKey));
 }
 public Builder SetTheirRatchetKey(ECPublicKey theirRatchetKey)
 {
     _theirRatchetKey = theirRatchetKey;
     return this;
 }
Example #26
0
        public bool HasMessageKeys(ECPublicKey senderEphemeral, UInt32 counter)
        {
            var chainAndIndex = GetReceiverChain(senderEphemeral);
            var chain = chainAndIndex.Item1;

            if(chain == null)
            {
                return false;
            }

            List<Chain.MessageKey> messageKeyList = chain.messageKeys;

            foreach(var mKey in messageKeyList)
            {
                if(mKey.index == counter)
                    return true;
            }

            return false;
        }
Example #27
0
 public ECKeyPair(ECPrivateKey privateKey, ECPublicKey publicKey)
 {
     PrivateKey = privateKey;
     PublicKey = publicKey;
 }
Example #28
0
 public bool HasReceiverChain(ECPublicKey senderEphemeral)
 {
     return GetReceiverChain(senderEphemeral) != null;
 }
Example #29
0
        public void VerifySignature(ECPublicKey signatureKey)
        {
            try
            {
                byte[][] parts = ByteUtil.Split(_serialized, _serialized.Length - SIGNATURE_LENGTH, SIGNATURE_LENGTH);

                if(!Curve.VerifySignature(signatureKey, parts[0], parts[1]))
                {
                    throw new InvalidMessageException("Invalid signature!");
                }

            }
            catch(Exception e)
            {
                throw new InvalidMessageException(e);
            }
        }
Example #30
0
        public MessageKeys RemoveMessageKeys(ECPublicKey senderEphemeral, UInt32 counter)
        {
            Tuple<Chain, UInt32> chainAndIndex = GetReceiverChain(senderEphemeral);
            Chain chain = chainAndIndex.Item1;

            if(chain == null)
            {
                return null;
            }

            MessageKeys result = null;

            // TODO: Check~
            foreach(var mK in chain.messageKeys)
            {
                if(mK.index == counter)
                {
                    result = new MessageKeys(mK.cipherKey, mK.macKey, mK.iv, mK.index);
                    chain.messageKeys.Remove(mK);
                    break;
                }
            }

            return result;
        }