Updage from NeuG 0.11

This commit is contained in:
NIIBE Yutaka
2013-09-25 13:39:33 +09:00
parent fae8c726b1
commit 8dc4022944
5 changed files with 329 additions and 178 deletions

View File

@@ -1,5 +1,8 @@
2013-09-25 Niibe Yutaka <gniibe@fsij.org> 2013-09-25 Niibe Yutaka <gniibe@fsij.org>
* src/sha256.h, src/adc.h
* src/neug.c, src/adc_stm32f103.c: Update from NeuG 0.11.
* chopstx: Upgrade to new Chopstx 0.00. * chopstx: Upgrade to new Chopstx 0.00.
* VERSION: New file. * VERSION: New file.

View File

@@ -8,6 +8,9 @@ void adc_start (void);
void adc_stop (void); void adc_stop (void);
#define ADC_SAMPLE_MODE 0 #define ADC_SAMPLE_MODE 0
#define ADC_CRC32_MODE 1 #define ADC_CRC32_MODE 1
void adc_start_conversion (int mode, uint32_t *p, int size);
void adc_wait (chopstx_intr_t *intr); extern uint32_t adc_buf[64];
void adc_start_conversion (int offset, int count);
int adc_wait_completion (chopstx_intr_t *intr);

View File

@@ -1,5 +1,7 @@
/* /*
* adc_stm32f103.c - ADC driver for STM32F103 * adc_stm32f103.c - ADC driver for STM32F103
* In this ADC driver, there are NeuG specific parts.
* You need to modify to use this as generic ADC driver.
* *
* Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan * Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org> * Author: NIIBE Yutaka <gniibe@fsij.org>
@@ -75,17 +77,11 @@
#endif #endif
#define NEUG_DMA_CHANNEL STM32_DMA1_STREAM1 #define NEUG_DMA_CHANNEL STM32_DMA1_STREAM1
#define NEUG_DMA_MODE_SAMPLE \ #define NEUG_DMA_MODE \
( STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY) \ ( STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY) \
| STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD \ | STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD \
| STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE \ | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE \
| STM32_DMA_CR_TEIE) | STM32_DMA_CR_TEIE )
#define NEUG_DMA_MODE_CRC32 \
( STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY) \
| STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD \
| STM32_DMA_CR_MINC \
| STM32_DMA_CR_TCIE | STM32_DMA_CR_TEIE)
#define NEUG_ADC_SETTING1_SMPR1 ADC_SMPR1_SMP_VREF(ADC_SAMPLE_VREF) \ #define NEUG_ADC_SETTING1_SMPR1 ADC_SMPR1_SMP_VREF(ADC_SAMPLE_VREF) \
| ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_SENSOR) | ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_SENSOR)
@@ -167,71 +163,54 @@ void adc_start (void)
ADC2->SQR3 = NEUG_ADC_SETTING2_SQR3; ADC2->SQR3 = NEUG_ADC_SETTING2_SQR3;
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
/*
* We could just let ADC run continuously always and only enable DMA
* to receive stable data from ADC. But our purpose is not to get
* correct data but noise. In fact, we can get more noise when we
* start/stop ADC each time.
*/
ADC2->CR2 = 0; ADC2->CR2 = 0;
ADC1->CR2 = 0; ADC1->CR2 = 0;
#else
/* Start conversion. */
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
#endif #endif
} }
static int adc_mode; uint32_t adc_buf[64];
static uint32_t *adc_ptr;
static int adc_size;
static uint32_t adc_buf[64];
static void adc_start_conversion_internal (void) void adc_start_conversion (int offset, int count)
{ {
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; /* SetPeripheral */
DMA1_Channel1->CMAR = (uint32_t)&adc_buf[offset]; /* SetMemory0 */
DMA1_Channel1->CNDTR = count; /* Counter */
DMA1_Channel1->CCR = NEUG_DMA_MODE | DMA_CCR1_EN; /* Mode */
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
/* Power on */ /* Power on */
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON; ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON); | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
/* Start conversion. tSTAB is 1uS, but we don't follow the spec. */ /*
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON; * Start conversion. tSTAB is 1uS, but we don't follow the spec, to
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART * get more noise.
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON); */
#else
ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON; ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
| ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON); | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
#endif #endif
} }
void adc_start_conversion (int mode, uint32_t *p, int size)
{
adc_mode = mode;
adc_ptr = p;
adc_size = size;
if (mode == ADC_SAMPLE_MODE)
{
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; /* SetPeripheral */
DMA1_Channel1->CMAR = (uint32_t)p; /* SetMemory0 */
DMA1_Channel1->CNDTR = (uint32_t)size / 4; /* counter */
DMA1_Channel1->CCR = NEUG_DMA_MODE_SAMPLE; /*mode*/
DMA1_Channel1->CCR |= DMA_CCR1_EN; /* Enable */
}
else
{
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; /* SetPeripheral */
DMA1_Channel1->CMAR = (uint32_t)adc_buf; /* SetMemory0 */
DMA1_Channel1->CNDTR = size; /* counter */
DMA1_Channel1->CCR = NEUG_DMA_MODE_CRC32; /*mode*/
DMA1_Channel1->CCR |= DMA_CCR1_EN; /* Enable */
}
adc_start_conversion_internal ();
}
static void adc_stop_conversion (void) static void adc_stop_conversion (void)
{ {
DMA1_Channel1->CCR &= ~DMA_CCR1_EN; DMA1_Channel1->CCR &= ~DMA_CCR1_EN;
#ifdef DELIBARATELY_DO_IT_WRONG_START_STOP #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
ADC1->CR2 = 0;
ADC2->CR2 = 0; ADC2->CR2 = 0;
#else ADC1->CR2 = 0;
ADC2->CR2 &= ~ADC_CR2_CONT;
ADC1->CR2 &= ~ADC_CR2_CONT;
#endif #endif
} }
@@ -248,43 +227,46 @@ void adc_stop (void)
} }
static void adc_lld_serve_rx_interrupt (uint32_t flags) static uint32_t adc_err;
{
if ((flags & STM32_DMA_ISR_TEIF) != 0) /* DMA errors */
{
/* Should never happened. If any, it's coding error. */
/* Access an unmapped address space or alignment violation. */
adc_stop_conversion ();
}
else
{
if ((flags & STM32_DMA_ISR_TCIF) != 0) /* Transfer complete */
{
adc_stop_conversion ();
if (adc_mode != ADC_SAMPLE_MODE) /*
{ * Return 0 on success.
int i; * Return 1 on error.
*/
for (i = 0; i < adc_size;) int adc_wait_completion (chopstx_intr_t *intr)
{
CRC->DR = adc_buf[i++];
CRC->DR = adc_buf[i++];
CRC->DR = adc_buf[i++];
CRC->DR = adc_buf[i++];
*adc_ptr++ = CRC->DR;
}
}
}
}
}
void adc_wait (chopstx_intr_t *intr)
{ {
uint32_t flags; uint32_t flags;
chopstx_intr_wait (intr); while (1)
flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause. */ {
DMA1->IFCR = STM32_DMA_ISR_MASK; /* Clear interrupt of channel 1. */ chopstx_intr_wait (intr);
adc_lld_serve_rx_interrupt (flags); flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause. */
/*
* Clear interrupt cause of channel 1.
*
* Note that CGIFx=0, as CGIFx=1 clears all of GIF, HTIF, TCIF
* and TEIF.
*/
DMA1->IFCR = (flags & ~1);
if ((flags & STM32_DMA_ISR_TEIF) != 0) /* DMA errors */
{
/* Should never happened. If any, it's coding error. */
/* Access an unmapped address space or alignment violation. */
adc_err++;
adc_stop_conversion ();
return 1;
}
else if ((flags & STM32_DMA_ISR_TCIF) != 0) /* Transfer complete */
{
adc_stop_conversion ();
return 0;
}
/*
* Even if STM32_DMA_CR_HTIE is unset, we come here with HTIF=1,
* with unknown reason. Just ignore the interrupt by HTIF to
* continue more data.
*/
}
} }

View File

@@ -41,8 +41,6 @@ static chopstx_cond_t mode_cond;
#define INTR_REQ_DMA1_Channel1 11 #define INTR_REQ_DMA1_Channel1 11
static uint32_t adc_buf[SHA256_BLOCK_SIZE/sizeof (uint32_t)];
static sha256_context sha256_ctx_data; static sha256_context sha256_ctx_data;
static uint32_t sha256_output[SHA256_DIGEST_SIZE/sizeof (uint32_t)]; static uint32_t sha256_output[SHA256_DIGEST_SIZE/sizeof (uint32_t)];
@@ -87,16 +85,37 @@ static uint32_t sha256_output[SHA256_DIGEST_SIZE/sizeof (uint32_t)];
static uint8_t ep_round; static uint8_t ep_round;
static void noise_source_continuous_test (uint8_t noise);
static void noise_source_continuous_test_word (uint8_t b0, uint8_t b1,
uint8_t b2, uint8_t b3);
/* /*
* Hash_df initial string: * Hash_df initial string:
* *
* 1, : counter = 1 * Initial five bytes are:
* 0, 0, 1, 0 : no_of_bits_returned (in big endian) * 1, : counter = 1
* 0, 0, 1, 0 : no_of_bits_returned (in big endian)
*
* Then, three-byte from noise source follows.
*
* One-byte was used in the previous turn, and we have three bytes in
* CRC->DR.
*/ */
static void ep_fill_initial_string (void) static void ep_fill_initial_string (void)
{ {
adc_buf[0] = 0x01000001; /* Regardless of endian */ uint32_t v = CRC->DR;
adc_buf[1] = (CRC->DR & 0xffffff00); uint8_t b1, b2, b3;
b3 = v >> 24;
b2 = v >> 16;
b1 = v >> 8;
noise_source_continuous_test (b1);
noise_source_continuous_test (b2);
noise_source_continuous_test (b3);
adc_buf[0] = 0x01000001;
adc_buf[1] = (v & 0xffffff00);
} }
static void ep_init (int mode) static void ep_init (int mode)
@@ -104,28 +123,24 @@ static void ep_init (int mode)
if (mode == NEUG_MODE_RAW) if (mode == NEUG_MODE_RAW)
{ {
ep_round = EP_ROUND_RAW; ep_round = EP_ROUND_RAW;
adc_start_conversion (ADC_CRC32_MODE, adc_buf, EP_ROUND_RAW_INPUTS); adc_start_conversion (0, EP_ROUND_RAW_INPUTS);
} }
else if (mode == NEUG_MODE_RAW_DATA) else if (mode == NEUG_MODE_RAW_DATA)
{ {
ep_round = EP_ROUND_RAW_DATA; ep_round = EP_ROUND_RAW_DATA;
adc_start_conversion (ADC_SAMPLE_MODE, adc_buf, EP_ROUND_RAW_DATA_INPUTS); adc_start_conversion (0, EP_ROUND_RAW_DATA_INPUTS / 4);
} }
else else
{ {
ep_round = EP_ROUND_0; ep_round = EP_ROUND_0;
ep_fill_initial_string (); ep_fill_initial_string ();
adc_start_conversion (ADC_CRC32_MODE, adc_start_conversion (2, EP_ROUND_0_INPUTS);
&adc_buf[2], EP_ROUND_0_INPUTS);
} }
} }
static void noise_source_continuous_test (uint8_t noise);
static void ep_fill_wbuf (int i, int flip, int test) static void ep_fill_wbuf_v (int i, int test, uint32_t v)
{ {
uint32_t v = adc_buf[i];
if (test) if (test)
{ {
uint8_t b0, b1, b2, b3; uint8_t b0, b1, b2, b3;
@@ -135,27 +150,94 @@ static void ep_fill_wbuf (int i, int flip, int test)
b1 = v >> 8; b1 = v >> 8;
b0 = v; b0 = v;
noise_source_continuous_test (b0); noise_source_continuous_test_word (b0, b1, b2, b3);
noise_source_continuous_test (b1);
noise_source_continuous_test (b2);
noise_source_continuous_test (b3);
} }
if (flip)
v = __builtin_bswap32 (v);
sha256_ctx_data.wbuf[i] = v; sha256_ctx_data.wbuf[i] = v;
} }
/* Here assumes little endian architecture. */ /* Here, we assume a little endian architecture. */
static int ep_process (int mode) static int ep_process (int mode)
{ {
int i, n; int i, n;
uint32_t v;
if (ep_round == EP_ROUND_RAW) if (ep_round == EP_ROUND_0)
{
sha256_start (&sha256_ctx_data);
sha256_ctx_data.wbuf[0] = adc_buf[0];
sha256_ctx_data.wbuf[1] = adc_buf[1];
for (i = 0; i < EP_ROUND_0_INPUTS / 4; i++)
{
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
CRC->DR = adc_buf[i*4 + 4];
CRC->DR = adc_buf[i*4 + 5];
v = CRC->DR;
ep_fill_wbuf_v (i+2, 1, v);
}
adc_start_conversion (0, EP_ROUND_1_INPUTS);
sha256_process (&sha256_ctx_data);
ep_round++;
return 0;
}
else if (ep_round == EP_ROUND_1)
{
for (i = 0; i < EP_ROUND_1_INPUTS / 4; i++)
{
CRC->DR = adc_buf[i*4];
CRC->DR = adc_buf[i*4 + 1];
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
v = CRC->DR;
ep_fill_wbuf_v (i, 1, v);
}
adc_start_conversion (0, EP_ROUND_2_INPUTS + 3);
sha256_process (&sha256_ctx_data);
ep_round++;
return 0;
}
else if (ep_round == EP_ROUND_2)
{
for (i = 0; i < EP_ROUND_2_INPUTS / 4; i++)
{
CRC->DR = adc_buf[i*4];
CRC->DR = adc_buf[i*4 + 1];
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
v = CRC->DR;
ep_fill_wbuf_v (i, 1, v);
}
CRC->DR = adc_buf[i*4];
CRC->DR = adc_buf[i*4 + 1];
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
v = CRC->DR & 0xff;
noise_source_continuous_test (v);
sha256_ctx_data.wbuf[i] = v;
ep_init (NEUG_MODE_CONDITIONED); /* The rest three-byte of
CRC->DR is used here. */
n = SHA256_DIGEST_SIZE / 2;
memcpy (((uint8_t *)sha256_ctx_data.wbuf) + EP_ROUND_2_INPUTS,
sha256_output, n);
sha256_ctx_data.total[0] = 5 + NUM_NOISE_INPUTS + n;
sha256_finish (&sha256_ctx_data, (uint8_t *)sha256_output);
return SHA256_DIGEST_SIZE / sizeof (uint32_t);
}
else if (ep_round == EP_ROUND_RAW)
{ {
for (i = 0; i < EP_ROUND_RAW_INPUTS / 4; i++) for (i = 0; i < EP_ROUND_RAW_INPUTS / 4; i++)
ep_fill_wbuf (i, 0, 1); {
CRC->DR = adc_buf[i*4];
CRC->DR = adc_buf[i*4 + 1];
CRC->DR = adc_buf[i*4 + 2];
CRC->DR = adc_buf[i*4 + 3];
v = CRC->DR;
ep_fill_wbuf_v (i, 1, v);
}
ep_init (mode); ep_init (mode);
return EP_ROUND_RAW_INPUTS / 4; return EP_ROUND_RAW_INPUTS / 4;
@@ -163,47 +245,16 @@ static int ep_process (int mode)
else if (ep_round == EP_ROUND_RAW_DATA) else if (ep_round == EP_ROUND_RAW_DATA)
{ {
for (i = 0; i < EP_ROUND_RAW_DATA_INPUTS / 4; i++) for (i = 0; i < EP_ROUND_RAW_DATA_INPUTS / 4; i++)
ep_fill_wbuf (i, 0, 0); {
v = adc_buf[i];
ep_fill_wbuf_v (i, 0, v);
}
ep_init (mode); ep_init (mode);
return EP_ROUND_RAW_DATA_INPUTS / 4; return EP_ROUND_RAW_DATA_INPUTS / 4;
} }
if (ep_round == EP_ROUND_0) return 0;
{
for (i = 0; i < 64 / 4; i++)
ep_fill_wbuf (i, 1, 1);
adc_start_conversion (ADC_CRC32_MODE, adc_buf, EP_ROUND_1_INPUTS);
sha256_start (&sha256_ctx_data);
sha256_process (&sha256_ctx_data);
ep_round++;
return 0;
}
else if (ep_round == EP_ROUND_1)
{
for (i = 0; i < 64 / 4; i++)
ep_fill_wbuf (i, 1, 1);
adc_start_conversion (ADC_CRC32_MODE, adc_buf, EP_ROUND_2_INPUTS);
sha256_process (&sha256_ctx_data);
ep_round++;
return 0;
}
else
{
for (i = 0; i < (EP_ROUND_2_INPUTS + 3) / 4; i++)
ep_fill_wbuf (i, 0, 1);
n = SHA256_DIGEST_SIZE / 2;
ep_init (NEUG_MODE_CONDITIONED); /* The three-byte is used here. */
memcpy (((uint8_t *)sha256_ctx_data.wbuf)
+ ((NUM_NOISE_INPUTS+5)%SHA256_BLOCK_SIZE),
sha256_output, n); /* Don't use the last three-byte. */
sha256_ctx_data.total[0] = 5 + NUM_NOISE_INPUTS + n;
sha256_finish (&sha256_ctx_data, (uint8_t *)sha256_output);
return SHA256_DIGEST_SIZE / sizeof (uint32_t);
}
} }
@@ -289,6 +340,47 @@ static void repetition_count_test (uint8_t sample)
} }
} }
static void repetition_count_test_word (uint8_t b0, uint8_t b1,
uint8_t b2, uint8_t b3)
{
if (rct_a == b0)
rct_b++;
else
{
rct_a = b0;
rct_b = 1;
}
if (rct_a == b1)
rct_b++;
else
{
rct_a = b1;
rct_b = 1;
}
if (rct_a == b2)
rct_b++;
else
{
rct_a = b2;
rct_b = 1;
}
if (rct_a == b3)
rct_b++;
else
{
rct_a = b3;
rct_b = 1;
}
if (rct_b >= REPITITION_COUNT_TEST_CUTOFF)
noise_source_error (REPETITION_COUNT);
if (rct_b > neug_rc_max)
neug_rc_max = rct_b;
}
/* Cuttoff = 18, when min-entropy = 4.2, W= 2^-30 */ /* Cuttoff = 18, when min-entropy = 4.2, W= 2^-30 */
/* With R, qbinom(1-2^-30,64,2^-4.2) */ /* With R, qbinom(1-2^-30,64,2^-4.2) */
#define ADAPTIVE_PROPORTION_64_TEST_CUTOFF 18 #define ADAPTIVE_PROPORTION_64_TEST_CUTOFF 18
@@ -299,24 +391,53 @@ static uint8_t ap64t_s;
static void adaptive_proportion_64_test (uint8_t sample) static void adaptive_proportion_64_test (uint8_t sample)
{ {
if (ap64t_s >= 64) if (ap64t_s++ >= 64)
{ {
ap64t_a = sample; ap64t_a = sample;
ap64t_s = 0; ap64t_s = 1;
ap64t_b = 0;
}
else
if (ap64t_a == sample)
{
ap64t_b++;
if (ap64t_b > ADAPTIVE_PROPORTION_64_TEST_CUTOFF)
noise_source_error (ADAPTIVE_PROPORTION_64);
if (ap64t_b > neug_p64_max)
neug_p64_max = ap64t_b;
}
}
static void adaptive_proportion_64_test_word (uint8_t b0, uint8_t b1,
uint8_t b2, uint8_t b3)
{
if (ap64t_s >= 64)
{
ap64t_a = b0;
ap64t_s = 4;
ap64t_b = 0; ap64t_b = 0;
} }
else else
{ {
ap64t_s++; ap64t_s += 4;
if (ap64t_a == sample)
{ if (ap64t_a == b0)
ap64t_b++; ap64t_b++;
if (ap64t_b > ADAPTIVE_PROPORTION_64_TEST_CUTOFF)
noise_source_error (ADAPTIVE_PROPORTION_64);
if (ap64t_b > neug_p64_max)
neug_p64_max = ap64t_b;
}
} }
if (ap64t_a == b1)
ap64t_b++;
if (ap64t_a == b2)
ap64t_b++;
if (ap64t_a == b3)
ap64t_b++;
if (ap64t_b > ADAPTIVE_PROPORTION_64_TEST_CUTOFF)
noise_source_error (ADAPTIVE_PROPORTION_64);
if (ap64t_b > neug_p64_max)
neug_p64_max = ap64t_b;
} }
/* Cuttoff = 315, when min-entropy = 4.2, W= 2^-30 */ /* Cuttoff = 315, when min-entropy = 4.2, W= 2^-30 */
@@ -329,32 +450,70 @@ static uint16_t ap4096t_s;
static void adaptive_proportion_4096_test (uint8_t sample) static void adaptive_proportion_4096_test (uint8_t sample)
{ {
if (ap4096t_s >= 4096) if (ap4096t_s++ >= 4096)
{ {
ap4096t_a = sample; ap4096t_a = sample;
ap4096t_s = 0; ap4096t_s = 1;
ap4096t_b = 0;
}
else
if (ap4096t_a == sample)
{
ap4096t_b++;
if (ap4096t_b > ADAPTIVE_PROPORTION_4096_TEST_CUTOFF)
noise_source_error (ADAPTIVE_PROPORTION_4096);
if (ap4096t_b > neug_p4k_max)
neug_p4k_max = ap4096t_b;
}
}
static void adaptive_proportion_4096_test_word (uint8_t b0, uint8_t b1,
uint8_t b2, uint8_t b3)
{
if (ap4096t_s >= 4096)
{
ap4096t_a = b0;
ap4096t_s = 4;
ap4096t_b = 0; ap4096t_b = 0;
} }
else else
{ {
ap4096t_s++; ap4096t_s += 4;
if (ap4096t_a == sample)
{ if (ap4096t_a == b0)
ap4096t_b++; ap4096t_b++;
if (ap4096t_b > ADAPTIVE_PROPORTION_4096_TEST_CUTOFF)
noise_source_error (ADAPTIVE_PROPORTION_4096);
if (ap4096t_b > neug_p4k_max)
neug_p4k_max = ap4096t_b;
}
} }
if (ap4096t_a == b1)
ap4096t_b++;
if (ap4096t_a == b2)
ap4096t_b++;
if (ap4096t_a == b3)
ap4096t_b++;
if (ap4096t_b > ADAPTIVE_PROPORTION_4096_TEST_CUTOFF)
noise_source_error (ADAPTIVE_PROPORTION_4096);
if (ap4096t_b > neug_p4k_max)
neug_p4k_max = ap4096t_b;
} }
static void noise_source_continuous_test (uint8_t noise) static void noise_source_continuous_test (uint8_t noise)
{ {
repetition_count_test (noise); repetition_count_test (noise);
adaptive_proportion_64_test (noise); adaptive_proportion_64_test (noise);
adaptive_proportion_4096_test (noise); adaptive_proportion_4096_test (noise);
} }
static void noise_source_continuous_test_word (uint8_t b0, uint8_t b1,
uint8_t b2, uint8_t b3)
{
repetition_count_test_word (b0, b1, b2, b3);
adaptive_proportion_64_test_word (b0, b1, b2, b3);
adaptive_proportion_4096_test_word (b0, b1, b2, b3);
}
/* /*
* Ring buffer, filled by generator, consumed by neug_get routine. * Ring buffer, filled by generator, consumed by neug_get routine.
@@ -431,12 +590,13 @@ rng (void *arg)
ep_init (mode); ep_init (mode);
while (!rng_should_terminate) while (!rng_should_terminate)
{ {
int err;
int n; int n;
adc_wait (&adc_intr); err = adc_wait_completion (&adc_intr);
chopstx_mutex_lock (&mode_mtx); chopstx_mutex_lock (&mode_mtx);
if (mode != neug_mode) if (err || mode != neug_mode)
{ {
mode = neug_mode; mode = neug_mode;
@@ -445,8 +605,11 @@ rng (void *arg)
/* Discarding data available, re-initiate from the start. */ /* Discarding data available, re-initiate from the start. */
ep_init (mode); ep_init (mode);
chopstx_cond_signal (&mode_cond); chopstx_cond_signal (&mode_cond);
chopstx_mutex_unlock (&mode_mtx);
continue;
} }
chopstx_mutex_unlock (&mode_mtx); else
chopstx_mutex_unlock (&mode_mtx);
if ((n = ep_process (mode))) if ((n = ep_process (mode)))
{ {

View File

@@ -8,10 +8,10 @@ typedef struct
uint32_t wbuf[16]; uint32_t wbuf[16];
} sha256_context; } sha256_context;
extern void sha256 (const unsigned char *input, unsigned int ilen, void sha256 (const unsigned char *input, unsigned int ilen,
unsigned char output[32]); unsigned char output[32]);
extern void sha256_start (sha256_context *ctx); void sha256_start (sha256_context *ctx);
extern void sha256_finish (sha256_context *ctx, unsigned char output[32]); void sha256_finish (sha256_context *ctx, unsigned char output[32]);
extern void sha256_update (sha256_context *ctx, const unsigned char *input, void sha256_update (sha256_context *ctx, const unsigned char *input,
unsigned int ilen); unsigned int ilen);
extern void sha256_process (sha256_context *ctx); void sha256_process (sha256_context *ctx);