Explorar el Código

begin Strobe instance

master
Mike Hamburg hace 9 años
padre
commit
6665bb497e
Se han modificado 5 ficheros con 519 adiciones y 135 borrados
  1. +1
    -1
      include/decaf.hxx
  2. +184
    -42
      include/shake.h
  3. +158
    -0
      include/shake.hxx
  4. +166
    -92
      src/shake.c
  5. +10
    -0
      test/bench_decaf.cxx

+ 1
- 1
include/decaf.hxx Ver fichero

@@ -211,7 +211,7 @@ public:
/** Move non-constructor */
inline SecureBuffer(Block &&move) { *this = (Block &)move; }

/** Move-assign constructor */
/** Move-assign constructor. TODO: check that this actually gets used.*/
inline SecureBuffer& operator=(SecureBuffer &&move) {
clear();
data_ = move.data_; move.data_ = NULL;


+ 184
- 42
include/shake.h Ver fichero

@@ -21,6 +21,10 @@
/** @cond internal */
#define API_VIS __attribute__((visibility("default")))
#define WARN_UNUSED __attribute__((warn_unused_result))
#define NONNULL1 __attribute__((nonnull(1)))
#define NONNULL2 __attribute__((nonnull(1,2)))
#define NONNULL13 __attribute__((nonnull(1,3)))
#define NONNULL3 __attribute__((nonnull(1,2,3)))
/** @endcond */

/* TODO: different containing structs for each primitive? */
@@ -32,14 +36,8 @@
/** @endcond */
} keccak_sponge_t[1];
struct kparams_s;
typedef struct { uint64_t opaque; } strobe_params_t[1];
#endif

typedef struct strobe_s {
keccak_sponge_t sponge;
strobe_params_t params;
} strobe_s, strobe_t[1];

#ifdef __cplusplus
extern "C" {
#endif
@@ -122,39 +120,39 @@ void sponge_hash (
/** @cond internal */
#define DECSHAKE(n) \
extern const struct kparams_s SHAKE##n##_params_s API_VIS; \
static inline void shake##n##_init(keccak_sponge_t sponge) { \
static inline void NONNULL1 shake##n##_init(keccak_sponge_t sponge) { \
sponge_init(sponge, &SHAKE##n##_params_s); \
} \
static inline void shake##n##_update(keccak_sponge_t sponge, const uint8_t *in, size_t inlen ) { \
static inline void NONNULL2 shake##n##_update(keccak_sponge_t sponge, const uint8_t *in, size_t inlen ) { \
sha3_update(sponge, in, inlen); \
} \
static inline void shake##n##_final(keccak_sponge_t sponge, uint8_t *out, size_t outlen ) { \
static inline void NONNULL2 shake##n##_final(keccak_sponge_t sponge, uint8_t *out, size_t outlen ) { \
sha3_output(sponge, out, outlen); \
sponge_init(sponge, &SHAKE##n##_params_s); \
} \
static inline void shake##n##_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { \
static inline void NONNULL13 shake##n##_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { \
sponge_hash(in,inlen,out,outlen,&SHAKE##n##_params_s); \
} \
static inline void shake##n##_destroy( keccak_sponge_t sponge ) { \
static inline void NONNULL1 shake##n##_destroy( keccak_sponge_t sponge ) { \
sponge_destroy(sponge); \
}
#define DECSHA3(n) \
extern const struct kparams_s SHA3_##n##_params_s API_VIS; \
static inline void sha3_##n##_init(keccak_sponge_t sponge) { \
static inline void NONNULL1 sha3_##n##_init(keccak_sponge_t sponge) { \
sponge_init(sponge, &SHA3_##n##_params_s); \
} \
static inline void sha3_##n##_update(keccak_sponge_t sponge, const uint8_t *in, size_t inlen ) { \
static inline void NONNULL2 sha3_##n##_update(keccak_sponge_t sponge, const uint8_t *in, size_t inlen ) { \
sha3_update(sponge, in, inlen); \
} \
static inline void sha3_##n##_final(keccak_sponge_t sponge, uint8_t *out, size_t outlen ) { \
static inline void NONNULL2 sha3_##n##_final(keccak_sponge_t sponge, uint8_t *out, size_t outlen ) { \
sha3_output(sponge, out, outlen); \
sponge_init(sponge, &SHA3_##n##_params_s); \
} \
static inline void sha3_##n##_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { \
static inline void NONNULL13 sha3_##n##_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { \
sponge_hash(in,inlen,out,outlen,&SHA3_##n##_params_s); \
} \
static inline void sha3_##n##_destroy( keccak_sponge_t sponge ) { \
static inline void NONNULL1 sha3_##n##_destroy( keccak_sponge_t sponge ) { \
sponge_destroy(sponge); \
}
/** @endcond */
@@ -180,7 +178,7 @@ void spongerng_init_from_buffer (
const uint8_t * __restrict__ in,
size_t len,
int deterministic
) API_VIS;
) NONNULL2 API_VIS;

/* FIXME!! This interface has the opposite retval convention from other functions
* in the library. (0=success). Should they be harmonized?
@@ -205,7 +203,7 @@ int spongerng_init_from_file (
const char *file,
size_t len,
int deterministic
) API_VIS WARN_UNUSED;
) NONNULL2 API_VIS WARN_UNUSED;


/* FIXME!! This interface has the opposite retval convention from other functions
@@ -249,7 +247,16 @@ void spongerng_stir (
keccak_sponge_t sponge,
const uint8_t * __restrict__ in,
size_t len
) API_VIS;
) NONNULL2 API_VIS;

extern const struct kparams_s STROBE_256 API_VIS;
extern const struct kparams_s STROBE_KEYED_128 API_VIS;
extern const struct kparams_s STROBE_KEYED_256 API_VIS;

/** TODO: remove this restriction?? */
#define STROBE_MAX_AUTH_BYTES 255

/** TODO: check "more" flags? */

/**
* @brief Initialize Strobe protocol context.
@@ -258,11 +265,88 @@ void spongerng_stir (
* @param [in] am_client Nonzero if this party
* is the client.
*/
void strobe_init(
strobe_t strobe,
void strobe_init (
keccak_sponge_t sponge,
const struct kparams_s *params,
uint8_t am_client
);
) NONNULL2 API_VIS;
/**
* @brief Send plaintext in strobe context.
* @param [inout] The initialized strobe object.
* @param [in] Strobe parameter descriptor
* @param [in] in The plaintext.
* @param [in] len The length of the plaintext.
* @param [in] iSent Nonzero if this side of exchange sent the plaintext.
* @param [in] more Nonzero if this is a continuation.
* @retval DECAF_SUCCESS The operation applied successfully.
* @retval DECAF_FAILURE The operation applied, but is dangerous
* because it breaks the usual flow (by doing keyed operations
* before a key is specified, or by specifying more when the previous
* operation didn't match).
*/
decaf_bool_t strobe_plaintext (
keccak_sponge_t sponge,
const unsigned char *in,
size_t len,
uint8_t iSent,
uint8_t more
) NONNULL2 API_VIS;
/**
* @brief Report authenticated data in strobe context.
* @param [inout] The initialized strobe object.
* @param [in] Strobe parameter descriptor
* @param [in] in The plaintext.
* @param [in] len The length of the ad.
* @param [in] more Nonzero if this is a continuation.
* @retval DECAF_SUCCESS The operation applied successfully.
* @retval DECAF_FAILURE The operation applied, but is dangerous
* because it breaks the usual flow (by doing keyed operations
* before a key is specified, or by specifying more when the previous
* operation didn't match).
*/
decaf_bool_t strobe_ad (
keccak_sponge_t sponge,
const unsigned char *in,
size_t len,
uint8_t more
) NONNULL2 API_VIS;
/**
* @brief Set nonce in strobe context.
* @param [inout] The initialized strobe object.
* @param [in] Strobe parameter descriptor
* @param [in] in The nonce.
* @param [in] len The length of the nonce.
* @param [in] more Nonzero if this is a continuation.
* @retval DECAF_SUCCESS The operation applied successfully.
* @retval DECAF_FAILURE The operation applied, but is dangerous
* because it breaks the usual flow (by doing keyed operations
* before a key is specified, or by specifying more when the previous
* operation didn't match).
*/
decaf_bool_t strobe_nonce (
keccak_sponge_t sponge,
const unsigned char *in,
size_t len,
uint8_t more
) NONNULL2 API_VIS;
/**
* @brief Set key in strobe context.
* @param [inout] The initialized strobe object.
* @param [in] Strobe parameter descriptor
* @param [in] in The key.
* @param [in] len The length of the key.
* @param [in] more Nonzero if this is a continuation.
*/
decaf_bool_t strobe_key (
keccak_sponge_t sponge,
const unsigned char *in,
size_t len,
uint8_t more
) NONNULL2 API_VIS;
/**
* @brief Produce an authenticator.
@@ -270,12 +354,61 @@ void strobe_init(
* @param [out] out The authenticator
* @param len The length, which must be no more than
* @todo 32?
* @retval DECAF_SUCCESS The operation applied successfully.
* @retval DECAF_FAILURE The operation applied, but is dangerous
* because it breaks the usual flow (by doing keyed operations
* before a key is specified, or by specifying more when the previous
* operation didn't match).
*/
void strobe_produce_auth (
strobe_t strobe,
decaf_bool_t strobe_produce_auth (
keccak_sponge_t sponge,
unsigned char *out,
size_t len
);
) NONNULL2 API_VIS;
/**
* @brief Encrypt bytes from in to out.
* @warning Doesn't produce an auth tag (TODO?)
* @param [inout] strobe The Strobe protocol context.
* @param [in] in The plaintext.
* @param [out] out The ciphertext.
* @param [in] len The length of plaintext and ciphertext.
* @param [in] more This is a continuation.
* @retval DECAF_SUCCESS The operation applied successfully.
* @retval DECAF_FAILURE The operation applied, but is dangerous
* because it breaks the usual flow (by doing keyed operations
* before a key is specified, or by specifying more when the previous
* operation didn't match).
*/
decaf_bool_t strobe_encrypt (
keccak_sponge_t sponge,
unsigned char *out,
const unsigned char *in,
size_t len,
uint8_t more
) NONNULL3 API_VIS;
/**
* @brief Decrypt bytes from in to out.
* @warning Doesn't check an auth tag (TODO?)
* @param [inout] strobe The Strobe protocol context.
* @param [in] in The ciphertext.
* @param [out] out The plaintext.
* @param [in] len The length of plaintext and ciphertext.
* @param [in] more This is a continuation.
* @retval DECAF_SUCCESS The operation applied successfully.
* @retval DECAF_FAILURE The operation applied, but is dangerous
* because it breaks the usual flow (by doing keyed operations
* before a key is specified, or by specifying more when the previous
* operation didn't match).
*/
decaf_bool_t strobe_decrypt (
keccak_sponge_t sponge,
unsigned char *out,
const unsigned char *in,
size_t len,
uint8_t more
) NONNULL3 API_VIS;

