lsnes/include/library/skein.hpp

117 lines
2.6 KiB
C++
Raw Normal View History

2013-10-31 14:53:59 +02:00
#ifndef _library__skein__hpp__included__
#define _library__skein__hpp__included__
#include <cstdint>
#include <cstdlib>
2013-12-22 05:48:58 +02:00
#include <stdexcept>
2013-10-31 14:53:59 +02:00
2013-12-22 05:48:58 +02:00
namespace skein
2013-10-31 14:53:59 +02:00
{
2013-12-22 05:48:58 +02:00
/**
* Skein hash function (v1.3).
*/
struct hash
{
/**
* Variant to use (256-bit, 512-bit, 1024-bit)
*/
2013-10-31 14:53:59 +02:00
enum variant { PIPE_256, PIPE_512, PIPE_1024 };
2013-12-22 05:48:58 +02:00
/**
* Data type for piece of data.
*/
2013-10-31 14:53:59 +02:00
enum datatype
{
T_KEY = 0,
T_PERSONALIZATION = 8,
T_PUBKEY = 12,
T_KEYID = 16,
T_NONCE = 20,
T_MESSAGE = 48
};
2013-12-22 05:48:58 +02:00
/**
* Create a new hash state.
*
* Parameter v: The variant to use.
* Parameter outbits: Number of output bits.
* Throws std::runtime_error: Variant is invalid.
*/
hash(variant v, uint64_t outbits) throw(std::runtime_error);
/**
* Write data to be hashed.
*
* Parameter data: The data to append.
* Parameter datalen: Number of bytes in data.
* Parameter type: The data type. Must be monotonically increasing.
* Throws std::runtime_error: Types not monotonic, or invalid type.
*
* Note: Data types 4 (CONFIG) and 63 (OUTPUT) are not allowed.
*/
void write(const uint8_t* data, size_t datalen, datatype type = T_MESSAGE) throw(std::runtime_error);
/**
* Read the output hash.
*
* Parameter output: Buffer to store the output to.
*/
void read(uint8_t* output) throw();
/**
* Read partial output hash.
*
* Parameter output: Buffer to store the output to.
* Parameter startblock: The block number (each block is 256/512/1024 bits depending on variant) to start from.
* Parameter bits: Number of bits to output.
*/
void read_partial(uint8_t* output, uint64_t startblock, uint64_t bits) throw();
2013-10-31 14:53:59 +02:00
private:
void typechange(uint8_t newtype);
void configure();
void flush_buffer(uint8_t type, bool final);
uint64_t chain[16];
uint8_t buffer[128];
void (*compress)(uint64_t* out, const uint64_t* data, const uint64_t* key, const uint64_t* tweak);
unsigned bufferfill;
unsigned fullbuffer;
uint64_t data_low;
uint64_t data_high;
uint64_t outbits;
int8_t last_type;
};
2013-12-22 05:48:58 +02:00
/**
* Skein PRNG.
*/
struct prng
{
public:
/**
* Construct a PRNG.
*
* Note: To seed the PRNG, write the initial seed there.
*/
prng() throw();
/**
* (Re)seed the PRNG and mark it seeded.
*
* Parameter buffer: Buffer to read the seed from.
* Parameter size: Number of bytes in seed.
*/
void write(const void* buffer, size_t size) throw();
/**
* Read data from PRNG.
*
* Parameter buffer: Buffer to write the data to.
* Parameter size: Number of random bytes to write.
* Throws std::runtime_error: Generator is not seeded.
*/
void read(void* buffer, size_t size) throw(std::runtime_error);
/**
* Is seeded?
*/
bool is_seeded() const throw();
private:
uint8_t state[128];
bool _is_seeded;
};
}
2013-10-31 14:53:59 +02:00
#endif