DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
ghash.h File Reference

GHASH (the GF(2^128) universal hash under AES-GCM, NIST SP 800-38D sec 6.3), 4-bit table. More...

#include <stddef.h>
#include <stdint.h>

Go to the source code of this file.

Classes

struct  GhashKey
 4-bit GHASH table for a fixed subkey H = E(K, 0^128): M[i] = i*H as four big-endian uint32 words (M[i][0] most significant). 256 bytes. More...
 

Namespaces

namespace  detws_ghash_detail
 

Functions

uint32_t detws_ghash_detail::be32 (const uint8_t *p)
 
void detws_ghash_detail::put_be32 (uint8_t *p, uint32_t v)
 
void ghash_key_init (GhashKey *t, const uint8_t h[16])
 Build the 4-bit multiplication table from the 16-byte subkey h. Call once per key.
 
void ghash_mul (const GhashKey *t, uint8_t acc[16])
 acc = acc * H in GF(2^128) with the GCM reduction, using the precomputed table t.
 
void ghash_update (const GhashKey *t, uint8_t acc[16], const uint8_t *data, size_t len)
 Fold len bytes of data into acc: acc = (acc XOR block) * H per 16 bytes, a final short block MSB-zero-padded.
 

Detailed Description

GHASH (the GF(2^128) universal hash under AES-GCM, NIST SP 800-38D sec 6.3), 4-bit table.

Shared by ssh_aesgcm (AES-256-GCM) and quic_aead (AES-128-GCM, also DTLS 1.3). The textbook GHASH is a 128-iteration bitwise GF(2^128) multiply per 16-byte block (~3,700 cyc/byte on an ESP32-S3), which made AES-GCM ~350x slower than raw AES-CTR and is the throughput floor of every AEAD record layer (measured, docs/FEATURE_PERFORMANCE.md). There is no hardware GF-multiply on the S3 (unlike the RSA/MPI MODMULT that accelerates curve25519), so the lever is algorithmic: the standard 4-bit table method (Shoup) - build a 16-entry table of i*H once per key, then fold four bits of the accumulator per step.

The 128-bit state is held as FOUR uint32 words (z[0] most significant), NOT two uint64: on the 32-bit Xtensa LX7 a uint64 >>4/<<60 compiles to a libgcc call (__lshrdi3/__ashldi3), which dominated an early uint64 version (~8,100 cyc/block); the 32-bit-word shifts are native register ops. Byte-exact versus the bitwise reference (the NIST/McGrew GCM KATs plus a direct fuzz cross-check, test_ssh_crypto). Header-only, zero heap, deterministic; the 256-byte table lives in the per-direction context (SSH, built once at key install) or on the stack (QUIC/DTLS, per packet).

Definition in file ghash.h.

Function Documentation

◆ ghash_key_init()

void ghash_key_init ( GhashKey t,
const uint8_t  h[16] 
)
inline

Build the 4-bit multiplication table from the 16-byte subkey h. Call once per key.

Definition at line 53 of file ghash.h.

References detws_ghash_detail::be32(), and GhashKey::M.

Referenced by ssh_aesgcm_init().

◆ ghash_mul()

void ghash_mul ( const GhashKey t,
uint8_t  acc[16] 
)
inline

acc = acc * H in GF(2^128) with the GCM reduction, using the precomputed table t.

Definition at line 87 of file ghash.h.

References GhashKey::M, and detws_ghash_detail::put_be32().

Referenced by ghash_update().

◆ ghash_update()

void ghash_update ( const GhashKey t,
uint8_t  acc[16],
const uint8_t *  data,
size_t  len 
)
inline

Fold len bytes of data into acc: acc = (acc XOR block) * H per 16 bytes, a final short block MSB-zero-padded.

Definition at line 128 of file ghash.h.

References ghash_mul().