[HARDWARE] Working on a VHDL design

John Price linux-guru at gcfl.net
Thu Jan 20 11:35:09 EST 2000


Hey folks.  I've been on and off the list for a while...

Now I'm taking a VHDL class (masters in CPE) and I have to do a project,
so I've been looking at an RC5 engine.

I can't find the rc5 C code that is referenced by Paul Campbell's Verilog
design, and I can't read Verilog anyway, so I've dug into the specs, and
written my own C program to do RC5 in an optimal way.

What I would like is for you folks to look at it and tell me if there is
other optimizations that I am missing, or point me to any sources for
reducing the RC5 algorithm.

I'm also interested in any other hardware implementations.

I've studied Paul Campbell's design, but I can't see how it works (it
doesn't seem to follow the algorithm), but as I said before, I don't know
Verilog, so excuse my ignorance.

Anyway, my code it attached.  All my code will also be placed on my web
page at http://www.gcfl.net/projects/rc5/ .

Thanx,
John

-- 
John Price <linux-guru at gcfl.net>

AIM ID "GCFL Owner"
ICQ 24079586

-----BEGIN GEEK CODE BLOCK-----
Version: 3.21 (http://www.geekcode.com to translate)
GE d-> s++:+ a C++ UL++++ P+ L+++> E- W+++ N+ o+ K- W--- O- M-- V--
PS-- PE+ Y+ PGP++> t+ 5 X++ R- tv+ b+ DI+ D+ G+ e++> h r+++ y+++
------END GEEK CODE BLOCK------

-------------- next part --------------
/*
 rc5test.c version 1.0

 This is RC5-32/12/8
 32-bit word size, 12 rounds, 8*8=64-bit key

  Copyright (C) 2000, John Price <linux-guru at gcfl.net>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation version 2.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; see the file COPYING.  If not, write to
  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.

 */


/*
 This code is available at http://www.gcfl.net/projects/rc5/

 Refer to http://www.rsa.com/rsalabs/97challenge/html/contests.html
 for information about the RC5 contests.

 */


#include <stdio.h>
#include <stdlib.h>
#include <time.h>


/* Define this to use practice values */
/* #define USE_PRACTICE_VALUES  */

/* Define this to continuously test randomly selected keys */
#define TEST_RANDOM_KEYS

/* Define this to have the program display the key rate every second */
#define SHOWTIME


#define ULONG unsigned long  /* 32-bit unsigned */

#define ROUNDS 12
#define S_SIZE (2*(ROUNDS+1))

/************************************************************
 The following is the practice values to test the program
 ************************************************************/
#ifdef USE_PRACTICE_VALUES
/* This is the practice KEY              */
#define KEY0 0x9F1BE582U
#define KEY1 0xF918C79CU

/* This is the practice IV               */
#define IV0  0xF839A5D9U
#define IV1  0xC41F78C1U

/* This is the practice plain text       */
#define PLAIN0 0x20656854U
#define PLAIN1 0x6E6B6E75U

/* This is the practice Cipher text      */
#define C0 0xB74BE041U
#define C1 0x496DEF29U

#else

/************************************************************
 The following is the REAL contest values
 ************************************************************/
/* This is the practice KEY              */
#define KEY0 0x9F1BE582U
#define KEY1 0xF918C79CU

/* This is the REAL contest IV           */
#define IV0  0xD5D5CE79U
#define IV1  0xFCEA7550U

/* This is the REAL contest plain text   */
#define PLAIN0 0x20656854U
#define PLAIN1 0x6E6B6E75U

/* This is the REAL contest Cipher text  */
#define C0 0x550155BFU
#define C1 0x49F226DCU

#endif


/************************************************************
 You should not have to change anything below here.
 ************************************************************/

#define P0 (PLAIN0 ^ IV0)
#define P1 (PLAIN1 ^ IV1)

#define P 0xB7E15163U
#define Q 0x9E3779B9U

static ULONG key0, key1;


/*#define ROL(a,b) ((a << (b & 0x1F)) | (a >> (0x20-(b & 0x1F))))  */
/*#define ROR(a,b) ((a >> (b & 0x1F)) | (a << (0x20-(b & 0x1F))))  */

/* This is a 32-bit roll left function. */
static ULONG ROL(ULONG a, ULONG b)
{
  int c = b & 0x1F;

  return (a << c) | (a >> (0x20-c));
}

/* This is a 32-bit roll left 3-bits function. */
static ULONG ROL3(ULONG a)
{
  return (a << 3) | (a >> 0x1D);
}

/* This is a 32-bit roll right function. */
static ULONG ROR(ULONG a, ULONG b)
{
  int c = b & 0x1F;

  return (a >> c) | (a << (0x20-c));
}

#define SINIT(n) (P+Q*n)

static int CheckAKey(void)
{
  ULONG S00,S01,S02,S03,S04,S05,S06,S07,S08,S09;
  ULONG S10,S11,S12,S13,S14,S15,S16,S17,S18,S19;
  ULONG S20,S21,S22,S23,S24,S25;
  ULONG L0,L1;
  ULONG t;

/*  S00 = ROL3(SINIT(0));    */
/*  L0 = ROL(key0+S00,S00);  */

  S00 = 0xBF0A8B1D;
  L0 = ROL(key0+0xBF0A8B1D,29);

  S01 = ROL3(SINIT(1)+0xBF0A8B1D+L0);
  t = S01+L0;
  L1 = ROL(key1+t,t);

  S02 = ROL3(SINIT(2)+S01+L1);
  t = S02+L1;
  L0 = ROL(L0+t,t);

  S03 = ROL3(SINIT(3)+S02+L0);
  t = S03+L0;
  L1 = ROL(L1+t,t);

  S04 = ROL3(SINIT(4)+S03+L1);
  t = S04+L1;
  L0 = ROL(L0+t,t);

  S05 = ROL3(SINIT(5)+S04+L0);
  t = S05+L0;
  L1 = ROL(L1+t,t);

  S06 = ROL3(SINIT(6)+S05+L1);
  t = S06+L1;
  L0 = ROL(L0+t,t);

  S07 = ROL3(SINIT(7)+S06+L0);
  t = S07+L0;
  L1 = ROL(L1+t,t);

  S08 = ROL3(SINIT(8)+S07+L1);
  t = S08+L1;
  L0 = ROL(L0+t,t);

  S09 = ROL3(SINIT(9)+S08+L0);
  t = S09+L0;
  L1 = ROL(L1+t,t);

  S10 = ROL3(SINIT(10)+S09+L1);
  t = S10+L1;
  L0 = ROL(L0+t,t);

  S11 = ROL3(SINIT(11)+S10+L0);
  t = S11+L0;
  L1 = ROL(L1+t,t);

  S12 = ROL3(SINIT(12)+S11+L1);
  t = S12+L1;
  L0 = ROL(L0+t,t);

  S13 = ROL3(SINIT(13)+S12+L0);
  t = S13+L0;
  L1 = ROL(L1+t,t);

  S14 = ROL3(SINIT(14)+S13+L1);
  t = S14+L1;
  L0 = ROL(L0+t,t);

  S15 = ROL3(SINIT(15)+S14+L0);
  t = S15+L0;
  L1 = ROL(L1+t,t);

  S16 = ROL3(SINIT(16)+S15+L1);
  t = S16+L1;
  L0 = ROL(L0+t,t);

  S17 = ROL3(SINIT(17)+S16+L0);
  t = S17+L0;
  L1 = ROL(L1+t,t);

  S18 = ROL3(SINIT(18)+S17+L1);
  t = S18+L1;
  L0 = ROL(L0+t,t);

  S19 = ROL3(SINIT(19)+S18+L0);
  t = S19+L0;
  L1 = ROL(L1+t,t);

  S20 = ROL3(SINIT(20)+S19+L1);
  t = S20+L1;
  L0 = ROL(L0+t,t);

  S21 = ROL3(SINIT(21)+S20+L0);
  t = S21+L0;
  L1 = ROL(L1+t,t);

  S22 = ROL3(SINIT(22)+S21+L1);
  t = S22+L1;
  L0 = ROL(L0+t,t);

  S23 = ROL3(SINIT(23)+S22+L0);
  t = S23+L0;
  L1 = ROL(L1+t,t);

  S24 = ROL3(SINIT(24)+S23+L1);
  t = S24+L1;
  L0 = ROL(L0+t,t);

  S25 = ROL3(SINIT(25)+S24+L0);
  t = S25+L0;
  L1 = ROL(L1+t,t);


  S00 = ROL3(0xBF0A8B1D+S25+L1);
  t = S00+L1;
  L0 = ROL(L0+t,t);

  S01 = ROL3(S01+S00+L0);
  t = S01+L0;
  L1 = ROL(L1+t,t);

  S02 = ROL3(S02+S01+L1);
  t = S02+L1;
  L0 = ROL(L0+t,t);

  S03 = ROL3(S03+S02+L0);
  t = S03+L0;
  L1 = ROL(L1+t,t);

  S04 = ROL3(S04+S03+L1);
  t = S04+L1;
  L0 = ROL(L0+t,t);

  S05 = ROL3(S05+S04+L0);
  t = S05+L0;
  L1 = ROL(L1+t,t);

  S06 = ROL3(S06+S05+L1);
  t = S06+L1;
  L0 = ROL(L0+t,t);

  S07 = ROL3(S07+S06+L0);
  t = S07+L0;
  L1 = ROL(L1+t,t);

  S08 = ROL3(S08+S07+L1);
  t = S08+L1;
  L0 = ROL(L0+t,t);

  S09 = ROL3(S09+S08+L0);
  t = S09+L0;
  L1 = ROL(L1+t,t);

  S10 = ROL3(S10+S09+L1);
  t = S10+L1;
  L0 = ROL(L0+t,t);

  S11 = ROL3(S11+S10+L0);
  t = S11+L0;
  L1 = ROL(L1+t,t);

  S12 = ROL3(S12+S11+L1);
  t = S12+L1;
  L0 = ROL(L0+t,t);

  S13 = ROL3(S13+S12+L0);
  t = S13+L0;
  L1 = ROL(L1+t,t);

  S14 = ROL3(S14+S13+L1);
  t = S14+L1;
  L0 = ROL(L0+t,t);

  S15 = ROL3(S15+S14+L0);
  t = S15+L0;
  L1 = ROL(L1+t,t);

  S16 = ROL3(S16+S15+L1);
  t = S16+L1;
  L0 = ROL(L0+t,t);

  S17 = ROL3(S17+S16+L0);
  t = S17+L0;
  L1 = ROL(L1+t,t);

  S18 = ROL3(S18+S17+L1);
  t = S18+L1;
  L0 = ROL(L0+t,t);

  S19 = ROL3(S19+S18+L0);
  t = S19+L0;
  L1 = ROL(L1+t,t);

  S20 = ROL3(S20+S19+L1);
  t = S20+L1;
  L0 = ROL(L0+t,t);

  S21 = ROL3(S21+S20+L0);
  t = S21+L0;
  L1 = ROL(L1+t,t);

  S22 = ROL3(S22+S21+L1);
  t = S22+L1;
  L0 = ROL(L0+t,t);

  S23 = ROL3(S23+S22+L0);
  t = S23+L0;
  L1 = ROL(L1+t,t);

  S24 = ROL3(S24+S23+L1);
  t = S24+L1;
  L0 = ROL(L0+t,t);

  S25 = ROL3(S25+S24+L0);
  t = S25+L0;
  L1 = ROL(L1+t,t);


  S00 = ROL3(S00+S25+L1);
  t = S00+L1;
  L0 = ROL(L0+t,t);

  S01 = ROL3(S01+S00+L0);
  t = S01+L0;
  L1 = ROL(L1+t,t);

  S02 = ROL3(S02+S01+L1);
  t = S02+L1;
  L0 = ROL(L0+t,t);

  S03 = ROL3(S03+S02+L0);
  t = S03+L0;
  L1 = ROL(L1+t,t);

  S04 = ROL3(S04+S03+L1);
  t = S04+L1;
  L0 = ROL(L0+t,t);

  S05 = ROL3(S05+S04+L0);
  t = S05+L0;
  L1 = ROL(L1+t,t);

  S06 = ROL3(S06+S05+L1);
  t = S06+L1;
  L0 = ROL(L0+t,t);

  S07 = ROL3(S07+S06+L0);
  t = S07+L0;
  L1 = ROL(L1+t,t);

  S08 = ROL3(S08+S07+L1);
  t = S08+L1;
  L0 = ROL(L0+t,t);

  S09 = ROL3(S09+S08+L0);
  t = S09+L0;
  L1 = ROL(L1+t,t);

  S10 = ROL3(S10+S09+L1);
  t = S10+L1;
  L0 = ROL(L0+t,t);

  S11 = ROL3(S11+S10+L0);
  t = S11+L0;
  L1 = ROL(L1+t,t);

  S12 = ROL3(S12+S11+L1);
  t = S12+L1;
  L0 = ROL(L0+t,t);

  S13 = ROL3(S13+S12+L0);
  t = S13+L0;
  L1 = ROL(L1+t,t);

  S14 = ROL3(S14+S13+L1);
  t = S14+L1;
  L0 = ROL(L0+t,t);

  S15 = ROL3(S15+S14+L0);
  t = S15+L0;
  L1 = ROL(L1+t,t);

  S16 = ROL3(S16+S15+L1);
  t = S16+L1;
  L0 = ROL(L0+t,t);

  S17 = ROL3(S17+S16+L0);
  t = S17+L0;
  L1 = ROL(L1+t,t);

  S18 = ROL3(S18+S17+L1);
  t = S18+L1;
  L0 = ROL(L0+t,t);

  S19 = ROL3(S19+S18+L0);
  t = S19+L0;
  L1 = ROL(L1+t,t);

  S20 = ROL3(S20+S19+L1);
  t = S20+L1;
  L0 = ROL(L0+t,t);

  S21 = ROL3(S21+S20+L0);
  t = S21+L0;
  L1 = ROL(L1+t,t);

  S22 = ROL3(S22+S21+L1);
  t = S22+L1;
  L0 = ROL(L0+t,t);

  S23 = ROL3(S23+S22+L0);
  t = S23+L0;
  L1 = ROL(L1+t,t);

  S24 = ROL3(S24+S23+L1);
  t = S24+L1;
  L0 = ROL(L0+t,t);

  S25 = ROL3(S25+S24+L0);



  L1 = ROR((C1 - S25),C0) ^ C0;
  L0 = ROR((C0 - S24),L1) ^ L1;

  L1 = ROR((L1 - S23),L0) ^ L0;
  L0 = ROR((L0 - S22),L1) ^ L1;

  L1 = ROR((L1 - S21),L0) ^ L0;
  L0 = ROR((L0 - S20),L1) ^ L1;

  L1 = ROR((L1 - S19),L0) ^ L0;
  L0 = ROR((L0 - S18),L1) ^ L1;

  L1 = ROR((L1 - S17),L0) ^ L0;
  L0 = ROR((L0 - S16),L1) ^ L1;

  L1 = ROR((L1 - S15),L0) ^ L0;
  L0 = ROR((L0 - S14),L1) ^ L1;

  L1 = ROR((L1 - S13),L0) ^ L0;
  L0 = ROR((L0 - S12),L1) ^ L1;

  L1 = ROR((L1 - S11),L0) ^ L0;
  L0 = ROR((L0 - S10),L1) ^ L1;

  L1 = ROR((L1 - S09),L0) ^ L0;
  L0 = ROR((L0 - S08),L1) ^ L1;

  L1 = ROR((L1 - S07),L0) ^ L0;
  L0 = ROR((L0 - S06),L1) ^ L1;

  L1 = ROR((L1 - S05),L0) ^ L0;
  L0 = ROR((L0 - S04),L1) ^ L1;

  L1 = ROR((L1 - S03),L0) ^ L0;
  L0 = ROR((L0 - S02),L1) ^ L1;

  L1 -= S01;
  L0 -= S00;

/* when these are equal, we have found the key.  */
/*  printf("A=%08lX  P0=%08lX\n",L0,P0);         */
/*  printf("B=%08lX  P1=%08lX\n",L1,P1);         */

  return (L0 == P0) && (L1 == P1);
}


int main(void)
{
  ULONG count=0;
  time_t t;
  int x;

#ifndef TEST_RANDOM_KEYS
  key1 = KEY1 & 0xFF000000U;
  key0 = KEY0;
#endif

#ifdef __MSDOS__
  srand(time(NULL));
#else
  srandom(time(NULL));
#endif


#ifdef SHOWTIME
  t = time(NULL);
#endif
  printf("RC5test written by John Price ["__DATE__"]\n\n");
  while (1)
  {
#ifdef SHOWTIME
    if (t != time(NULL))
    {
      t = time(NULL);
      printf("%08lX %08lX   ",key0,key1);
      printf("%u keys/sec\n",count);
      count = 0;
    }
#endif

    for (x=1000;x;x--)
    {
#ifdef TEST_RANDOM_KEYS
      key0 = rand();
      key1 = rand();
#else
      key1++;
#endif
/*      printf("%08lX %08lX\r",key0,key1);   */
      count++;
      if (CheckAKey())
      {
        printf("Key found!\n");
        printf("KEY = %08lX %08lX\n", key0, key1);
        return 0;
      }
#ifdef TEST_RANDOM_KEYS
      count++;
      {
        ULONG temp = key0;

        key0 = key1;
        key1 = temp;
      }
/*      printf("%08lX %08lX\r",key0,key1);   */
      if (CheckAKey())
      {
        printf("Key found!\n");
        printf("KEY = %08lX %08lX\n", key0, key1);
        return 0;
      }
#endif
    }
  }

  return 0;
}



More information about the Hardware mailing list