mirror of
https://github.com/wiz0u/WTelegramClient.git
synced 2025-12-06 06:52:01 +01:00
some more optimizations
This commit is contained in:
parent
a45cd0f44e
commit
79097cdf8d
|
|
@ -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);
|
||||
```
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue