# RC6 encryption and decryption

By , 14 Jul 2002

## Introduction

RC6 is an evolutionary improvement of RC5, designed to meet the requirements of the Advanced Encryption Standard (AES). Like RC5, RC6 makes essential use of data-dependent rotations. New features of RC6 include the use of four working registers instead of two, and the inclusion of integer multiplication as an additional primitive operation. The use of multiplication greatly increases the diffusion achieved per round, allowing for greater security, fewer rounds, and increased throughput. I found an article about it online and fulfilled the algorithm using C++ for fun. Hope it'd be helpful to some interested people.

## Details of RC6

Like RC5, RC6 is a fully parameterized family of encryption algorithms. A version of RC6 is more accurately specified as RC6-w/r/b where the word size is w bits, encryption consists of a nonnegative number of rounds r, and b denotes the length of the encryption key in bytes. Since the AES submission is targeted at w = 32 and r = 20, we shall use RC6 as shorthand to refer to such versions. When any other value of w or r is intended in the text, the parameter values will be specified as RC6-w/r. Of particular relevance to the AES effort will be the versions of RC6 with 16-, 24-, and 32-byte keys. For all variants, RC6-w/r/b operates on units of four w-bit words using the following six basic operations. The base-two logarithm of w will be denoted by lgw.

• a + b: integer addition modulo 2^w
• a - b: integer subtraction modulo 2^w
• a @ b: bitwise exclusive-or of w-bit words
• a * b: integer multiplication modulo 2^w
• a <<< b: rotate the w-bit word a to the left by the amount given by the least significant lgw bits of b
• a >>> b: rotate the w-bit word a to the right by the amount given by the least significant lgw bits of b

Note that in the description of RC6 the term "round" is somewhat analogous to the usual DES-like idea of a round: half of the data is updated by the other half; and the two are then swapped. In RC5, the term "half-round" was used to describe this style of action, and an RC5 round was deemed to consist of two half-rounds. This seems to have become a potential cause of confusion, and so RC6 reverts to using the term "round" in the more established way.

To get the detailed algorithm description of RC6-w/r/b. Please read the article "The RC6 Block Cipher" by Ronald L. Rivest, M.J.B. Robshaw, R. Sidney and, Y.L. Yin.

## Details of Code

In my program, I fulfilled RC6-32/16. Since the integer addition, subtraction and multiplication don't exceed 2^32 in my program, I don't let their results modulo 2^32 like the operations described above. Anyway, the encryption and decryption go well.

I wrapped the bits rotation operations in two functions ```DWORD CHexDoc::LeftRotate(DWORD dwVar, DWORD dwOffset)``` and `DWORD CHexDoc::RightRotate(DWORD dwVar, DWORD dwOffset)`.

```DWORD CHexDoc::LeftRotate(DWORD dwVar, DWORD dwOffset)
{
DWORD temp1, temp2;

temp1 = dwVar >> (W - dwOffset);
temp2 = dwVar << dwOffset;
temp2 = temp2 | temp1;

return temp2;
}

DWORD CHexDoc::RightRotate(DWORD dwVar, DWORD dwOffset)
{
DWORD temp1, temp2;

temp1 = dwVar << (W - dwOffset);
temp2 = dwVar >> dwOffset;
temp2 = temp2 | temp1;

return temp2;
}
```

The key generation part is like

```void CHexDoc::KeyGen(DWORD dwKey)
{
DWORD P32 = 0xB7E15163;
DWORD Q32 = 0x9E3779B9;
DWORD i, A, B;
DWORD dwByteOne, dwByteTwo, dwByteThree, dwByteFour;

dwByteOne = dwKey >> 24;
dwByteTwo = dwKey >> 8;
dwByteTwo = dwByteTwo & 0x0010;
dwByteThree = dwKey << 8;
dwByteThree = dwByteThree & 0x0100;
dwByteFour = dwKey << 24;

dwKey = dwByteOne | dwByteTwo | dwByteThree
| dwByteFour;

m_dwS[0] = P32;

for(i = 1; i < 2 * R + 4; i++)
m_dwS[i] = m_dwS[i - 1] + Q32;

i = A = B = 0;

int v = 3 * max(1, 2 * R + 4);

for(int s = 1; s <= v; s++)
{
A = m_dwS[i] = LeftRotate(m_dwS[i] + A + B,
OffsetAmount(3));
B = dwKey = LeftRotate(dwKey + A + B,
OffsetAmount(A + B));

i = (i + 1) % (2 * R + 4);
}
}
```

