Skip to main content

ferogram_crypto/
auth_key.rs

1/*
2 * Copyright (c) 2026 Ankit Chaubey <ankitchaubey.dev@gmail.com>
3 * https://github.com/ankit-chaubey
4 *
5 * Project: ferogram
6 * Website: https://ferogram.dev
7 *
8 * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
9 * https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
10 * <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
11 * This file may not be copied, modified, or distributed except according
12 * to those terms.
13 */
14
15use crate::sha1;
16
17/// A Telegram authorization key (256 bytes) plus pre-computed identifiers.
18#[derive(Clone)]
19pub struct AuthKey {
20    pub(crate) data: [u8; 256],
21    pub(crate) aux_hash: [u8; 8],
22    pub(crate) key_id: [u8; 8],
23}
24
25impl AuthKey {
26    /// Construct from raw 256-byte DH output.
27    pub fn from_bytes(data: [u8; 256]) -> Self {
28        let sha = sha1!(&data);
29        let mut aux_hash = [0u8; 8];
30        aux_hash.copy_from_slice(&sha[..8]);
31        let mut key_id = [0u8; 8];
32        key_id.copy_from_slice(&sha[12..20]);
33        Self {
34            data,
35            aux_hash,
36            key_id,
37        }
38    }
39
40    /// Return the raw 256-byte representation.
41    pub fn to_bytes(&self) -> [u8; 256] {
42        self.data
43    }
44
45    /// The 8-byte key identifier (SHA-1(key)[12..20]).
46    pub fn key_id(&self) -> [u8; 8] {
47        self.key_id
48    }
49
50    /// Compute the new-nonce hash needed for `DhGenOk/Retry/Fail` verification.
51    pub fn calc_new_nonce_hash(&self, new_nonce: &[u8; 32], number: u8) -> [u8; 16] {
52        let data: Vec<u8> = new_nonce
53            .iter()
54            .copied()
55            .chain([number])
56            .chain(self.aux_hash.iter().copied())
57            .collect();
58        let sha = sha1!(&data);
59        let mut out = [0u8; 16];
60        out.copy_from_slice(&sha[4..]);
61        out
62    }
63}
64
65impl std::fmt::Debug for AuthKey {
66    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67        write!(f, "AuthKey(id={})", u64::from_le_bytes(self.key_id))
68    }
69}
70
71impl PartialEq for AuthKey {
72    fn eq(&self, other: &Self) -> bool {
73        self.key_id == other.key_id
74    }
75}