Skip to main content

layer_crypto/
auth_key.rs

1// Copyright (c) Ankit Chaubey <ankitchaubey.dev@gmail.com>
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4// NOTE:
5// The "Layer" project is no longer maintained or supported.
6// Its original purpose for personal SDK/APK experimentation and learning
7// has been fulfilled.
8//
9// Please use Ferogram instead:
10// https://github.com/ankit-chaubey/ferogram
11// Ferogram will receive future updates and development, although progress
12// may be slower.
13//
14// Ferogram is an async Telegram MTProto client library written in Rust.
15// Its implementation follows the behaviour of the official Telegram clients,
16// particularly Telegram Desktop and TDLib, and aims to provide a clean and
17// modern async interface for building Telegram clients and tools.
18
19//! Telegram `AuthKey`: 256-byte key derived from the DH handshake.
20
21use crate::sha1;
22
23/// A Telegram authorization key (256 bytes) plus pre-computed identifiers.
24#[derive(Clone)]
25pub struct AuthKey {
26    pub(crate) data: [u8; 256],
27    pub(crate) aux_hash: [u8; 8],
28    pub(crate) key_id: [u8; 8],
29}
30
31impl AuthKey {
32    /// Construct from raw 256-byte DH output.
33    pub fn from_bytes(data: [u8; 256]) -> Self {
34        let sha = sha1!(&data);
35        let mut aux_hash = [0u8; 8];
36        aux_hash.copy_from_slice(&sha[..8]);
37        let mut key_id = [0u8; 8];
38        key_id.copy_from_slice(&sha[12..20]);
39        Self {
40            data,
41            aux_hash,
42            key_id,
43        }
44    }
45
46    /// Return the raw 256-byte representation.
47    pub fn to_bytes(&self) -> [u8; 256] {
48        self.data
49    }
50
51    /// The 8-byte key identifier (SHA-1(key)[12..20]).
52    pub fn key_id(&self) -> [u8; 8] {
53        self.key_id
54    }
55
56    /// Compute the new-nonce hash needed for `DhGenOk/Retry/Fail` verification.
57    pub fn calc_new_nonce_hash(&self, new_nonce: &[u8; 32], number: u8) -> [u8; 16] {
58        let data: Vec<u8> = new_nonce
59            .iter()
60            .copied()
61            .chain([number])
62            .chain(self.aux_hash.iter().copied())
63            .collect();
64        let sha = sha1!(&data);
65        let mut out = [0u8; 16];
66        out.copy_from_slice(&sha[4..]);
67        out
68    }
69}
70
71impl std::fmt::Debug for AuthKey {
72    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73        write!(f, "AuthKey(id={})", u64::from_le_bytes(self.key_id))
74    }
75}
76
77impl PartialEq for AuthKey {
78    fn eq(&self, other: &Self) -> bool {
79        self.key_id == other.key_id
80    }
81}