Finally, the core parts of encryption and decryption are as following:

```// encrypt the file
void CHexDoc::EncodeFile()
{
DWORD* pdwTemp;

for(UINT i = 0; i < m_nDocLength; i += 16)
{
pdwTemp = (DWORD*)&m_pFileData[i];

pdwTemp[0] = (pdwTemp[0] - m_dwS[2 * R + 2]);
pdwTemp[2] = (pdwTemp[2] - m_dwS[2 * R + 3]);

for(int j = R; j >= 1; j--)
{
DWORD temp = pdwTemp[3];
pdwTemp[3] = pdwTemp[2];
pdwTemp[2] = pdwTemp[1];
pdwTemp[1] = pdwTemp[0];
pdwTemp[0] = temp;

DWORD t =
LeftRotate((pdwTemp[1] * (2 * pdwTemp[1] + 1)),
OffsetAmount((DWORD)(log((double)W)/log(2.0))));
DWORD u =
LeftRotate((pdwTemp[3] * (2 * pdwTemp[3] + 1)),
OffsetAmount((DWORD)(log((double)W)/log(2.0))));
pdwTemp[0] =
(RightRotate((pdwTemp[0] - m_dwS[2 * j]),
OffsetAmount(u))) ^ t;
pdwTemp[2] =
(RightRotate((pdwTemp[2] - m_dwS[2 * j + 1]),
OffsetAmount(t))) ^ u;
}

pdwTemp[1] = (pdwTemp[1] - m_dwS[0]);
pdwTemp[3] = (pdwTemp[3] - m_dwS[1]);
}
pdwTemp = NULL;
SetModifiedFlag(TRUE);

POSITION pos = GetFirstViewPosition();
while(pos != NULL)
{
CView* pView = GetNextView(pos);
pView->RedrawWindow();
}
}

// decrypt the file
void CHexDoc::DecodeFile()
{
DWORD* pdwTemp;

for(UINT i = 0; i < m_nDocLength; i += 16)
{
pdwTemp = (DWORD*)&m_pFileData[i];

pdwTemp[1] = (pdwTemp[1] + m_dwS[0]);
pdwTemp[3] = (pdwTemp[3] + m_dwS[1]);

for(int j = 1; j <= R; j++)
{
DWORD t =
LeftRotate((pdwTemp[1] * (2 * pdwTemp[1] + 1)),
OffsetAmount((DWORD)(log((double)W)/log(2.0))));
DWORD u =
LeftRotate((pdwTemp[3] * (2 * pdwTemp[3] + 1)),
OffsetAmount((DWORD)(log((double)W)/log(2.0))));
pdwTemp[0] =
(LeftRotate(pdwTemp[0] ^ t, OffsetAmount(u)) +
m_dwS[2 * j]);
pdwTemp[2] =
(LeftRotate(pdwTemp[2] ^ u, OffsetAmount(t)) +
m_dwS[2 * j + 1]);

DWORD temp = pdwTemp[0];
pdwTemp[0] = pdwTemp[1];
pdwTemp[1] = pdwTemp[2];
pdwTemp[2] = pdwTemp[3];
pdwTemp[3] = temp;
}

pdwTemp[0] = (pdwTemp[0] + m_dwS[2 * R + 2]);
pdwTemp[2] = (pdwTemp[2] + m_dwS[2 * R + 3]);
}
pdwTemp = NULL;
SetModifiedFlag(TRUE);

POSITION pos = GetFirstViewPosition();
while(pos != NULL)
{
CView* pView = GetNextView(pos);
pView->RedrawWindow();
}
}
```

## Conclusion

