Matrix-Based RSA Encryption of Streaming Data Prendergast 20210804
Matrix-Based RSA Encryption of Streaming Data Prendergast 20210804
Abstract
This paper describes a new method for performing secure encryption of blocks of streaming data.
This algorithm is an extension of the RSA encryption algorithm. Instead of using a public key
(𝑒, 𝑛) where 𝑛 is the product of two large primes and e is relatively prime to the Euler Totient
function, 𝜑(𝑛), one uses a public key (𝑛, 𝑚, 𝐸), where m is the rank of the matrix 𝐸 and E is an
invertible matrix in 𝐺𝐿(𝑚, 𝜑(𝑛)). When m is 1, this last condition is equivalent to saying that E
is relatively prime to 𝜑(𝑛), which is a requirement for standard RSA encryption. Rather than a
secret private key (d,𝜑(𝑛)) where d is the inverse of e (mod 𝜑(𝑛)), the private key is (D,𝜑(𝑛)),
where D is the inverse of E (mod (𝜑(𝑛)). The key to making this generalization work is a matrix
generalization of the scalar exponentiation operator that maps 𝑍𝑛𝑚 , the set of 𝑚-dimensional
vectors with integer coefficients modulo 𝑛, onto itself.
1. Background
In public key encryption systems, a transmitter and receiver share a public key and the receiver
possesses a secret key known only to himself. The transmitter encrypts and sends a secret
message using the public key. Without expending considerable time and resources, only the
receiver with the private key is capable of decrypting the secret message.
The RSA algorithm, named after its inventors, Rivest-Shamir-Adleman, is a public key
encryption system described in [Rivest, 1983]. In its simplest form, keys are generated as
follows:
Step 1: Choose two large primes, 𝑝 and 𝑞 and compute 𝑛 = 𝑝 ∗ 𝑞.
Step 2: Compute 𝜑(𝑛) = (𝑝 − 1) ∗ (𝑞 − 1).
Step 3: Find an exponent 𝑒 such that 𝑔𝑐𝑑(𝜑(𝑛), 𝑒) = 1.
Step 4: Compute 𝑑 = 𝑒 −1 𝑚𝑜𝑑(𝜑(𝑛)).
Step 5: Publish (𝑛, 𝑒) as the public key, and keep (𝑑, 𝜑(𝑛)) as the secret private key.
To encrypt, the sender first maps the message to a value M between 1 and 𝑛 − 1. 𝑀 is then
encrypted according to the formula
𝐶 = 𝑀𝑒 (𝑚𝑜𝑑 𝑛). (1)
The receiver decrypts the message by computing
(𝑀𝑒 )𝑑 (𝑚𝑜𝑑 𝑛) = 𝑀𝑒𝑑 (𝑚𝑜𝑑 𝑛) = 𝑀 (𝑚𝑜𝑑 𝑛) (2)
by Fermat’s little theorem, since 𝑒𝑑 = 1 𝑚𝑜𝑑(𝜑(𝑛)).
The RSA algorithm is not used on plaintext messages of arbitrary length for several reasons.
First, note from above that each data block must be mapped to a value 𝑀 between 1 and 𝑛 − 1.
This prevents outright encryption of an entire message unless the message is small.
However, breaking the message into smaller data blocks creates other problems. We see from (1)
that repeated encryption of the same text with the same encryption key always yields the same
result. This can make the technique vulnerable to both frequency analysis attacks and chosen
ciphertext attacks.
To see an example of a frequency analysis attack, suppose that a long message is encrypted using
standard RSA encryption, and that each letter in the message is individually encrypted using the
same RSA encryption key. Since each encryption of the letter “e” is the same, one might be able
to discern which encryption represented the letter “e” from a frequency analysis.
To illustrate the RSA vulnerability to a chosen ciphertext attack, suppose that an attacker knew a
value k which was easily invertible (𝑚𝑜𝑑 𝑛). Suppose also that he did not know the decryption
of an encrypted message (𝑀)𝑒 (𝑚𝑜𝑑 𝑛), but he was given access to the decryption of
𝑘(𝑀)𝑒 (𝑚𝑜𝑑 𝑛) for some scalar k. The decryption is given by
(𝑘(𝑀)𝑒 )𝑑 = 𝑘 𝑑 𝑀𝑒𝑑 = 𝑘 𝑑 𝑀 = 𝑘 −𝑒 𝑀(𝑚𝑜𝑑 𝑛).
But since k is easily invertible and e is known, 𝑘 −𝑒 can also be computed and hence M can be
discovered.
Therefore, repeated application of the standard RSA algorithm with the same encryption key is
not recommended for decrypting streaming data. Instead, a more secure approach is to use the
RSA encryption to agree on a block hash. This hash is then used in a block encryption algorithm
(such as AES, see [NIST, 2001]), where the message is broken into data blocks of fixed length,
and each data block is encrypted using a function dependent on the hash and the previous data
blocks.
This paper describes a matrix generalization of the RSA encryption algorithm that overcomes
these obstacles. This generalization permits encryption of a data block to be dependent on
previous data blocks or random nonce, guaranteeing that repeated encryption of the same
message does not yield the same ciphertext. This blocks the chosen ciphertext and frequency
analysis attack vulnerabilities described above.
Previously proposed matrix-based public key encryption systems (such as [Backal, 2001],
[Chuang, 1991], [Singh, 2004] and [Slavin, 2008]) have mapped a message into one or more
matrices, and then performed encryption on these matrices. For example, [Chuang, 1991]
encrypts by mapping the message into the off-diagonal elements of a triangular matrix, and
applies the Cayley-Hamilton theorem to perform scalar exponentiation of the matrix.
This approach is different, because it generalizes the RSA algorithm to operate on entire
matrices, instead of applying standard RSA to operate on scalar data that resides within a matrix.
For example, the key generation process is modified to choose an invertible matrix 𝐸 in the
general linear group of 𝑚x𝑚 invertible matrices (𝑚𝑜𝑑 𝛷(𝑛)) instead of a scalar 𝑒. In step 4, the
matrix inverse 𝐷 is computed instead of a scalar 𝑑.
With appropriately defined vector exponentiation, equations (1) and (2) continue to hold. These
changes allow for confusion across encrypted data blocks, and allow RSA encryption on
streaming data.
1.1. Mathematical Notation
Throughout this paper, we use 𝛷(𝑛) to represent the number of positive integers not exceeding
the integer 𝑛 and relatively prime to 𝑛. This is commonly known as Euler’s Totient function.
We also use the expression 𝐺𝐿(𝑚, 𝑠) to represent the general linear group of invertible 𝑚 𝑥 𝑚
matrices with coefficients in the field of integers modulo s.
For integer x and z, the expression 𝑥(𝑚𝑜𝑑 𝑧) denotes the integral remainder when x is divided by
z. When the expression preceding (𝑚𝑜𝑑 𝑧) is a matrix, the integral remainder is computed for
each component of the matrix. Hence
13 27 3 7
( )= ( ) (𝑚𝑜𝑑 10).
41 −4 1 6
Now we define a generalization of scalar exponentiation that can be applied to vectors of length
𝑚 > 1. Let 𝑍𝑠 be the ring of integers modulo s, and let
𝑎1,1 𝑎1,2 𝑎𝑚,1
⋯
𝑎2,1 𝑎2,2 𝑎𝑚,2
𝐴=[ ⋮ ⋮ ⋱ ⋮ ]
𝑎𝑚,1 𝑎𝑚,2 𝑎𝑚,𝑚
∏𝑚
𝑗=1 𝑥𝑗
𝑎1,𝑗
∏𝑚
𝑗=1 𝑥𝑗
𝑎2,𝑗
𝑋^^𝐴 = , (3)
⋮
∏𝑚 𝑥 𝑎𝑚,𝑗
( 𝑗=1 𝑗 )
Note that (3) confuses the inputs; each output 𝑦𝑖 depends on all inputs 𝑥𝑗 for which 𝑎𝑖,𝑗 ≠ 0.
Two additional important properties of the definition (3) are:
𝑋^^𝐼 = 𝑋 (4)
and
((𝑋^^𝐴)^^𝐵) = (𝑋^^(𝐵 ∗ 𝐴)) (5).
Equation (4) follows directly from (3). For (5), note that the 𝑖-th component of (𝑋^^𝐴)^^𝐵 is
given by
𝑚 𝑏𝑖,𝑘 𝑚
𝑧𝑖 = ∏𝑚
𝑘=1 (∏𝑗=1 𝑥𝑗
𝑎𝑘,𝑗
) = ∏𝑚
𝑘=1 (∏𝑗=1 𝑥𝑗
𝑎𝑘,𝑗 𝑏𝑖,𝑘
)
𝑚
∑𝑘=1 𝑎𝑘,𝑗 𝑏𝑖,𝑘
= ∏𝑚
𝑗=1 𝑥𝑗 (6).
But the (𝑖, 𝑗) component of 𝐵𝐴 is given by
(𝐵𝐴)𝑖,𝑗 = ∑𝑚
𝑘=1 𝑏𝑖,𝑘 𝑎𝑘,𝑗 (7).
Hence, combining (6) and (7),
𝑚
∑𝑘=1 𝑎𝑘,𝑗 𝑏𝑖,𝑘 (𝐵𝐴)𝑖,𝑗
𝑧𝑖 = ∏𝑚
𝑗=1 𝑥𝑗 = ∏𝑚
𝑗=1 𝑥𝑗 ,
which proves (5).
1.2. Paper Overview
Section 2 provides a high-level overview of how matrix-based RSA encryption works, and
illustrates encryption and decryption of a simple message using this approach.
A detailed description of the algorithm is provided in section 3. Section 3.1 presents several
alternatives for key generation, including randomized selection of matrix components, similarity
transformation on diagonal matrices, and LU compositions with randomized off-diagonal
elements. Streaming data encryption approaches are outlined in section 3.2, and include
encryption with previously encrypted data blocks, encryption with random nonce, and
combinations of both previous data blocks and random nonce. Section 3.3 describes the
decryption process steps.
Security and performance notes are found in section 4, and the author’s summary and
conclusions are found in section 5. References cited in this paper are listed in section 6.
Transmit all 𝑚 encrypted data blocks to the receiver. (The 𝑆1 can be generated from
prior data blocks, prior data block encryptions, or random nonce.)
5. (Decryption). For each set of 𝑚 encrypted blocks of data received from the sender,
decrypt them using the decryption matrix 𝐷 by computing
(𝑆1 , 𝑆2 , … , 𝑆𝑚−1 , 𝐵𝑘 )𝑇 = [(𝐸1 , 𝐸2 , … , 𝐸𝑚−1 , 𝐸𝑚 )^^𝐷]𝑇 (𝑚𝑜𝑑 𝑛).
17 20 (𝑚𝑜𝑑
𝐸 = 𝑃𝛬−1 𝑃−1 = ( ) 160).
70 127
Set i=0
Set
No Yes Yes
i<m?
No Publish
Set public key
(n,m,E)
End
First p, q and the rank m are chosen. We set 𝑛 = 𝑝𝑞 and 𝜑(𝑛) = (𝑝 − 1) ∗ (𝑞 − 1).
Next, we choose the diagonal elements 𝑖 to be relatively prime to 𝜑(𝑛), and create two random
lower- and upper-triangular matrices with ones on the diagonal. We set 𝑃 = 𝐿𝑈(𝑚𝑜𝑑 𝜑(𝑛))
and define the encryption matrix by 𝐸 = 𝑃𝛬𝑃 −1 (𝑚𝑜𝑑 𝜑(𝑛)). Set 𝐷 = 𝐸 −1 (𝑚𝑜𝑑 𝜑(𝑛)). We
publish the public key (n, m, E) and keep the hidden secret key (𝜑(𝑛), 𝐷).
Since 𝛬 is a diagonal matrix in 𝐺𝐿(𝑚, 𝜑(𝑛)), its inverse
𝑑1,1 −1 0 … 0
−1
0 𝑑2,2 0 ⋮
𝛬−1 =
0 0 ⋱ 0
[ 0 0 … 𝑑𝑚,𝑚 −1 ]
exists since each diagonal element of 𝛬, 𝑑𝑖,𝑖 , is relatively prime to 𝜑(𝑛). The diagonal elements
can be calculated by solving 𝑎𝑖 ∗ 𝑑𝑖,𝑖 + 𝑏𝑖 ∗ 𝜑(𝑛) = 1 for 𝑎𝑖 and 𝑏𝑖 using Euclid’s algorithm.
The solutions 𝑎𝑖 satisfy 𝑎𝑖 = 𝑑𝑖,𝑖 −1 , and
𝑎1 0 … 0
0 𝑎2 0 ⋮
𝛬−1 =[ ] .
0 0 ⋱ 0
0 0 … 𝑎𝑚
Since 𝐿 and 𝑈 are triangular matrices, their inverses can also be readily computed by Gaussian
elimination. For example, if
1 0 0
𝐿 = [𝑙2,1 1 0]
𝑙3,1 𝑙3,2 1
,
Note that if 𝑚 = 1 and 𝑔𝑐𝑑(𝐸, 𝜑(𝑛)) = 1, this procedure is equivalent to the RSA key
generation procedure.
3.2. Encryption Method
During key generation, we saw that the encrypting agent selected two large primes, 𝑝 and 𝑞, and
computed the Euler totient function 𝜑(𝑛) = (𝑝 − 1) ∗ (𝑞 − 1). The encrypting agent then
selected an invertible 𝑚 𝑥 𝑚 matrix E (𝑚 ≥ 1) from 𝐺𝐿(𝑚, 𝜑(𝑛)), the general linear group of
invertible 𝑚 𝑥 𝑚 matrices (𝑚𝑜𝑑 𝜑(𝑛)), and computed the matrix inverse 𝐷 = 𝐸 −1. Note that
D and E are both matrices with elements in the field of integers (𝑚𝑜𝑑 𝜑(𝑛)). The encrypting
agent then published (𝑛, 𝑚, 𝐸) as the public key, and retains (𝜑(𝑛), 𝐷) as the secret private key.
Figure 2 shows one way in which these keys can be used to encrypt a fixed sequence of data
blocks (𝐵1 , 𝐵2 , … ), Each data block must be of length less than 𝐿𝑜𝑔2 (𝑛) bits. Using an
assignment method, each data block is mapped to an integer between 1 and 𝑛 − 1, each
relatively prime to n. (Note that 0 is not used in the mapping, because each mapped element must
be relatively prime to both 𝑝 and 𝑞.)
Start
Increment
Initialize Block
Index (
Read Next
Initialize
Block
to nonce
Set
to
Output
No EOF Yes
? End
An initial set of 𝑚 − 1 blocks (𝐸2−𝑚 , 𝐸3−𝑚 , … , 𝐸0 ) are set to random nonce. Then each new data
block 𝐵𝑘 is encrypted with the previously 𝑚 − 1 data blocks (𝐸𝑖+1 , 𝐸𝑖+2 , … , 𝐸𝑖+𝑚−1 ). The first
block is therefore encrypted with random nonce. Subsequent iterations, however, will encrypt a
combination of the current data block, previous encryptions and the initial random nonce
together.
In a computer program, this is performed in two steps ((8) and (9)). First the encrypted data are
encrypted and confused:
(𝐹𝑖+1 , 𝐹𝑖+2 , … , 𝐹𝑖+𝑚 )𝑇 = ((𝐸𝑖+1 , 𝐸𝑖+2 , … , 𝐸𝑖+𝑚−1 , 𝐵𝑖+𝑚 )𝑇 )^^𝐸(𝑚𝑜𝑑 𝑛) (8)
Then the encryption results are stored for the next block:
(𝐸𝑖+1 , 𝐸𝑖+2 , … , 𝐸𝑖+𝑚 )𝑇 = (𝐹𝑖+1 , 𝐹𝑖+2 , … , 𝐹𝑖+𝑚 )𝑇 (9)
Two points should be noted with this approach. First, changing one data block in a message
stream will in general change all of the ciphertext that follows that data block. This is because if
a bit in data block 𝐵𝑗 changes, then the encryption 𝐸𝑗 changes, which causes all subsequent
encryptions to change, due to (8). Second, two encryptions of the same data blocks (𝐵1 , 𝐵2 , … )
will have different cyphertexts, because they start with different random nonces.
Other approaches are also possible. If storage is not an issue, each data block 𝐵𝑖+𝑚 could be
uniquely encrypted with 𝑚 − 1 data blocks of random nonce (𝑅𝑖+1 , 𝑅𝑖+2 , … , 𝑅𝑖+𝑚−1 ) according
to the mapping
(𝐸𝑖+1 , 𝐸𝑖+2 , … , 𝐸𝑖+𝑚 )𝑇 = ((𝑅𝑖+1 , 𝑅𝑖+2 , … , 𝑅𝑖+𝑚−1 , 𝐵𝑖+𝑚 )𝑇 )^^𝐸 (𝑚𝑜𝑑 𝑛)
Here only the last data block is of interest, the others are just noise.
Matrix-based encryptions that include combinations of random nonce and previously encrypted
blocks together with the current block are also possible,
Start
Set
to
Store
Decrement
k
No k=0 Yes
End
?
As before, we use a counter 𝑘 to keep track of the data blocks that have been received for
decryption. Since decryption reverses the encryption process, the counter k is initially set to the
last block number in the set of data blocks.
Just as with encryption, decryption is performed 𝑚 data blocks at a time, where 𝑚 is the rank of
the encryption matrix 𝐸.
If m data blocks (𝑀𝑖+1 , 𝑀𝑖+2 , … , 𝑀𝑖+𝑚−1 , 𝑀𝑖+𝑚 ) are encrypted by
((𝐸𝑖+1 , 𝐸𝑖+2 , … , 𝐸𝑖+𝑚 )𝑇 )(𝑚𝑜𝑑 𝑛) = (((𝑀𝑖+1 , 𝑀𝑖+2 , … , 𝑀𝑖+𝑚−1 , 𝑀𝑖+𝑚 )𝑇 )^^𝐸)(𝑚𝑜𝑑 𝑛),
then decryption using the private key is
((𝐸𝑖+1 , 𝐸𝑖+2 , … , 𝐸𝑖+𝑚 )𝑇 )^^𝐷(𝑚𝑜𝑑 𝑛 = (((𝑀𝑖+1 , 𝑀𝑖+2 , … , 𝑀𝑖+𝑚−1 , 𝑀𝑖+𝑚 )𝑇 )^^𝐸)^^𝐷(𝑚𝑜𝑑 𝑛)
= (𝑀𝑖+1 , 𝑀𝑖+2 , … , 𝑀𝑖+𝑚−1 , 𝑀𝑖+𝑚 )𝑇 ^^(𝐷 ∗ 𝐸)(𝑚𝑜𝑑 𝑛) (10)
= (𝑀𝑖+1 , 𝑀𝑖+2 , … , 𝑀𝑖+𝑚−1 , 𝑀𝑖+𝑚 )𝑇 (𝑚𝑜𝑑 𝑛).
This last equation is true by Fermat’s little theorem since 𝐷 ∗ 𝐸 = 𝐼 (𝑚𝑜𝑑 𝜑(𝑛)).
For the example of Figure 2, each data block is encrypted with the encryptions of the previous
𝑚 − 1 data blocks,
((𝐹𝑖+1 , 𝐹𝑖+2 , … , 𝐹𝑖+𝑚 )𝑇 )(𝑚𝑜𝑑 𝑛) = (((𝐸𝑖+1 , 𝐸𝑖+2 , … , 𝐸𝑖+𝑚−1 , 𝐵𝑖+𝑚 )𝑇 )^^𝐸)(𝑚𝑜𝑑 𝑛)
and so, from (10), decryption using the private key is performed according to the formula
((𝐹𝑖+1 , 𝐹𝑖+2 , … , 𝐹𝑖+𝑚 )𝑇 )^^𝐷(𝑚𝑜𝑑 𝑛) = (((𝐸𝑖+1 , 𝐸𝑖+2 , … , 𝐸𝑖+𝑚−1 , 𝐵𝑖+𝑚 )𝑇 )^^𝐸)^^𝐷(𝑚𝑜𝑑 𝑛)
= (𝐸𝑖+1 , 𝐸𝑖+2 , … , 𝐸𝑖+𝑚−1 , 𝐵𝑖+𝑚 )𝑇 ^^(𝐷 ∗ 𝐸)(𝑚𝑜𝑑 𝑛) (11)
= (𝐸𝑖+1 , 𝐸𝑖+2 , … , 𝐸𝑖+𝑚−1 , 𝐵𝑖+𝑚 )𝑇 (𝑚𝑜𝑑 𝑛).
Recall that when this set of data blocks was originally encrypted, it consisted of one unencrypted
value, 𝐵𝑘 , and 𝑚 − 1 previously encrypted data elements, 𝐸𝑘−1 , 𝐸𝑘−2 , …, 𝐸𝑘−𝑚+1 , Since
decryption simply reverses this process, the output of decryption is one unencrypted value 𝐵𝑘
and 𝑚 − 1 previously encrypted values.
The revealed value 𝐵𝑘 is stripped off, k is decremented and the process repeats.
To illustrate this approach further, if 𝑚 = 3 and the encrypted message contains 𝑘 = 5 data
blocks, then:
• Set (𝐸3 , 𝐸4 , 𝐵5 ) equal to the decryption of (𝐸3 , 𝐸4 , 𝐸5 ).
• Set (𝐸2 , 𝐸3 , 𝐵4 ) equal to the decryption of (𝐸2 , 𝐸3 , 𝐸4 ).
• Set (𝐸1 , 𝐸2 , 𝐵3 ) equal to the decryption of (𝐸1 , 𝐸2 , 𝐸3 ).
• Set (𝐸0 , 𝐸1 , 𝐵2 ) equal to the decryption of (𝐸0 , 𝐸1 , 𝐸2 ).
• Set (𝐸−1 , 𝐸0 , 𝐵1 ) equal to the decryption of (𝐸−1 , 𝐸0 , 𝐸1 ).
The decrypted data stream is then given by (𝐵1 , 𝐵2 , 𝐵3 , 𝐵4 , 𝐵5 ).
In the case where each of the data blocks is encrypted, one block at a time, with 𝑚 − 1 blocks of
random nonce, equation (10) becomes
((𝐸𝑖+1 , 𝐸𝑖+2 , … , 𝐸𝑖+𝑚 )𝑇 )^^𝐷 = (((𝑅𝑖+1 , 𝑅𝑖+2 , … , 𝑅𝑖+𝑚−1 , 𝐵𝑖+𝑚 )𝑇 )^^𝐸)^^𝐷(𝑚𝑜𝑑 𝑛)
= (𝑅𝑖+1 , 𝑅𝑖+2 , … , 𝑅𝑖+𝑚−1 , 𝐵𝑖+𝑚 )𝑇 ^^(𝐷 ∗ 𝐸)(𝑚𝑜𝑑 𝑛)
= (𝑅𝑖+1 , 𝑅𝑖+2 , … , 𝑅𝑖+𝑚−1 , 𝐵𝑖+𝑚 )𝑇 .
5. Conclusion
RSA encryption is rarely used for streaming data, in part because it can be susceptible to
frequency analysis attacks and chosen ciphertext attacks.
In this paper, we have shown how the RSA algorithm can be generalized to support full matrix-
based encryption using matrix encryption and decryption keys and a novel matrix generalization
of scalar exponentiation. When random nonce is added to the data stream, encryption results will
vary from run to run, defeating frequency analysis attacks. The algorithm also supports
confusion across data blocks, which defeats chosen ciphertext attacks.
Security is just as strong as scalar RSA encryption and in general requires ability to factor the
product of two large primes.
In short, matrix-based RSA is a valid encryption alternative for handling streaming data.
6. References
1. Backal, “Virtual matrix encryption (VME) and virtual key cryptographic method and
apparatus”, US Patent US7346162, published April 17, 2001.
2. Chuang, Chih-Chwen and James George Dunham, “Matrix Extensions of the RSA
Algorithm”, Advances in Cryptology – CRYPTO ’90, A.J. Menezes and S.A. Vanstone (Eds.):
LNCS 537, pp. 140-155, 1991. © Springer-Verlag Berlin Heidelberg 1991
3. Glatfelter and Raab, “Cryptography using a symmetric frequency-based encryption
algorithm”, US Patent US8855303, published October 7, 2014.
4. LeVeque, William J., Fundamentals of Number Theory, ISBN-13: 9780486689067, Dover
Publications, 1996.
5. Rivest, et. al., “Cryptographic Communication System and Method”, US Patent US4405829,
published September 20, 1983.
6. Singh, “Cryptosystems”, US Patent US20040174995, published September 9, 2004.
7. Slavin, “Public key cryptograph using matrices”, US Patent US7346162, published March 28,
2008.
8. Strang, Gilbert, Introduction to Linear Algebra, Fourth Edition, ISBN-13: 9780980232714,
Wellesley-Cambridge Press, 2009.
9. United States National Institute of Standards and Technology (NIST), "Announcing the
ADVANCED ENCRYPTION STANDARD (AES)" (PDF). Federal Information Processing
Standards Publication 197, November 26, 2001.