travisgoodspeed / goodwatch

Replacement board for Casio Calculator Watches using the CC430F6147
504 stars 55 forks source link

Adds a RNG based on clock differentials used to seed PRNG and a demo passphrase app #63

Closed ea closed 6 years ago

ea commented 6 years ago

Ever since Travis shared the idea for this watch, I wanted it to generate words for passphrases not unlike diceware.

The PRNG is there, but needed an actual random seed. As it is currently, RNG is used to seed the PRNG at init time. RNG is based on SLAA338 application report, so somebody more knowledgeable with this particular cc430 should take a look to see if I haven't messed something up with clocks and timers. It should be restoring everything properly though.

As far as I could test it, the RNG passes the FIPS test outlined in the SLAA338 (using the same code TI provided).

Second part of this pull request is Diceware app. It's real simple, just chooses a random word from an array. It's incomplete though, as the dictionary is small. Actual diceware dictionary is about 65k so it will have to go somewhere else. That's an obvious limit to this being practical, but I thought I'd share it now in case somebody else needs the RNG.

Cheers, Aleks

travisgoodspeed commented 6 years ago

Patching three bugs and then merging. We should probably add a command to export random samples for external testing.

const char * const word_array[] = {
ea commented 6 years ago

Didn't know about .text vs .data requirement here.

dice.c calling rand() was actually intended, as true_rand is supposed to be used just as a seed for stdlib's rand(). In main.c, I seed the PRNG using true_rand(), so subsequent calls to rand() are actually random at each run.

That being said, I didn't check which PRNG algorithm rand() uses, I was just weary of using true_rand in an app because it messes with timers and clocks and interrupts.

travisgoodspeed commented 6 years ago

Yeah, the .text/.data thing is a bit weird and unique to microcontrollers with so little memory. The jist is that anything in .text only costs us Flash memory, but anything in .data takes both Flash and RAM. (.bss and .noinit only cost RAM, of course.)

rand() is an LFSR whose 16-bits of state are set by srand().

.text:0000CB50 ; =============== S U B R O U T I N E =======================================
.text:0000CB50
.text:0000CB50
.text:0000CB50                 .def rand
.text:0000CB50 rand:
.text:0000CB50                 mov.w   #4E6Dh, R12
.text:0000CB54                 mov.w   #41C6h, R13
.text:0000CB58                 mov.w   &next, R14
.text:0000CB5C                 mov.w   &word_1C1E, R15
.text:0000CB60                 call    #__mulsi3
.text:0000CB64                 add.w   #3039h, R14
.text:0000CB68                 adc.w   R15
.text:0000CB6A                 mov.w   R14, &next
.text:0000CB6E                 mov.w   R15, &word_1C1E
.text:0000CB72                 mov.w   R14, R15
.text:0000CB74                 ret
.text:0000CB74 ; End of function rand
.text:0000CB74
.text:0000CB76
.text:0000CB76 ; =============== S U B R O U T I N E =======================================
.text:0000CB76
.text:0000CB76
.text:0000CB76                 .def srand
.text:0000CB76 srand:                                  ; CODE XREF: main+18p
.text:0000CB76                                         ; DATA XREF: main+18o
.text:0000CB76                 mov.w   R15, &next
.text:0000CB7A                 clr.w   &word_1C1E
.text:0000CB7E                 ret
.text:0000CB7E ; End of function srand

I'm reasonably confident that true_rand() won't cause a catastrophe with its clock meddling, but it wouldn't hurt to take a second look. Should I open an issue for that?

Cheers from Pizza Rat City, --Travis

ea commented 6 years ago

Ah, I see, yeah that's too small of a state space even for this silly application. I'll do some more testing of using true_rand directly.