/**
* @brief Produce a session-bound pseudorandom value.
@@ -289,12 +422,19 @@ void strobe_produce_auth (
* @param [inout] strobe The Strobe protocol context
* @param [out] out The authenticator
* @param len The length.
*
* @retval DECAF_SUCCESS The operation applied successfully.
* @retval DECAF_FAILURE The operation applied, but is dangerous
* because it breaks the usual flow (by doing keyed operations
* before a key is specified, or by specifying more when the previous
* operation didn't match).
*/
void strobe_prng (
strobe_t strobe,
decaf_bool_t strobe_prng (
keccak_sponge_t sponge,
unsigned char *out,
size_t len
);
size_t len,
uint8_t more
) NONNULL2 API_VIS;

/**
* @brief Verify an authenticator.
@@ -302,12 +442,15 @@ void strobe_prng (
* @param [in] in The authenticator
* @param len The length, which must be no more than
* @todo 32?
* @retval DECAF_SUCCESS The operation applied successfully.
* @retval DECAF_FAILURE The operation failed because of a
* bad validator (or because you aren't keyed)
*/
decaf_bool_t strobe_verify_auth (
strobe_t strobe,
keccak_sponge_t sponge,
const unsigned char *in,
size_t len
);
) WARN_UNUSED NONNULL2 API_VIS;

/**
* @brief Respecify Strobe protocol object's crypto.
@@ -315,19 +458,14 @@ decaf_bool_t strobe_verify_auth (
* @param [in] Strobe parameter descriptor
* @param [in] am_client Nonzero if this party
* is the client.
* @retval DECAF_SUCCESS The operation applied successfully.
* @retval DECAF_FAILURE The operation failed because of a
* bad validator (or because you aren't keyed)
*/
void strobe_respec (
strobe_t strobe,
decaf_bool_t strobe_respec (
keccak_sponge_t sponge,
const struct kparams_s *params
);

/**
* @brief Destroy a Strobe context.
* @param [out] strobe The object to destroy.
*/
void strobe_destroy (
strobe_t strobe
);
) NONNULL2 API_VIS;

#ifdef __cplusplus
} /* extern "C" */
@@ -335,5 +473,9 @@ void strobe_destroy (

#undef API_VIS
#undef WARN_UNUSED
#undef NONNULL1
#undef NONNULL13
#undef NONNULL2
#undef NONNULL3
#endif /* __SHAKE_H__ */

+ 158
- 0
include/shake.hxx Ver fichero

@@ -130,6 +130,13 @@ template<> const struct kparams_s *SHA3<256>::get_params() { return &SHA3_256_pa
template<> const struct kparams_s *SHA3<384>::get_params() { return &SHA3_384_params_s; }
template<> 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 : private KeccakSponge {
@@ -194,6 +201,157 @@ decaf<448>::Point::Point(SpongeRng &rng, bool uniform) {
}
}
/**@endcond*/

class Strobe : private KeccakSponge {
public:
/* TODO: pull out parameters */
/** Am I a server or a client? */
enum client_or_server { SERVER, CLIENT };
inline Strobe (
client_or_server whoami,
const kparams_s &params = STROBE_256
) NOEXCEPT : KeccakSponge(NOINIT()) {
strobe_init(sp, &params, whoami == CLIENT);
}

inline void key (
const Block &data, bool more = false
) throw(ProtocolException) {
if (!strobe_key(sp, data, data.size(), more)) throw ProtocolException();
}

inline void nonce(const Block &data, bool more = false
) throw(ProtocolException) {
if (!strobe_nonce(sp, data, data.size(), more)) throw ProtocolException();
}

inline void plaintext(const Block &data, bool iSent, bool more = false
) throw(ProtocolException) {
if (!strobe_plaintext(sp, data, data.size(), iSent, more))
throw(ProtocolException());
}

inline void ad(const Block &data, bool more = false
) throw(ProtocolException) {
if (!strobe_ad(sp, data, data.size(), more))
throw(ProtocolException());
}
inline void encrypt_no_auth(
Buffer &out, const Block &data, bool more = false
) throw(LengthException,ProtocolException) {
if (out.size() != data.size()) throw LengthException();
if (!strobe_encrypt(sp, out, data, data.size(), more)) throw(ProtocolException());
}
inline void encrypt_no_auth(
TmpBuffer out, const Block &data, bool more = false
) throw(LengthException,ProtocolException) {
encrypt_no_auth((Buffer &)out, data, more);
}
inline SecureBuffer encrypt_no_auth(const Block &data, bool more = false
) throw(ProtocolException) {
SecureBuffer out(data.size()); encrypt_no_auth(out, data, more); return out;
}
inline void decrypt_no_auth(
Buffer &out, const Block &data, bool more = false
) throw(LengthException,ProtocolException) {
if (out.size() != data.size()) throw LengthException();
if (!strobe_decrypt(sp, out, data, data.size(), more)) throw ProtocolException();
}
inline void decrypt_no_auth(
TmpBuffer out, const Block &data, bool more = false
) throw(LengthException,ProtocolException) {
decrypt_no_auth((Buffer &)out, data, more);
}
inline SecureBuffer decrypt_no_auth(const Block &data, bool more = false
) throw(ProtocolException) {
SecureBuffer out(data.size()); decrypt_no_auth(out, data, more); return out;
}
inline void produce_auth(Buffer &out) throw(LengthException,ProtocolException) {
if (out.size() > STROBE_MAX_AUTH_BYTES) throw LengthException();
if (!strobe_produce_auth(sp, out, out.size())) throw ProtocolException();
}
inline void produce_auth(TmpBuffer out) throw(LengthException,ProtocolException) {
produce_auth((Buffer &)out);
}
inline SecureBuffer produce_auth(
uint8_t bytes = 8
) throw(ProtocolException) {
SecureBuffer out(bytes); produce_auth(out); return out;
}
inline void encrypt(
Buffer &out, const Block &data, uint8_t auth = 8
) throw(LengthException,ProtocolException) {
if (out.size() < data.size() || out.size() != data.size() + auth) throw LengthException();
encrypt(out.slice(0,data.size()), data);
produce_auth(out.slice(data.size(),auth));
}
inline void encrypt (
TmpBuffer out, const Block &data, uint8_t auth = 8
) throw(LengthException,ProtocolException) {
encrypt((Buffer &)out, data, auth);
}
inline SecureBuffer encrypt (
const Block &data, uint8_t auth = 8
) throw(LengthException,ProtocolException,std::bad_alloc ){
SecureBuffer out(data.size() + auth); encrypt(out, data, auth); return out;
}
inline void decrypt (
Buffer &out, const Block &data, uint8_t bytes = 8
) throw(LengthException, CryptoException, ProtocolException) {
if (out.size() > data.size() || out.size() != data.size() - bytes) throw LengthException();
decrypt(out, data.slice(0,out.size()));
verify_auth(data.slice(out.size(),bytes));
}
inline void decrypt (
TmpBuffer out, const Block &data, uint8_t bytes = 8
) throw(LengthException,CryptoException,ProtocolException) {
decrypt((Buffer &)out, data, bytes);
}
inline SecureBuffer decrypt (
const Block &data, uint8_t bytes = 8
) throw(LengthException,CryptoException,ProtocolException,std::bad_alloc) {
if (data.size() < bytes) throw LengthException();
SecureBuffer out(data.size() - bytes); decrypt(out, data, bytes); return out;
}
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, auth.size())) throw CryptoException();
}
inline void prng(Buffer &out, bool more = false) NOEXCEPT {
(void)strobe_prng(sp, out, out.size(), more);
}
inline void prng(TmpBuffer out, bool more = false) NOEXCEPT {
prng((Buffer &)out, more);
}
inline SecureBuffer prng(size_t bytes, bool more = false) {
SecureBuffer out(bytes); prng(out, more); return out;
}
inline void respec(const kparams_s &params) throw(ProtocolException) {
if (!strobe_respec(sp, &params)) throw(ProtocolException());
}
};
} /* namespace decaf */



+ 166
- 92
src/shake.c Ver fichero

@@ -58,13 +58,9 @@ typedef union {
} kdomain_t[1];

typedef struct kparams_s {
uint8_t position, flags, rate, startRound, pad, ratePad, maxOut, _;
uint8_t position, flags, rate, startRound, pad, ratePad, maxOut, client;
} kparams_t[1];

typedef struct strobe_params_s {
uint8_t client, _[7];
} strobe_params_t[1];

typedef struct keccak_sponge_s {
kdomain_t state;
kparams_t params;
@@ -451,14 +447,18 @@ int spongerng_init_from_dev_urandom (
return spongerng_init_from_file(sponge, "/dev/urandom", 64, 0);
}

const struct kparams_s STROBE_256 = { 0, 0, 200-256/4, 0, 0, 0, 0, 0 };
const struct kparams_s STROBE_KEYED_256 = { 0, 0, 200-256/4, 12, 0, 0, 0, 0 };
const struct kparams_s STROBE_KEYED_128 = { 0, 0, 200-128/4, 12, 0, 0, 0, 0 };

/* Strobe is different in that its rate is padded by one byte. */
void strobe_init(
strobe_t strobe,
keccak_sponge_t sponge,
const struct kparams_s *params,
uint8_t am_client
) {
sponge_init(strobe->sponge,params);
strobe->params->client = !!am_client;
sponge_init(sponge,params);
sponge->params->client = !!am_client;
}

static void strobe_duplex (
@@ -493,6 +493,28 @@ static void strobe_duplex (
}
}

static void strobe_forget (
keccak_sponge_t sponge,
size_t len
) {
assert(sponge->params->rate < sizeof(sponge->state));
assert(sponge->params->position <= sizeof(sponge->params->rate));
if (sizeof(sponge->state) - sponge->params->rate < len) {
/** Tiny case */
unsigned char tmp[len];
strobe_duplex(sponge,tmp,NULL,len);
if (sponge->params->position) dokeccak(sponge);
strobe_duplex(sponge,tmp,NULL,len);
decaf_bzero(tmp,len);
} else {
if (sponge->params->rate < len + sponge->params->position) {
dokeccak(sponge);
}
memset(sponge->state->b, 0, len);
sponge->params->position = len;
}
}

static void strobe_unduplex (
keccak_sponge_t sponge,
unsigned char *out,
@@ -525,138 +547,190 @@ static void strobe_unduplex (
}
}

enum { KEY, NONCE, AD, PLAINTEXT, CIPHERTEXT, TAGFORGET, DIVERSIFIER, PRNG, FORK, JOIN, RESPEC };
enum { KEY=1, NONCE, AD, PLAINTEXT, CIPHERTEXT, TAGFORGET, DIVERSIFIER, PRNG, FORK, JOIN, RESPEC };

#define CLIENT_TO_SERVER 0
#define SERVER_TO_CLIENT 1
#define SERVER_TO_CLIENT 0x80

struct strobe_control {
uint8_t next;
uint8_t bytes;
uint8_t flags;
} __attribute__((packed));

static void strobe_control_word (
strobe_t strobe,
const struct strobe_control *control
static decaf_bool_t strobe_control_word (
keccak_sponge_t sponge,
const unsigned char *control,
size_t len,
uint8_t more
) {
assert(strobe->sponge->params->rate < sizeof(strobe->sponge->state));
strobe_duplex(strobe->sponge,NULL,(const unsigned char *)control,sizeof(*control));
strobe->sponge->state->b[strobe->sponge->params->position] ^= 0x1;
strobe->sponge->state->b[strobe->sponge->params->rate] ^= 0x2;
dokeccak(strobe->sponge);
assert(sponge->params->rate < sizeof(sponge->state));
decaf_bool_t ret = DECAF_SUCCESS;
if (!more) {
strobe_duplex(sponge,NULL,control,len);
sponge->state->b[sponge->params->position] ^= 0x1;
sponge->state->b[sponge->params->rate] ^= 0x2;
dokeccak(sponge);
sponge->params->flags = control[len-1];
} else if (sponge->params->flags && sponge->params->flags != control[len-1]) {
ret = DECAF_FAILURE;
}
sponge->params->flags = control[len-1];
return ret;
}

void strobe_encrypt (
strobe_t strobe,
decaf_bool_t strobe_encrypt (
keccak_sponge_t sponge,
unsigned char *out,
const unsigned char *in,
size_t len
size_t len,
uint8_t more
) {
struct strobe_control cont = { CIPHERTEXT, 0,
strobe->params->client ? CLIENT_TO_SERVER : SERVER_TO_CLIENT };
strobe_control_word(strobe, &cont);
strobe_duplex(strobe->sponge, out, in, len);
unsigned char control[] = { CIPHERTEXT |
(sponge->params->client ? CLIENT_TO_SERVER : SERVER_TO_CLIENT)
};
decaf_bool_t ret = strobe_control_word(sponge, control, sizeof(control), more);
strobe_duplex(sponge, out, in, len);
if (!sponge->params->pad/*keyed*/) ret = DECAF_FAILURE;
return ret;
}

void strobe_decrypt (
strobe_t strobe,
decaf_bool_t strobe_decrypt (
keccak_sponge_t sponge,
unsigned char *out,
const unsigned char *in,
size_t len
size_t len,
uint8_t more
) {
unsigned char control[] = { CIPHERTEXT |
(sponge->params->client ? SERVER_TO_CLIENT : CLIENT_TO_SERVER)
};
decaf_bool_t ret = strobe_control_word(sponge, control, sizeof(control), more);
strobe_duplex(sponge, out, in, len);
if (!sponge->params->pad/*keyed*/) ret = DECAF_FAILURE;
return ret;
}

decaf_bool_t strobe_plaintext (
keccak_sponge_t sponge,
const unsigned char *in,
size_t len,
uint8_t iSent,
uint8_t more
) {
unsigned char control[] = { PLAINTEXT |
((sponge->params->client == !!iSent) ? CLIENT_TO_SERVER : SERVER_TO_CLIENT)
};
decaf_bool_t ret = strobe_control_word(sponge, control, sizeof(control), more);
strobe_duplex(sponge, NULL, in, len);
return ret;
}

decaf_bool_t strobe_key (
keccak_sponge_t sponge,
const unsigned char *in,
size_t len,
uint8_t more
) {
unsigned char control[] = { KEY };
decaf_bool_t ret = strobe_control_word(sponge, control, sizeof(control), more);
strobe_duplex(sponge, NULL, in, len);
sponge->params->pad/*=keyed*/ = 1;
return ret;
}

decaf_bool_t strobe_nonce (
keccak_sponge_t sponge,
const unsigned char *in,
size_t len,
uint8_t more
) {
struct strobe_control cont = { CIPHERTEXT, 0,
strobe->params->client ? SERVER_TO_CLIENT : CLIENT_TO_SERVER };
strobe_control_word(strobe, &cont);
strobe_duplex(strobe->sponge, out, in, len);
unsigned char control[] = { NONCE };
decaf_bool_t ret = strobe_control_word(sponge, control, sizeof(control), more);
strobe_duplex(sponge, NULL, in, len);
return ret;
}

void strobe_plaintext (
strobe_t strobe,
decaf_bool_t strobe_ad (
keccak_sponge_t sponge,
const unsigned char *in,
size_t len,
uint8_t iSent
uint8_t more
) {
struct strobe_control cont = { CIPHERTEXT, 0,
(strobe->params->client == !!iSent) ? CLIENT_TO_SERVER : SERVER_TO_CLIENT };
strobe_control_word(strobe, &cont);
strobe_duplex(strobe->sponge, NULL, in, len);
unsigned char control[] = { AD };
decaf_bool_t ret = strobe_control_word(sponge, control, sizeof(control), more);
strobe_duplex(sponge, NULL, in, len);
return ret;
}

#define STROBE_FORGET_BYTES 32

void strobe_produce_auth (
strobe_t strobe,
decaf_bool_t strobe_produce_auth (
keccak_sponge_t sponge,
unsigned char *out,
size_t len
) {
assert(len < strobe->sponge->params->rate - STROBE_FORGET_BYTES);
struct strobe_control cont = { TAGFORGET, len,
strobe->params->client ? CLIENT_TO_SERVER : SERVER_TO_CLIENT };
strobe_control_word(strobe, &cont);
strobe_duplex(strobe->sponge, out, NULL, len);
strobe_duplex(strobe->sponge, NULL,
&strobe->sponge->state->b[strobe->sponge->params->position],
STROBE_FORGET_BYTES
);
unsigned char control[] = {
(unsigned char)len,
(unsigned char)STROBE_FORGET_BYTES,
TAGFORGET | (sponge->params->client ? CLIENT_TO_SERVER : SERVER_TO_CLIENT)
};
decaf_bool_t ret = strobe_control_word(sponge, control, sizeof(control), 0);
strobe_duplex(sponge, out, NULL, len);
strobe_forget(sponge, STROBE_FORGET_BYTES);
if (!sponge->params->pad/*keyed*/) ret = DECAF_FAILURE;
return ret;
}

void strobe_prng (
strobe_t strobe,
decaf_bool_t strobe_prng (
keccak_sponge_t sponge,
unsigned char *out,
size_t len
size_t len,
uint8_t more
) {
struct strobe_control cont = { PRNG, 0, 0 };
strobe_control_word(strobe, &cont);
strobe_duplex(strobe->sponge, out, NULL, len);
/* Forget. TODO: ORLY? */
cont.next = TAGFORGET;
strobe_control_word(strobe, &cont);
strobe_duplex(strobe->sponge, NULL,
&strobe->sponge->state->b[0],
STROBE_FORGET_BYTES
);
/* FIXME: length?? */
unsigned char control[] = { PRNG };
decaf_bool_t ret = strobe_control_word(sponge, control, sizeof(control), more);
strobe_duplex(sponge, out, NULL, len);
// /** TODO: orly? */
// unsigned char control2[] = { 0, STROBE_FORGET_BYTES, TAGFORGET };
// ret &= strobe_control_word(sponge, control2, sizeof(control2));
// strobe_forget(sponge, STROBE_FORGET_BYTES);
if (!sponge->params->pad/*keyed*/) ret = DECAF_FAILURE;
return ret;
}

/* TODO: remove reliance on decaf? */
decaf_bool_t strobe_verify_auth (
strobe_t strobe,
keccak_sponge_t sponge,
const unsigned char *in,
size_t len
) {
unsigned char control[] = {
(unsigned char)len,
(unsigned char)STROBE_FORGET_BYTES,
TAGFORGET | (sponge->params->client ? SERVER_TO_CLIENT : CLIENT_TO_SERVER)
};
decaf_bool_t ret = strobe_control_word(sponge, control, sizeof(control), 0);
unsigned char zero[len];
decaf_bool_t chain=0;
assert(len < strobe->sponge->params->rate - STROBE_FORGET_BYTES);
struct strobe_control cont = { TAGFORGET, len,
strobe->params->client ? CLIENT_TO_SERVER : SERVER_TO_CLIENT };
strobe_control_word(strobe, &cont);
strobe_unduplex(strobe->sponge, zero, in, len);
strobe_duplex(strobe->sponge, NULL,
&strobe->sponge->state->b[strobe->sponge->params->position],
STROBE_FORGET_BYTES);
strobe_unduplex(sponge, zero, in, len);
strobe_forget(sponge, STROBE_FORGET_BYTES);
/* Check for 0 */
decaf_bool_t chain=0;
unsigned i;
for (i=0; i<len; i++) {
chain |= zero[i];
}
return ((decaf_dword_t)chain-1)>>(8*sizeof(decaf_word_t));
ret &= ((decaf_dword_t)chain-1)>>(8*sizeof(decaf_word_t));
if (!sponge->params->pad/*keyed*/) ret = DECAF_FAILURE;
return ret;
}

void strobe_destroy (
strobe_t strobe
) {
decaf_bzero(strobe,sizeof(strobe_t));
}

void strobe_respec (
strobe_t strobe,
decaf_bool_t strobe_respec (
keccak_sponge_t sponge,
const struct kparams_s *params
) {
struct strobe_control cont = { RESPEC, params->rate, params->startRound };
strobe_control_word(strobe, &cont);
strobe->sponge->params[0] = params[0];
unsigned char control[] = { params->rate, params->startRound, RESPEC };
decaf_bool_t ret = strobe_control_word(sponge, control, sizeof(control), 0);
if (!sponge->params->pad/*keyed*/) ret = DECAF_FAILURE;
sponge->params->rate = params->rate;
sponge->params->startRound = params->startRound;
return ret;
}

/* TODO: Keyak instances, etc */

+ 10
- 0
test/bench_decaf.cxx Ver fichero

@@ -66,6 +66,7 @@ static void printSI(double x, const char *unit, const char *spacer = " ") {
class Benchmark {
static const int NTESTS = 1000;
static double totalCy, totalS;
/* FIXME Tcy if get descheduled */
public:
int i, ntests;
double begin;
@@ -138,10 +139,19 @@ int main(int argc, char **argv) {
decaf::SHAKE<128> shake1;
decaf::SHAKE<256> shake2;
decaf::SHA3<512> sha5;
decaf::Strobe strobe(decaf::Strobe::CLIENT);
unsigned char b1024[1024] = {1};
for (Benchmark b("SHAKE128 1kiB", 30); b.iter(); ) { shake1 += decaf::TmpBuffer(b1024,1024); }
for (Benchmark b("SHAKE256 1kiB", 30); b.iter(); ) { shake2 += decaf::TmpBuffer(b1024,1024); }
for (Benchmark b("SHA3-512 1kiB", 30); b.iter(); ) { sha5 += decaf::TmpBuffer(b1024,1024); }
strobe.key(decaf::TmpBuffer(b1024,1024));
for (Benchmark b("STROBE256 1kiB", 30); b.iter(); ) {
strobe.encrypt_no_auth(decaf::TmpBuffer(b1024,1024),decaf::TmpBuffer(b1024,1024),b.i>1);
}
strobe.respec(STROBE_KEYED_128);
for (Benchmark b("STROBEk128 1kiB", 30); b.iter(); ) {
strobe.encrypt_no_auth(decaf::TmpBuffer(b1024,1024),decaf::TmpBuffer(b1024,1024),b.i>1);
}
for (Benchmark b("Scalar add", 1000); b.iter(); ) { s+=t; }
for (Benchmark b("Scalar times", 100); b.iter(); ) { s*=t; }
for (Benchmark b("Scalar inv", 1); b.iter(); ) { s.inverse(); }


Cargando…
Cancelar
Guardar