```
/*
// RC6 & RC5 block cipher supporting unusual block sizes. This
// implementation is designed only for testing interoperability.
//
// Written by Ted Krovetz (ted@krovetz.net). Modified April 10, 2018.
//
// RC6 and RC5 were both patented and trademarked around the time
// each was invented. The author of this code believes the patents
// have expired and that the trademarks may still be in force. Seek
// legal advice before using RC5 or RC6 in any project.
//
// This is free and unencumbered software released into the public
// domain.
//
// Anyone is free to copy, modify, publish, use, compile, sell, or
// distribute this software, either in source code form or as a
// compiled binary, for any purpose, commercial or non-commercial,
// and by any means.
//
// In jurisdictions that recognize copyright laws, the author or
// authors of this software dedicate any and all copyright interest
Krovetz Expires October 13, 2018 [Page 15]
Internet-Draft RC6 and RC5 Test Vectors April 2018
// in the software to the public domain. We make this dedication for
// the benefit of the public at large and to the detriment of our
// heirs and successors. We intend this dedication to be an overt act
// of relinquishment in perpetuity of all present and future rights
// to this software under copyright law.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// For more information, please refer to
```
*/
#include
#include
#include
/* set vectors non-zero to print intermediate setup/encrypt values */
static int vectors = 0;
/* pbuf is used to print sequences of bytes from in memory */
static void pbuf(const void *p, int len, const void *s)
{
int i;
if (s) printf("%s", (char *)s);
for (i=0; i0; n--) d[n-1] = a[n-1] ^ b[n-1];
}
/* d[0..n-1] = a[0..n-1] + b[0..n-1] (mod 2^8n) */
static void add(unsigned char d[], unsigned char a[],
unsigned char b[], int n) {
int tmp, carry = 0;
for ( ; n>0; n--) {
d[n-1] = tmp = a[n-1] + b[n-1] + carry;
carry = tmp >> 8;
}
}
/* d[0..n-1] = a[0..n-1] - b[0..n-1] (mod 2^8n) */
static void sub(unsigned char d[], unsigned char a[],
unsigned char b[], int n) {
int tmp, borrow = 0;
for ( ; n>0; n--) {
d[n-1] = tmp = a[n-1] - b[n-1] - borrow;
borrow = (tmp < 0 ? 1 : 0);
}
}
/* d[0..n-1] = a[0..n-1] * b[0..n-1] (mod 2^8n) */
static void mul(unsigned char d[], unsigned char a[],
unsigned char b[], int n) {
int i,j;
unsigned char t[MAXSZ] = {0};
for (i=0; i> 8;
}
}
memcpy(d,t,n);
}
/* d[0..n-1] = a[0..n-1] rotated left r bits */
static void rotl(unsigned char d[], unsigned char a[], int r, int n){
int i;
unsigned char t[MAXSZ];
for (i = 0; i < n; i++)
t[i] = (a[(i+r/8)%n] << r%8) | (a[(i+r/8+1)%n] >> (8-r%8));
memcpy(d,t,n);
}
/* Calculate floor(base-2 log of x) for any x>0. */
static int lg2(int x) {
int ans=0;
for ( ; x!=1; x>>=1)
ans++;
return ans;
}
/* Return last nbits of a[0..n-1] as int. Pre: 0 <= nbits <= 16. */
static int bits(unsigned char a[], int n, int nbits) {
int mask = ((1 << nbits) - 1);
if (nbits <= 8) return a[n-1] & mask;
else return ((a[n-2] << 8) | a[n-1]) & mask;
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* A R C 6 A N D A R C 5 F U N C T I O N S
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Preconditions: 0 < w <=1024, w%8==0, 0 <= r < 256, 0 <= b < 256 */
static int setup(void *rkey, int rk_words,
int w, int r, int b, void *key) {
if (w<=0 || w>MAXSZ*8 || w%8!=0 || r<0 || r>255 || b<0 || b>255)
return -1;
else {
unsigned char L[256+MAXSZ], Q[MAXSZ];
unsigned char A[MAXSZ] = {0}, B[MAXSZ] = {0};
unsigned char *rk = (unsigned char *)rkey;
int i, mix_steps, n = w/8, lgw = lg2(w);
Krovetz Expires October 13, 2018 [Page 18]
Internet-Draft RC6 and RC5 Test Vectors April 2018
int l_words = (b==0 ? 1 : (b+n-1)/n);
memcpy(Q, QQ, n); Q[n-1] |= 1; /* Load Q, make odd */
/* Initialize rkey with specified P & Q constant values */
memcpy(rk, PP, n); rk[n-1] |= 1; /* Load P, make odd */
for (i=1; il_words ? rk_words : l_words);
for (i=0; i < mix_steps; i++) {
unsigned rot_amt, ko = i%rk_words*n, lo = i%l_words*n;
add(A,A,B,n); add(A,A,rk+ko,n); rotl(A,A,3,n);
memcpy(rk+ko,A,n);
add(B,B,A,n); rot_amt = bits(B,n,lgw);
add(B,B,L+lo,n); rotl(B,B,rot_amt,n);
memcpy(L+lo,B,n);
if (vectors) { /* Print new values of L and S */
printf(" l[%3d]=", lo/n); pbuf(B,n,0);
}
}
return 0;
}
}
int rc5_setup(void *rkey, int w, int r, int b, void *key) {
return setup(rkey, 2*r+2, w, r, b, key);
}
int rc6_setup(void *rkey, int w, int r, int b, void *key) {
return setup(rkey, 2*r+4, w, r, b, key);
}
void rc5_encrypt(void *rkey, int w, int r, void *pt, void *ct) {
unsigned char A[MAXSZ], B[MAXSZ];
unsigned char *rk = (unsigned char *)rkey,
*p = (unsigned char *)pt,
*c = (unsigned char *)ct;
int rot_amt, i, n = w/8, lgw = lg2(w);
/* Read A and B in byte-reverse order */
for (i=0; i
A.2. C code for RC5 Vector Generation
Substituting the following for the print_vector function of the C
program will generate test vectors for RC5 instead of RC6.
Krovetz Expires October 13, 2018 [Page 22]
Internet-Draft RC6 and RC5 Test Vectors April 2018
```
static void print_vector(int w, int r, int b) {
if (w%8!=0 || w<8 || w/8>MAXSZ || r<0 || r>255 || b<0 || b>255) {
printf("Unsupported w/r/b: %d/%d/%d\n", w, r, b);
} else {
int j, bpw=w/8, bpb=2*bpw; /* bytes per: word and block */
unsigned char *rkey = (unsigned char *)malloc((2*r+2)*bpw);
unsigned char *key = (unsigned char *)malloc(b);
unsigned char *buf = (unsigned char *)malloc(bpb);
for (j=0; j
```**
Author's Address
Ted Krovetz
Computer Science Department
California State University
6000 J Street
Sacramento, CA 95819-6021
USA
Email: ted@krovetz.net
Krovetz Expires October 13, 2018 [Page 23]
**