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;
        }
Beispiel #2
0
        public WhisperMessage(byte[] serialized)
        {
            try
            {
                byte[][] messageParts = ByteUtil.split(serialized, 1, serialized.Length - 1 - MAC_LENGTH, MAC_LENGTH);
                byte     version      = messageParts[0][0];
                byte[]   message      = messageParts[1];
                byte[]   mac          = messageParts[2];

                if (ByteUtil.highBitsToInt(version) <= CiphertextMessage.UNSUPPORTED_VERSION)
                {
                    throw new LegacyMessageException("Legacy message: " + ByteUtil.highBitsToInt(version));
                }

                if (ByteUtil.highBitsToInt(version) > CURRENT_VERSION)
                {
                    throw new InvalidMessageException("Unknown version: " + ByteUtil.highBitsToInt(version));
                }

                WhisperProtos.WhisperMessage whisperMessage = WhisperProtos.WhisperMessage.ParseFrom(message);

                if (!whisperMessage.HasCiphertext ||
                    !whisperMessage.HasCounter ||
                    !whisperMessage.HasRatchetKey)
                {
                    throw new InvalidMessageException("Incomplete message.");
                }

                this.serialized       = serialized;
                this.senderRatchetKey = Curve.decodePoint(whisperMessage.RatchetKey.ToByteArray(), 0);
                this.messageVersion   = (uint)ByteUtil.highBitsToInt(version);
                this.counter          = whisperMessage.Counter;
                this.previousCounter  = whisperMessage.PreviousCounter;
                this.ciphertext       = whisperMessage.Ciphertext.ToByteArray();
            }
            catch (/*InvalidProtocolBufferException | InvalidKeyException | Parse*/ Exception e)
            {
                throw new InvalidMessageException(e);
            }
        }