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); }
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; }
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"); } }
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); }
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!"); } }
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"); } }
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); }
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); } }
public abstract int CompareTo(ECPublicKey another);
public UnacknowledgedPreKeyMessageItems(Maybe<UInt32> preKeyId, UInt32 signedPreKeyId, ECPublicKey baseKey) { PreKeyId = preKeyId; SignedPreKeyId = signedPreKeyId; BaseKey = baseKey; }
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; }
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; }
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; }
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); }
public IdentityKey(ECPublicKey publicKey) { PublicKey = publicKey; }
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; }
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; }
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; }
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; }
public ECKeyPair(ECPrivateKey privateKey, ECPublicKey publicKey) { PrivateKey = privateKey; PublicKey = publicKey; }
public bool HasReceiverChain(ECPublicKey senderEphemeral) { return GetReceiverChain(senderEphemeral) != null; }
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); } }
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; }