From 3306c42e89dbecb1328bcc44969062140999a1d7 Mon Sep 17 00:00:00 2001 From: levlam Date: Sun, 25 Aug 2019 01:02:39 +0300 Subject: [PATCH] Better public key generation. GitOrigin-RevId: 1fd0b8e824620c90901168a2d12e97b92b76e37a --- td/mtproto/TlsInit.cpp | 45 +++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/td/mtproto/TlsInit.cpp b/td/mtproto/TlsInit.cpp index a1a3b71b7..c07732294 100644 --- a/td/mtproto/TlsInit.cpp +++ b/td/mtproto/TlsInit.cpp @@ -295,18 +295,16 @@ class TlsHelloStore { auto key = dest_.substr(0, 32); while (true) { Random::secure_bytes(key); + key[31] = static_cast(key[31] & 127); + BigNum x = BigNum::from_binary(key); - BigNum::mod_mul(x, x, x, mod, big_num_context); - BigNum y = x.clone(); - BigNum coef = BigNum::from_decimal("486662").move_as_ok(); - BigNum::mod_add(y, y, coef, mod, big_num_context); - BigNum::mod_mul(y, y, x, mod, big_num_context); - BigNum one = BigNum::from_decimal("1").move_as_ok(); - BigNum::mod_add(y, y, one, mod, big_num_context); - BigNum::mod_mul(y, y, x, mod, big_num_context); - // y = x^3 + 486662 * x^2 + x + BigNum y = get_y2(x, mod, big_num_context); if (is_quadratic_residue(y)) { + for (int i = 0; i < 3; i++) { + x = get_double_x(x, mod, big_num_context); + } key.copy_from(x.to_le_binary(32)); + LOG(ERROR) << td::format::as_hex_dump<0>(td::Slice(key)); break; } } @@ -352,6 +350,35 @@ class TlsHelloStore { MutableSlice dest_; std::vector scope_offset_; + static BigNum get_y2(BigNum &x, const BigNum &mod, BigNumContext &big_num_context) { + // returns y = x^3 + 486662 * x^2 + x + BigNum y = x.clone(); + BigNum coef = BigNum::from_decimal("486662").move_as_ok(); + BigNum::mod_add(y, y, coef, mod, big_num_context); + BigNum::mod_mul(y, y, x, mod, big_num_context); + BigNum one = BigNum::from_decimal("1").move_as_ok(); + BigNum::mod_add(y, y, one, mod, big_num_context); + BigNum::mod_mul(y, y, x, mod, big_num_context); + return y; + } + + static BigNum get_double_x(BigNum &x, const BigNum &mod, BigNumContext &big_num_context) { + // returns x_2 = (x^2 - 1)^2/(4*y^2) + BigNum denominator = get_y2(x, mod, big_num_context); + BigNum coef = BigNum::from_decimal("4").move_as_ok(); + BigNum::mod_mul(denominator, denominator, coef, mod, big_num_context); + + BigNum numerator; + BigNum::mod_mul(numerator, x, x, mod, big_num_context); + BigNum one = BigNum::from_decimal("1").move_as_ok(); + BigNum::mod_sub(numerator, numerator, one, mod, big_num_context); + BigNum::mod_mul(numerator, numerator, numerator, mod, big_num_context); + + BigNum::mod_inverse(denominator, denominator, mod, big_num_context); + BigNum::mod_mul(numerator, numerator, denominator, mod, big_num_context); + return numerator; + } + static bool is_quadratic_residue(const BigNum &a) { // 2^255 - 19 BigNum mod = BigNum::from_hex("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed").move_as_ok();