<commit_before>// ***********************************************************************
// prandom.c
// ***********************************************************************
//
// Containes functions which generate pseudo-random values. At the moment
// this covers whitening of random inputs and deterministic private key
// generation.
//
// This file is licensed as described by the file LICENCE.

// Defining this will facilitate testing
//#define TEST
// Defining this will provide useless stubs for interface functions, to stop
// linker errors from occuring
//#define INTERFACE_STUBS

#include "common.h"
#include "sha256.h"
#include "aes.h"
#include "bignum256.h"
#include "prandom.h"
#include "hwinterface.h"

#ifdef TEST
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#endif // #ifdef TEST

// XOR 16 bytes specified by r with the 16 bytes specified by op1.
void xor16Bytes(uint8_t *r, uint8_t *op1)
{
	uint8_t i;

	for (i = 0; i < 16; i++)
	{
		r[i] ^= op1[i];
	}
}

#define ENTROPY_SAFETY_FACTOR	2

// Uses a block cipher to mix data from the hardware random number generator.
// A block cipher is an appropriate choice for a mixing function, because
// an ideal block cipher should not reveal any information about the plaintext
// or key. Therefore, correlations or biases in the hardware random number
// generator will become hidden.
// Entropy is accumulated by running the cipher in CBC mode (albeit with a
// changing key) until the total entropy as reported by the hardware number
// generator is at least 256 * ENTROPY_SAFETY_FACTOR bits.
void getRandom256(BigNum256 n)
{
	uint16_t total_entropy;
	uint8_t key[32];
	uint8_t random_bytes[32];
	uint8_t expanded_key[EXPANDED_KEY_SIZE];
	uint8_t i;

	total_entropy = 0;
	for (i = 0; i < 32; i++)
	{
		n[i] = 0;
	}
	while (total_entropy < (256 * ENTROPY_SAFETY_FACTOR))
	{
		total_entropy = (uint16_t)(total_entropy + hardwareRandomBytes(key, 32));
		total_entropy = (uint16_t)(total_entropy + hardwareRandomBytes(random_bytes, 32));
		// Mix plaintext with output of previous round.
		xor16Bytes(n, random_bytes);
		aesExpandKey(expanded_key, &(key[0]));
		aesEncrypt(&(n[16]), &(n[0]), expanded_key);
		xor16Bytes(&(n[16]), &(random_bytes[16]));
		aesExpandKey(expanded_key, &(key[16]));
		aesEncrypt(&(n[0]), &(n[16]), expanded_key);
	}
}

// First part of deterministic 256-bit number generation.
// See comments to generateDeterministic256() for details.
// It was split into two parts to most efficiently use stack space.
static NOINLINE void generateDeterministic256Part1(uint8_t *hash, uint8_t *seed, uint32_t num)
{
	uint8_t i;
	HashState hs;

	sha256Begin(&hs);
	for (i = 32; i < 64; i++)
	{
		sha256WriteByte(&hs, seed[i]);
	}
	for (i = 0; i < 4; i++)
	{
		sha256WriteByte(&hs, 0);
	}
	sha256WriteByte(&hs, (uint8_t)(num >> 24));<commit_msg>using hash function to accumulate entropy<commit_after>// ***********************************************************************
// prandom.c
// ***********************************************************************
//
// Containes functions which generate pseudo-random values. At the moment
// this covers whitening of random inputs and deterministic private key
// generation.
//
// This file is licensed as described by the file LICENCE.

// Defining this will facilitate testing
//#define TEST
// Defining this will provide useless stubs for interface functions, to stop
// linker errors from occuring
//#define INTERFACE_STUBS

#include "common.h"
#include "sha256.h"
#include "aes.h"
#include "bignum256.h"
#include "prandom.h"
#include "hwinterface.h"

#ifdef TEST
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#endif // #ifdef TEST

// XOR 16 bytes specified by r with the 16 bytes specified by op1.
void xor16Bytes(uint8_t *r, uint8_t *op1)
{
	uint8_t i;

	for (i = 0; i < 16; i++)
	{
		r[i] ^= op1[i];
	}
}

#define ENTROPY_SAFETY_FACTOR	2

// Uses a hash function to accumulate entropy from a hardware random number
// generator (HWRNG) and writes the resulting 256-bit number into n.
//
// To justify why a cryptographic hash is an appropriate means of entropy
// accumulation, see the paper "Yarrow-160: Notes on the Design and Analysis
// of the Yarrow Cryptographic Pseudorandom Number Generator" by <NAME>,
// <NAME> and <NAME>, obtained from
// http://www.schneier.com/paper-yarrow.html on 14-April-2012. Specifically,
// section 5.2 addresses entropy accumulation by a hash function.
//
// Entropy is accumulated by hashing bytes obtained from the HWRNG until the
// total entropy (as reported by the HWRNG) is at least
// 256 * ENTROPY_SAFETY_FACTOR bits.
void getRandom256(BigNum256 n)
{
	uint16_t total_entropy;
	uint8_t random_bytes[32];
	HashState hs;
	uint8_t i;

	total_entropy = 0;
	sha256Begin(&hs);
	while (total_entropy < (256 * ENTROPY_SAFETY_FACTOR))
	{
		total_entropy = (uint16_t)(total_entropy + hardwareRandomBytes(random_bytes, 32));
		for (i = 0; i < 32; i++)
		{
			sha256WriteByte(&hs, random_bytes[i]);
		}
	}
	sha256Finish(&hs);
	writeHashToByteArray(n, &hs, 1);
}

// First part of deterministic 256-bit number generation.
// See comments to generateDeterministic256() for details.
// It was split into two parts to most efficiently use stack space.
static NOINLINE void generateDeterministic256Part1(uint8_t *hash, uint8_t *seed, uint32_t num)
{
	uint8_t i;
	HashState hs;

	sha256Begin(&hs);
	for (i = 32; i < 64; i++)
	{
		sha256WriteByte(&hs, seed[i]);
	}
	for (i = 0; i < 4; i++)
	{
		sha256WriteByte(&hs, 0);
	}
	sha256WriteByte(&hs, (uint8_t)(num >> 24));
{'fraction_non_alphanumeric': 0.16435643564356436, 'fraction_numerical': 0.039603960396039604, 'mean_word_length': 4.409931840311587, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3035757', 'n_tokens_mistral': 2056, 'n_tokens_neox': 1822, 'n_words': 611}