some more optimizations

This commit is contained in:
Wizou 2022-10-04 00:52:44 +02:00
parent a45cd0f44e
commit 79097cdf8d
5 changed files with 31 additions and 30 deletions

View file

@ -469,6 +469,9 @@ var msg = history.Messages[0] as Message; // last message of source chat
// • Forward the message (only the source message id is necessary)
await client.Messages_ForwardMessages(from_chat, new[] { msg.ID }, new[] { WTelegram.Helpers.RandomLong() }, to_chat);
// • Copy the message (without the "Forwarded" header)
// • Copy the message without the "Forwarded" header (only the source message id is necessary)
await client.Messages_ForwardMessages(from_chat, new[] { msg.ID }, new[] { WTelegram.Helpers.RandomLong() }, to_chat, drop_author: true);
// • Alternative solution to copy the message (the full message is needed)
await client.SendMessageAsync(to_chat, msg.message, msg.media?.ToInputMedia(), entities: msg.entities);
```
```

View file

@ -1180,7 +1180,7 @@ namespace WTelegram
try
{
using var memStream = new MemoryStream(1024);
using var writer = new BinaryWriter(memStream, Encoding.UTF8);
using var writer = new BinaryWriter(memStream);
writer.Write(0); // int32 payload_len (to be patched with payload length)
if (_dcSession.AuthKeyID == 0) // send unencrypted message
@ -1196,7 +1196,7 @@ namespace WTelegram
else
{
using var clearStream = new MemoryStream(1024);
using var clearWriter = new BinaryWriter(clearStream, Encoding.UTF8);
using var clearWriter = new BinaryWriter(clearStream);
clearWriter.Write(_dcSession.AuthKey, 88, 32);
clearWriter.Write(_dcSession.Salt); // int64 salt
clearWriter.Write(_dcSession.Id); // int64 session_id
@ -1210,7 +1210,7 @@ namespace WTelegram
clearWriter.WriteTLObject(msg); // bytes message_data
int clearLength = (int)clearStream.Length - 32; // length before padding (= 32 + message_data_length)
int padding = (0x7FFFFFF0 - clearLength) % 16;
padding += _random.Next(1, 64) * 16; // MTProto 2.0 padding must be between 12..1024 with total length divisible by 16
padding += _random.Next(2, 16) * 16; // MTProto 2.0 padding must be between 12..1024 with total length divisible by 16
clearStream.SetLength(32 + clearLength + padding);
byte[] clearBuffer = clearStream.GetBuffer();
BinaryPrimitives.WriteInt32LittleEndian(clearBuffer.AsSpan(60), clearLength - 32); // patch message_data_length

View file

@ -62,7 +62,7 @@ namespace WTelegram
{
//4.1) RSA_PAD(data, server_public_key)
using var clearStream = new MemoryStream(256);
using var writer = new BinaryWriter(clearStream, Encoding.UTF8);
using var writer = new BinaryWriter(clearStream);
byte[] aes_key = new byte[32], zero_iv = new byte[32];
var n = BigEndianInteger(publicKey.n);
do
@ -108,16 +108,17 @@ namespace WTelegram
if (serverDHinnerData.server_nonce != resPQ.server_nonce) throw new ApplicationException("Server Nonce mismatch");
var g_a = BigEndianInteger(serverDHinnerData.g_a);
var dh_prime = BigEndianInteger(serverDHinnerData.dh_prime);
ValidityChecks(dh_prime, serverDHinnerData.g);
CheckGoodPrime(dh_prime, serverDHinnerData.g);
session.LastSentMsgId = 0;
session.ServerTicksOffset = (serverDHinnerData.server_time - localTime).Ticks;
Helpers.Log(1, $"Time offset: {session.ServerTicksOffset} | Server: {serverDHinnerData.server_time.TimeOfDay} UTC | Local: {localTime.TimeOfDay} UTC");
//6)
var bData = new byte[256];
RNG.GetBytes(bData);
var b = BigEndianInteger(bData);
var salt = new byte[256];
RNG.GetBytes(salt);
var b = BigEndianInteger(salt);
var g_b = BigInteger.ModPow(serverDHinnerData.g, b, dh_prime);
ValidityChecksDH(g_a, g_b, dh_prime);
CheckGoodGaAndGb(g_a, dh_prime);
CheckGoodGaAndGb(g_b, dh_prime);
var clientDHinnerData = new ClientDHInnerData
{
nonce = nonce,
@ -128,7 +129,7 @@ namespace WTelegram
{
using var clearStream = new MemoryStream(384);
clearStream.Position = 20; // skip SHA1 area (to be patched)
using var writer = new BinaryWriter(clearStream, Encoding.UTF8);
using var writer = new BinaryWriter(clearStream);
writer.WriteTLObject(clientDHinnerData);
int clearLength = (int)clearStream.Length; // length before padding (= 20 + message_data_length)
int paddingToAdd = (0x7FFFFFF0 - clearLength) % 16;
@ -182,21 +183,20 @@ namespace WTelegram
}
}
internal static void ValidityChecks(BigInteger p, int g)
internal static void CheckGoodPrime(BigInteger p, int g)
{
Helpers.Log(2, "Verifying encryption key safety... (this should happen only once per DC)");
// check that 2^2047 <= p < 2^2048
if (p.GetBitLength() != 2048) throw new ApplicationException("p is not 2048-bit number");
// check that g generates a cyclic subgroup of prime order (p - 1) / 2, i.e. is a quadratic residue mod p.
BigInteger mod_r;
if (g switch
{
2 => p % 8 != 7,
3 => p % 3 != 2,
4 => false,
5 => (mod_r = p % 5) != 1 && mod_r != 4,
6 => (mod_r = p % 24) != 19 && mod_r != 23,
7 => (mod_r = p % 7) != 3 && mod_r != 5 && mod_r != 6,
5 => (int)(p % 5) is not 1 and not 4,
6 => (int)(p % 24) is not 19 and not 23,
7 => (int)(p % 7) is not 3 and not 5 and not 6,
_ => true,
})
throw new ApplicationException("Bad prime mod 4g");
@ -227,13 +227,11 @@ namespace WTelegram
0x73, 0x3F, 0xF1, 0x70, 0x2F, 0x52, 0x6C, 0x8E, 0x04, 0xC9, 0xB1, 0xC6, 0xB9, 0xAE, 0x1C, 0xC7, 0x00
})};
internal static void ValidityChecksDH(BigInteger g_a, BigInteger g_b, BigInteger dh_prime)
internal static void CheckGoodGaAndGb(BigInteger g, BigInteger dh_prime)
{
// check that g, g_a and g_b are greater than 1 and less than dh_prime - 1.
// We recommend checking that g_a and g_b are between 2^{2048-64} and dh_prime - 2^{2048-64} as well.
var l = BigInteger.One << (2048 - 64);
var r = dh_prime - l;
if (g_a < l || g_a > r || g_b < l || g_b > r)
if (g.GetBitLength() < 2048 - 64 || (dh_prime - g).GetBitLength() < 2048 - 64)
throw new ApplicationException("g^a or g^b is not between 2^{2048-64} and dh_prime - 2^{2048-64}");
}
@ -405,7 +403,7 @@ j4WcDuXc2CTHgH8gFTNhp/Y8/SpDOhvn9QIDAQAB
var g = new BigInteger(algo.g);
var p = BigEndianInteger(algo.p);
var validTask = Task.Run(() => ValidityChecks(p, algo.g));
var validTask = Task.Run(() => CheckGoodPrime(p, algo.g));
System.Threading.Thread.Sleep(100);
Helpers.Log(3, $"This account has enabled 2FA. A password is needed. {accountPassword.hint}");

View file

@ -4699,6 +4699,7 @@ namespace TL
cdn = 0x8,
/// <summary>If set, this IP should be used when connecting through a proxy</summary>
static_ = 0x10,
/// <summary>If set, clients must connect using only the specified port, without trying any other port.</summary>
this_port_only = 0x20,
/// <summary>Field <see cref="secret"/> has a value</summary>
has_secret = 0x400,
@ -4832,7 +4833,7 @@ namespace TL
has_static_maps_provider = 0x1000,
/// <summary>Whether <a href="https://corefork.telegram.org/api/pfs">pfs</a> was used</summary>
pfs_enabled = 0x2000,
/// <summary>Whether to forcefully try connecting using IPv6 <see cref="DcOption"/></summary>
/// <summary>Whether to forcefully connect using IPv6 <see cref="DcOption"/>, even if the client knows that IPv4 is available.</summary>
force_try_ipv6 = 0x4000,
/// <summary>Field <see cref="reactions_default"/> has a value</summary>
has_reactions_default = 0x8000,
@ -12215,7 +12216,6 @@ namespace TL
has_reply_to_peer_id = 0x1,
/// <summary>Field <see cref="reply_to_top_id"/> has a value</summary>
has_reply_to_top_id = 0x2,
/// <summary>Whether this message replies to a scheduled message</summary>
reply_to_scheduled = 0x4,
}
}
@ -13505,7 +13505,7 @@ namespace TL
[TLDef(0x661D4037)]
public class ChatReactionsSome : ChatReactions
{
/// <summary>Allowed reactions</summary>
/// <summary>Allowed set of reactions: the <a href="https://corefork.telegram.org/api/config#reactions-in-chat-max">reactions_in_chat_max</a> configuration field indicates the maximum number of reactions that can be specified in this field.</summary>
public Reaction[] reactions;
}

