Sign in to follow this  

Weird hex values from std::cout.

Recommended Posts

I'm testing a cryptographic random number generator library based on Blum Blum Shub. The library I found seems to work, but the test program I wrote does not.

Here is the test program code:
#include <iostream>
#include <iomanip>

#include <mpir.h>
#include <gmpbbs.h>

int main()
{
	long		i;
	rndbbs_t	*test_random;
	char		*rand_val;

	//Excuse the mix of C and C++. The RNG library is written in C. Soon to be remedied...

	test_random = rndbbs_new();

	rndbbs_gen_blumint(test_random,2048);
	rndbbs_gen_x(test_random);

	rand_val = new char[16];
	for (i = 0; i < 16; ++i)
		rand_val[i] = (char)0;

	rand_val = rndbbs_randbytes(test_random,16);

	std::cout.setf(std::ios::hex,std::ios::basefield);
	std::cout.setf(std::ios::uppercase);
	for(i = 0;i < 16;++i)
		std::cout << std::setfill('0') << std::setw(2) << static_cast<unsigned int>(rand_val[i]) << " ";

	delete [] rand_val;
	rndbbs_destroy(test_random);

	while(1);
	return 0;
}
This is the output:

error.jpg

The leading "FFFFFF" on several of the printed bytes are not generated by the RNG.

The output should read: "47 0F 8E 9F 33 1A B0 A9 EB 79 E4 BC 8A 25 94 9A".

I have never seen this before and cannot find any solutions through Google. Any idea why this is happening? Edited by MarkS

Share this post


Link to post
Share on other sites
Never mind. I fixed it.

Changing this:

std::cout << std::setfill('0') << std::setw(2) << static_cast<unsigned int>(rand_val[i]) << " ";

to this:

std::cout << std::setfill('0') << std::setw(2) << static_cast<unsigned char>(rand_val[i]) + 0 << " ";

did the trick.

[edit] Posted before I refreshed the page. Thanks guys! Edited by MarkS

Share this post


Link to post
Share on other sites

std::cout << std::setfill('0') << std::setw(2) << static_cast<unsigned char>(rand_val[i]) + 0 << " ";

By adding a signed in constant you're implicitly converting the sign-extended explictly-cast unsigned int implicitly widened from a (maybe signed, maybe not, it depends) char value in your array into a signed int, which exceeds the range of the int and invokes undefined behaviour.

 

I'd still recommend you use the right data type in the first place (unsigned char to hold a byte) rather than simply plaster some undefined behaviour into your program in the hopes that it will not simply reformat your hard drive.

 

I mean, it's just a thought, but I'd steer away from undefined behaviour if I were you.

Share this post


Link to post
Share on other sites
Bregma, are you saying that casting a char to unsigned char can invoke undefined behavior?

Section "4.7 Integral conversions" of the C++14 standard says:

If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source
integer (modulo 2^n where n is the number of bits used to represent the unsigned type).



This sounds to me like the conversion is just dandy. But I find the language in the standard pretty confusing, so perhaps I am missing something? Edited by Álvaro

Share this post


Link to post
Share on other sites

Bregma, are you saying that casting a char to unsigned char can invoke undefined behavior?

Ah, I'm wrong.  It's implementation-defined behaviour.  He's converting it from char to unsigned char and then widening it to (signed) int.  It's well-defined, just not reliable behaviour.  The difference is that undefined behaviour can do anything at all, whereas implementation-defined behaviour is restricted to given some valid integral result (which depends on the vendor and hardware architecture) or crashing.

 

I still stand by my statement that if he had used unsigned char to store unsigned bytes, there would have been no problem and no need for casting about.

Share this post


Link to post
Share on other sites

I'd still recommend you use the right data type in the first place (unsigned char to hold a byte) rather than simply plaster some undefined behaviour into your program in the hopes that it will not simply reformat your hard drive.


The library's function returns a char array, so that's not entirely up to me. I am rewriting the library to remove the dependency on C and use C++, so that can and will change.

Share this post


Link to post
Share on other sites

Any reason not to use std::random_device? Are you working with machines that don't have randomness generators?


I'm working on a test bed for an application that will eventually run on an embedded microcontroller. Everything must be hand rolled.

Share this post


Link to post
Share on other sites

Good times.


Actually, I was just looking at an Atmel microcontroller tonight based on the ARM Cortex-A5 architecture that has built in hardware-based encryption and a cryptographically secure random number generator. Hmmm....

Share this post


Link to post
Share on other sites

 

Good times.


Actually, I was just looking at an Atmel microcontroller tonight based on the ARM Cortex-A5 architecture that has built in hardware-based encryption and a cryptographically secure random number generator. Hmmm....

 

Yeah, been playing with a LoPy my self, has the same plus a MicroPython interpreter, kinda fun actually.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this