-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
aes: improve top-level naming and params #77
- Updates AES::Algorithm to use more spec-conformant names and improve documentation - Fixes a bug in key expansion for decryption and simplify associated APIs - Removes unnecssary parameterization in AES::Algorithm
- Loading branch information
Showing
5 changed files
with
80 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,78 @@ | ||
// Cryptol AES Implementation | ||
// Copyright (c) 2010-2018, Galois Inc. | ||
// | ||
// @copyright Galois Inc. | ||
// @author Nichole Shimanski <[email protected]> | ||
// @author Marcella Hastings <[email protected]> | ||
// www.cryptol.net | ||
|
||
// This is a fairly close implementation of the FIPS-197 standard: | ||
// http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf | ||
// | ||
// | ||
// References | ||
// [FIPS-197u1]: Morris J. Dworkin, Elaine B. Barker, James R. Nechvatal, | ||
// James Foti, Lawrence E. Bassham, E. Roback, and James F. Dray Jr. | ||
// Advanced Encryption Standard (AES). Federal Inf. Process. Stds. (NIST FIPS) | ||
// 197, update 1. May 2023. | ||
// | ||
|
||
module Primitive::Symmetric::Cipher::Block::AES::Algorithm where | ||
|
||
import Primitive::Symmetric::Cipher::Block::AES::State (State, RoundKey, msgToState, stateToMsg) | ||
import Primitive::Symmetric::Cipher::Block::AES::Round (AESFinalRound, AESFinalInvRound) | ||
import Primitive::Symmetric::Cipher::Block::AES::Round as Round | ||
|
||
parameter | ||
/** 0: AES128, 1: AES192, 2: AES256 */ | ||
type Mode : # | ||
|
||
type constraint (2 >= Mode) | ||
|
||
encRound : RoundKey -> State -> State | ||
decRound : RoundKey -> State -> State | ||
/* The following section encodes [FIPS-197u1] Section 5, Table 3 | ||
* The table is described in terms of the `Mode`. | ||
*/ | ||
|
||
|
||
/** Number of 32 bit words in the key */ | ||
/** Key length: number of 32 bit words in the key */ | ||
type Nk = 4 + 2 * Mode | ||
|
||
/** Number of rounds */ | ||
type Nr = 6 + Nk | ||
|
||
/** Key size in bits */ | ||
type AESKeySize = 32 * Nk | ||
|
||
/** The keys for all the rounds */ | ||
type KeySchedule = (RoundKey, [Nr-1]RoundKey, RoundKey) | ||
|
||
/** AES Encryption with an expanded key. | ||
This is useful if many things will be encrypted with the same key. */ | ||
encrypt : KeySchedule -> [128] -> [128] | ||
encrypt (kInit,ks,kFinal) pt = | ||
stateToMsg (AESFinalRound kFinal (rounds ! 0)) | ||
/** | ||
* The general function for executing AES with 128-, 192-, or 256-bit keys. | ||
* | ||
* Corresponds to [FIPS-197u1] Section 5.1, Algorithm 1. | ||
* | ||
* In the spec, the three inputs to `Cipher` are the input data, the number of | ||
* rounds `Nr`, and the round keys. In this implementation, we don't explicitly | ||
* pass `Nr` as a parameter; instead it's defined as a type above. We also | ||
* switch the order of the input and keys. | ||
*/ | ||
cipher: KeySchedule -> [128] -> [128] | ||
cipher (kInit,ks,kFinal) pt = | ||
// Lines 10-13 | ||
stateToMsg (Round::AESFinalRound kFinal (rounds ! 0)) | ||
where | ||
state0 = kInit ^ msgToState pt | ||
rounds = [state0] # [ encRound rk s | rk <- ks | s <- rounds ] | ||
|
||
/** AES decryption with an expanded key. | ||
This is useful if many things will be decrypted with the same key. */ | ||
decrypt : KeySchedule -> [128] -> [128] | ||
decrypt (kInit, ks, kFinal) ct = | ||
stateToMsg (AESFinalInvRound kFinal (rounds ! 0)) | ||
// Lines 2-3 | ||
state0 = kInit ^ msgToState pt | ||
// Lines 4-9 | ||
rounds = [state0] # [ Round::AESRound rk s | rk <- ks | s <- rounds ] | ||
|
||
/** | ||
* The general function for inverting AES with 128-, 192-, or 256-bit keys. | ||
* | ||
* This inverts and reverses the order of the transformations in `cipher`. | ||
* Corresponds to [FIPS-197u1] Section 5.3, Algorithm 3. | ||
* | ||
* In the spec, the three inputs to `InvCipher` are the input data, the number of | ||
* rounds `Nr`, and the round keys. In this implementation, we don't explicitly | ||
* pass `Nr` as a parameter; instead it's defined as a type above. We also | ||
* switch the order of the input and keys. | ||
*/ | ||
invCipher: KeySchedule -> [128] -> [128] | ||
invCipher (kInit, ks, kFinal) ct = | ||
// Lines 10-13 | ||
stateToMsg (Round::AESFinalInvRound kInit (rounds ! 0)) | ||
where | ||
state0 = kInit ^ msgToState ct | ||
rounds = [state0] # [ decRound rk s | rk <- ks | s <- rounds ] | ||
|
||
|
||
|
||
// Lines 2-3 | ||
state0 = kFinal ^ msgToState ct | ||
// Lines 4-9 | ||
rounds = [state0] # [ Round::AESInvRound rk s | rk <- (reverse ks) | s <- rounds ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,20 @@ | ||
module Primitive::Symmetric::Cipher::Block::AES::SubBytePlain where | ||
|
||
import Common::GF28 as GF28' | ||
private type GF28 = GF28'::GF28 | ||
import Common::GF28 as GF28 | ||
private type GF28 = GF28::GF28 | ||
|
||
// The SubBytes transform and its inverse | ||
SubByte : GF28 -> GF28 | ||
SubByte b = xformByte (GF28'::inverse b) | ||
SubByte b = xformByte (GF28::inverse b) | ||
|
||
InvSubByte : GF28 -> GF28 | ||
InvSubByte b = GF28'::inverse (xformByte' b) | ||
InvSubByte b = GF28::inverse (xformByte' b) | ||
|
||
|
||
// The affine transform and its inverse | ||
xformByte : GF28 -> GF28 | ||
xformByte b = GF28'::add [b, (b >>> 4), (b >>> 5), (b >>> 6), (b >>> 7), c] | ||
xformByte b = GF28::add [b, (b >>> 4), (b >>> 5), (b >>> 6), (b >>> 7), c] | ||
where c = 0x63 | ||
|
||
xformByte' : GF28 -> GF28 | ||
xformByte' b = GF28'::add [(b >>> 2), (b >>> 5), (b >>> 7), d] where d = 0x05 | ||
xformByte' b = GF28::add [(b >>> 2), (b >>> 5), (b >>> 7), d] where d = 0x05 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters