Skip to content
This repository has been archived by the owner on Apr 6, 2024. It is now read-only.

Commit

Permalink
Major reorganization of the files
Browse files Browse the repository at this point in the history
* Set the base version to `v2rev1`
* Rename the project name to `avrhwrng` for simplicity
* Move all old files under `references/`
* Keep v2rev1 source only under the main tree
* Revise readme docs
  • Loading branch information
jj1bdx committed Jun 1, 2016
1 parent e2de29a commit 69104e2
Show file tree
Hide file tree
Showing 74 changed files with 541 additions and 163 deletions.
12 changes: 6 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
## NOTE: GNU Make only

## General Flags
PROJECT = avrhwrng-v2
PROJECT = avrhwrng
#MCU = atmega168
MCU = atmega328p
TARGET = avrhwrng-v2.elf
TARGET = avrhwrng.elf
CC = avr-gcc

## Options common to compile, link and assembly rules
Expand All @@ -21,7 +21,7 @@ CFLAGS += -MD -MP -MT $(*F).o -MF $(@F).d

## Linker flags
LDFLAGS = $(COMMON)
LDFLAGS += -Wl,-Map=avrhwrng-v2.map
LDFLAGS += -Wl,-Map=avrhwrng.map

## Intel Hex file production flags
HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
Expand All @@ -31,13 +31,13 @@ HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings

## Objects that must be built in order to link
OBJECTS = avrhwrng-v2.o
OBJECTS = avrhwrng.o

## Objects explicitly added by the user
LINKONLYOBJECTS =

## Build
all: $(TARGET) avrhwrng-v2.hex avrhwrng-v2.eep avrhwrng-v2.lss size
all: $(TARGET) avrhwrng.hex avrhwrng.eep avrhwrng.lss size

## Compile

