Random Number Generator

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Hello,

   

I'm looking for a random seed to throw into a simple random number generator algorithm, such as https://en.wikipedia.org/wiki/Xorshift 

   

I was thinking of using the least significant bits of the die temperature (http://www.cypress.com/file/139101/download). Does anyone know if there's a better way to do this, or if Cypress provides some sort of random generator?

   

 

   

Thanks,

   

Alex

0 Likes
20 Replies
Anonymous
Not applicable

Hi,

   

Yes, it is fine. You can use the Die Temp as the seed to your random number generator.

   

Regards,

   

- Madhu Sudhan

0 Likes
Anonymous
Not applicable

Is the Die Temperature-v2.0 only available to PSoC chips and not PRoC chips?

There is an example inn the PSoC Creator 4.0 software called 'DieTemp_BasicTest' that just has the DieTemperature component in it, but the component version is 2.0. In my project (using a PRoC) I am only able to use the 1.0 version. 

0 Likes
Anonymous
Not applicable

Hi,

   

There is no other way of doing this to my knowledge. I don't think that Cypress has any such algorithm for the random generator. The method opted by you is the correct one.

   

 

   

-----------
Regards,
Sarang Kaith
Theappsmiths Reviews

0 Likes
Anonymous
Not applicable

The basis for RNG is to grab random values from the environment that aren't deterministic in the software; Hence, grabbing the die temp, random noise from RF, etc.

   

The die temp is probably the easiest approach. You might be able to get some results from using RSSI() values from the antenna, but I wouldn't bet on its entropy.

0 Likes
Anonymous
Not applicable

Does anyone have any recommendations on the best way to configure the PSoC Components to achieve this? When I was doing it I couldn't get it to vary much.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

As you probably know already:

   

The random number generators deliver a random number sequence. This sequence repeats after its period which depends on the width the generator uses. But the sequence is always the same, only the starting point is chosen with the seed value.

   

Best way to get a random value will be to measure noise. There are a couple of sources for that, diode voltages, resistors, transistors... each of those deliver a noisy signal which you can measure using an ADC with high resolution. The noise will play in the lower bits only, thus the variation is not too much. The resolution for the die temperature measure is something like 7 to 8 bits only, that is not much. Another idea could be to use the ILO frequency which has a tremendous variation of up to 60%, but I didn't test that for repeating values.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

If you want something unique to each module, you could use some mathematical transformation upon the bluetooth address generated for the unit. Ideally, you would mix that with some noise like @Bob mentioned.

   

Since the die temp doesn't vary much, it will take longer/more samples to achieve the same entropy as other methods. If you only use the lowest bit or two, and then append them together, you can achieve larger random numbers from the die temp without needing more hardware/changes. Unfortunately, you will need more time to ensure the bits don't cross-correlate, but still doable if it's a one-time seed.

   

Ex (pseudo code):

   

uint16 seed = 0xAA;

   

for i = 0 to 15

   
    

uint8 sample = ReadDieTemp()

    

if sample % 2

    

        seed = (seed << 1) & 1

    

else

    

        seed = seed << 1

    

end if

   
   

end for

   

//You should now have 16 bits of random bits from the dietemp

   

//Will take more/less time depending on the number of bits that are random for each sample read that you can use "safely"

0 Likes
Anonymous
Not applicable

I was thinking of reading the least significant 2 bits from the die temp multiple times in a row, however each time I read the die temp the least significant bits are still the same or very similar. 

   

Here is an example of the different values I'm getting (see below for the code)

   

 channel A: 000005A9 , mVolts: 725 die temp in C: 20
 channel A: 000005A8 , mVolts: 724 die temp in C: 20
 channel A: 000005A9 , mVolts: 725 die temp in C: 20
 channel A: 000005A8 , mVolts: 724 die temp in C: 20
 channel A: 000005A9 , mVolts: 725 die temp in C: 20
 channel A: 000005A9 , mVolts: 725 die temp in C: 20

   



here is an image of how I have it configured in my top design: https://snag.gy/bWRIZe.jpg

   

In my code I start the scan and enable the interrupt, in my ISR I clear the interrupt flag and set a variable from 0 to 1. In my main.c for(;;) loop I check if that variable is a 1 or a 0. If the variable is a 1 I print out the values and then set the variable to 0 and start the scan again:

   

 

   

  for(;;) {
    if (adc_data_ready) {  // if result is TRUE, then ADC convertion is finished
            adc_data_ready = 0;
      DBG_PRINT_TEXT("\r\n channel A: "); DBG_PRINT_HEX(ADC_GetResult16(0));
      DBG_PRINT_TEXT(", mVolts: "); DBG_PRINT_DEC(ADC_CountsTo_mVolts(0, ADC_GetResult16(0)));
      DBG_PRINT_TEXT(" die temp in C: "); DBG_PRINT_DEC(DieTemp_1_CountsTo_Celsius(ADC_GetResult16(0)));
      ADC_Start();  // starts the ADC component, but does not start an actual ADC scan
      ADC_IRQ_Enable();  // enable ADC interrupts
      ADC_StartConvert();  // starts an ADC scan

   

} // end if adc_data_ready

   

}// end for(;;)

   

 

   

 

   

And here is my ISR code:

   

 

   

CY_ISR (ADC_ISR) {
  uint32 intr_status = ADC_SAR_INTR_MASKED_REG;

   

  if((intr_status & ADC_EOS_MASK) != 0u) {
    adc_data_ready = 1;
    //ADC_SAR_INTR_REG |= ADC_EOS_MASK;  // this clears just the EOS mask
    ADC_SAR_INTR_REG = intr_status;  // this clears all interrupt flags
  }
}

0 Likes
Anonymous
Not applicable

Yeah, I agree with your approach. I would also go with grabbing only the lowest bit/two and combining them to form larger random values. 

   

For example:

   

int bitcount = 0

   

int randomvalue = 0

   

//run the following when getting a new ADC read

   

if bitcount < 32

   

     randomvalue ^= adc_bit << bitcount     //^ is the bit XOR operation, << is the bit shift operation

   

​     bitcount += 1     //increment bitcount so that it circles over the randomvalue variable

   

else

   

     bitcount = 0

   

endif

   

 

   

//randomvalue should hold a changing/randomizing value

   

//grabbing it some random number of iterations of the ADC should yield more or less random values depending on how long you wait between interations.

   

Edit: If you want some way to test how random the values are, you can do an arithmetic mean on the randomvalues coming out; The average of all of the values generated from it should be visibly different values with an average around 50% 1's and 50% 0's.

0 Likes
Anonymous
Not applicable

The ADC/DieTemp component configuration I have right now often doesn't provide any randomness. Most of the time when I run my code the output value stays exactly the same. The output that I copied/pasted earlier was some of the best random outputs I was able to find while looking through my console output. 

   

Do you have any suggestions on how to configure it differently to measure more noise?

0 Likes
Anonymous
Not applicable

Hmmmmm; Besides increasing the sensitivity of the ADC from the dietemp, I'm not sure there is much else you can do to increase the temperature fluctuations of the chip. Some other options might be to read ADC values off of some input pins that are floating, and see what kind of arbitrary values you can get from it.

   

Another option would be to implement a simple timer, and then pull values from the timer at events/based on some other signalling. This has the fallacy that any timing-correlation between the events to read the timer will result in very similar times pulled from the timer, but is relatively simple and doesn't require external hardware.

   

Another option, if you are processing data (SPI, I2C, BLE, etc) Any communications data you receive will contain some varying data; For example, reading an arbitrary byte from a SPI bus as it communicates would give values distributed based on the average SPI bus values.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Depending on the usage of your random seed there are some other practical ways:

   

When you just need different seeds for each of your devices you can use the unique device ID which is a 64 bit value.

   

When you need the seed after a connection has been made a good value would be the number of µs it took to establish the connection.

   

When you maintain an RTC on your board the unix time would be a good value.

   

Otherwise a good approach is to measure a noisy analog signal (e.pratt: do not use a floating pin, that may cause other dangerous trouble).

   

An ADC with a resolution of 12 bits will provide you with a 800µV resolution which will not be sufficient to isolate noise from a diode or transistor.

   

When your device has got an accelerometer or a digital compass the source for random data is easy.

   

A question: What do you want to do with the random number sequence after the generator was started with your seed??

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Yeah, reading from a floating pin can have unintended things happen 😞

   

But essentially, just reading from a different noise source than the die temp.

   

It might vary between chipsets, but I've been able to use the ADC on a floating pin to get random values, although that was on a microchip and not a cypress chipset.

0 Likes
Anonymous
Not applicable

I want to create a random number to use as a private authorization token that the phone would read and use in subsequent connections. Although now that I think about it....I don't think there is a risk in having the phone generate a random number and send that to my BLE device. Although, if I needed two BLE devices to talk to each other using a token without a phone I don't know if that would ever work.  

   

This random variable would be used to seed the random number and generate new random numbers, which could also be mixed with the seed to create a new seed to make it even harder to track.

   

I was thinking that the device ID might be good, but isn't that just determined from the MAC Address? 

0 Likes
Anonymous
Not applicable

There are numbers specific to each chip that are written by the factory at manufacturing time to identify each chip's lot, die, etc. Those numbers should be unique. (They might be used to create the device address, but I am not sure on the specifics.)

Try the function that @Bob mentioned. And as far as authorization tokens, if you are thinking you can just send the token to each BLE when you set it up with your phone, then you could potentially also tell them the tokens for each other as well.

0 Likes
Anonymous
Not applicable

Bob, what kind of other "dangerous troubles" can it cause measuring a floating pin? Other than of course if someone grounds it. But if there is a physical access to the MCU, any external means of random generation can be attacked, as well the Die Temperature. What am I overlooking here?

0 Likes
Anonymous
Not applicable

Having a floating pin leaves the issue of the pin being charged to one direction or the other. Some digital circuits might have issues with a floating pin affecting the internals depending on how the signal is routed/connected to the floating pin. Floating pins are generally avoided, as logic gates don't interact well with them, and analog readings/measurements will be biased towards all positive/negative depending on electric charge on the floating pin.

One method of having the floating pin for analog measurements would be to have a sufficiently large resistor-divider bridge from Vpp to Vss with the "floating" pin measuring in the middle. If the resistor values are chosen to be large enough, the measurements will fluctuate with electronic/physics noise, but won't get stuck with a biased reading for too long of a period.

This would of course still be susceptible to physical attack, but the whole chip will be vulnerable to physical attack regardless, with techniques and methods generally only mitigating the level of skill and time needed to compromise the device.

0 Likes

Due to stray voltages a latch-up may occur with floating analog pins.

I have a different idea: When you use BLE to make a connection you can measure the time in µs to get an answer (needs a TCPWM). That value will be random and is probably not reproducable.

Bob

Anonymous
Not applicable

Although, it means you need to reconnect for every RNG you want. Provided the assumption of random connection times holds

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

There is a unique 64 bit identifier which is provided by Cypress. Check the void CyGetUniqueID(uint32* uniqueId) API

   

 

   

Bob

0 Likes