In the view window, I showed the Hex and Char content of the loaded file and their addresses. You can see the changes every time you encrypt/decrypt it. Thanks!

A list of licenses authors might use can be found here

 Mingming Lu Web Developer United States Member
Hey you,
Out there in the cold,
Getting lonely, getting old,
Can you feel me?
Hey you,
Standing in the aisle,
With itchy feet and fading smile,
Can you feel me?
Hey you,
Don't help them to bury the light.
Don't give in without a fight.

Votes of 3 or less require a comment

 Search this forum Profile popups    Spacing RelaxedCompactTight   Noise Very HighHighMediumLowVery Low   Layout Open AllThread ViewNo JavascriptPreview   Per page 102550
 First PrevNext
 rc6 in jar endra hermawan 27 May '09 - 22:55
 The bug with overrun mircea131313 25 Apr '09 - 1:24
 I've compiled the code in VS 2005. but if i try to encrypt a file whose length does not devide by 16 (DWORD) i canot decrypt it back. this bug was mentioned in an previous post:   Load a short file with text which has a length not divisible by 16; debug using [View menu][debug windows][Memory] window to watch the buffer pdwTemp[0] in the CHexDoc::EncodeFile() function: Set the window once you've stepped over this line: pdwTemp = (DWORD*)&m_pFileData[i]; Then Step Out Of the function and watch as the code writes onto the FDFDFDFD marking the end of the buffer which belong to the system...   This is a consequence of the 4-DWORD-at-a-time access: for(UINT i = 0; i < m_nDocLength; i += 16) so you must make sure that the data you're encrypting is in a buffer with an extra 16 Bytes of 'space' after it to avoid overwriting memory. Just how you implement this will depend on the application: memcpy or CString::GetBufferSetLength(...) may be useful. regards   Has anyone solved this ? Thank you! Sign In·View Thread·Permalink
 is there a rc6 algorithm in vb.net moonshaddow 30 Oct '08 - 15:35
 Hep block error... Roel Virgel L. Baldon 6 Oct '08 - 23:28
 I have encountered a heap block error pointing to dbgheap.c _CrtIsMemoryBlock function.   I noticed that this only happened if the file is around 240KB or more. Is this one of the limit of the application?   If not, can somebody please help me fix this error. Sign In·View Thread·Permalink
 I have a errors, help me [modified] Srgteam 22 Nov '07 - 14:58
 Hello to all, I dowbload the source code of this project and opened im Visual Studio 2005, then i converted this project. (Visual Studio asked me) And when i start compiling i see one error:   In function CHexView::FormatLine hexenc_src\hexencview.cpp(182) : error C2679: binary '+=' : no operator found which takes a right-hand operand of type 'BYTE [17]' (or there is no acceptable conversion)   Tell me please, what need to do?     Sorry for my English Sign In·View Thread·Permalink
 Pls Help~~; ofuka 14 Mar '06 - 22:07
 Im doing my FYP for the final year..My supervisor had asked me to include the encryption for the password that contained inside a text file..... I had downloaded this source code and run it..but it shows me two errors..i don't know what's wrong with the code..... below was the error that was pointed to....   typedef UINT_PTR KSPIN_LOCK;   ofuka Sign In·View Thread·Permalink
 DES cryptanalysis with 6 rounds nasor 6 May '05 - 23:14
 Is there any body that has a code in C++ for differential attack on reduced DES to 6 rounds? If you have, please send me a copy of it, if possible for you.   Thanks a lot in advance. Regards, Nasoor   salame man be to yare ghadimi Sign In·View Thread·Permalink
 RC3, RC4, RC5, RC6 Mansureh Shahraki 3 Feb '05 - 6:00
 Re: RC3, RC4, RC5, RC6 Mingming Lu 3 Feb '05 - 6:14
 you may wanna check out the book "Applied Cryptography, Second Edition: Protocols, Algorthms, and Source Code in C" by Bruce Schneier. It has the exhausted descriptions of many cryptography algorithms. BTW, google is another good way to meet your needs.   IS THERE ANYBODY OUT THERE? Sign In·View Thread·Permalink