Expand Down Expand Up @@ -65,4 +65,4 @@ size: ${TARGET}
## Clean target
.PHONY: clean
clean:
-rm -rf $(OBJECTS) avrhwrng-v2.elf dep/* avrhwrng-v2.hex avrhwrng-v2.eep avrhwrng-v2.lss avrhwrng-v2.map
-rm -rf $(OBJECTS) *.o.d avrhwrng.elf dep/* avrhwrng.hex avrhwrng.eep avrhwrng.lss avrhwrng.map
162 changes: 24 additions & 138 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,103 +3,30 @@
This repository contains a sample code with avr-gcc and the schematics
for a shield (extended piece of hardware) for Arduino Duemilanove / Arduino UNO.

Note: the code is *not* written in the Arduino programming framework; it
is written in C and avr-libc at <http://www.nongnu.org/avr-libc/>.
Note: The code is solely written in C and [avr-libc](http://www.nongnu.org/avr-libc/); no Arduino framework.

## LICENSE

* All AVR source code files are licensed by the MIT License.
* All schematics files are licensed by CC-BY-4.0.

## Documentation

* See `ipsj-iots2015/` for the set of the documentation (PDF paper in Japanese,
slides in English) of my presentation at IPSJ IOTS2015 Symposium on 27-NOV-2015.

## Makefiles

The default `Makefile` is a copy of `Makefile.v2`.

* `Makefile.v1`: for the v1 code
* `Makefile.v2`: for the v2 code
* `Makefile.rawtest`: for the rawtest code

## Preliminary test on the rawtest code

26-OCT-2015: removal of filtering from the noise generation circuits conducted.
## Hardware

By running `avrhwrng-rawtest.c`, all the mixing/filtering code have been
*removed*, and the AVR outputs random number bytes are just filled in by the
sampled raw two-bit sequence of PD7 and PD6. No other alteration.
The current circuit version is called `v2rev1`. The v2rev1 consists of two
independent noise generator circuits, and the outputs are amplified to the CMOS
digital levels, which are connected to ATmega168/328P's input pins (PD6/PD7, or
Pin 6/7).

The test was conducted on an Arduino Uno R3 with avrhwrng v2rev1 board. The
sampling rate was 400kHz, and the output rate was 1Mbps. The actual output rate
measured was ~76kbytes/sec.
Schematics and photos are available in `schematics/` and `photos/` directories, respectively.

Obviously the output will not pass the statictic tests due to possible skew and
bias. Filtering this by SHA512 as a function defined as
## Firmware

```
[512 bytes raw input] + [32 byte output from the previous SHA512 output] -> [64
bytes of SHA512 output as a part of random number stream]
```

made the output perfectly usable as a well-whitened random number sequence.

The FIPS 140-2 rngtest result for 1597357500 bytes of output resulted as
follows (summary: test failure rate: 0.079%):

```
~/src/rngtest/rngtest -c 638943 < poi1filt.bin
rngtest 2-unofficial-mt.14
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
rngtest: starting FIPS tests...
rngtest: bits received from input: 12778860032
rngtest: FIPS 140-2 successes: 638440
rngtest: FIPS 140-2 failures: 503
rngtest: FIPS 140-2(2001-10-10) Monobit: 62
rngtest: FIPS 140-2(2001-10-10) Poker: 74
rngtest: FIPS 140-2(2001-10-10) Runs: 188
rngtest: FIPS 140-2(2001-10-10) Long run: 180
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=762.939; avg=12736.675; max=19073.486)Mibits/s
rngtest: FIPS tests speed: (min=35.453; avg=126.549; max=129.752)Mibits/s
rngtest: Program run time: 97340320 microseconds
```

TestU01 Rabbit and Alphabit tests passed in most cases (~94.8%) on 1Mbit
samples; 1180 failures detected out of 22750 tests (1 Rabbit, 6 Alphabit tests
for each sample) performed on 3250 samples. The longer bit sample tests of
TestU01 Rabbit and Alphabit tests for the 1992Mbit (249Mbyte) sample were all
passed.

Result updated 11-MOV-2015: a dieharder result of the 2179368064 byte output
was very good, only the following three tests showed WEAK, no FAILED test (note
that the input sequence was rewound as dieharder demanded):

```
diehard_rank_6x8| 0| 100000| 100|0.99942491| WEAK
diehard_sums| 0| 100| 100|0.00071977| WEAK
rgb_lagged_sum| 31| 1000000| 100|0.00057416| WEAK
```
* The current version is called `v2rev1`.
* The v2rev1 gives ~10kbytes/sec of filtered output.

The result poses a fundamental question: *filtering on the hardware RNG board
is utterly meaningless if a sufficient whitening or
statictically/cryptographically strong bit mixing is performed on the host
side.* Further investigation needed.
### How the firmware works

## How it works on Version 2

Two independent noise generator circuits, amplified to the CMOS digital levels,
are connected to ATmega168/328P's input pins (PD6/PD7, or Pin 6/7).

The Timer 0 is set to CTC mode with the closest larger value to the theoretical
limit, 46 machine cycles or 2.875 microseconds. The theoretical limit of the
speed is 352000bps or 2.84 microseconds, which is equal to 11000 bytes * 8
bits/byte * 2 (for von-Neumann test) * 2 (for XORing byte filter). Sampling in
an equal timing improves the quality of the obtained randomness.
The Timer 0 of ATmega168/328P is set to CTC mode with the closest larger value
to the theoretical limit, 46 machine cycles or 2.875 microseconds. The
theoretical limit of the speed is 352000bps or 2.84 microseconds, which is
equal to 11000 bytes * 8 bits/byte * 2 (for von-Neumann test) * 2 (for XORing
byte filter). Sampling in an equal timing improves the quality of the obtained
randomness.

The MCU runs the following program without any hardware interrupt as an infinite loop:

Expand All @@ -116,14 +43,6 @@ The MCU runs the following program without any hardware interrupt as an infinite
Random number stream is obtained through the tty device of Arduino as a binary
byte stream.

The code runs either on ATmega168 or ATmega328P (only a vector address
difference). Tested both on Arduino Duemilanove and Arduino UNO R3 boards.

See `noiseshield-v2/` directory for the schematics (drawn by xcircuit). The
entire circuits can be built on a standard Arduino prototype board.

## On stream mixing strategy

The current sampling strategy of only applying von Neumann algorithm
independently for each bit stream and mixing the output into single byte stream
is chosen for reducing statistical errors.
Expand All @@ -138,19 +57,12 @@ Noise gen at PD7 --- von Neumann filter 1
Noise gen at PD6 --- von Neumann filter 2
```

Treating the two bit streams of PD7 and PD6 as two independent XORing byte
streams caused the following TestU01 Rabbit test errors:

```
1 MultinomialBitsOver eps
2 ClosePairsBitMatch, t = 2 1.9e-68
3 ClosePairsBitMatch, t = 4 1.0e-146
```
The code runs either on ATmega168 or ATmega328P (only a vector address
difference). Tested both on Arduino Duemilanove and Arduino UNO R3 boards.

## Changes for Version 2
## Documentation

* 25-SEP-2015: Add Timer 0 synchronization code
* 24-SEP-2015: Initial revision, change PD7/PD6 to digital input, reduce LED blinking from each output bit to each output *byte*, remove interrupt-driven code
* See `presentations/ipsj-iots2015/` for the set of the documentation (PDF paper in Japanese, slides in English) of my presentation at IPSJ IOTS2015 Symposium on 27-NOV-2015.

## How to compile

Expand Down Expand Up @@ -222,36 +134,10 @@ For the tagged binary `v2rev1-20150925`:

* The code is compiled with avr-gcc 4.9.2 running on OS X 10.10.5. Different compilers may generate different binaries.
* This program is compatible with [optiboot bootloader](https://github.com/Optiboot/optiboot/).
* PySerial required for the sample Python code. See <http://pythonhosted.org/pyserial/pyserial.html#installation>

## FYI: changes for Version 1

* 23-SEP-2015: Use -O3 altogether
* 12-AUG-2015: Canceled A0/A1 setup, no connection assumed between AIN1/D7-A1 and AIN0/D6-A0
* 23-JUL-2015: Performance values revised / *CANCELED*: assumes connection between AIN1/D7-A1 and AIN0/D6-A0 (A0/A1 set to input, no pullup)
* 19-JUL-2015: Code now targeted for ATmega168 and ATmega328p (modify Makefile: default is for ATmega168).
* 6-JUL-2015: Code tested under avr-gcc 4.9.2 with HomeBrew build environment.
* 7-MAR-2009: Code tested under AVR Studio 4.15 with WinAVR-20081205.

## FYI: how it works on Version 1

Two independent noise generator circuits are connected to ATmega168/328P's
analog comparator inputs (AIN0/AIN1, PD6/PD7, or Pin 6/7). The MCU samples the
comparator output in a fixed frequency of the Timer 0 interrupts (4
microseconds = 250kHz).

The sampled output bit stream from AVR analog comparator is filtered through
von Neumann algorithm of two adjacent sampled bits into a byte stream. Each of
the two-byte pairs of the byte stream is again filtered into one-byte stream by
XORing the bytes of the pair with each other.

The code will run either on ATmega168 or ATmega328P.

## FYI: actual output rate for Version 1
## LICENSE

* Sampling rate: 4 us = 250kHz
* Output rate for v1rev2: ~2100bytes/sec = 17.6kHz
* Output rate for v1amp: ~3500bytes/sec = 28kHz
* Transfer rate from Arduino: 115200bps, 8-bit, no parity raw bytes
* All AVR source code files are licensed by the MIT License.
* All schematics files are licensed by CC-BY-4.0.

[End of README.md]
File renamed without changes.
Loading

0 comments on commit 69104e2

Please sign in to comment.