Sirac
Sirac

Reputation: 693

creating random int by rand

I want to write a cryptography application and need a function to create an iv. to create that iv i want to use rand() (even if thats not secure, i want to rewrite most parts of the code later anyway). That leads me to my problem: rand() does only return values from 0 to RAND_MAX (on my machine RAND_MAX is 32767), and i don't know if i could use code like this if RAND_MAX >= 65535:

void generate_iv(unsigned char* char_buf, int len){
    union { //treat char_buf like a short_buf
        unsigned char* char_buf;
        unsigned short* short_buf;
    }
    int i;
    for (i = 0; i < len / 2; i++){ //fill short_buf with random values
        short_buf[i] = (unsigned short) rand();
    }
    if (len & 0x01){ //could not fill char_buf with 2-byte short values completely
        char_buf[len - 1] = (unsigned char) rand();
    }
}

Of course this will compile easily on every machine, but it wont work on machines where RAND_MAX < 65535, because then the function does not fill every bit.

Code that would always work is:

void generate_iv(unsigned char* char_buf, int len){
    int i;
    for (i = 0; i < len; i++){
        char_buf = (unsigned char) rand();
    }
}

This code should work without problems, but it is not effective as the code above. My question is: Is there any optimum beetween effiency and portability in this case and is there maybe a more secury way (which could be easy to implement) to produce random numbers or a way to get random numbers with a constant size?

Upvotes: 0

Views: 210

Answers (1)

barak manos
barak manos

Reputation: 30136

As you mention, rand() is not secured, so I will refer to the problem at hand regardless of that issue.

Given that rand() generates a 15-bit number, and you want a 16-bit number, you can simply do:

int a = rand();
int b = rand()&1;
return a | (b<<15);

Or generally, given that RAND_MAX < 0xFFFF and that RAND_MAX+1 is a power of 2:

int len = BIT_LEN(RAND_MAX);
int mask = (1<<(16-len))-1;
int a = rand();
int b = rand()&mask;
return a | (b<<len);

BTW, don't forget to seed the RNG with some random input at the beginning of your program, e.g.:

srand((unsigned int)time(NULL));

Upvotes: 2

Related Questions