Coverage Report

Created: 2026-01-16 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/ghash-0.4.4/src/lib.rs
Line
Count
Source
1
//! **GHASH**: universal hash over GF(2^128) used by AES-GCM for message
2
//! authentication (i.e. GMAC).
3
//!
4
//! ## Implementation Notes
5
//!
6
//! The implementation of GHASH found in this crate internally uses the
7
//! [`polyval`] crate, which provides a similar universal hash function used by
8
//! AES-GCM-SIV (RFC 8452).
9
//!
10
//! By implementing GHASH in terms of POLYVAL, the two universal hash functions
11
//! can share a common core, meaning any optimization work (e.g. CPU-specific
12
//! SIMD implementations) which happens upstream in the `polyval` crate
13
//! benefits GHASH as well.
14
//!
15
//! From RFC 8452 Appendix A:
16
//! <https://tools.ietf.org/html/rfc8452#appendix-A>
17
//!
18
//! > GHASH and POLYVAL both operate in GF(2^128), although with different
19
//! > irreducible polynomials: POLYVAL works modulo x^128 + x^127 + x^126 +
20
//! > x^121 + 1 and GHASH works modulo x^128 + x^7 + x^2 + x + 1.  Note
21
//! > that these irreducible polynomials are the "reverse" of each other.
22
//!
23
//! [`polyval`]: https://github.com/RustCrypto/universal-hashes/tree/master/polyval
24
25
#![no_std]
26
#![doc(
27
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
28
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
29
    html_root_url = "https://docs.rs/ghash/0.4.3"
30
)]
31
#![warn(missing_docs, rust_2018_idioms)]
32
33
pub use polyval::universal_hash;
34
35
use polyval::Polyval;
36
use universal_hash::{consts::U16, NewUniversalHash, UniversalHash};
37
38
#[cfg(feature = "zeroize")]
39
use zeroize::Zeroize;
40
41
/// GHASH keys (16-bytes)
42
pub type Key = universal_hash::Key<GHash>;
43
44
/// GHASH blocks (16-bytes)
45
pub type Block = universal_hash::Block<GHash>;
46
47
/// GHASH tags (16-bytes)
48
pub type Tag = universal_hash::Output<GHash>;
49
50
/// **GHASH**: universal hash over GF(2^128) used by AES-GCM.
51
///
52
/// GHASH is a universal hash function used for message authentication in
53
/// the AES-GCM authenticated encryption cipher.
54
#[derive(Clone)]
55
pub struct GHash(Polyval);
56
57
impl NewUniversalHash for GHash {
58
    type KeySize = U16;
59
60
    /// Initialize GHASH with the given `H` field element
61
    #[inline]
62
1.32k
    fn new(h: &Key) -> Self {
63
1.32k
        let mut h = *h;
64
1.32k
        h.reverse();
65
66
        #[allow(unused_mut)]
67
1.32k
        let mut h_polyval = polyval::mulx(&h);
68
69
        #[cfg(feature = "zeroize")]
70
        h.zeroize();
71
72
        #[allow(clippy::let_and_return)]
73
1.32k
        let result = GHash(Polyval::new(&h_polyval));
74
75
        #[cfg(feature = "zeroize")]
76
        h_polyval.zeroize();
77
78
1.32k
        result
79
1.32k
    }
80
}
81
82
impl UniversalHash for GHash {
83
    type BlockSize = U16;
84
85
    /// Input a field element `X` to be authenticated
86
    #[inline]
87
139k
    fn update(&mut self, x: &Block) {
88
139k
        let mut x = *x;
89
139k
        x.reverse();
90
139k
        self.0.update(&x);
91
139k
    }
92
93
    /// Reset internal state
94
    #[inline]
95
    fn reset(&mut self) {
96
        self.0.reset();
97
    }
98
99
    /// Get GHASH output
100
    #[inline]
101
3.41k
    fn finalize(self) -> Tag {
102
3.41k
        let mut output = self.0.finalize().into_bytes();
103
3.41k
        output.reverse();
104
3.41k
        Tag::new(output)
105
3.41k
    }
106
}
107
108
opaque_debug::implement!(GHash);