private ReqDHParamsArgs CreateReqDhParamsArgs(ResPQ resPQ, out PQInnerData pqInnerData) { Int256 pq = resPQ.Pq.ToInt256(asLittleEndian: false); Int256 p, q; pq.GetPrimeMultipliers(out p, out q); Int256 newNonce = _nonceGenerator.GetNonce(32).ToInt256(); pqInnerData = new PQInnerData { Pq = resPQ.Pq, P = p.ToBytes(false, true), Q = q.ToBytes(false, true), Nonce = resPQ.Nonce, ServerNonce = resPQ.ServerNonce, NewNonce = newNonce }; byte[] data = _tlRig.Serialize(pqInnerData); byte[] dataHash = ComputeSHA1(data); Debug.Assert((dataHash.Length + data.Length) <= 255); // data_with_hash := SHA1(data) + data + (any random bytes); such that the length equal 255 bytes; var dataWithHash = new byte[255]; using (var streamer = new TLStreamer(dataWithHash)) { streamer.Write(dataHash); streamer.Write(data); streamer.WriteRandomDataTillEnd(); } PublicKey publicKey = _keyChain.GetFirst(resPQ.ServerPublicKeyFingerprints); if (publicKey == null) { throw new PublicKeyNotFoundException(resPQ.ServerPublicKeyFingerprints); } byte[] encryptedData = _encryptionServices.RSAEncrypt(dataWithHash, publicKey); var reqDhParamsArgs = new ReqDHParamsArgs { Nonce = pqInnerData.Nonce, ServerNonce = pqInnerData.ServerNonce, P = pqInnerData.P, Q = pqInnerData.Q, PublicKeyFingerprint = publicKey.Fingerprint, EncryptedData = encryptedData }; return reqDhParamsArgs; }
private byte[] PrependHashAndAlign(byte[] data, int alignment) { int dataLength = data.Length; byte[] dataHash = ComputeSHA1(data); int length = HashLength + dataLength; int mod = length%alignment; length += mod > 0 ? alignment - mod : 0; var dataWithHash = new byte[length]; using (var streamer = new TLStreamer(dataWithHash)) { streamer.Write(dataHash); streamer.Write(data); streamer.WriteRandomDataTillEnd(); } return dataWithHash; }