View file

@ -869,7 +869,7 @@ namespace TL
/// <summary>Get theme information <para>See <a href="https://corefork.telegram.org/method/account.getTheme"/></para> <para>Possible <see cref="RpcException"/> codes: 400 (<a href="https://corefork.telegram.org/method/account.getTheme#possible-errors">details</a>)</para></summary>
/// <param name="format">Theme format, a string that identifies the theming engines supported by the client</param>
/// <param name="theme">Theme</param>
/// <param name="document_id">Document ID</param>
/// <param name="document_id">Deprecated: should always be <c>0</c></param>
public static Task<Theme> Account_GetTheme(this Client client, string format, InputThemeBase theme, long document_id)
=> client.Invoke(new Account_GetTheme
{
@ -1931,7 +1931,7 @@ namespace TL
unsave = unsave,
});
/// <summary>Query an inline bot <para>See <a href="https://corefork.telegram.org/method/messages.getInlineBotResults"/></para> <para>Possible <see cref="RpcException"/> codes: -503,400 (<a href="https://corefork.telegram.org/method/messages.getInlineBotResults#possible-errors">details</a>)</para></summary>
/// <summary>Query an inline bot <para>See <a href="https://corefork.telegram.org/method/messages.getInlineBotResults"/></para> <para>Possible <see cref="RpcException"/> codes: 400,-503 (<a href="https://corefork.telegram.org/method/messages.getInlineBotResults#possible-errors">details</a>)</para></summary>
/// <param name="bot">The bot to query</param>
/// <param name="peer">The currently opened chat</param>
/// <param name="geo_point">The geolocation, if requested</param>
@ -2042,7 +2042,7 @@ namespace TL
entities = entities,
});
/// <summary>Press an inline callback button and get a callback answer from the bot <para>See <a href="https://corefork.telegram.org/method/messages.getBotCallbackAnswer"/></para> <para>Possible <see cref="RpcException"/> codes: -503,400 (<a href="https://corefork.telegram.org/method/messages.getBotCallbackAnswer#possible-errors">details</a>)</para></summary>
/// <summary>Press an inline callback button and get a callback answer from the bot <para>See <a href="https://corefork.telegram.org/method/messages.getBotCallbackAnswer"/></para> <para>Possible <see cref="RpcException"/> codes: 400,-503 (<a href="https://corefork.telegram.org/method/messages.getBotCallbackAnswer#possible-errors">details</a>)</para></summary>
/// <param name="game">Whether this is a "play game" button</param>
/// <param name="peer">Where was the inline keyboard sent</param>
/// <param name="msg_id">ID of the Message with the inline keyboard</param>
@ -2408,7 +2408,7 @@ namespace TL
/// <param name="update_stickersets_order">Whether to move used stickersets to top, <a href="https://corefork.telegram.org/api/stickers#recent-stickersets">see here for more info on this flag »</a></param>
/// <param name="peer">The destination chat</param>
/// <param name="reply_to_msg_id">The message to reply to</param>
/// <param name="multi_media">The medias to send</param>
/// <param name="multi_media">The medias to send: note that they must be separately uploaded using <a href="https://corefork.telegram.org/method/messages.uploadMedia">messages.uploadMedia</a> first, using raw <c>inputMediaUploaded*</c> constructors is not supported.</param>
/// <param name="schedule_date">Scheduled message date for scheduled messages</param>
/// <param name="send_as">Send this message as the specified peer</param>
public static Task<UpdatesBase> Messages_SendMultiMedia(this Client client, InputPeer peer, InputSingleMedia[] multi_media, bool silent = false, bool background = false, bool clear_draft = false, bool noforwards = false, bool update_stickersets_order = false, int? reply_to_msg_id = null, DateTime? schedule_date = null, InputPeer send_as = null)
@ -3115,7 +3115,7 @@ namespace TL
hash = hash,
});
/// <summary>Change default emoji reaction to use in the quick reaction menu: the value is synced across devices and can be fetched using <a href="https://corefork.telegram.org/api/config#reactions-default">help.getAppConfig, <c>reactions_default</c> field</a>. <para>See <a href="https://corefork.telegram.org/method/messages.setDefaultReaction"/></para> <para>Possible <see cref="RpcException"/> codes: 400 (<a href="https://corefork.telegram.org/method/messages.setDefaultReaction#possible-errors">details</a>)</para></summary>
/// <summary>Change default emoji reaction to use in the quick reaction menu: the value is synced across devices and can be fetched using <a href="https://corefork.telegram.org/method/help.getConfig">help.getConfig, <c>reactions_default</c> field</a>. <para>See <a href="https://corefork.telegram.org/method/messages.setDefaultReaction"/></para> <para>Possible <see cref="RpcException"/> codes: 400 (<a href="https://corefork.telegram.org/method/messages.setDefaultReaction#possible-errors">details</a>)</para></summary>
/// <param name="reaction">New emoji reaction</param>
public static Task<bool> Messages_SetDefaultReaction(this Client client, Reaction reaction)
=> client.Invoke(new Messages_SetDefaultReaction