pub fn calculate_2fa(
    salt1: &[u8],
    salt2: &[u8],
    g: &i32,
    p: &[u8],
    g_b: Vec<u8>,
    a: Vec<u8>,
    password: impl AsRef<[u8]>,
) -> (Vec<u8>, Vec<u8>) {
    // Prepare our parameters
    let big_p = BigUint::from_bytes_be(&p);

    let g_b = pad_to_256(&g_b);
    let a = pad_to_256(&a);

    let g_for_hash = vec![*g as u8];
    let g_for_hash = pad_to_256(&g_for_hash);

    let big_g_b = BigUint::from_bytes_be(&g_b);

    let big_g = BigUint::from(*g as u32);
    let big_a = BigUint::from_bytes_be(&a);

    // k := H(p | g)
    let k = h!(&p, &g_for_hash);
    let big_k = BigUint::from_bytes_be(&k);

    // g_a := pow(g, a) mod p
    let g_a = big_g.modpow(&big_a, &big_p);
    let g_a = pad_to_256(&g_a.to_bytes_be());

    // u := H(g_a | g_b)
    let u = h!(&g_a, &g_b);
    let u = BigUint::from_bytes_be(&u);

    // x := PH2(password, salt1, salt2)
    let x = ph2(&password, &salt1, &salt2);
    let x = BigUint::from_bytes_be(&x);

    // v := pow(g, x) mod p
    let big_v = big_g.modpow(&x, &big_p);

    // k_v := (k * v) mod p
    let k_v = (big_k * big_v) % &big_p;

    // t := (g_b - k_v) mod p (positive modulo, if the result is negative increment by p)
    let sub = if big_g_b > k_v {
        big_g_b - k_v
    } else {
        k_v - big_g_b
    };
    let big_t = sub % &big_p;

    // s_a := pow(t, a + u * x) mod p
    let first = u * x;
    let second = big_a + first;
    let big_s_a = big_t.modpow(&(second), &big_p);

    // k_a := H(s_a)
    let k_a = h!(&pad_to_256(&big_s_a.to_bytes_be()));

    // M1 := H(H(p) xor H(g) | H(salt1) | H(salt2) | g_a | g_b | k_a)
    let h_p = h!(&p);
    let h_g = h!(&g_for_hash);

    let p_xor_g: Vec<u8> = xor(&h_p, &h_g);

    let m1 = h!(&p_xor_g, &h!(&salt1), &h!(&salt2), &g_a, &g_b, &k_a).to_vec();

    (m1, g_a)
}
/// Prepare the password for sending to telegram for verification.
/// The method returns M1 and g_a parameters that should be sent to the telegram
///   (without a raw password)
///
/// The algorithm is described here: https://core.telegram.org/api/srp
Prepare the password for sending to telegram for verification.
The method returns M1 and g_a parameters that should be sent to the telegram
(without a raw password)


Prepare the password for sending to telegram for verification . The method returns M1 and g_a parameters that should be sent to the telegram ( without a raw password )
pub fn calculate_2fa(
    salt1: &[u8],
    salt2: &[u8],
    g: &i32,
    p: &[u8],
    g_b: Vec<u8>,
    a: Vec<u8>,
    password: impl AsRef<[u8]>,
) -> (Vec<u8>, Vec<u8>) {
    // Prepare our parameters
    let big_p = BigUint::from_bytes_be(&p);
    let g_b = pad_to_256(&g_b);
    let a = pad_to_256(&a);
    let g_for_hash = vec![*g as u8];
    let g_for_hash = pad_to_256(&g_for_hash);
    let big_g_b = BigUint::from_bytes_be(&g_b);
    let big_g = BigUint::from(*g as u32);
    let big_a = BigUint::from_bytes_be(&a);
    // k := H(p | g)
    let k = h!(&p, &g_for_hash);
    let big_k = BigUint::from_bytes_be(&k);
    // g_a := pow(g, a) mod p
    let g_a = big_g.modpow(&big_a, &big_p);
    let g_a = pad_to_256(&g_a.to_bytes_be());
    // u := H(g_a | g_b)
    let u = h!(&g_a, &g_b);
    let u = BigUint::from_bytes_be(&u);
    // x := PH2(password, salt1, salt2)
    let x = ph2(&password, &salt1, &salt2);
    let x = BigUint::from_bytes_be(&x);
    // v := pow(g, x) mod p
    let big_v = big_g.modpow(&x, &big_p);
    // k_v := (k * v) mod p
    let k_v = (big_k * big_v) % &big_p;
    // t := (g_b - k_v) mod p (positive modulo, if the result is negative increment by p)
    let sub = if big_g_b > k_v {
        big_g_b - k_v
    } else {
        k_v - big_g_b
    };
    let big_t = sub % &big_p;
    // s_a := pow(t, a + u * x) mod p
    let first = u * x;
    let second = big_a + first;
    let big_s_a = big_t.modpow(&(second), &big_p);
    // k_a := H(s_a)
    let k_a = h!(&pad_to_256(&big_s_a.to_bytes_be()));
    // M1 := H(H(p) xor H(g) | H(salt1) | H(salt2) | g_a | g_b | k_a)
    let h_p = h!(&p);
    let h_g = h!(&g_for_hash);
    let p_xor_g: Vec<u8> = xor(&h_p, &h_g);
    let m1 = h!(&p_xor_g, &h!(&salt1), &h!(&salt2), &g_a, &g_b, &k_a).to_vec();
    (m1, g_a)
}
pub fn calculate_2fa ( salt1 : & [ u8 ] , salt2 : & [ u8 ] , g : & i32 , p : & [ u8 ] , g_b : Vec < u8 > , a : Vec < u8 > , password : impl AsRef < [ u8 ] > , ) -> ( Vec < u8 > , Vec < u8 > ) { // Prepare our parameters let big_p = BigUint :: from_bytes_be ( & p ) ; let g_b = pad_to_256 ( & g_b ) ; let a = pad_to_256 ( & a ) ; let g_for_hash = vec ! [ g as u8 ] ; let g_for_hash = pad_to_256 ( & g_for_hash ) ; let big_g_b = BigUint :: from_bytes_be ( & g_b ) ; let big_g = BigUint :: from ( * g as u32 ) ; let big_a = BigUint :: from_bytes_be ( & a ) ; // k := H(p | g) let k = h ! ( p g_for_hash ) ; let big_k = BigUint :: from_bytes_be ( & k ) ; // g_a := pow(g, a) mod p let g_a = big_g . modpow ( & big_a , & big_p ) ; let g_a = pad_to_256 ( & g_a . to_bytes_be ( ) ) ; // u := H(g_a | g_b) let u = h ! ( g_a g_b ) ; let u = BigUint :: from_bytes_be ( & u ) ; // x := PH2(password, salt1, salt2) let x = ph2 ( & password , & salt1 , & salt2 ) ; let x = BigUint :: from_bytes_be ( & x ) ; // v := pow(g, x) mod p let big_v = big_g . modpow ( & x , & big_p ) ; // k_v := (k * v) mod p let k_v = ( big_k * big_v ) % & big_p ; // t := (g_b - k_v) mod p (positive modulo, if the result is negative increment by p) let sub = if big_g_b > k_v { big_g_b - k_v } else { k_v - big_g_b } ; let big_t = sub % & big_p ; // s_a := pow(t, a + u * x) mod p let first = u * x ; let second = big_a + first ; let big_s_a = big_t . modpow ( & ( second ) , & big_p ) ; // k_a := H(s_a) let k_a = h ! ( pad_to_256 ( big_s_a to_bytes_be ( ) ) ) ; // M1 := H(H(p) xor H(g) | H(salt1) | H(salt2) | g_a | g_b | k_a) let h_p = h ! ( p ) ; let h_g = h ! ( g_for_hash ) ; let p_xor_g : Vec < u8 > = xor ( & h_p , & h_g ) ; let m1 = h ! ( p_xor_g h ( salt1 ) h ( salt2 ) g_a g_b k_a ) . to_vec ( ) ; ( m1 , g_a ) }
Prepare the password for sending to telegram for verification.
Prepare the password for sending to telegram for verification .
salt1
&[u8]
salt2
&[u8]
g
&i32
p
&[u8]
g_b
Vec<u8>
a
Vec<u8>
password
impl AsRef<[u8]>
salt1
&[u8]
salt2
&[u8]
g
&i32
p
&[u8]
g_b
Vec<u8>
a
Vec<u8>
password
impl AsRef<[u8]>