How RC6 encryption algorithm works

RC6 is a symmetric key algorithm for block encryption designed by Ron Rivest in 1998, four years after the proposal of its predecessor, the RC5 encryption algorithm.

Although the high-level processing remains very similar to RC5, there are a few differences between the two algorithms, as outlined below:

Differences between RC6 and RC5 algorithms

RC6

RC5

Uses four working registers to hold the input and output values, which greatly increases speed.

Uses two working registers to hold values.

Consists of four primitive operations and their inverses: addition, multiplication, bitwise XOR, and circular shifts.

Consists of three primitive operations and their inverses: addition, bitwise XOR, and circular shifts.

Inclusion of integer multiplication as an operation allows for lesser rounds and greater security.

There is a trade-off between speed and security, where greater rounds imply higher security but lower speed.

Parameterization

Similar to RC5, RC6 is parameterized, word-oriented algorithm. Since it uses four registers, there is a four-word input (plaintext) and a four-word output (ciphertext), each of size ww bits. The parameters are as follows:

Word size: ww

This is the word size in bits. As RC6 uses four-word inputs and outputs, the blocks are 4w4w bits long each. For instance, if ww is 3232 bits, then the input block will be 128128 bit long.

Number of rounds: rr

This is the non-negative number of rounds. This parameter influences the size tt of the expanded key table SS that is derived from the user-supplied secret key. The formula for tt is as follows:

Length of secret key: bb

This is the number of bytes in the secret key, KK, provided by the user. Supported key sizes include 16,24,16, 24, and 3232 bytes up to 255255 bytes (20402040 bits).

Given these parameters, the notation for the algorithm is as follows:

The proposed version of the algorithm was RC632/20/xRC6-32/20/x, which implies there are four 3232 bit word blocks and 2020 rounds. xx denotes key sizes of 16,32,16, 32,and 6464 bytes.

Primitive operations

RC6 uses four primitive operations and their inverses. These are:

  • Addition: This refers to the two's complement addition of words and is denoted by ++. The inverse of this is subtraction, denoted by -.

  • Bitwise XOR: This is the bitwise exclusive-OR of words and is denoted by \oplus.

  • Left rotation: This is the cyclic left rotation of words, denoted by x<<<y x <<< y, where xx is the word, and yy is the number of bits to be shifted. The inverse is cyclic right rotation, represented by x>>>yx>>>y.

  • Integer multiplication: This refers to multiplication modulo 2w2^w and is denoted by ×\times.

The algorithm

The RC6 algorithm consists of three main components, as mentioned:

  • Key expansion

  • Encryption

  • Decryption

Let us take a look at each of these in detail.

Key expansion algorithm

The key expansion algorithm is almost identical to RC5, except that it derives more words (four instead of two) from the secret key. This process is carried out over four steps, as detailed below:

Step one: Initializing P and Q

RC6 uses two word-sized constants, PP and QQ. They are defined as follows:

Where e e is the base of natural logarithms and ϕ\phi is the golden ratio.

Step two: Converting the secret key KK from bytes to words

The secret key array, K[0...b1]K[0...b-1], is used to initialize a new array, L[0...c1]L[0...c-1], where c=b/uc=\lceil b/u \rceil and u=w/8u=w/8 bytes per word. LL is first initialized with 00, and the pseudocode for loading KK to it is as follows:

for i = b-1 to 0:
L[i/u] = (L[i/u] <<< 8) + K[i]

Step three: Initializing the array SS

Recall that SS is the expanded key table of size t=2(r+2)t=2(r+2). Using the magic constants, PP and QQ, we use the following pseudocode to initialize the expanded key table:

S[0] = P
for i = 0 to t-1:
S[i] = S[i-1] + Q

Step four: Key mixing

The last step of the key expansion algorithm involves mixing the provided secret key thrice over the arrays SS and LL. In the given pseudocode, AA and BB are registers that hold the input words.

i = 0
j = 0
do 3 * max(t, c) times:
A = S[i] = (S[i] + A + B) <<< 3
B = L[j] = (L[j] + A + B) <<< (A + B)
i = (i + 1) % t
j = (j + 1) % c

Encryption

Now that we have the expanded key in the array S[0...t1]S[0...t-1], we can perform the encryption algorithm as specified below. The registers are A,B,C,A, B, C, and DD which hold both the input (plaintext) and output (ciphertext). Moreover, the first byte of the plaintext (or ciphertext) is placed in the least-significant byte of AA while the last byte of the plaintext is placed in the most-significant byte of DD.

The final pseudocode is as follows:

B = B + S[0]
D = D + S[1]
for i = 1 to r:
t = (B x (2 * B + 1)) <<< log(w)
u = (D X (2 * D + 1)) <<< log(w)
A = ((A ^ t) <<< u) + S[2 * i]
C = ((C ^ u) <<< t) + S[2 * i + 1]
A = B, B = C, C = D, D = A
A = A + S[t - 2]
C = C + S[t - 1]

At the end of rr rounds, registers A,B,C,A, B, C, and DD hold the ciphertext.

The diagram below illustrates the encryption process:

The complete flow of the RC6 encryption algorithm

Decryption

The pseudocode for the decryption algorithm is the exact reverse of the encryption algorithm, as shown:

C = C - S[t - 1]
A = A - S[t - 2]
for i = r to 1:
A = D, D = C, C = B, D = C
u = (D X (2 * D + 1)) <<< log(w)
t = (B x (2 * B + 1)) <<< log(w)
C = ((C - S[2 * i + 1]) >>> t) ^ u
A = ((A - S[2 * i]) >>> u) ^ t
D = D - S[1]
B = B - S[0]

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved