@@ -13,6 +13,7 @@ | |||
#include <stdlib.h> | |||
#include "field.h" | |||
#include "f_field.h" | |||
#include "decaf.h" | |||
#include "decaf_config.h" | |||
@@ -59,16 +60,15 @@ static void scalar_print(const char *name, const API_NS(scalar_t) sc) { /* UNIFY | |||
} | |||
static void field_print(const gf f) { /* UNIFY */ | |||
const int GF_SER_BYTES = (GF_BITS + 7) / 8; | |||
unsigned char ser[GF_SER_BYTES]; | |||
unsigned char ser[SER_BYTES]; | |||
gf_serialize(ser,f); | |||
int b=0, i, comma=0; | |||
unsigned long long limb = 0; | |||
printf("{FIELD_LITERAL("); | |||
for (i=0; i<GF_SER_BYTES; i++) { | |||
for (i=0; i<SER_BYTES; i++) { | |||
limb |= ((uint64_t)ser[i])<<b; | |||
b += 8; | |||
if (b >= GF_LIT_LIMB_BITS || i == GF_SER_BYTES-1) { | |||
if (b >= GF_LIT_LIMB_BITS || i == SER_BYTES-1) { | |||
limb &= (1ull<<GF_LIT_LIMB_BITS) -1; | |||
b -= GF_LIT_LIMB_BITS; | |||
if (comma) printf(","); | |||
@@ -49,8 +49,6 @@ public: | |||
/** Serialization size. */ | |||
static const size_t SER_BYTES = sizeof(Wrapped); | |||
/* TODO: convenience types like signature? */ | |||
/** Read a private key from a string*/ | |||
inline explicit PublicKey(const FixedBlock<SER_BYTES> &b) NOEXCEPT { | |||
memcpy(wrapped,b.data(),sizeof(wrapped)); | |||
@@ -70,7 +68,7 @@ public: | |||
/** Serialization size. */ | |||
inline size_t serSize() const NOEXCEPT { return SER_BYTES; } | |||
/* TODO: verify_strobe */ | |||
/* FUTURE: verify_strobe */ | |||
/** Verify a message */ | |||
inline void verify( | |||
@@ -32,9 +32,6 @@ | |||
* a naive autovectorizer will do with constant_time_lookup on Intel). | |||
* | |||
* Instead, we're putting our trust in the loop unroller and unswitcher. | |||
* | |||
* TODO: verify correctness and performance on each platform, to make sure | |||
* that there are no regressions. | |||
*/ | |||
@@ -251,7 +251,7 @@ malloc_vector(size_t size) { | |||
/* PERF: vectorize vs unroll */ | |||
#ifdef __clang__ | |||
#if 100*__clang_major__ + __clang_minor__ > 305 | |||
#define UNROLL _Pragma("clang loop unroll(full)") // PERF TODO: vectorize? | |||
#define UNROLL _Pragma("clang loop unroll(full)") | |||
#endif | |||
#endif | |||
@@ -87,7 +87,7 @@ void gf_mulw (gf_s *__restrict__ cs, const gf as, uint64_t b) { | |||
} | |||
void gf_sqr (gf_s *__restrict__ cs, const gf as) { | |||
gf_mul(cs,as,as); // PERF | |||
gf_mul(cs,as,as); /* Performs better with dedicated square */ | |||
} | |||
@@ -57,5 +57,5 @@ void gf_mulw (gf_s *__restrict__ cs, const gf as, uint64_t b) { | |||
} | |||
void gf_sqr (gf_s *__restrict__ cs, const gf as) { | |||
gf_mul(cs,as,as); // PERF | |||
gf_mul(cs,as,as); /* Performs better with dedicated square */ | |||
} |
@@ -100,6 +100,6 @@ void gf_mulw (gf_s *__restrict__ cs, const gf as, uint64_t b) { | |||
} | |||
void gf_sqr (gf_s *__restrict__ cs, const gf as) { | |||
gf_mul(cs,as,as); /* PERF */ | |||
gf_mul(cs,as,as); /* Performs better with a dedicated square */ | |||
} | |||
@@ -6,19 +6,14 @@ | |||
* Released under the MIT License. See LICENSE.txt for license information. | |||
* @author Mike Hamburg | |||
* @brief SHA-3-n and SHAKE-n instances, C++ wrapper. | |||
* @warning EXPERIMENTAL! The names, parameter orders etc are likely to change. | |||
*/ | |||
#ifndef __SHAKE_HXX__ | |||
#define __SHAKE_HXX__ | |||
#ifndef __DECAF_SHAKE_HXX__ | |||
#define __DECAF_SHAKE_HXX__ | |||
#include <decaf/shake.h> | |||
#include <decaf/strobe.h> /* TODO remove */ | |||
#include <decaf/spongerng.h> /* TODO remove */ | |||
#include <string> | |||
#include <sys/types.h> | |||
#include <errno.h> | |||
/** @cond internal */ | |||
#if __cplusplus >= 201103L | |||
@@ -140,268 +135,10 @@ template<> inline const struct kparams_s *SHA3<256>::get_params() { return &SHA3 | |||
template<> inline const struct kparams_s *SHA3<384>::get_params() { return &SHA3_384_params_s; } | |||
template<> inline const struct kparams_s *SHA3<512>::get_params() { return &SHA3_512_params_s; } | |||
/** @endcond */ | |||
/** @brief An exception for misused protocol, eg encrypt with no key. */ | |||
class ProtocolException : public std::exception { | |||
public: | |||
/** @return "ProtocolException" */ | |||
virtual const char * what() const NOEXCEPT { return "ProtocolException"; } | |||
}; | |||
/** Sponge-based random-number generator */ | |||
class SpongeRng : public Rng { | |||
private: | |||
/** C wrapped object */ | |||
keccak_prng_t sp; | |||
public: | |||
/** Exception thrown when The RNG fails (to seed itself) */ | |||
class RngException : public std::exception { | |||
private: | |||
/** @cond internal */ | |||
const char *const what_; | |||
/** @endcond */ | |||
public: | |||
const int err_code; /**< errno that caused the reseed to fail. */ | |||
const char *what() const NOEXCEPT { return what_; } /**< Description of exception. */ | |||
RngException(int err_code, const char *what_) NOEXCEPT : what_(what_), err_code(err_code) {} /**< Construct */ | |||
}; | |||
/** Initialize, deterministically by default, from block */ | |||
inline SpongeRng( const Block &in, bool deterministic = true ) { | |||
spongerng_init_from_buffer(sp,in.data(),in.size(),deterministic); | |||
} | |||
/** Initialize, non-deterministically by default, from C/C++ filename */ | |||
inline SpongeRng( const std::string &in = "/dev/urandom", size_t len = 32, bool deterministic = false ) | |||
throw(RngException) { | |||
decaf_error_t ret = spongerng_init_from_file(sp,in.c_str(),len,deterministic); | |||
if (!decaf_successful(ret)) { | |||
throw RngException(errno, "Couldn't load from file"); | |||
} | |||
} | |||
/** Stir in new data */ | |||
inline void stir( const Block &data ) NOEXCEPT { | |||
spongerng_stir(sp,data.data(),data.size()); | |||
} | |||
/** Securely destroy by overwriting state. */ | |||
inline ~SpongeRng() NOEXCEPT { spongerng_destroy(sp); } | |||
using Rng::read; | |||
/** Read data to a buffer. */ | |||
virtual inline void read(Buffer buffer) NOEXCEPT | |||
#if __cplusplus >= 201103L | |||
final | |||
#endif | |||
{ spongerng_next(sp,buffer.data(),buffer.size()); } | |||
private: | |||
SpongeRng(const SpongeRng &) DELETE; | |||
SpongeRng &operator=(const SpongeRng &) DELETE; | |||
}; | |||
/**@endcond*/ | |||
/** STROBE protocol framework object */ | |||
class Strobe { | |||
private: | |||
/** The wrapped object */ | |||
keccak_strobe_t sp; | |||
public: | |||
/** Number of bytes in a default authentication size. */ | |||
static const uint16_t DEFAULT_AUTH_SIZE = 16; | |||
/** Am I a server or a client? */ | |||
enum client_or_server { SERVER, CLIENT }; | |||
/** Create protocol object. */ | |||
inline Strobe ( | |||
const char *description, /**< Description of this protocol. */ | |||
client_or_server whoami, /**< Am I client or server? */ | |||
const kparams_s ¶ms = STROBE_256 /**< Strength parameters */ | |||
) NOEXCEPT { | |||
strobe_init(sp, ¶ms, description, whoami == CLIENT); | |||
keyed = false; | |||
} | |||
/** Securely destroy by overwriting state. */ | |||
inline ~Strobe() NOEXCEPT { strobe_destroy(sp); } | |||
/** Stir in fixed key, from a C++ block. */ | |||
inline void fixed_key ( | |||
const Block &data /**< The key. */ | |||
) throw(ProtocolException) { | |||
strobe_fixed_key(sp, data.data(), data.size()); | |||
keyed = true; | |||
} | |||
/** Stir in fixed key, from a serializeable object. */ | |||
template<class T> inline void fixed_key ( | |||
const Serializable<T> &data /**< The key. */ | |||
) throw(ProtocolException) { | |||
fixed_key(data.serialize()); | |||
} | |||
/** Stir in DH key, from a C++ block. */ | |||
inline void dh_key ( | |||
const Block &data /**< The key. */ | |||
) throw(ProtocolException) { | |||
strobe_dh_key(sp, data.data(), data.size()); | |||
keyed = true; | |||
} | |||
/** Stir in DH key, from a serializeable object. */ | |||
template<class T> inline void dh_key ( | |||
const Serializable<T> &data /**< The key. */ | |||
) throw(ProtocolException) { | |||
dh_key(data.serialize()); | |||
} | |||
/** Stir in an explicit nonce. */ | |||
inline void nonce(const Block &data) NOEXCEPT { | |||
strobe_nonce(sp, data.data(), data.size()); | |||
} | |||
/** Stir in data we sent as plaintext. NB This doesn't actually send anything. */ | |||
inline void send_plaintext(const Block &data) NOEXCEPT { | |||
strobe_plaintext(sp, data.data(), data.size(), true); | |||
} | |||
/** Stir in serializeable data we sent as plaintext. NB This doesn't actually send anything. */ | |||
template<class T> inline void send_plaintext(const Serializable<T> &data) NOEXCEPT { | |||
send_plaintext(data.serialize()); | |||
} | |||
/** Stir in data we received as plaintext. NB This doesn't actually receive anything. */ | |||
inline void recv_plaintext(const Block &data) NOEXCEPT { | |||
strobe_plaintext(sp, data.data(), data.size(), false); | |||
} | |||
/** Stir in associated data. */ | |||
inline void ad(const Block &data) { | |||
strobe_ad(sp, data.data(), data.size()); | |||
} | |||
/** Stir in associated serializable data. */ | |||
template<class T> inline void ad(const Serializable<T> &data) NOEXCEPT { | |||
ad(data.serialize()); | |||
} | |||
/** Encrypt into a buffer, without appending authentication data */ | |||
inline void encrypt_no_auth(Buffer out, const Block &data) throw(LengthException,ProtocolException) { | |||
if (!keyed) throw ProtocolException(); | |||
if (out.size() != data.size()) throw LengthException(); | |||
strobe_encrypt(sp, out.data(), data.data(), data.size()); | |||
} | |||
/** Encrypt, without appending authentication data */ | |||
inline SecureBuffer encrypt_no_auth(const Block &data) throw(ProtocolException) { | |||
SecureBuffer out(data.size()); encrypt_no_auth(out, data); return out; | |||
} | |||
/** Encrypt a serializable object, without appending authentication data */ | |||
template<class T> inline SecureBuffer encrypt_no_auth(const Serializable<T> &data) throw(ProtocolException) { | |||
return encrypt_no_auth(data.serialize()); | |||
} | |||
/** Decrypt into a buffer, without checking authentication data. */ | |||
inline void decrypt_no_auth(Buffer out, const Block &data) throw(LengthException,ProtocolException) { | |||
if (!keyed) throw ProtocolException(); | |||
if (out.size() != data.size()) throw LengthException(); | |||
strobe_decrypt(sp, out.data(), data.data(), data.size()); | |||
} | |||
/** Decrypt, without checking authentication data. */ | |||
inline SecureBuffer decrypt_no_auth(const Block &data) throw(ProtocolException) { | |||
SecureBuffer out(data.size()); decrypt_no_auth(out, data); return out; | |||
} | |||
/** Produce an authenticator into a buffer. */ | |||
inline void produce_auth(Buffer out, bool even_though_unkeyed = false) throw(LengthException,ProtocolException) { | |||
if (!keyed && !even_though_unkeyed) throw ProtocolException(); | |||
if (out.size() > STROBE_MAX_AUTH_BYTES) throw LengthException(); | |||
strobe_produce_auth(sp, out.data(), out.size()); | |||
} | |||
/** Produce an authenticator. */ | |||
inline SecureBuffer produce_auth(uint8_t bytes = DEFAULT_AUTH_SIZE) throw(ProtocolException) { | |||
SecureBuffer out(bytes); produce_auth(out); return out; | |||
} | |||
/** Encrypt into a buffer and append authentication data */ | |||
inline void encrypt( | |||
Buffer out, const Block &data, uint8_t auth = DEFAULT_AUTH_SIZE | |||
) throw(LengthException,ProtocolException) { | |||
if (out.size() < data.size() || out.size() != data.size() + auth) throw LengthException(); | |||
encrypt_no_auth(out.slice(0,data.size()), data); | |||
produce_auth(out.slice(data.size(),auth)); | |||
} | |||
/** Encrypt and append authentication data */ | |||
inline SecureBuffer encrypt ( | |||
const Block &data, uint8_t auth = DEFAULT_AUTH_SIZE | |||
) throw(LengthException,ProtocolException,std::bad_alloc ){ | |||
SecureBuffer out(data.size() + auth); encrypt(out, data, auth); return out; | |||
} | |||
/** Encrypt a serializable object and append authentication data */ | |||
template<class T> inline SecureBuffer encrypt ( | |||
const Serializable<T> &data, uint8_t auth = DEFAULT_AUTH_SIZE | |||
) throw(LengthException,ProtocolException,std::bad_alloc ){ | |||
return encrypt(data.serialize(), auth); | |||
} | |||
/** Decrypt into a buffer and check authentication data */ | |||
inline void decrypt ( | |||
Buffer out, const Block &data, uint8_t bytes = DEFAULT_AUTH_SIZE | |||
) throw(LengthException, CryptoException, ProtocolException) { | |||
if (out.size() > data.size() || out.size() != data.size() - bytes) throw LengthException(); | |||
decrypt_no_auth(out, data.slice(0,out.size())); | |||
verify_auth(data.slice(out.size(),bytes)); | |||
} | |||
/** Decrypt and check authentication data */ | |||
inline SecureBuffer decrypt ( | |||
const Block &data, uint8_t bytes = DEFAULT_AUTH_SIZE | |||
) throw(LengthException,CryptoException,ProtocolException,std::bad_alloc) { | |||
if (data.size() < bytes) throw LengthException(); | |||
SecureBuffer out(data.size() - bytes); decrypt(out, data, bytes); return out; | |||
} | |||
/** Check authentication data */ | |||
inline void verify_auth(const Block &auth) throw(LengthException,CryptoException) { | |||
if (auth.size() == 0 || auth.size() > STROBE_MAX_AUTH_BYTES) throw LengthException(); | |||
if (strobe_verify_auth(sp, auth.data(), auth.size()) != DECAF_SUCCESS) throw CryptoException(); | |||
} | |||
/** Fill pseudorandom data into a buffer */ | |||
inline void prng(Buffer out) NOEXCEPT { | |||
(void)strobe_prng(sp, out.data(), out.size()); | |||
} | |||
/** Return pseudorandom data */ | |||
inline SecureBuffer prng(size_t bytes) { | |||
SecureBuffer out(bytes); prng(out); return out; | |||
} | |||
/** Change specs, perhaps to a faster spec that takes advantage of being keyed. | |||
* @warning Experimental. | |||
*/ | |||
inline void respec(const kparams_s ¶ms) throw(ProtocolException) { | |||
if (!keyed) throw(ProtocolException()); | |||
strobe_respec(sp, ¶ms); | |||
} | |||
private: | |||
bool keyed; | |||
}; | |||
} /* namespace decaf */ | |||
#undef NOEXCEPT | |||
#undef DELETE | |||
#endif /* __SHAKE_HXX__ */ | |||
#endif /* __DECAF_SHAKE_HXX__ */ |
@@ -0,0 +1,98 @@ | |||
/** | |||
* @file decaf/strobe.hxx | |||
* @copyright | |||
* Based on CC0 code by David Leon Gil, 2015 \n | |||
* Copyright (c) 2015 Cryptography Research, Inc. \n | |||
* Released under the MIT License. See LICENSE.txt for license information. | |||
* @author Mike Hamburg | |||
* @brief Sponge RNG instances, C++ wrapper. | |||
* @warning The guts of this are subject to change. Please don't implement | |||
* anything that depends on the deterministic RNG being stable across versions | |||
* of this library. | |||
*/ | |||
#ifndef __DECAF_SPONGERNG_HXX__ | |||
#define __DECAF_SPONGERNG_HXX__ | |||
#include <decaf/spongerng.h> | |||
#include <string> | |||
#include <sys/types.h> | |||
#include <errno.h> | |||
/** @cond internal */ | |||
#if __cplusplus >= 201103L | |||
#define NOEXCEPT noexcept | |||
#define DELETE = delete | |||
#else | |||
#define NOEXCEPT throw() | |||
#define DELETE | |||
#endif | |||
/** @endcond */ | |||
namespace decaf { | |||
/** Sponge-based random-number generator */ | |||
class SpongeRng : public Rng { | |||
private: | |||
/** C wrapped object */ | |||
keccak_prng_t sp; | |||
public: | |||
/** Exception thrown when The RNG fails (to seed itself) */ | |||
class RngException : public std::exception { | |||
private: | |||
/** @cond internal */ | |||
const char *const what_; | |||
/** @endcond */ | |||
public: | |||
const int err_code; /**< errno that caused the reseed to fail. */ | |||
const char *what() const NOEXCEPT { return what_; } /**< Description of exception. */ | |||
RngException(int err_code, const char *what_) NOEXCEPT : what_(what_), err_code(err_code) {} /**< Construct */ | |||
}; | |||
/** Initialize, deterministically by default, from block */ | |||
inline SpongeRng( const Block &in, bool deterministic = true ) { | |||
spongerng_init_from_buffer(sp,in.data(),in.size(),deterministic); | |||
} | |||
/** Initialize, non-deterministically by default, from C/C++ filename */ | |||
inline SpongeRng( const std::string &in = "/dev/urandom", size_t len = 32, bool deterministic = false ) | |||
throw(RngException) { | |||
decaf_error_t ret = spongerng_init_from_file(sp,in.c_str(),len,deterministic); | |||
if (!decaf_successful(ret)) { | |||
throw RngException(errno, "Couldn't load from file"); | |||
} | |||
} | |||
/** Stir in new data */ | |||
inline void stir( const Block &data ) NOEXCEPT { | |||
spongerng_stir(sp,data.data(),data.size()); | |||
} | |||
/** Securely destroy by overwriting state. */ | |||
inline ~SpongeRng() NOEXCEPT { spongerng_destroy(sp); } | |||
using Rng::read; | |||
/** Read data to a buffer. */ | |||
virtual inline void read(Buffer buffer) NOEXCEPT | |||
#if __cplusplus >= 201103L | |||
final | |||
#endif | |||
{ spongerng_next(sp,buffer.data(),buffer.size()); } | |||
private: | |||
SpongeRng(const SpongeRng &) DELETE; | |||
SpongeRng &operator=(const SpongeRng &) DELETE; | |||
}; | |||
/**@endcond*/ | |||
} /* namespace decaf */ | |||
#undef NOEXCEPT | |||
#undef DELETE | |||
#endif /* __DECAF_SPONGERNG_HXX__ */ |
@@ -0,0 +1,240 @@ | |||
/** | |||
* @file decaf/strobe.hxx | |||
* @copyright | |||
* Based on CC0 code by David Leon Gil, 2015 \n | |||
* Copyright (c) 2015 Cryptography Research, Inc. \n | |||
* Released under the MIT License. See LICENSE.txt for license information. | |||
* @author Mike Hamburg | |||
* @brief STROBE instances, C++ wrapper. | |||
* @warning This protocol framework is entirely experimental, and shouldn't be | |||
* relied on for anything serious yet. | |||
*/ | |||
#ifndef __DECAF_STROBE_HXX__ | |||
#define __DECAF_STROBE_HXX__ | |||
#include <decaf/strobe.h> | |||
#include <sys/types.h> | |||
/** @cond internal */ | |||
#if __cplusplus >= 201103L | |||
#define NOEXCEPT noexcept | |||
#define DELETE = delete | |||
#else | |||
#define NOEXCEPT throw() | |||
#define DELETE | |||
#endif | |||
/** @endcond */ | |||
namespace decaf { | |||
/** @brief An exception for misused protocol, eg encrypt with no key. */ | |||
class ProtocolException : public std::exception { | |||
public: | |||
/** @return "ProtocolException" */ | |||
virtual const char * what() const NOEXCEPT { return "ProtocolException"; } | |||
}; | |||
/** STROBE protocol framework object */ | |||
class Strobe { | |||
private: | |||
/** The wrapped object */ | |||
keccak_strobe_t sp; | |||
public: | |||
/** Number of bytes in a default authentication size. */ | |||
static const uint16_t DEFAULT_AUTH_SIZE = 16; | |||
/** Am I a server or a client? */ | |||
enum client_or_server { SERVER, CLIENT }; | |||
/** Create protocol object. */ | |||
inline Strobe ( | |||
const char *description, /**< Description of this protocol. */ | |||
client_or_server whoami, /**< Am I client or server? */ | |||
const kparams_s ¶ms = STROBE_256 /**< Strength parameters */ | |||
) NOEXCEPT { | |||
strobe_init(sp, ¶ms, description, whoami == CLIENT); | |||
keyed = false; | |||
} | |||
/** Securely destroy by overwriting state. */ | |||
inline ~Strobe() NOEXCEPT { strobe_destroy(sp); } | |||
/** Stir in fixed key, from a C++ block. */ | |||
inline void fixed_key ( | |||
const Block &data /**< The key. */ | |||
) throw(ProtocolException) { | |||
strobe_fixed_key(sp, data.data(), data.size()); | |||
keyed = true; | |||
} | |||
/** Stir in fixed key, from a serializeable object. */ | |||
template<class T> inline void fixed_key ( | |||
const Serializable<T> &data /**< The key. */ | |||
) throw(ProtocolException) { | |||
fixed_key(data.serialize()); | |||
} | |||
/** Stir in DH key, from a C++ block. */ | |||
inline void dh_key ( | |||
const Block &data /**< The key. */ | |||
) throw(ProtocolException) { | |||
strobe_dh_key(sp, data.data(), data.size()); | |||
keyed = true; | |||
} | |||
/** Stir in DH key, from a serializeable object. */ | |||
template<class T> inline void dh_key ( | |||
const Serializable<T> &data /**< The key. */ | |||
) throw(ProtocolException) { | |||
dh_key(data.serialize()); | |||
} | |||
/** Stir in an explicit nonce. */ | |||
inline void nonce(const Block &data) NOEXCEPT { | |||
strobe_nonce(sp, data.data(), data.size()); | |||
} | |||
/** Stir in data we sent as plaintext. NB This doesn't actually send anything. */ | |||
inline void send_plaintext(const Block &data) NOEXCEPT { | |||
strobe_plaintext(sp, data.data(), data.size(), true); | |||
} | |||
/** Stir in serializeable data we sent as plaintext. NB This doesn't actually send anything. */ | |||
template<class T> inline void send_plaintext(const Serializable<T> &data) NOEXCEPT { | |||
send_plaintext(data.serialize()); | |||
} | |||
/** Stir in data we received as plaintext. NB This doesn't actually receive anything. */ | |||
inline void recv_plaintext(const Block &data) NOEXCEPT { | |||
strobe_plaintext(sp, data.data(), data.size(), false); | |||
} | |||
/** Stir in associated data. */ | |||
inline void ad(const Block &data) { | |||
strobe_ad(sp, data.data(), data.size()); | |||
} | |||
/** Stir in associated serializable data. */ | |||
template<class T> inline void ad(const Serializable<T> &data) NOEXCEPT { | |||
ad(data.serialize()); | |||
} | |||
/** Encrypt into a buffer, without appending authentication data */ | |||
inline void encrypt_no_auth(Buffer out, const Block &data) throw(LengthException,ProtocolException) { | |||
if (!keyed) throw ProtocolException(); | |||
if (out.size() != data.size()) throw LengthException(); | |||
strobe_encrypt(sp, out.data(), data.data(), data.size()); | |||
} | |||
/** Encrypt, without appending authentication data */ | |||
inline SecureBuffer encrypt_no_auth(const Block &data) throw(ProtocolException) { | |||
SecureBuffer out(data.size()); encrypt_no_auth(out, data); return out; | |||
} | |||
/** Encrypt a serializable object, without appending authentication data */ | |||
template<class T> inline SecureBuffer encrypt_no_auth(const Serializable<T> &data) throw(ProtocolException) { | |||
return encrypt_no_auth(data.serialize()); | |||
} | |||
/** Decrypt into a buffer, without checking authentication data. */ | |||
inline void decrypt_no_auth(Buffer out, const Block &data) throw(LengthException,ProtocolException) { | |||
if (!keyed) throw ProtocolException(); | |||
if (out.size() != data.size()) throw LengthException(); | |||
strobe_decrypt(sp, out.data(), data.data(), data.size()); | |||
} | |||
/** Decrypt, without checking authentication data. */ | |||
inline SecureBuffer decrypt_no_auth(const Block &data) throw(ProtocolException) { | |||
SecureBuffer out(data.size()); decrypt_no_auth(out, data); return out; | |||
} | |||
/** Produce an authenticator into a buffer. */ | |||
inline void produce_auth(Buffer out, bool even_though_unkeyed = false) throw(LengthException,ProtocolException) { | |||
if (!keyed && !even_though_unkeyed) throw ProtocolException(); | |||
if (out.size() > STROBE_MAX_AUTH_BYTES) throw LengthException(); | |||
strobe_produce_auth(sp, out.data(), out.size()); | |||
} | |||
/** Produce an authenticator. */ | |||
inline SecureBuffer produce_auth(uint8_t bytes = DEFAULT_AUTH_SIZE) throw(ProtocolException) { | |||
SecureBuffer out(bytes); produce_auth(out); return out; | |||
} | |||
/** Encrypt into a buffer and append authentication data */ | |||
inline void encrypt( | |||
Buffer out, const Block &data, uint8_t auth = DEFAULT_AUTH_SIZE | |||
) throw(LengthException,ProtocolException) { | |||
if (out.size() < data.size() || out.size() != data.size() + auth) throw LengthException(); | |||
encrypt_no_auth(out.slice(0,data.size()), data); | |||
produce_auth(out.slice(data.size(),auth)); | |||
} | |||
/** Encrypt and append authentication data */ | |||
inline SecureBuffer encrypt ( | |||
const Block &data, uint8_t auth = DEFAULT_AUTH_SIZE | |||
) throw(LengthException,ProtocolException,std::bad_alloc ){ | |||
SecureBuffer out(data.size() + auth); encrypt(out, data, auth); return out; | |||
} | |||
/** Encrypt a serializable object and append authentication data */ | |||
template<class T> inline SecureBuffer encrypt ( | |||
const Serializable<T> &data, uint8_t auth = DEFAULT_AUTH_SIZE | |||
) throw(LengthException,ProtocolException,std::bad_alloc ){ | |||
return encrypt(data.serialize(), auth); | |||
} | |||
/** Decrypt into a buffer and check authentication data */ | |||
inline void decrypt ( | |||
Buffer out, const Block &data, uint8_t bytes = DEFAULT_AUTH_SIZE | |||
) throw(LengthException, CryptoException, ProtocolException) { | |||
if (out.size() > data.size() || out.size() != data.size() - bytes) throw LengthException(); | |||
decrypt_no_auth(out, data.slice(0,out.size())); | |||
verify_auth(data.slice(out.size(),bytes)); | |||
} | |||
/** Decrypt and check authentication data */ | |||
inline SecureBuffer decrypt ( | |||
const Block &data, uint8_t bytes = DEFAULT_AUTH_SIZE | |||
) throw(LengthException,CryptoException,ProtocolException,std::bad_alloc) { | |||
if (data.size() < bytes) throw LengthException(); | |||
SecureBuffer out(data.size() - bytes); decrypt(out, data, bytes); return out; | |||
} | |||
/** Check authentication data */ | |||
inline void verify_auth(const Block &auth) throw(LengthException,CryptoException) { | |||
if (auth.size() == 0 || auth.size() > STROBE_MAX_AUTH_BYTES) throw LengthException(); | |||
if (strobe_verify_auth(sp, auth.data(), auth.size()) != DECAF_SUCCESS) throw CryptoException(); | |||
} | |||
/** Fill pseudorandom data into a buffer */ | |||
inline void prng(Buffer out) NOEXCEPT { | |||
(void)strobe_prng(sp, out.data(), out.size()); | |||
} | |||
/** Return pseudorandom data */ | |||
inline SecureBuffer prng(size_t bytes) { | |||
SecureBuffer out(bytes); prng(out); return out; | |||
} | |||
/** Change specs, perhaps to a faster spec that takes advantage of being keyed. | |||
* @warning Experimental. | |||
*/ | |||
inline void respec(const kparams_s ¶ms) throw(ProtocolException) { | |||
if (!keyed) throw(ProtocolException()); | |||
strobe_respec(sp, ¶ms); | |||
} | |||
private: | |||
bool keyed; | |||
}; | |||
} /* namespace decaf */ | |||
#undef NOEXCEPT | |||
#undef DELETE | |||
#endif /* __DECAF_STROBE_HXX__ */ |
@@ -11,6 +11,8 @@ | |||
#include <decaf.hxx> | |||
#include <decaf/shake.hxx> | |||
#include <decaf/strobe.hxx> | |||
#include <decaf/spongerng.hxx> | |||
#include <decaf/crypto_255.h> | |||
#include <decaf/crypto_448.h> | |||
#include <decaf/crypto.hxx> | |||
@@ -10,7 +10,7 @@ | |||
*/ | |||
#include <decaf.hxx> | |||
#include <decaf/shake.hxx> | |||
#include <decaf/spongerng.hxx> | |||
#include <decaf/crypto.h> | |||
#include <decaf/crypto.hxx> | |||
#include <stdio.h> | |||
@@ -10,7 +10,7 @@ | |||
*/ | |||
#include <decaf.hxx> | |||
#include <decaf/shake.hxx> | |||
#include <decaf/spongerng.hxx> | |||
#include <decaf/crypto.h> | |||
#include <decaf/crypto.hxx> | |||
#include <stdio.h> | |||