1
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

typedef unsigned long int WORD;  /* Should be 32-bit = 4 bytes        */
#define w         32             /* word size in bits                 */
#define r         12             /* number of rounds                  */
#define b         16             /* number of bytes in key            */
#define c          4             /* number words in key               */
                                 /* c = max(1,ceil(8*b/w))            */
#define t         26             /* size of table S = 2*(r+1) words   */
WORD S [t],L[c];                        /* expanded key table         */
WORD P = 0xb7e15163, Q = 0x9e3779b9;    /* magic constants            */
/* Rotation operators. x must be unsigned, to get logical right shift*/
#define ROTL(x,y) (((x)<<(y&(w-1))) | ((x)>>(w-(y&(w-1)))))
#define ROTR(x,y) (((x)>>(y&(w-1))) | ((x)<<(w-(y&(w-1)))))    

void RC5_DECRYPT(WORD *ct, WORD *pt) /* 2 WORD input ct/output pt     */
{
    WORD i, B = ct[1], A = ct[0];
    for (i = r; i > 0; i--)
    {
        B = ROTR(B - S[2 * i + 1], A)^A;
        A = ROTR(A - S[2 * i], B)^B;
    }
    pt[1] = B - S[1]; pt[0] = A - S[0];
}

void RC5_SETUP(unsigned char *K) /* secret input key K 0...b-1]       */
{
    WORD i, j, k, u = w/8, A, B, L[c];

    /* Initialize L, then S, then mix key into S */
    for (i = b - 1, L[c - 1] = 0; i != -1; i--) 
        L[i/u] = (L[i/u] << 8) + K[i];

    for (S[0] = P, i = 1; i < t; i++) 
        S[i] = S[i - 1] + Q;

    for (A=B=i=j=k=0; k<3*t; k++,i=(i+1)%t,j=(j+1)%c)      /* 3*t > 3*c */
    {
        A = S[i] = ROTL(S [i]+(A+B),3);
        B = L[j] = ROTL(L[j]+(A+B),(A+B));
    }
}

void printword(WORD A)
{
    WORD k;
    for (k=0 ;k<w; k+=8) 
        printf("%02.2lX",(A>>k)&0xFF);
}

int main()
{ 
    WORD i, j, k, pt [2], pt2 [2], ct [2] = {0,0};
    unsigned char key[b];
    ofstream out("cpt.txt");
    ifstream in("key.txt");

    if (!in)
    { 
        cout << "Cannot open file.\n"; 
        return 1; 
    }  

    if (!out)
    { 
        cout << "Cannot open file.\n"; 
        return 1; 
    }  

    key="111111000001111";

    RC5_SETUP(key);
    ct[0]=2185970173;
    ct[1]=3384368406;

    for (i=1; i<2; i++)
    {
         RC5_DECRYPT(ct,pt2);
         printf("\n   plaintext "); 
         printword(pt[0]); 
         printword(pt[1]);
    }

    return 0;
}

When I compile this code i get two warnings and also an error saying that I cant assign a char value to my character array. Why is that?

6
  • I love this comment /* magic constants */ Commented May 3, 2010 at 22:35
  • He's obviously copied this code from elsewhere and is trying to modify it, without really understanding it. No shame in that, either. Commented May 3, 2010 at 22:40
  • This code is a cut-n-paste (or pretty dang close) to what was published in the original RC5 description by Ron Rivest (see the Appendix of "The RC5 Encryption Algorithm" paper: people.csail.mit.edu/rivest/Rivest-rc5rev.pdf). I think Rivest might be described as a mathematician rather than an engineer. Commented May 3, 2010 at 22:44
  • @Michael Neither mathematicians nor engineers can program, in my somewhat extensive experience with both, though never with as some one as well-known as Rivest. Still, I think I would have told him to get a clue. Commented May 3, 2010 at 22:53
  • 1
    @Neil, in my experience, mathematicians, engineers and physicists often make far superior developers and architects as they tend to (but not always) understand the problems at hand better than a comp scientist. They tend to have better inherent design and analysis skills than a CS specialist. I've also observed better reach-out to standard libraries than immediately suffering from NIHS. In fact, one of the best programmers I've ever known came from a philosophy background. The above code aside, your blanket statement is rather bigoted and unjustified in this context. Commented May 4, 2010 at 0:02

3 Answers 3

2

Change:

key="111111000001111";

to

strncpy((char *)key, "111111000001111", sizeof(key));

Sign up to request clarification or add additional context in comments.

2 Comments

still the error remains .. now the error is rcdec.cpp:66: error: invalid conversion from ‘unsigned char*’ to ‘char*’ rcdec.cpp:66: error: initializing argument 1 of ‘char* strcpy(char*, const char*)’
@mekasperasky: OK - it sounds like you're compiling with fairly strict options - solution edited above to take this into account and also to avoid an overrun of the key buffer.
1

You can't set the value of the key array using a statement like:

key = "111111000001111";

You'll need to use strcpy(), or memcpy(), or something like (the non-standard, but arguably less error prone) strlcpy().

However, you can initialize it like so:

unsigned char key[b] = "111111000001111";

But note that as long as the string is one character less than the dimension you'll get a null terminated string, but if the number of characters is equal to the dimension you'll get an array of characters that is not null terminated, without an error (though you might get a warning). In C++ that scenario should generate an error. See Why doesn't the compiler detect out-of-bounds in string constant initialization? for details.

Comments

0

Because key = "111111000001111"; is not valid in any way. You cannot assign values to an array this way in either C or C++. Try using strcpy or memcpy with the appropriate casts.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.