AES-DH Implementation
Loading...
Searching...
No Matches
aes::gcm Namespace Reference

Functions related to AES-GCM. More...

Functions

void increment (state_array &X)
 The Nonce Increment Function.
 
state_array mult (const state_array &X, const state_array &Y)
 Perform a multiplication on two blocks of data.
 
state_array GHASH (const state &X, const state_array &H)
 Calculate the GHASH for a state.
 
state GCTR (state s, state_array ICB)
 Apply AES-CTR to a message.
 
std::string Enc (const std::string &in, const std::array< uint64_t, 4 > &k, const uint64_t Nr, uint64_t nonce)
 
std::string Dec (const std::string &in, const std::array< uint64_t, 4 > &k, const uint64_t Nr, uint64_t nonce)
 Decrypt a message with AES-GCM.
 

Detailed Description

Functions related to AES-GCM.

Remarks
These functions have been created in reference to: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf Herein referred to as "The Reference" (The AES reference is not Used here).

Function Documentation

◆ Dec()

std::string aes::gcm::Dec ( const std::string & in,
const std::array< uint64_t, 4 > & k,
const uint64_t Nr,
uint64_t nonce )

Decrypt a message with AES-GCM.

Parameters
inThe ciphertext.
kThe key.
NrThe number of rounds to perform.
nonceThe nonce value/IV.
Returns
The plaintext message.
Exceptions
std::runtime_errorif the message has been modified or an incorrect key was supplied.

◆ GCTR()

state aes::gcm::GCTR ( state s,
state_array ICB )

Apply AES-CTR to a message.

Parameters
sThe state to operate on.
ICBThe initial vector, or nonce.
Returns
The encrypted/decrypted state.
Remarks
See 6.5 of the Reference, and Figure 2.
As the name suggests, this is pretty much identical to AES-CTR, Specifically the Ctr function in This file. The only difference is that our nonce is a state_array, instead of a number (Which isn't specific To GCM or CTR, but is just how we implemented it in this case), we increment by a special function, rather than just adding one, and we return the state, rather than the unravelled string, so that we can compute the GHASH.

◆ GHASH()

state_array aes::gcm::GHASH ( const state & X,
const state_array & H )

Calculate the GHASH for a state.

Parameters
XThe state
HThe hash subkey.
Returns
The hash block.
Remarks
See 6.4 of the Reference.
This function operates almost identically to a MAC, like HMAC-SHA256 (Hence the name). Basically we set an initial generation of Y, and then Update that value for every block in the state. We do this with a fast XOR, And then apply our multiplication on the hash subkey. Since the hash subkey Is derived from the key and nonce, this is essentially the key in an HMAC, And the state is the data that runs through the hashing algorithm. By The end of the iteration, we have a block that has been influenced by not only the key, but every block in the state, hence arriving at a hash that, if the key or any block has been modified, will not match. Since it's also a state_array itself, We can trivially append it to the end of the state, and unravel the entire thing Without needing to send an explicit HMAC value across.

◆ increment()

void aes::gcm::increment ( state_array & X)

The Nonce Increment Function.

Parameters
thestate array used as the counter.
Remarks
GCM uses a "more sophisticated" means of stepping the Counter that is passed to AES with the Key to generate the Pad.
See 6.2 of the Reference.
I couldn't find a reason for why the increment is performed This way. By only incrementing the first four bytes, it technically limits the size of the message to 4294967296 blocks, and we then repeat A nonce, which would be disaterous. That value is equal to 64GB. My best Guess is that a more performant implementation (One that wouldn't need to deconstruct the last four bytes into a new number), would be able to just cast The last bits, treat it like the very fast uint32_t directly, and increment it with instructions that are blazingly fast with this datatype (int defaults to 32bit specifically because it's fast, even faster than the native register size of 64bit. You can see this by using uint_fast32_t, which C++ mandates as an integer at least 32 bits, but can be faster if performance will improve (See https://en.cppreference.com/w/cpp/types/integer). Yet, on every computer I've personally used, it will always be a 32 bit value, not a 64 bit, which is neat).

◆ mult()

state_array aes::gcm::mult ( const state_array & X,
const state_array & Y )

Perform a multiplication on two blocks of data.

Parameters
XThe first block.
YThe second block.
Returns
: The resultant block.
Remarks
See 6.3 of the Reference.