diff --git a/HISTORY.txt b/HISTORY.txt index d044652..0c56ada 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -1,3 +1,11 @@ +April 22, 2017: + Remove STROBE in preparation for 1.0 release. STROBE has its own + repo now at https://strobe.sourceforge.io. I might re-integrate + it into Decaf once I have produced a version that matches the + STROBE v1 spec, but it's just confusing to keep v0.2 in here. + + Change x{25519,448}_generate_key to _derive_public_key. + January 15, 2016: Lots of changes since the last entry in HISTORY.TXT. diff --git a/Makefile b/Makefile index e0f6769..a92f2d6 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# Copyright (c) 2014 Cryptography Research, Inc. +# Copyright (c) 2014-2017 Cryptography Research, Inc. # Released under the MIT License. See LICENSE.txt for license information. @@ -77,9 +77,9 @@ GEN_CODE= $(GEN_CODE_1:%.tmpl.hxx=%.hxx) HEADERS= Makefile $(shell find src test -name "*.h") $(BUILD_OBJ)/timestamp $(GEN_CODE) # components needed by the lib -LIBCOMPONENTS = $(BUILD_OBJ)/utils.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/strobe.o $(BUILD_OBJ)/sha512.o # and per-field components +LIBCOMPONENTS = $(BUILD_OBJ)/utils.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/sha512.o $(BUILD_OBJ)/spongerng.o # and per-field components -BENCHCOMPONENTS = $(BUILD_OBJ)/bench.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/strobe.o +BENCHCOMPONENTS = $(BUILD_OBJ)/bench.o $(BUILD_OBJ)/shake.o all: lib $(BUILD_IBIN)/test $(BUILD_IBIN)/bench $(BUILD_BIN)/shakesum @@ -174,10 +174,9 @@ endef define define_curve LIBCOMPONENTS += $$(BUILD_OBJ)/$(1)/decaf.o $$(BUILD_OBJ)/$(1)/elligator.o $$(BUILD_OBJ)/$(1)/scalar.o \ - $$(BUILD_OBJ)/$(1)/crypto.o $$(BUILD_OBJ)/$(1)/eddsa.o $$(BUILD_OBJ)/$(1)/decaf_tables.o + $$(BUILD_OBJ)/$(1)/eddsa.o $$(BUILD_OBJ)/$(1)/decaf_tables.o PER_OBJ_DIRS += $$(BUILD_OBJ)/$(1) GLOBAL_HEADERS_OF_$(1) = $(BUILD_INC)/decaf/point_$(3).h $(BUILD_INC)/decaf/point_$(3).hxx \ - $(BUILD_C)/decaf/crypto_$(3).h $(BUILD_C)/decaf/crypto_$(3).hxx \ $(BUILD_INC)/decaf/ed$(3).h $(BUILD_INC)/decaf/ed$(3).hxx HEADERS_OF_$(1) = $$(HEADERS_OF_$(2)) $$(GLOBAL_HEADERS_OF_$(1)) HEADERS += $$(GLOBAL_HEADERS_OF_$(1)) @@ -199,9 +198,6 @@ $$(BUILD_INC)/decaf/elligator_$(3).%: src/per_curve/elligator.tmpl.% src/generat $$(BUILD_INC)/decaf/scalar_$(3).%: src/per_curve/scalar.tmpl.% src/generator/* Makefile python -B src/generator/template.py --per=curve --item=$(1) --guard=$$(@:$(BUILD_INC)/%=%) -o $$@ $$< - -$$(BUILD_C)/decaf/crypto_$(3).%: src/per_curve/crypto.tmpl.% src/generator/* Makefile - python -B src/generator/template.py --per=curve --item=$(1) --guard=$$(@:$(BUILD_INC)/%=%) -o $$@ $$< $$(BUILD_IBIN)/decaf_gen_tables_$(1): $$(BUILD_OBJ)/$(1)/decaf_gen_tables.o \ $$(BUILD_OBJ)/$(1)/decaf.o $$(BUILD_OBJ)/$(1)/scalar.o $$(BUILD_OBJ)/utils.o \ diff --git a/README.md b/README.md index 7372203..869cdfe 100644 --- a/README.md +++ b/README.md @@ -60,19 +60,6 @@ The Decaf library doesn't implement much symmetric crypto, but it does contain the hash functions required by the CFRG cryptosystems: SHA512, SHA-3 and SHAKE. -The library also includes some work on an experimental protocol framework -called STROBE (based on Markku-Juhani Saarinen's BLINKER). This -framework is incomplete and will change in the future! There's also a -significant chance that it's insecure in its current form. Therefore, -all the STROBE interfaces have been marked as TOY for this version. -Please don't use them for anything serious. - -The Decaf library contains a random number generator, SpongeRNG, which -uses STROBE internally. This is used in the test suite to generate -random tests. It's probably secure, but since STROBE is not final, -its internals will almost certainly change. I recommend using your own -RNG instead for now. For example, consider libottery. - ## Internals The "decaf" technique is described in https://eprint.iacr.org/2015/673 diff --git a/src/GENERATED/c/curve25519/crypto.c b/src/GENERATED/c/curve25519/crypto.c deleted file mode 100644 index 5f12270..0000000 --- a/src/GENERATED/c/curve25519/crypto.c +++ /dev/null @@ -1,231 +0,0 @@ -/** - * @file curve25519/crypto.c - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * @cond internal - * @brief Example Decaf crypto routines - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ -#include -#include - -#define API_NAME "decaf_255" -#define API_NS(_id) decaf_255_##_id -#define API_NS_TOY(_id) decaf_255_TOY_##_id -#define SCALAR_BITS DECAF_255_SCALAR_BITS -#define SCALAR_BYTES ((SCALAR_BITS + 7)/8) -#define SER_BYTES DECAF_255_SER_BYTES - - /* TODO: canonicalize and freeze the STROBE constants in this file - * (and STROBE itself for that matter) - */ -static const char *DERIVE_MAGIC = API_NAME"::derive_private_key"; -static const char *SIGN_MAGIC = API_NAME"::sign"; -static const char *SHARED_SECRET_MAGIC = API_NAME"::shared_secret"; -static const uint16_t SHARED_SECRET_MAX_BLOCK_SIZE = 1<<12; -static const unsigned int SCALAR_OVERKILL_BYTES = SCALAR_BYTES + 8; - -void API_NS_TOY(derive_private_key) ( - API_NS_TOY(private_key_t) priv, - const API_NS_TOY(symmetric_key_t) proto -) { - uint8_t encoded_scalar[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) pub; - - keccak_decaf_TOY_strobe_t strobe; - decaf_TOY_strobe_init(strobe, &STROBE_256, DERIVE_MAGIC, 0); - decaf_TOY_strobe_fixed_key(strobe, proto, sizeof(API_NS_TOY(symmetric_key_t))); - decaf_TOY_strobe_prng(strobe, encoded_scalar, sizeof(encoded_scalar)); - decaf_TOY_strobe_destroy(strobe); - - memcpy(priv->sym, proto, sizeof(API_NS_TOY(symmetric_key_t))); - API_NS(scalar_decode_long)(priv->secret_scalar, encoded_scalar, sizeof(encoded_scalar)); - - API_NS(precomputed_scalarmul)(pub, API_NS(precomputed_base), priv->secret_scalar); - API_NS(point_encode)(priv->pub, pub); - - decaf_bzero(encoded_scalar, sizeof(encoded_scalar)); -} - -void API_NS_TOY(destroy_private_key) ( - API_NS_TOY(private_key_t) priv -) { - decaf_bzero((void*)priv, sizeof(API_NS_TOY(private_key_t))); -} - -void API_NS_TOY(private_to_public) ( - API_NS_TOY(public_key_t) pub, - const API_NS_TOY(private_key_t) priv -) { - memcpy(pub, priv->pub, sizeof(API_NS_TOY(public_key_t))); -} - -/* Performance vs consttime tuning. - * Specifying true here might give better DOS resistance in certain corner - * cases. Specifying false gives a tighter result in test_ct. - */ -#ifndef DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT -#define DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT DECAF_FALSE -#endif - -decaf_error_t API_NS_TOY(shared_secret) ( - uint8_t *shared, - size_t shared_bytes, - const API_NS_TOY(private_key_t) my_privkey, - const API_NS_TOY(public_key_t) your_pubkey, - int me_first -) { - keccak_decaf_TOY_strobe_t strobe; - decaf_TOY_strobe_init(strobe, &STROBE_256, SHARED_SECRET_MAGIC, 0); - - uint8_t ss_ser[SER_BYTES]; - - if (me_first) { - decaf_TOY_strobe_ad(strobe,my_privkey->pub,sizeof(API_NS_TOY(public_key_t))); - decaf_TOY_strobe_ad(strobe,your_pubkey,sizeof(API_NS_TOY(public_key_t))); - } else { - decaf_TOY_strobe_ad(strobe,your_pubkey,sizeof(API_NS_TOY(public_key_t))); - decaf_TOY_strobe_ad(strobe,my_privkey->pub,sizeof(API_NS_TOY(public_key_t))); - } - decaf_error_t ret = API_NS(direct_scalarmul)( - ss_ser, your_pubkey, my_privkey->secret_scalar, DECAF_FALSE, - DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT - ); - - decaf_TOY_strobe_transact(strobe,NULL,ss_ser,sizeof(ss_ser),STROBE_CW_DH_KEY); - - while (shared_bytes) { - uint16_t cando = (shared_bytes > SHARED_SECRET_MAX_BLOCK_SIZE) - ? SHARED_SECRET_MAX_BLOCK_SIZE : shared_bytes; - decaf_TOY_strobe_prng(strobe,shared,cando); - shared_bytes -= cando; - shared += cando; - } - - decaf_TOY_strobe_destroy(strobe); - decaf_bzero(ss_ser, sizeof(ss_ser)); - - return ret; -} - -void API_NS_TOY(sign_strobe) ( - keccak_decaf_TOY_strobe_t strobe, - API_NS_TOY(signature_t) sig, - const API_NS_TOY(private_key_t) priv -) { - uint8_t overkill[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) point; - API_NS(scalar_t) nonce, challenge; - - /* Stir pubkey */ - decaf_TOY_strobe_transact(strobe,NULL,priv->pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK); - - /* Derive nonce */ - keccak_decaf_TOY_strobe_t strobe2; - memcpy(strobe2,strobe,sizeof(strobe2)); - decaf_TOY_strobe_fixed_key(strobe2,priv->sym,sizeof(API_NS_TOY(symmetric_key_t))); - decaf_TOY_strobe_prng(strobe2,overkill,sizeof(overkill)); - decaf_TOY_strobe_destroy(strobe2); - - API_NS(scalar_decode_long)(nonce, overkill, sizeof(overkill)); - API_NS(precomputed_scalarmul)(point, API_NS(precomputed_base), nonce); - API_NS(point_encode)(sig, point); - - - /* Derive challenge */ - decaf_TOY_strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH); - decaf_TOY_strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); - API_NS(scalar_decode_long)(challenge, overkill, sizeof(overkill)); - - /* Respond */ - API_NS(scalar_mul)(challenge, challenge, priv->secret_scalar); - API_NS(scalar_sub)(nonce, nonce, challenge); - - /* Save results */ - API_NS(scalar_encode)(overkill, nonce); - decaf_TOY_strobe_transact(strobe,&sig[SER_BYTES],overkill,SCALAR_BYTES,STROBE_CW_SIG_RESP); - - /* Clean up */ - API_NS(scalar_destroy)(nonce); - API_NS(scalar_destroy)(challenge); - decaf_bzero(overkill,sizeof(overkill)); -} - -decaf_error_t API_NS_TOY(verify_strobe) ( - keccak_decaf_TOY_strobe_t strobe, - const API_NS_TOY(signature_t) sig, - const API_NS_TOY(public_key_t) pub -) { - decaf_bool_t ret; - - uint8_t overkill[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) point, pubpoint; - API_NS(scalar_t) challenge, response; - - /* Stir pubkey */ - decaf_TOY_strobe_transact(strobe,NULL,pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK); - - /* Derive nonce */ - decaf_TOY_strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH); - ret = decaf_successful( API_NS(point_decode)(point, sig, DECAF_TRUE) ); - - /* Derive challenge */ - decaf_TOY_strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); - API_NS(scalar_decode_long)(challenge, overkill, sizeof(overkill)); - - /* Decode response */ - decaf_TOY_strobe_transact(strobe,overkill,&sig[SER_BYTES],SCALAR_BYTES,STROBE_CW_SIG_RESP); - ret &= decaf_successful( API_NS(scalar_decode)(response, overkill) ); - ret &= decaf_successful( API_NS(point_decode)(pubpoint, pub, DECAF_FALSE) ); - - API_NS(base_double_scalarmul_non_secret) ( - pubpoint, response, pubpoint, challenge - ); - - ret &= API_NS(point_eq)(pubpoint, point); - - /* Nothing here is secret, so don't do these things: - decaf_bzero(overkill,sizeof(overkill)); - API_NS(point_destroy)(point); - API_NS(point_destroy)(pubpoint); - API_NS(scalar_destroy)(challenge); - API_NS(scalar_destroy)(response); - */ - - return decaf_succeed_if(ret); -} - -void -API_NS_TOY(sign) ( - API_NS_TOY(signature_t) sig, - const API_NS_TOY(private_key_t) priv, - const unsigned char *message, - size_t message_len -) { - keccak_decaf_TOY_strobe_t ctx; - decaf_TOY_strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0); - decaf_TOY_strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); - API_NS_TOY(sign_strobe)(ctx, sig, priv); - decaf_TOY_strobe_destroy(ctx); -} - -decaf_error_t -API_NS_TOY(verify) ( - const API_NS_TOY(signature_t) sig, - const API_NS_TOY(public_key_t) pub, - const unsigned char *message, - size_t message_len -) { - keccak_decaf_TOY_strobe_t ctx; - decaf_TOY_strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0); - decaf_TOY_strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); - decaf_error_t ret = API_NS_TOY(verify_strobe)(ctx, sig, pub); - decaf_TOY_strobe_destroy(ctx); - return ret; -} diff --git a/src/GENERATED/c/decaf/crypto.h b/src/GENERATED/c/decaf/crypto.h deleted file mode 100644 index 41f13df..0000000 --- a/src/GENERATED/c/decaf/crypto.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @file decaf/crypto.h - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * Example Decaf crypto routines, metaheader. - * @warning These are merely examples, though they ought to be secure. But real - * protocols will decide differently on magic numbers, formats, which items to - * hash, etc. - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ - -#ifndef __DECAF_CRYPTO_H__ -#define __DECAF_CRYPTO_H__ 1 - -#include -#include - -#endif /* __DECAF_CRYPTO_H__ */ diff --git a/src/GENERATED/c/decaf/crypto_255.h b/src/GENERATED/c/decaf/crypto_255.h deleted file mode 100644 index 3751f14..0000000 --- a/src/GENERATED/c/decaf/crypto_255.h +++ /dev/null @@ -1,178 +0,0 @@ -/** - * @file src/GENERATED/c/decaf/crypto_255.h - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * Example Decaf crypto routines. - * @warning These are merely examples, though they ought to be secure. But real - * protocols will decide differently on magic numbers, formats, which items to - * hash, etc. - * @warning Experimental! The names, parameter orders etc are likely to change. - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ - -#ifndef __SRC_GENERATED_C_DECAF_CRYPTO_255_H__ -#define __SRC_GENERATED_C_DECAF_CRYPTO_255_H__ 1 - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Number of bytes for a symmetric key (expanded to full key) */ -#define DECAF_255_SYMMETRIC_KEY_BYTES 32 - -/** A symmetric key, the compressed point of a private key. */ -typedef unsigned char decaf_255_TOY_symmetric_key_t[DECAF_255_SYMMETRIC_KEY_BYTES]; - -/** An encoded public key. */ -typedef unsigned char decaf_255_TOY_public_key_t[DECAF_255_SER_BYTES]; - -/** A signature. */ -typedef unsigned char decaf_255_TOY_signature_t[DECAF_255_SER_BYTES + DECAF_255_SCALAR_BYTES]; - -typedef struct { - /** @cond internal */ - /** The symmetric key from which everything is expanded */ - decaf_255_TOY_symmetric_key_t sym; - - /** The scalar x */ - decaf_255_scalar_t secret_scalar; - - /** x*Base */ - decaf_255_TOY_public_key_t pub; - /** @endcond */ -} /** Private key structure for pointers. */ - decaf_255_TOY_private_key_s, - /** A private key (gmp array[1] style). */ - decaf_255_TOY_private_key_t[1]; - -/** - * Derive a key from its compressed form. - * @param [out] priv The derived private key. - * @param [in] proto The compressed or proto-key, which must be 32 random bytes. - */ -void decaf_255_TOY_derive_private_key ( - decaf_255_TOY_private_key_t priv, - const decaf_255_TOY_symmetric_key_t proto -) NONNULL API_VIS; - -/** - * Destroy a private key. - */ -void decaf_255_TOY_destroy_private_key ( - decaf_255_TOY_private_key_t priv -) NONNULL API_VIS; - -/** - * Convert a private key to a public one. - * @param [out] pub The extracted private key. - * @param [in] priv The private key. - */ -void decaf_255_TOY_private_to_public ( - decaf_255_TOY_public_key_t pub, - const decaf_255_TOY_private_key_t priv -) NONNULL API_VIS; - -/** - * Compute a Diffie-Hellman shared secret. - * - * This is an example routine; real protocols would use something - * protocol-specific. - * - * @param [out] shared A buffer to store the shared secret. - * @param [in] shared_bytes The size of the buffer. - * @param [in] my_privkey My private key. - * @param [in] your_pubkey Your public key. - * @param [in] me_first Direction flag to break symmetry. - * - * @retval DECAF_SUCCESS Key exchange was successful. - * @retval DECAF_FAILURE Key exchange failed. - */ -decaf_error_t -decaf_255_TOY_shared_secret ( - uint8_t *shared, - size_t shared_bytes, - const decaf_255_TOY_private_key_t my_privkey, - const decaf_255_TOY_public_key_t your_pubkey, - int me_first -) NONNULL WARN_UNUSED API_VIS; - -/** - * Sign a message from a STROBE context. - * - * @param [out] sig The signature. - * @param [in] priv Your private key. - * @param [in] strobe A STROBE context with the message. - */ -void -decaf_255_TOY_sign_strobe ( - keccak_decaf_TOY_strobe_t strobe, - decaf_255_TOY_signature_t sig, - const decaf_255_TOY_private_key_t priv -) NONNULL API_VIS; - -/** - * Sign a message. - * - * @param [out] sig The signature. - * @param [in] priv Your private key. - * @param [in] message The message. - * @param [in] message_len The message's length. - */ -void -decaf_255_TOY_sign ( - decaf_255_TOY_signature_t sig, - const decaf_255_TOY_private_key_t priv, - const unsigned char *message, - size_t message_len -) NONNULL API_VIS; - -/** - * Verify a signed message from its STROBE context. - * - * @param [in] sig The signature. - * @param [in] pub The public key. - * @param [in] strobe A STROBE context with the message. - * - * @return DECAF_SUCCESS The signature verified successfully. - * @return DECAF_FAILURE The signature did not verify successfully. - */ -decaf_error_t -decaf_255_TOY_verify_strobe ( - keccak_decaf_TOY_strobe_t strobe, - const decaf_255_TOY_signature_t sig, - const decaf_255_TOY_public_key_t pub -) NONNULL API_VIS WARN_UNUSED; - -/** - * Verify a signed message. - * - * @param [in] sig The signature. - * @param [in] pub The public key. - * @param [in] message The message. - * @param [in] message_len The message's length. - * - * @return DECAF_SUCCESS The signature verified successfully. - * @return DECAF_FAILURE The signature did not verify successfully. - */ -decaf_error_t -decaf_255_TOY_verify ( - const decaf_255_TOY_signature_t sig, - const decaf_255_TOY_public_key_t pub, - const unsigned char *message, - size_t message_len -) NONNULL API_VIS WARN_UNUSED; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* __SRC_GENERATED_C_DECAF_CRYPTO_255_H__ */ diff --git a/src/GENERATED/c/decaf/crypto_255.hxx b/src/GENERATED/c/decaf/crypto_255.hxx deleted file mode 100644 index 2e2da39..0000000 --- a/src/GENERATED/c/decaf/crypto_255.hxx +++ /dev/null @@ -1,216 +0,0 @@ -/** - * @file src/GENERATED/c/decaf/crypto_255.hxx - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ - -#ifndef __SRC_GENERATED_C_DECAF_CRYPTO_255_HXX__ -#define __SRC_GENERATED_C_DECAF_CRYPTO_255_HXX__ 1 -/* - * Example Decaf cyrpto routines, C++ wrapper. - * @warning These are merely examples, though they ought to be secure. But real - * protocols will decide differently on magic numbers, formats, which items to - * hash, etc. - * @warning Experimental! The names, parameter orders etc are likely to change. - */ - -#include -#include -#include - -/** @cond internal */ -#if __cplusplus >= 201103L -#define NOEXCEPT noexcept -#else -#define NOEXCEPT throw() -#endif -/** @endcond */ - -namespace decaf { namespace TOY { - -/** A public key for crypto over some Group */ -template class PublicKey; - -/** A private key for crypto over some Group */ -template class PrivateKey; - -/** A public key for crypto over Iso-Ed25519 */ -template<> class PublicKey - : public Serializable< PublicKey > { -private: -/** @cond internal */ - typedef decaf_255_TOY_public_key_t Wrapped; - Wrapped wrapped; - template friend class PrivateKey; -/** @endcond */ -public: - /** Underlying group */ - typedef IsoEd25519 Group; - - /** Signature size. */ - static const size_t SIG_BYTES = sizeof(decaf_255_TOY_signature_t); - - /** Serialization size. */ - static const size_t SER_BYTES = sizeof(Wrapped); - - /** Read a private key from a string*/ - inline explicit PublicKey(const FixedBlock &b) NOEXCEPT { - memcpy(wrapped,b.data(),sizeof(wrapped)); - } - - /** Read a private key from a string*/ - inline explicit PublicKey(const PrivateKey &b) NOEXCEPT; - - /** Create but don't initialize */ - inline explicit PublicKey(const NOINIT&) NOEXCEPT { } - - /** Serialize into a buffer. */ - inline void serialize_into(unsigned char *x) const NOEXCEPT { - memcpy(x,wrapped,sizeof(wrapped)); - } - - /** Serialization size. */ - inline size_t ser_size() const NOEXCEPT { return SER_BYTES; } - - /** Verify a message */ - inline void verify( - const Block &message, - const FixedBlock &sig - ) const throw(CryptoException) { - if (DECAF_SUCCESS != decaf_255_TOY_verify(sig.data(),wrapped,message.data(),message.size())) { - throw(CryptoException()); - } - } - - /** Verify a message */ - inline void verify( - Strobe &context, - const FixedBlock &sig - ) const throw(CryptoException) { - if (DECAF_SUCCESS != decaf_255_TOY_verify_strobe(context.wrapped,sig.data(),wrapped)) { - throw(CryptoException()); - } - } -}; - -/** A private key for crypto over Iso-Ed25519 */ -template<> class PrivateKey - : public Serializable< PrivateKey > { -private: -/** @cond internal */ - typedef decaf_255_TOY_private_key_t Wrapped; - Wrapped wrapped; - template friend class PublicKey; -/** @endcond */ -public: - /** Underlying group */ - typedef IsoEd25519 Group; - - /** Signature size. */ - static const size_t SIG_BYTES = sizeof(decaf_255_TOY_signature_t); - - /** Serialization size. */ - static const size_t SER_BYTES = sizeof(Wrapped); - - /** Compressed size. */ - static const size_t SYM_BYTES = DECAF_255_SYMMETRIC_KEY_BYTES; - - /** Create but don't initialize */ - inline explicit PrivateKey(const NOINIT&) NOEXCEPT { } - - /** Read a private key from a string*/ - inline explicit PrivateKey(const FixedBlock &b) NOEXCEPT { - memcpy(wrapped,b.data(),sizeof(wrapped)); - } - - /** Read a private key from a string*/ - inline explicit PrivateKey(const FixedBlock &b) NOEXCEPT { - decaf_255_TOY_derive_private_key(wrapped, b.data()); - } - - /** Create at random */ - inline explicit PrivateKey(Rng &r) NOEXCEPT { - FixedArrayBuffer tmp(r); - decaf_255_TOY_derive_private_key(wrapped, tmp.data()); - } - - /** Secure destructor */ - inline ~PrivateKey() NOEXCEPT { - decaf_255_TOY_destroy_private_key(wrapped); - } - - /** Serialization size. */ - inline size_t ser_size() const NOEXCEPT { return SER_BYTES; } - - /** Serialize into a buffer. */ - inline void serialize_into(unsigned char *x) const NOEXCEPT { - memcpy(x,wrapped,sizeof(wrapped)); - } - - /** Compressed serialize. */ - inline SecureBuffer compress() const throw(std::bad_alloc) { - SecureBuffer ret(sizeof(wrapped->sym)); - memcpy(ret.data(),wrapped->sym,sizeof(wrapped->sym)); - return ret; - } - - /** Get the public key */ - inline PublicKey pub() const NOEXCEPT { - PublicKey ret(*this); return ret; - } - - /** Derive a shared secret */ - inline SecureBuffer shared_secret( - const PublicKey &pub, - size_t bytes, - bool me_first - ) const throw(CryptoException,std::bad_alloc) { - SecureBuffer ret(bytes); - if (DECAF_SUCCESS != decaf_255_TOY_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) { - throw(CryptoException()); - } - return ret; - } - - /** Derive a shared secret */ - inline decaf_error_t __attribute__((warn_unused_result)) - shared_secret_noexcept( - Buffer ret, - const PublicKey &pub, - bool me_first - ) const NOEXCEPT { - return decaf_255_TOY_shared_secret(ret.data(),ret.size(),wrapped,pub.wrapped,me_first); - } - - /** Sign a message. */ - inline SecureBuffer sign(const Block &message) const { - SecureBuffer sig(SIG_BYTES); - decaf_255_TOY_sign(sig.data(), wrapped, message.data(), message.size()); - return sig; - } - - /** Sign a message. */ - inline SecureBuffer verify(Strobe &context) const { - SecureBuffer sig(SIG_BYTES); - decaf_255_TOY_sign_strobe(context.wrapped, sig.data(), wrapped); - return sig; - } -}; - -/** @cond internal */ -PublicKey::PublicKey(const PrivateKey &b) NOEXCEPT { - decaf_255_TOY_private_to_public(wrapped,b.wrapped); -} -/** @endcond */ - -#undef NOEXCEPT -}} /* namespace decaf::TOY */ -#endif /* __SRC_GENERATED_C_DECAF_CRYPTO_255_HXX__ */ diff --git a/src/GENERATED/c/decaf/crypto_448.h b/src/GENERATED/c/decaf/crypto_448.h deleted file mode 100644 index 43c6f13..0000000 --- a/src/GENERATED/c/decaf/crypto_448.h +++ /dev/null @@ -1,178 +0,0 @@ -/** - * @file src/GENERATED/c/decaf/crypto_448.h - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * Example Decaf crypto routines. - * @warning These are merely examples, though they ought to be secure. But real - * protocols will decide differently on magic numbers, formats, which items to - * hash, etc. - * @warning Experimental! The names, parameter orders etc are likely to change. - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ - -#ifndef __SRC_GENERATED_C_DECAF_CRYPTO_448_H__ -#define __SRC_GENERATED_C_DECAF_CRYPTO_448_H__ 1 - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Number of bytes for a symmetric key (expanded to full key) */ -#define DECAF_448_SYMMETRIC_KEY_BYTES 32 - -/** A symmetric key, the compressed point of a private key. */ -typedef unsigned char decaf_448_TOY_symmetric_key_t[DECAF_448_SYMMETRIC_KEY_BYTES]; - -/** An encoded public key. */ -typedef unsigned char decaf_448_TOY_public_key_t[DECAF_448_SER_BYTES]; - -/** A signature. */ -typedef unsigned char decaf_448_TOY_signature_t[DECAF_448_SER_BYTES + DECAF_448_SCALAR_BYTES]; - -typedef struct { - /** @cond internal */ - /** The symmetric key from which everything is expanded */ - decaf_448_TOY_symmetric_key_t sym; - - /** The scalar x */ - decaf_448_scalar_t secret_scalar; - - /** x*Base */ - decaf_448_TOY_public_key_t pub; - /** @endcond */ -} /** Private key structure for pointers. */ - decaf_448_TOY_private_key_s, - /** A private key (gmp array[1] style). */ - decaf_448_TOY_private_key_t[1]; - -/** - * Derive a key from its compressed form. - * @param [out] priv The derived private key. - * @param [in] proto The compressed or proto-key, which must be 32 random bytes. - */ -void decaf_448_TOY_derive_private_key ( - decaf_448_TOY_private_key_t priv, - const decaf_448_TOY_symmetric_key_t proto -) NONNULL API_VIS; - -/** - * Destroy a private key. - */ -void decaf_448_TOY_destroy_private_key ( - decaf_448_TOY_private_key_t priv -) NONNULL API_VIS; - -/** - * Convert a private key to a public one. - * @param [out] pub The extracted private key. - * @param [in] priv The private key. - */ -void decaf_448_TOY_private_to_public ( - decaf_448_TOY_public_key_t pub, - const decaf_448_TOY_private_key_t priv -) NONNULL API_VIS; - -/** - * Compute a Diffie-Hellman shared secret. - * - * This is an example routine; real protocols would use something - * protocol-specific. - * - * @param [out] shared A buffer to store the shared secret. - * @param [in] shared_bytes The size of the buffer. - * @param [in] my_privkey My private key. - * @param [in] your_pubkey Your public key. - * @param [in] me_first Direction flag to break symmetry. - * - * @retval DECAF_SUCCESS Key exchange was successful. - * @retval DECAF_FAILURE Key exchange failed. - */ -decaf_error_t -decaf_448_TOY_shared_secret ( - uint8_t *shared, - size_t shared_bytes, - const decaf_448_TOY_private_key_t my_privkey, - const decaf_448_TOY_public_key_t your_pubkey, - int me_first -) NONNULL WARN_UNUSED API_VIS; - -/** - * Sign a message from a STROBE context. - * - * @param [out] sig The signature. - * @param [in] priv Your private key. - * @param [in] strobe A STROBE context with the message. - */ -void -decaf_448_TOY_sign_strobe ( - keccak_decaf_TOY_strobe_t strobe, - decaf_448_TOY_signature_t sig, - const decaf_448_TOY_private_key_t priv -) NONNULL API_VIS; - -/** - * Sign a message. - * - * @param [out] sig The signature. - * @param [in] priv Your private key. - * @param [in] message The message. - * @param [in] message_len The message's length. - */ -void -decaf_448_TOY_sign ( - decaf_448_TOY_signature_t sig, - const decaf_448_TOY_private_key_t priv, - const unsigned char *message, - size_t message_len -) NONNULL API_VIS; - -/** - * Verify a signed message from its STROBE context. - * - * @param [in] sig The signature. - * @param [in] pub The public key. - * @param [in] strobe A STROBE context with the message. - * - * @return DECAF_SUCCESS The signature verified successfully. - * @return DECAF_FAILURE The signature did not verify successfully. - */ -decaf_error_t -decaf_448_TOY_verify_strobe ( - keccak_decaf_TOY_strobe_t strobe, - const decaf_448_TOY_signature_t sig, - const decaf_448_TOY_public_key_t pub -) NONNULL API_VIS WARN_UNUSED; - -/** - * Verify a signed message. - * - * @param [in] sig The signature. - * @param [in] pub The public key. - * @param [in] message The message. - * @param [in] message_len The message's length. - * - * @return DECAF_SUCCESS The signature verified successfully. - * @return DECAF_FAILURE The signature did not verify successfully. - */ -decaf_error_t -decaf_448_TOY_verify ( - const decaf_448_TOY_signature_t sig, - const decaf_448_TOY_public_key_t pub, - const unsigned char *message, - size_t message_len -) NONNULL API_VIS WARN_UNUSED; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* __SRC_GENERATED_C_DECAF_CRYPTO_448_H__ */ diff --git a/src/GENERATED/c/decaf/crypto_448.hxx b/src/GENERATED/c/decaf/crypto_448.hxx deleted file mode 100644 index 253c98e..0000000 --- a/src/GENERATED/c/decaf/crypto_448.hxx +++ /dev/null @@ -1,216 +0,0 @@ -/** - * @file src/GENERATED/c/decaf/crypto_448.hxx - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ - -#ifndef __SRC_GENERATED_C_DECAF_CRYPTO_448_HXX__ -#define __SRC_GENERATED_C_DECAF_CRYPTO_448_HXX__ 1 -/* - * Example Decaf cyrpto routines, C++ wrapper. - * @warning These are merely examples, though they ought to be secure. But real - * protocols will decide differently on magic numbers, formats, which items to - * hash, etc. - * @warning Experimental! The names, parameter orders etc are likely to change. - */ - -#include -#include -#include - -/** @cond internal */ -#if __cplusplus >= 201103L -#define NOEXCEPT noexcept -#else -#define NOEXCEPT throw() -#endif -/** @endcond */ - -namespace decaf { namespace TOY { - -/** A public key for crypto over some Group */ -template class PublicKey; - -/** A private key for crypto over some Group */ -template class PrivateKey; - -/** A public key for crypto over Ed448-Goldilocks */ -template<> class PublicKey - : public Serializable< PublicKey > { -private: -/** @cond internal */ - typedef decaf_448_TOY_public_key_t Wrapped; - Wrapped wrapped; - template friend class PrivateKey; -/** @endcond */ -public: - /** Underlying group */ - typedef Ed448Goldilocks Group; - - /** Signature size. */ - static const size_t SIG_BYTES = sizeof(decaf_448_TOY_signature_t); - - /** Serialization size. */ - static const size_t SER_BYTES = sizeof(Wrapped); - - /** Read a private key from a string*/ - inline explicit PublicKey(const FixedBlock &b) NOEXCEPT { - memcpy(wrapped,b.data(),sizeof(wrapped)); - } - - /** Read a private key from a string*/ - inline explicit PublicKey(const PrivateKey &b) NOEXCEPT; - - /** Create but don't initialize */ - inline explicit PublicKey(const NOINIT&) NOEXCEPT { } - - /** Serialize into a buffer. */ - inline void serialize_into(unsigned char *x) const NOEXCEPT { - memcpy(x,wrapped,sizeof(wrapped)); - } - - /** Serialization size. */ - inline size_t ser_size() const NOEXCEPT { return SER_BYTES; } - - /** Verify a message */ - inline void verify( - const Block &message, - const FixedBlock &sig - ) const throw(CryptoException) { - if (DECAF_SUCCESS != decaf_448_TOY_verify(sig.data(),wrapped,message.data(),message.size())) { - throw(CryptoException()); - } - } - - /** Verify a message */ - inline void verify( - Strobe &context, - const FixedBlock &sig - ) const throw(CryptoException) { - if (DECAF_SUCCESS != decaf_448_TOY_verify_strobe(context.wrapped,sig.data(),wrapped)) { - throw(CryptoException()); - } - } -}; - -/** A private key for crypto over Ed448-Goldilocks */ -template<> class PrivateKey - : public Serializable< PrivateKey > { -private: -/** @cond internal */ - typedef decaf_448_TOY_private_key_t Wrapped; - Wrapped wrapped; - template friend class PublicKey; -/** @endcond */ -public: - /** Underlying group */ - typedef Ed448Goldilocks Group; - - /** Signature size. */ - static const size_t SIG_BYTES = sizeof(decaf_448_TOY_signature_t); - - /** Serialization size. */ - static const size_t SER_BYTES = sizeof(Wrapped); - - /** Compressed size. */ - static const size_t SYM_BYTES = DECAF_448_SYMMETRIC_KEY_BYTES; - - /** Create but don't initialize */ - inline explicit PrivateKey(const NOINIT&) NOEXCEPT { } - - /** Read a private key from a string*/ - inline explicit PrivateKey(const FixedBlock &b) NOEXCEPT { - memcpy(wrapped,b.data(),sizeof(wrapped)); - } - - /** Read a private key from a string*/ - inline explicit PrivateKey(const FixedBlock &b) NOEXCEPT { - decaf_448_TOY_derive_private_key(wrapped, b.data()); - } - - /** Create at random */ - inline explicit PrivateKey(Rng &r) NOEXCEPT { - FixedArrayBuffer tmp(r); - decaf_448_TOY_derive_private_key(wrapped, tmp.data()); - } - - /** Secure destructor */ - inline ~PrivateKey() NOEXCEPT { - decaf_448_TOY_destroy_private_key(wrapped); - } - - /** Serialization size. */ - inline size_t ser_size() const NOEXCEPT { return SER_BYTES; } - - /** Serialize into a buffer. */ - inline void serialize_into(unsigned char *x) const NOEXCEPT { - memcpy(x,wrapped,sizeof(wrapped)); - } - - /** Compressed serialize. */ - inline SecureBuffer compress() const throw(std::bad_alloc) { - SecureBuffer ret(sizeof(wrapped->sym)); - memcpy(ret.data(),wrapped->sym,sizeof(wrapped->sym)); - return ret; - } - - /** Get the public key */ - inline PublicKey pub() const NOEXCEPT { - PublicKey ret(*this); return ret; - } - - /** Derive a shared secret */ - inline SecureBuffer shared_secret( - const PublicKey &pub, - size_t bytes, - bool me_first - ) const throw(CryptoException,std::bad_alloc) { - SecureBuffer ret(bytes); - if (DECAF_SUCCESS != decaf_448_TOY_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) { - throw(CryptoException()); - } - return ret; - } - - /** Derive a shared secret */ - inline decaf_error_t __attribute__((warn_unused_result)) - shared_secret_noexcept( - Buffer ret, - const PublicKey &pub, - bool me_first - ) const NOEXCEPT { - return decaf_448_TOY_shared_secret(ret.data(),ret.size(),wrapped,pub.wrapped,me_first); - } - - /** Sign a message. */ - inline SecureBuffer sign(const Block &message) const { - SecureBuffer sig(SIG_BYTES); - decaf_448_TOY_sign(sig.data(), wrapped, message.data(), message.size()); - return sig; - } - - /** Sign a message. */ - inline SecureBuffer verify(Strobe &context) const { - SecureBuffer sig(SIG_BYTES); - decaf_448_TOY_sign_strobe(context.wrapped, sig.data(), wrapped); - return sig; - } -}; - -/** @cond internal */ -PublicKey::PublicKey(const PrivateKey &b) NOEXCEPT { - decaf_448_TOY_private_to_public(wrapped,b.wrapped); -} -/** @endcond */ - -#undef NOEXCEPT -}} /* namespace decaf::TOY */ -#endif /* __SRC_GENERATED_C_DECAF_CRYPTO_448_HXX__ */ diff --git a/src/GENERATED/c/ed448goldilocks/crypto.c b/src/GENERATED/c/ed448goldilocks/crypto.c deleted file mode 100644 index 7d6aa97..0000000 --- a/src/GENERATED/c/ed448goldilocks/crypto.c +++ /dev/null @@ -1,231 +0,0 @@ -/** - * @file ed448goldilocks/crypto.c - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * @cond internal - * @brief Example Decaf crypto routines - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ -#include -#include - -#define API_NAME "decaf_448" -#define API_NS(_id) decaf_448_##_id -#define API_NS_TOY(_id) decaf_448_TOY_##_id -#define SCALAR_BITS DECAF_448_SCALAR_BITS -#define SCALAR_BYTES ((SCALAR_BITS + 7)/8) -#define SER_BYTES DECAF_448_SER_BYTES - - /* TODO: canonicalize and freeze the STROBE constants in this file - * (and STROBE itself for that matter) - */ -static const char *DERIVE_MAGIC = API_NAME"::derive_private_key"; -static const char *SIGN_MAGIC = API_NAME"::sign"; -static const char *SHARED_SECRET_MAGIC = API_NAME"::shared_secret"; -static const uint16_t SHARED_SECRET_MAX_BLOCK_SIZE = 1<<12; -static const unsigned int SCALAR_OVERKILL_BYTES = SCALAR_BYTES + 8; - -void API_NS_TOY(derive_private_key) ( - API_NS_TOY(private_key_t) priv, - const API_NS_TOY(symmetric_key_t) proto -) { - uint8_t encoded_scalar[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) pub; - - keccak_decaf_TOY_strobe_t strobe; - decaf_TOY_strobe_init(strobe, &STROBE_256, DERIVE_MAGIC, 0); - decaf_TOY_strobe_fixed_key(strobe, proto, sizeof(API_NS_TOY(symmetric_key_t))); - decaf_TOY_strobe_prng(strobe, encoded_scalar, sizeof(encoded_scalar)); - decaf_TOY_strobe_destroy(strobe); - - memcpy(priv->sym, proto, sizeof(API_NS_TOY(symmetric_key_t))); - API_NS(scalar_decode_long)(priv->secret_scalar, encoded_scalar, sizeof(encoded_scalar)); - - API_NS(precomputed_scalarmul)(pub, API_NS(precomputed_base), priv->secret_scalar); - API_NS(point_encode)(priv->pub, pub); - - decaf_bzero(encoded_scalar, sizeof(encoded_scalar)); -} - -void API_NS_TOY(destroy_private_key) ( - API_NS_TOY(private_key_t) priv -) { - decaf_bzero((void*)priv, sizeof(API_NS_TOY(private_key_t))); -} - -void API_NS_TOY(private_to_public) ( - API_NS_TOY(public_key_t) pub, - const API_NS_TOY(private_key_t) priv -) { - memcpy(pub, priv->pub, sizeof(API_NS_TOY(public_key_t))); -} - -/* Performance vs consttime tuning. - * Specifying true here might give better DOS resistance in certain corner - * cases. Specifying false gives a tighter result in test_ct. - */ -#ifndef DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT -#define DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT DECAF_FALSE -#endif - -decaf_error_t API_NS_TOY(shared_secret) ( - uint8_t *shared, - size_t shared_bytes, - const API_NS_TOY(private_key_t) my_privkey, - const API_NS_TOY(public_key_t) your_pubkey, - int me_first -) { - keccak_decaf_TOY_strobe_t strobe; - decaf_TOY_strobe_init(strobe, &STROBE_256, SHARED_SECRET_MAGIC, 0); - - uint8_t ss_ser[SER_BYTES]; - - if (me_first) { - decaf_TOY_strobe_ad(strobe,my_privkey->pub,sizeof(API_NS_TOY(public_key_t))); - decaf_TOY_strobe_ad(strobe,your_pubkey,sizeof(API_NS_TOY(public_key_t))); - } else { - decaf_TOY_strobe_ad(strobe,your_pubkey,sizeof(API_NS_TOY(public_key_t))); - decaf_TOY_strobe_ad(strobe,my_privkey->pub,sizeof(API_NS_TOY(public_key_t))); - } - decaf_error_t ret = API_NS(direct_scalarmul)( - ss_ser, your_pubkey, my_privkey->secret_scalar, DECAF_FALSE, - DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT - ); - - decaf_TOY_strobe_transact(strobe,NULL,ss_ser,sizeof(ss_ser),STROBE_CW_DH_KEY); - - while (shared_bytes) { - uint16_t cando = (shared_bytes > SHARED_SECRET_MAX_BLOCK_SIZE) - ? SHARED_SECRET_MAX_BLOCK_SIZE : shared_bytes; - decaf_TOY_strobe_prng(strobe,shared,cando); - shared_bytes -= cando; - shared += cando; - } - - decaf_TOY_strobe_destroy(strobe); - decaf_bzero(ss_ser, sizeof(ss_ser)); - - return ret; -} - -void API_NS_TOY(sign_strobe) ( - keccak_decaf_TOY_strobe_t strobe, - API_NS_TOY(signature_t) sig, - const API_NS_TOY(private_key_t) priv -) { - uint8_t overkill[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) point; - API_NS(scalar_t) nonce, challenge; - - /* Stir pubkey */ - decaf_TOY_strobe_transact(strobe,NULL,priv->pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK); - - /* Derive nonce */ - keccak_decaf_TOY_strobe_t strobe2; - memcpy(strobe2,strobe,sizeof(strobe2)); - decaf_TOY_strobe_fixed_key(strobe2,priv->sym,sizeof(API_NS_TOY(symmetric_key_t))); - decaf_TOY_strobe_prng(strobe2,overkill,sizeof(overkill)); - decaf_TOY_strobe_destroy(strobe2); - - API_NS(scalar_decode_long)(nonce, overkill, sizeof(overkill)); - API_NS(precomputed_scalarmul)(point, API_NS(precomputed_base), nonce); - API_NS(point_encode)(sig, point); - - - /* Derive challenge */ - decaf_TOY_strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH); - decaf_TOY_strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); - API_NS(scalar_decode_long)(challenge, overkill, sizeof(overkill)); - - /* Respond */ - API_NS(scalar_mul)(challenge, challenge, priv->secret_scalar); - API_NS(scalar_sub)(nonce, nonce, challenge); - - /* Save results */ - API_NS(scalar_encode)(overkill, nonce); - decaf_TOY_strobe_transact(strobe,&sig[SER_BYTES],overkill,SCALAR_BYTES,STROBE_CW_SIG_RESP); - - /* Clean up */ - API_NS(scalar_destroy)(nonce); - API_NS(scalar_destroy)(challenge); - decaf_bzero(overkill,sizeof(overkill)); -} - -decaf_error_t API_NS_TOY(verify_strobe) ( - keccak_decaf_TOY_strobe_t strobe, - const API_NS_TOY(signature_t) sig, - const API_NS_TOY(public_key_t) pub -) { - decaf_bool_t ret; - - uint8_t overkill[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) point, pubpoint; - API_NS(scalar_t) challenge, response; - - /* Stir pubkey */ - decaf_TOY_strobe_transact(strobe,NULL,pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK); - - /* Derive nonce */ - decaf_TOY_strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH); - ret = decaf_successful( API_NS(point_decode)(point, sig, DECAF_TRUE) ); - - /* Derive challenge */ - decaf_TOY_strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); - API_NS(scalar_decode_long)(challenge, overkill, sizeof(overkill)); - - /* Decode response */ - decaf_TOY_strobe_transact(strobe,overkill,&sig[SER_BYTES],SCALAR_BYTES,STROBE_CW_SIG_RESP); - ret &= decaf_successful( API_NS(scalar_decode)(response, overkill) ); - ret &= decaf_successful( API_NS(point_decode)(pubpoint, pub, DECAF_FALSE) ); - - API_NS(base_double_scalarmul_non_secret) ( - pubpoint, response, pubpoint, challenge - ); - - ret &= API_NS(point_eq)(pubpoint, point); - - /* Nothing here is secret, so don't do these things: - decaf_bzero(overkill,sizeof(overkill)); - API_NS(point_destroy)(point); - API_NS(point_destroy)(pubpoint); - API_NS(scalar_destroy)(challenge); - API_NS(scalar_destroy)(response); - */ - - return decaf_succeed_if(ret); -} - -void -API_NS_TOY(sign) ( - API_NS_TOY(signature_t) sig, - const API_NS_TOY(private_key_t) priv, - const unsigned char *message, - size_t message_len -) { - keccak_decaf_TOY_strobe_t ctx; - decaf_TOY_strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0); - decaf_TOY_strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); - API_NS_TOY(sign_strobe)(ctx, sig, priv); - decaf_TOY_strobe_destroy(ctx); -} - -decaf_error_t -API_NS_TOY(verify) ( - const API_NS_TOY(signature_t) sig, - const API_NS_TOY(public_key_t) pub, - const unsigned char *message, - size_t message_len -) { - keccak_decaf_TOY_strobe_t ctx; - decaf_TOY_strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0); - decaf_TOY_strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); - decaf_error_t ret = API_NS_TOY(verify_strobe)(ctx, sig, pub); - decaf_TOY_strobe_destroy(ctx); - return ret; -} diff --git a/src/include/decaf/crypto.tmpl.h b/src/include/decaf/crypto.tmpl.h deleted file mode 100644 index dec7617..0000000 --- a/src/include/decaf/crypto.tmpl.h +++ /dev/null @@ -1,10 +0,0 @@ -/** - * Example Decaf crypto routines, metaheader. - * @warning These are merely examples, though they ought to be secure. But real - * protocols will decide differently on magic numbers, formats, which items to - * hash, etc. - */ - -$("\n".join([ - "#include " % g for g in sorted([c["bits"] for _,c in curve.iteritems()]) -])) diff --git a/src/include/decaf/strobe.h b/src/include/decaf/strobe.h deleted file mode 100644 index 3021630..0000000 --- a/src/include/decaf/strobe.h +++ /dev/null @@ -1,341 +0,0 @@ -/** - * @file decaf/strobe.h - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * @author Mike Hamburg - * @brief STROBE experimental protocol framework. - * @warning EXPERIMENTAL! The names, parameter orders etc are likely to change. - */ - -#ifndef __DECAF_STROBE_H__ -#define __DECAF_STROBE_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Keccak STROBE structure as struct. */ -typedef struct { - decaf_keccak_sponge_t sponge; /**< Internal sponge object. */ -} keccak_decaf_TOY_strobe_s; - -/** Keccak STROBE structure as one-element array */ -typedef keccak_decaf_TOY_strobe_s keccak_decaf_TOY_strobe_t[1]; - -/** STROBE parameters, 128-bit estimated security for hashing and encryption */ -extern const struct decaf_kparams_s STROBE_128 API_VIS; - -/** STROBE parameters, 256-bit estimated security for hashing and encryption */ -extern const struct decaf_kparams_s STROBE_256 API_VIS; - -/** STROBE parameters, 128-bit estimated security for encryption only (not hashing) */ -extern const struct decaf_kparams_s STROBE_KEYED_128 API_VIS; - -/** STROBE parameters, 256-bit estimated security for encryption only (not hashing) */ -extern const struct decaf_kparams_s STROBE_KEYED_256 API_VIS; - - -/** Initialize Strobe protocol context. */ -void decaf_TOY_strobe_init ( - keccak_decaf_TOY_strobe_t strobe, /**< [out] The uninitialized strobe object. */ - const struct decaf_kparams_s *params, /**< [in] Parameter set descriptor. */ - const char *proto, /**< [in] Unique identifier for the protocol. TODO: define namespaces for this */ - uint8_t am_client /**< [in] Nonzero if this party. */ -) NONNULL API_VIS; - -/** Run a transaction against a STROBE state. */ -void decaf_TOY_strobe_transact ( - keccak_decaf_TOY_strobe_t strobe, /**< [inout] The initialized STROBE object. */ - unsigned char *out, /**< [out] The output. */ - const unsigned char *in, /**< [in] The input. */ - size_t len, /**< [in] The length of the input/output. */ - uint32_t cw_flags /**< [in] The control word with flags. */ -) __attribute__((nonnull(1))) API_VIS; - -/** Record a message sent in plaintext */ -static INLINE UNUSED NONNULL void decaf_TOY_strobe_plaintext ( - keccak_decaf_TOY_strobe_t strobe, /**< [inout] The STROBE object */ - const unsigned char *in, /**< [in] The message. */ - uint16_t len, /**< [in] The length of the message. */ - uint8_t iSent /**< [in] If nonzero, I sent the message. */ -); - -/** Report authenticated data in strobe context. */ -static INLINE UNUSED NONNULL void -decaf_TOY_strobe_ad ( - keccak_decaf_TOY_strobe_t strobe, /**< [inout] The strobe object. */ - const unsigned char *in, /**< [in] The plaintext. */ - size_t len /**< [in] The length of the ad. */ -); - -/** Set nonce in strobe context. */ -static INLINE UNUSED NONNULL void -decaf_TOY_strobe_nonce ( - keccak_decaf_TOY_strobe_t strobe, /**< [inout] The initialized strobe object. */ - const unsigned char *in, /**< [in] The nonce. */ - uint16_t len /**< [in] The length of the nonce. */ -); - -/** Set fixed key in strobe context. */ -static INLINE UNUSED NONNULL void -decaf_TOY_strobe_fixed_key ( - keccak_decaf_TOY_strobe_t strobe, /**< [inout] The initialized strobe object. */ - const unsigned char *in, /**< [in] The key. */ - uint16_t len /**< [in] The length of the key. */ -); - -/** Set Diffie-Hellman key in strobe context. */ -static INLINE UNUSED NONNULL void -decaf_TOY_strobe_dh_key ( - keccak_decaf_TOY_strobe_t strobe, /**< [inout] The initialized strobe object. */ - const unsigned char *in, /**< [in] The key. */ - uint16_t len /**< [in] The length of the key. */ -); - -/** The maximum number of bytes that decaf_TOY_strobe_produce_auth can spit out. */ -#define STROBE_MAX_AUTH_BYTES 32 - -/** Produce an authenticator. */ -static INLINE UNUSED NONNULL void -decaf_TOY_strobe_produce_auth ( - keccak_decaf_TOY_strobe_t strobe, /**< [inout] The Strobe protocol context. */ - unsigned char *out, /**< [out] The authenticator. */ - uint16_t len /**< [in] The length, at most STROBE_MAX_AUTH_BYTES. */ -); - -/** - * @brief Verify an authenticator. - * @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_error_t decaf_TOY_strobe_verify_auth ( - keccak_decaf_TOY_strobe_t strobe, /**< [inout] The Strobe protocol context */ - const unsigned char *in, /**< [in] The authenticator */ - uint16_t len /**< [in] The length, at most STROBE_MAX_AUTH_BYTES. */ -) WARN_UNUSED NONNULL API_VIS; - -/** - * @brief Encrypt bytes from in to out. - * @warning Doesn't produce an auth tag. - */ -static INLINE UNUSED NONNULL void -decaf_TOY_strobe_encrypt ( - keccak_decaf_TOY_strobe_t strobe, /**< [inout] strobe The Strobe protocol context. */ - unsigned char *out, /**< [out] The ciphertext. */ - const unsigned char *in, /**< [in] The plaintext. */ - uint16_t len /**< [in] The length of plaintext and ciphertext. */ -); - -/** - * Decrypt bytes from in to out. - * @warning Doesn't check an auth tag. - */ -static INLINE UNUSED NONNULL void -decaf_TOY_strobe_decrypt ( - keccak_decaf_TOY_strobe_t strobe, /**< [inout] The Strobe protocol context. */ - unsigned char *out, /**< [out] The plaintext. */ - const unsigned char *in, /**< [in] The ciphertext. */ - uint16_t len /**< [in] The length of plaintext and ciphertext. */ -); - -/** - * @brief Produce a session-bound pseudorandom value. - * - * @warning This "prng" value is NOT suitable for - * refreshing forward secrecy! It's to replace things - * like TCP session hash. - */ -static inline void NONNULL decaf_TOY_strobe_prng ( - keccak_decaf_TOY_strobe_t strobe, /**< [inout] The Strobe protocol context */ - unsigned char *out, /**< [out] The output random data. */ - uint16_t len /**< The length. */ -); - -/** Respecify Strobe protocol object's crypto. */ -void decaf_TOY_strobe_respec ( - keccak_decaf_TOY_strobe_t strobe, /**< [inout] The initialized strobe context. */ - const struct decaf_kparams_s *params /**< [in] Strobe parameter descriptor. */ -) NONNULL API_VIS; - -/** Securely destroy a STROBE object by overwriting it. */ -static INLINE UNUSED NONNULL void -decaf_TOY_strobe_destroy ( - keccak_decaf_TOY_strobe_t doomed /**< [in] The object to destroy. */ -); - -/** @cond internal */ - -/************************************************************************/ -/* Declarations of various constants and operating modes, for extension */ -/************************************************************************/ - -/** STROBE modes of operation */ -typedef enum { - STROBE_MODE_ABSORB = 0, - STROBE_MODE_DUPLEX = 1, - STROBE_MODE_ABSORB_R = 2, - STROBE_MODE_DUPLEX_R = 3, - /* FIXME: no bits allocated in .py version */ - STROBE_MODE_PLAINTEXT = 4, - STROBE_MODE_SQUEEZE = 5, - STROBE_MODE_FORGET = 6, - STROBE_MODE_SQUEEZE_R = 7 -} decaf_TOY_strobe_mode_t; - -#define STROBE_FLAG_CLIENT_SENT (1<<8) /**< Set if the client this message. */ -#define STROBE_FLAG_IMPLICIT (1<<9) /**< Set if nobody set this message. */ -#define STROBE_FLAG_FORGET (1<<12) /**< After this operation, destroy bytes to prevent rollback. */ -/* TODO: maybe just make STROBE heavy non-invertible? */ -#define STROBE_FLAG_NO_LENGTH (1<<15) /**< This operation has an unknown length (for streaming). */ - -/* After 1<<16, flags don't go to the sponge anymore, they just affect the handling */ -#define STROBE_FLAG_RECV (1<<16) /**< I received this packet, so reverse directions. */ -#define STROBE_FLAG_RUN_F (1<<17) /**< Must run F between control word and data. */ -#define STROBE_FLAG_MORE (1<<18) /**< Set for all operations in an unknown-length streaming operation after the first */ -#define STROBE_FLAG_LENGTH_64 (1<<19) /**< Length is a 64-bit word instead of a 16-bit one. */ -#define STROBE_FLAG_NONDIR (STROBE_FLAG_IMPLICIT) - -/** Automatic flags implied by the mode */ -/* NB: SQUEEZE_R is treated as directional because its' MAC. - * can of course override by orring in IMPLICIT|NONDIR - */ -#define STROBE_AUTO_FLAGS(_mode) \ - ( (((_mode)&1) ? STROBE_FLAG_RUN_F : 0) \ - | (( ((_mode) & ~2) == STROBE_MODE_ABSORB \ - || (_mode) == STROBE_MODE_SQUEEZE \ - || (_mode) == STROBE_MODE_FORGET \ - ) ? STROBE_FLAG_IMPLICIT|STROBE_FLAG_NONDIR : 0) \ - ) - -/**@ Define a control word for STROBE protocols. */ -#define STROBE_CONTROL_WORD(_name,_id,_mode,_flags) \ - static const uint32_t _name = _id | (_mode<<10) | (_mode<<29) | _flags | STROBE_AUTO_FLAGS(_mode) - -STROBE_CONTROL_WORD(STROBE_CW_INIT, 0x00, STROBE_MODE_ABSORB, 0); /**< Initialization with protocol name */ - -/* Ciphers */ -STROBE_CONTROL_WORD(STROBE_CW_FIXED_KEY, 0x10, STROBE_MODE_ABSORB, 0); /**< Fixed symmetric/preshared key */ -STROBE_CONTROL_WORD(STROBE_CW_STATIC_PUB, 0x11, STROBE_MODE_PLAINTEXT, 0); /**< Static public key of other party */ -STROBE_CONTROL_WORD(STROBE_CW_DH_EPH, 0x12, STROBE_MODE_PLAINTEXT, 0); /**< DH ephemeral key on the wire */ -STROBE_CONTROL_WORD(STROBE_CW_DH_KEY, 0x13, STROBE_MODE_ABSORB, 0); /**< DH shared secret key */ -STROBE_CONTROL_WORD(STROBE_CW_PRNG, 0x18, STROBE_MODE_SQUEEZE, STROBE_FLAG_FORGET); /**< Generate random bits (for PRNG) */ -STROBE_CONTROL_WORD(STROBE_CW_SESSION_HASH, 0x19, STROBE_MODE_SQUEEZE, 0); /**< Generate session hash */ - -/* Reuse for PRNG */ -STROBE_CONTROL_WORD(STROBE_CW_PRNG_INITIAL_SEED, 0x10, STROBE_MODE_ABSORB, STROBE_FLAG_NO_LENGTH); /**< Initial seeding for PRNG */ -STROBE_CONTROL_WORD(STROBE_CW_PRNG_RESEED, 0x11, STROBE_MODE_ABSORB, STROBE_FLAG_NO_LENGTH); /**< Later seeding for PRNG */ -STROBE_CONTROL_WORD(STROBE_CW_PRNG_CPU_SEED, 0x12, STROBE_MODE_ABSORB, 0); /**< Seed from CPU-builin RNG */ -STROBE_CONTROL_WORD(STROBE_CW_PRNG_USER_SEED, 0x13, STROBE_MODE_ABSORB, STROBE_FLAG_LENGTH_64); /**< Seed from user */ -STROBE_CONTROL_WORD(STROBE_CW_PRNG_PRNG, 0x14, STROBE_MODE_SQUEEZE, STROBE_FLAG_LENGTH_64 | STROBE_FLAG_FORGET); /**< Call to generate bits */ - -/* Signatures */ -STROBE_CONTROL_WORD(STROBE_CW_SIG_SCHEME, 0x20, STROBE_MODE_ABSORB, 0); /**< Name of the signature scheme we're using. */ -STROBE_CONTROL_WORD(STROBE_CW_SIG_PK, 0x21, STROBE_MODE_ABSORB, 0); /**< Public (verification key) */ -STROBE_CONTROL_WORD(STROBE_CW_SIG_EPH, 0x22, STROBE_MODE_PLAINTEXT, 0); /**< Schnorr ephemeral. */ -STROBE_CONTROL_WORD(STROBE_CW_SIG_CHAL, 0x23, STROBE_MODE_SQUEEZE, 0); /**< Schnorr challenge. */ -STROBE_CONTROL_WORD(STROBE_CW_SIG_RESP, 0x24, STROBE_MODE_DUPLEX, 0); /**< Schnoll response. */ - -/* Payloads and encrypted data */ - -STROBE_CONTROL_WORD(STROBE_CW_PAYLOAD_PLAINTEXT, 0x30, STROBE_MODE_PLAINTEXT, 0); -STROBE_CONTROL_WORD(STROBE_CW_PAYLOAD_CIPHERTEXT, 0x31, STROBE_MODE_DUPLEX, 0); -STROBE_CONTROL_WORD(STROBE_CW_MAC, 0x32, STROBE_MODE_SQUEEZE_R, STROBE_FLAG_FORGET); -STROBE_CONTROL_WORD(STROBE_CW_AD_EXPLICIT, 0x34, STROBE_MODE_PLAINTEXT, 0); -STROBE_CONTROL_WORD(STROBE_CW_AD_IMPLICIT, 0x35, STROBE_MODE_ABSORB, 0); -STROBE_CONTROL_WORD(STROBE_CW_NONCE_EXPLICIT, 0x36, STROBE_MODE_PLAINTEXT, 0); -STROBE_CONTROL_WORD(STROBE_CW_NONCE_IMPLICIT, 0x37, STROBE_MODE_ABSORB, 0); - -STROBE_CONTROL_WORD(STROBE_CW_STREAMING_PLAINTEXT,0x30, STROBE_MODE_PLAINTEXT, STROBE_FLAG_NO_LENGTH); /* TODO: orly? */ - -/* Change spec, control flow, etc */ -STROBE_CONTROL_WORD(STROBE_CW_COMPRESS, 0x40, STROBE_MODE_ABSORB_R, 0); -/* FIXME: adjust this respec logic */ -STROBE_CONTROL_WORD(STROBE_CW_RESPEC_INFO, 0x41, STROBE_MODE_ABSORB, STROBE_FLAG_RUN_F | STROBE_FLAG_FORGET); -STROBE_CONTROL_WORD(STROBE_CW_RESPEC, 0x42, STROBE_MODE_ABSORB_R, STROBE_FLAG_RUN_F); -STROBE_CONTROL_WORD(STROBE_CW_FORK, 0x43, STROBE_MODE_ABSORB_R, STROBE_FLAG_RUN_F | STROBE_FLAG_FORGET); -/* FIXME: instance can be rolled back to recover other INSTANCEs */ -STROBE_CONTROL_WORD(STROBE_CW_INSTANCE, 0x44, STROBE_MODE_ABSORB_R, STROBE_FLAG_FORGET); -STROBE_CONTROL_WORD(STROBE_CW_ACKNOWLEDGE, 0x45, STROBE_MODE_PLAINTEXT, 0); - -/** Reverse a keyword because it's being received instead of sent */ -static INLINE UNUSED WARN_UNUSED uint32_t -decaf_TOY_strobe_cw_recv(uint32_t cw) { - uint32_t recv_toggle = (cw & STROBE_FLAG_NONDIR) ? 0 : STROBE_FLAG_RECV; - if (cw & STROBE_FLAG_IMPLICIT) { - return cw ^ recv_toggle; - } else { - uint32_t modes_2[8] = { - /* Note: most of these really shouldn't happen... */ - STROBE_MODE_ABSORB, - STROBE_MODE_DUPLEX_R, - STROBE_MODE_ABSORB_R, - STROBE_MODE_DUPLEX, - STROBE_MODE_PLAINTEXT, - STROBE_MODE_SQUEEZE, - STROBE_MODE_FORGET, - STROBE_MODE_ABSORB - }; - - return ((cw & ((1<<29)-1)) | (modes_2[cw>>29]<<29)) ^ recv_toggle; - } -} - -/***************************************/ -/* Implementations of inline functions */ -/***************************************/ - -void decaf_TOY_strobe_plaintext(keccak_decaf_TOY_strobe_t strobe, const unsigned char *in, uint16_t len, uint8_t iSent) { - decaf_TOY_strobe_transact( - strobe, NULL, in, len, - iSent ? STROBE_CW_PAYLOAD_PLAINTEXT - : decaf_TOY_strobe_cw_recv(STROBE_CW_PAYLOAD_PLAINTEXT) - ); -} - -void decaf_TOY_strobe_ad(keccak_decaf_TOY_strobe_t strobe, const unsigned char *in, size_t len) { - decaf_TOY_strobe_transact( strobe, NULL, in, len, STROBE_CW_AD_EXPLICIT ); -} - -void decaf_TOY_strobe_nonce (keccak_decaf_TOY_strobe_t strobe, const unsigned char *in, uint16_t len) { - decaf_TOY_strobe_transact( strobe, NULL, in, len, STROBE_CW_NONCE_EXPLICIT ); -} - -void decaf_TOY_strobe_fixed_key (keccak_decaf_TOY_strobe_t strobe, const unsigned char *in, uint16_t len) { - decaf_TOY_strobe_transact( strobe, NULL, in, len, STROBE_CW_FIXED_KEY ); -} - -void decaf_TOY_strobe_dh_key (keccak_decaf_TOY_strobe_t strobe, const unsigned char *in, uint16_t len) { - decaf_TOY_strobe_transact( strobe, NULL, in, len, STROBE_CW_DH_KEY ); -} - -void decaf_TOY_strobe_produce_auth (keccak_decaf_TOY_strobe_t strobe, unsigned char *out, uint16_t len) { - decaf_TOY_strobe_transact( strobe, out, NULL, len, STROBE_CW_MAC ); -} - -void decaf_TOY_strobe_encrypt (keccak_decaf_TOY_strobe_t strobe, unsigned char *out, const unsigned char *in, uint16_t len) { - decaf_TOY_strobe_transact(strobe, out, in, len, STROBE_CW_PAYLOAD_CIPHERTEXT); -} - -void decaf_TOY_strobe_decrypt(keccak_decaf_TOY_strobe_t strobe, unsigned char *out, const unsigned char *in, uint16_t len) { - decaf_TOY_strobe_transact(strobe, out, in, len, decaf_TOY_strobe_cw_recv(STROBE_CW_PAYLOAD_CIPHERTEXT)); -} - -void decaf_TOY_strobe_prng(keccak_decaf_TOY_strobe_t strobe, unsigned char *out, uint16_t len) { - decaf_TOY_strobe_transact( strobe, out, NULL, len, STROBE_CW_PRNG ); -} - -void decaf_TOY_strobe_destroy (keccak_decaf_TOY_strobe_t doomed) { - decaf_sponge_destroy(doomed->sponge); -} - -/** @endcond */ /* internal */ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* __DECAF_STROBE_H__ */ diff --git a/src/include/decaf/strobe.hxx b/src/include/decaf/strobe.hxx deleted file mode 100644 index 06331e0..0000000 --- a/src/include/decaf/strobe.hxx +++ /dev/null @@ -1,239 +0,0 @@ -/** - * @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 - -#include - - -/** @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 { -public: - /** The wrapped object */ - keccak_decaf_TOY_strobe_t wrapped; - - /** 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 decaf_kparams_s ¶ms = STROBE_256 /**< Strength parameters */ - ) NOEXCEPT { - decaf_TOY_strobe_init(wrapped, ¶ms, description, whoami == CLIENT); - keyed = false; - } - - /** Securely destroy by overwriting state. */ - inline ~Strobe() NOEXCEPT { decaf_TOY_strobe_destroy(wrapped); } - - /** Stir in fixed key, from a C++ block. */ - inline void fixed_key ( - const Block &data /**< The key. */ - ) throw(ProtocolException) { - decaf_TOY_strobe_fixed_key(wrapped, data.data(), data.size()); - keyed = true; - } - - /** Stir in fixed key, from a serializeable object. */ - template inline void fixed_key ( - const Serializable &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) { - decaf_TOY_strobe_dh_key(wrapped, data.data(), data.size()); - keyed = true; - } - - /** Stir in DH key, from a serializeable object. */ - template inline void dh_key ( - const Serializable &data /**< The key. */ - ) throw(ProtocolException) { - dh_key(data.serialize()); - } - - /** Stir in an explicit nonce. */ - inline void nonce(const Block &data) NOEXCEPT { - decaf_TOY_strobe_nonce(wrapped, 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 { - decaf_TOY_strobe_plaintext(wrapped, data.data(), data.size(), true); - } - - /** Stir in serializeable data we sent as plaintext. NB This doesn't actually send anything. */ - template inline void send_plaintext(const Serializable &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 { - decaf_TOY_strobe_plaintext(wrapped, data.data(), data.size(), false); - } - - /** Stir in associated data. */ - inline void ad(const Block &data) { - decaf_TOY_strobe_ad(wrapped, data.data(), data.size()); - } - - /** Stir in associated serializable data. */ - template inline void ad(const Serializable &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(); - decaf_TOY_strobe_encrypt(wrapped, 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 inline SecureBuffer encrypt_no_auth(const Serializable &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(); - decaf_TOY_strobe_decrypt(wrapped, 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(); - decaf_TOY_strobe_produce_auth(wrapped, 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 inline SecureBuffer encrypt ( - const Serializable &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 (decaf_TOY_strobe_verify_auth(wrapped, auth.data(), auth.size()) != DECAF_SUCCESS) throw CryptoException(); - } - - /** Fill pseudorandom data into a buffer */ - inline void prng(Buffer out) NOEXCEPT { - (void)decaf_TOY_strobe_prng(wrapped, 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 decaf_kparams_s ¶ms) throw(ProtocolException) { - if (!keyed) throw(ProtocolException()); - decaf_TOY_strobe_respec(wrapped, ¶ms); - } - -private: - bool keyed; -}; - -} /* namespace decaf */ - -#undef NOEXCEPT -#undef DELETE - -#endif /* __DECAF_STROBE_HXX__ */ diff --git a/src/include/keccak_internal.h b/src/include/keccak_internal.h index b0875a1..15d1be4 100644 --- a/src/include/keccak_internal.h +++ b/src/include/keccak_internal.h @@ -5,7 +5,7 @@ * Copyright (c) 2016 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * @author Mike Hamburg - * @brief Keccak internal interfaces, used by STROBE. + * @brief Keccak internal interfaces. Will be used by STROBE once reintegrated. */ #ifndef __DECAF_KECCAK_INTERNAL_H__ #define __DECAF_KECCAK_INTERNAL_H__ 1 @@ -18,8 +18,8 @@ typedef union { } kdomain_t[1]; typedef struct decaf_kparams_s { - uint8_t position, flags, rate, start_round, pad, rate_pad, max_out, client; /* client = max_outRemaining for decaf_sha3 */ -} decaf_kparams_t[1]; + uint8_t position, flags, rate, start_round, pad, rate_pad, max_out, remaining; +} decaf_kparams_s, decaf_kparams_t[1]; typedef struct decaf_keccak_sponge_s { kdomain_t state; diff --git a/src/per_curve/crypto.tmpl.c b/src/per_curve/crypto.tmpl.c deleted file mode 100644 index a169013..0000000 --- a/src/per_curve/crypto.tmpl.c +++ /dev/null @@ -1,222 +0,0 @@ -/** - * @cond internal - * @brief Example Decaf crypto routines - */ - -#include -#include - -#define API_NAME "$(c_ns)" -#define API_NS(_id) $(c_ns)_##_id -#define API_NS_TOY(_id) $(c_ns)_TOY_##_id -#define SCALAR_BITS $(C_NS)_SCALAR_BITS -#define SCALAR_BYTES ((SCALAR_BITS + 7)/8) -#define SER_BYTES $(C_NS)_SER_BYTES - - /* TODO: canonicalize and freeze the STROBE constants in this file - * (and STROBE itself for that matter) - */ -static const char *DERIVE_MAGIC = API_NAME"::derive_private_key"; -static const char *SIGN_MAGIC = API_NAME"::sign"; -static const char *SHARED_SECRET_MAGIC = API_NAME"::shared_secret"; -static const uint16_t SHARED_SECRET_MAX_BLOCK_SIZE = 1<<12; -static const unsigned int SCALAR_OVERKILL_BYTES = SCALAR_BYTES + 8; - -void API_NS_TOY(derive_private_key) ( - API_NS_TOY(private_key_t) priv, - const API_NS_TOY(symmetric_key_t) proto -) { - uint8_t encoded_scalar[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) pub; - - keccak_decaf_TOY_strobe_t strobe; - decaf_TOY_strobe_init(strobe, &STROBE_256, DERIVE_MAGIC, 0); - decaf_TOY_strobe_fixed_key(strobe, proto, sizeof(API_NS_TOY(symmetric_key_t))); - decaf_TOY_strobe_prng(strobe, encoded_scalar, sizeof(encoded_scalar)); - decaf_TOY_strobe_destroy(strobe); - - memcpy(priv->sym, proto, sizeof(API_NS_TOY(symmetric_key_t))); - API_NS(scalar_decode_long)(priv->secret_scalar, encoded_scalar, sizeof(encoded_scalar)); - - API_NS(precomputed_scalarmul)(pub, API_NS(precomputed_base), priv->secret_scalar); - API_NS(point_encode)(priv->pub, pub); - - decaf_bzero(encoded_scalar, sizeof(encoded_scalar)); -} - -void API_NS_TOY(destroy_private_key) ( - API_NS_TOY(private_key_t) priv -) { - decaf_bzero((void*)priv, sizeof(API_NS_TOY(private_key_t))); -} - -void API_NS_TOY(private_to_public) ( - API_NS_TOY(public_key_t) pub, - const API_NS_TOY(private_key_t) priv -) { - memcpy(pub, priv->pub, sizeof(API_NS_TOY(public_key_t))); -} - -/* Performance vs consttime tuning. - * Specifying true here might give better DOS resistance in certain corner - * cases. Specifying false gives a tighter result in test_ct. - */ -#ifndef DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT -#define DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT DECAF_FALSE -#endif - -decaf_error_t API_NS_TOY(shared_secret) ( - uint8_t *shared, - size_t shared_bytes, - const API_NS_TOY(private_key_t) my_privkey, - const API_NS_TOY(public_key_t) your_pubkey, - int me_first -) { - keccak_decaf_TOY_strobe_t strobe; - decaf_TOY_strobe_init(strobe, &STROBE_256, SHARED_SECRET_MAGIC, 0); - - uint8_t ss_ser[SER_BYTES]; - - if (me_first) { - decaf_TOY_strobe_ad(strobe,my_privkey->pub,sizeof(API_NS_TOY(public_key_t))); - decaf_TOY_strobe_ad(strobe,your_pubkey,sizeof(API_NS_TOY(public_key_t))); - } else { - decaf_TOY_strobe_ad(strobe,your_pubkey,sizeof(API_NS_TOY(public_key_t))); - decaf_TOY_strobe_ad(strobe,my_privkey->pub,sizeof(API_NS_TOY(public_key_t))); - } - decaf_error_t ret = API_NS(direct_scalarmul)( - ss_ser, your_pubkey, my_privkey->secret_scalar, DECAF_FALSE, - DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT - ); - - decaf_TOY_strobe_transact(strobe,NULL,ss_ser,sizeof(ss_ser),STROBE_CW_DH_KEY); - - while (shared_bytes) { - uint16_t cando = (shared_bytes > SHARED_SECRET_MAX_BLOCK_SIZE) - ? SHARED_SECRET_MAX_BLOCK_SIZE : shared_bytes; - decaf_TOY_strobe_prng(strobe,shared,cando); - shared_bytes -= cando; - shared += cando; - } - - decaf_TOY_strobe_destroy(strobe); - decaf_bzero(ss_ser, sizeof(ss_ser)); - - return ret; -} - -void API_NS_TOY(sign_strobe) ( - keccak_decaf_TOY_strobe_t strobe, - API_NS_TOY(signature_t) sig, - const API_NS_TOY(private_key_t) priv -) { - uint8_t overkill[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) point; - API_NS(scalar_t) nonce, challenge; - - /* Stir pubkey */ - decaf_TOY_strobe_transact(strobe,NULL,priv->pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK); - - /* Derive nonce */ - keccak_decaf_TOY_strobe_t strobe2; - memcpy(strobe2,strobe,sizeof(strobe2)); - decaf_TOY_strobe_fixed_key(strobe2,priv->sym,sizeof(API_NS_TOY(symmetric_key_t))); - decaf_TOY_strobe_prng(strobe2,overkill,sizeof(overkill)); - decaf_TOY_strobe_destroy(strobe2); - - API_NS(scalar_decode_long)(nonce, overkill, sizeof(overkill)); - API_NS(precomputed_scalarmul)(point, API_NS(precomputed_base), nonce); - API_NS(point_encode)(sig, point); - - - /* Derive challenge */ - decaf_TOY_strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH); - decaf_TOY_strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); - API_NS(scalar_decode_long)(challenge, overkill, sizeof(overkill)); - - /* Respond */ - API_NS(scalar_mul)(challenge, challenge, priv->secret_scalar); - API_NS(scalar_sub)(nonce, nonce, challenge); - - /* Save results */ - API_NS(scalar_encode)(overkill, nonce); - decaf_TOY_strobe_transact(strobe,&sig[SER_BYTES],overkill,SCALAR_BYTES,STROBE_CW_SIG_RESP); - - /* Clean up */ - API_NS(scalar_destroy)(nonce); - API_NS(scalar_destroy)(challenge); - decaf_bzero(overkill,sizeof(overkill)); -} - -decaf_error_t API_NS_TOY(verify_strobe) ( - keccak_decaf_TOY_strobe_t strobe, - const API_NS_TOY(signature_t) sig, - const API_NS_TOY(public_key_t) pub -) { - decaf_bool_t ret; - - uint8_t overkill[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) point, pubpoint; - API_NS(scalar_t) challenge, response; - - /* Stir pubkey */ - decaf_TOY_strobe_transact(strobe,NULL,pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK); - - /* Derive nonce */ - decaf_TOY_strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH); - ret = decaf_successful( API_NS(point_decode)(point, sig, DECAF_TRUE) ); - - /* Derive challenge */ - decaf_TOY_strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); - API_NS(scalar_decode_long)(challenge, overkill, sizeof(overkill)); - - /* Decode response */ - decaf_TOY_strobe_transact(strobe,overkill,&sig[SER_BYTES],SCALAR_BYTES,STROBE_CW_SIG_RESP); - ret &= decaf_successful( API_NS(scalar_decode)(response, overkill) ); - ret &= decaf_successful( API_NS(point_decode)(pubpoint, pub, DECAF_FALSE) ); - - API_NS(base_double_scalarmul_non_secret) ( - pubpoint, response, pubpoint, challenge - ); - - ret &= API_NS(point_eq)(pubpoint, point); - - /* Nothing here is secret, so don't do these things: - decaf_bzero(overkill,sizeof(overkill)); - API_NS(point_destroy)(point); - API_NS(point_destroy)(pubpoint); - API_NS(scalar_destroy)(challenge); - API_NS(scalar_destroy)(response); - */ - - return decaf_succeed_if(ret); -} - -void -API_NS_TOY(sign) ( - API_NS_TOY(signature_t) sig, - const API_NS_TOY(private_key_t) priv, - const unsigned char *message, - size_t message_len -) { - keccak_decaf_TOY_strobe_t ctx; - decaf_TOY_strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0); - decaf_TOY_strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); - API_NS_TOY(sign_strobe)(ctx, sig, priv); - decaf_TOY_strobe_destroy(ctx); -} - -decaf_error_t -API_NS_TOY(verify) ( - const API_NS_TOY(signature_t) sig, - const API_NS_TOY(public_key_t) pub, - const unsigned char *message, - size_t message_len -) { - keccak_decaf_TOY_strobe_t ctx; - decaf_TOY_strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0); - decaf_TOY_strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); - decaf_error_t ret = API_NS_TOY(verify_strobe)(ctx, sig, pub); - decaf_TOY_strobe_destroy(ctx); - return ret; -} diff --git a/src/per_curve/crypto.tmpl.h b/src/per_curve/crypto.tmpl.h deleted file mode 100644 index 71faf57..0000000 --- a/src/per_curve/crypto.tmpl.h +++ /dev/null @@ -1,163 +0,0 @@ -/** - * Example Decaf crypto routines. - * @warning These are merely examples, though they ought to be secure. But real - * protocols will decide differently on magic numbers, formats, which items to - * hash, etc. - * @warning Experimental! The names, parameter orders etc are likely to change. - */ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** Number of bytes for a symmetric key (expanded to full key) */ -#define $(C_NS)_SYMMETRIC_KEY_BYTES 32 - -/** A symmetric key, the compressed point of a private key. */ -typedef unsigned char $(c_ns)_TOY_symmetric_key_t[$(C_NS)_SYMMETRIC_KEY_BYTES]; - -/** An encoded public key. */ -typedef unsigned char $(c_ns)_TOY_public_key_t[$(C_NS)_SER_BYTES]; - -/** A signature. */ -typedef unsigned char $(c_ns)_TOY_signature_t[$(C_NS)_SER_BYTES + $(C_NS)_SCALAR_BYTES]; - -typedef struct { - /** @cond internal */ - /** The symmetric key from which everything is expanded */ - $(c_ns)_TOY_symmetric_key_t sym; - - /** The scalar x */ - $(c_ns)_scalar_t secret_scalar; - - /** x*Base */ - $(c_ns)_TOY_public_key_t pub; - /** @endcond */ -} /** Private key structure for pointers. */ - $(c_ns)_TOY_private_key_s, - /** A private key (gmp array[1] style). */ - $(c_ns)_TOY_private_key_t[1]; - -/** - * Derive a key from its compressed form. - * @param [out] priv The derived private key. - * @param [in] proto The compressed or proto-key, which must be 32 random bytes. - */ -void $(c_ns)_TOY_derive_private_key ( - $(c_ns)_TOY_private_key_t priv, - const $(c_ns)_TOY_symmetric_key_t proto -) NONNULL API_VIS; - -/** - * Destroy a private key. - */ -void $(c_ns)_TOY_destroy_private_key ( - $(c_ns)_TOY_private_key_t priv -) NONNULL API_VIS; - -/** - * Convert a private key to a public one. - * @param [out] pub The extracted private key. - * @param [in] priv The private key. - */ -void $(c_ns)_TOY_private_to_public ( - $(c_ns)_TOY_public_key_t pub, - const $(c_ns)_TOY_private_key_t priv -) NONNULL API_VIS; - -/** - * Compute a Diffie-Hellman shared secret. - * - * This is an example routine; real protocols would use something - * protocol-specific. - * - * @param [out] shared A buffer to store the shared secret. - * @param [in] shared_bytes The size of the buffer. - * @param [in] my_privkey My private key. - * @param [in] your_pubkey Your public key. - * @param [in] me_first Direction flag to break symmetry. - * - * @retval DECAF_SUCCESS Key exchange was successful. - * @retval DECAF_FAILURE Key exchange failed. - */ -decaf_error_t -$(c_ns)_TOY_shared_secret ( - uint8_t *shared, - size_t shared_bytes, - const $(c_ns)_TOY_private_key_t my_privkey, - const $(c_ns)_TOY_public_key_t your_pubkey, - int me_first -) NONNULL WARN_UNUSED API_VIS; - -/** - * Sign a message from a STROBE context. - * - * @param [out] sig The signature. - * @param [in] priv Your private key. - * @param [in] strobe A STROBE context with the message. - */ -void -$(c_ns)_TOY_sign_strobe ( - keccak_decaf_TOY_strobe_t strobe, - $(c_ns)_TOY_signature_t sig, - const $(c_ns)_TOY_private_key_t priv -) NONNULL API_VIS; - -/** - * Sign a message. - * - * @param [out] sig The signature. - * @param [in] priv Your private key. - * @param [in] message The message. - * @param [in] message_len The message's length. - */ -void -$(c_ns)_TOY_sign ( - $(c_ns)_TOY_signature_t sig, - const $(c_ns)_TOY_private_key_t priv, - const unsigned char *message, - size_t message_len -) NONNULL API_VIS; - -/** - * Verify a signed message from its STROBE context. - * - * @param [in] sig The signature. - * @param [in] pub The public key. - * @param [in] strobe A STROBE context with the message. - * - * @return DECAF_SUCCESS The signature verified successfully. - * @return DECAF_FAILURE The signature did not verify successfully. - */ -decaf_error_t -$(c_ns)_TOY_verify_strobe ( - keccak_decaf_TOY_strobe_t strobe, - const $(c_ns)_TOY_signature_t sig, - const $(c_ns)_TOY_public_key_t pub -) NONNULL API_VIS WARN_UNUSED; - -/** - * Verify a signed message. - * - * @param [in] sig The signature. - * @param [in] pub The public key. - * @param [in] message The message. - * @param [in] message_len The message's length. - * - * @return DECAF_SUCCESS The signature verified successfully. - * @return DECAF_FAILURE The signature did not verify successfully. - */ -decaf_error_t -$(c_ns)_TOY_verify ( - const $(c_ns)_TOY_signature_t sig, - const $(c_ns)_TOY_public_key_t pub, - const unsigned char *message, - size_t message_len -) NONNULL API_VIS WARN_UNUSED; - -#ifdef __cplusplus -} /* extern "C" */ -#endif diff --git a/src/per_curve/crypto.tmpl.hxx b/src/per_curve/crypto.tmpl.hxx deleted file mode 100644 index 1afcbff..0000000 --- a/src/per_curve/crypto.tmpl.hxx +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Example Decaf cyrpto routines, C++ wrapper. - * @warning These are merely examples, though they ought to be secure. But real - * protocols will decide differently on magic numbers, formats, which items to - * hash, etc. - * @warning Experimental! The names, parameter orders etc are likely to change. - */ - -#include -#include -#include - -/** @cond internal */ -#if __cplusplus >= 201103L -#define NOEXCEPT noexcept -#else -#define NOEXCEPT throw() -#endif -/** @endcond */ - -namespace decaf { namespace TOY { - -/** A public key for crypto over some Group */ -template class PublicKey; - -/** A private key for crypto over some Group */ -template class PrivateKey; - -/** A public key for crypto over $(name) */ -template<> class PublicKey<$(cxx_ns)> - : public Serializable< PublicKey<$(cxx_ns)> > { -private: -/** @cond internal */ - typedef $(c_ns)_TOY_public_key_t Wrapped; - Wrapped wrapped; - template friend class PrivateKey; -/** @endcond */ -public: - /** Underlying group */ - typedef $(cxx_ns) Group; - - /** Signature size. */ - static const size_t SIG_BYTES = sizeof($(c_ns)_TOY_signature_t); - - /** Serialization size. */ - static const size_t SER_BYTES = sizeof(Wrapped); - - /** Read a private key from a string*/ - inline explicit PublicKey(const FixedBlock &b) NOEXCEPT { - memcpy(wrapped,b.data(),sizeof(wrapped)); - } - - /** Read a private key from a string*/ - inline explicit PublicKey(const PrivateKey<$(cxx_ns)> &b) NOEXCEPT; - - /** Create but don't initialize */ - inline explicit PublicKey(const NOINIT&) NOEXCEPT { } - - /** Serialize into a buffer. */ - inline void serialize_into(unsigned char *x) const NOEXCEPT { - memcpy(x,wrapped,sizeof(wrapped)); - } - - /** Serialization size. */ - inline size_t ser_size() const NOEXCEPT { return SER_BYTES; } - - /** Verify a message */ - inline void verify( - const Block &message, - const FixedBlock &sig - ) const throw(CryptoException) { - if (DECAF_SUCCESS != $(c_ns)_TOY_verify(sig.data(),wrapped,message.data(),message.size())) { - throw(CryptoException()); - } - } - - /** Verify a message */ - inline void verify( - Strobe &context, - const FixedBlock &sig - ) const throw(CryptoException) { - if (DECAF_SUCCESS != $(c_ns)_TOY_verify_strobe(context.wrapped,sig.data(),wrapped)) { - throw(CryptoException()); - } - } -}; - -/** A private key for crypto over $(name) */ -template<> class PrivateKey<$(cxx_ns)> - : public Serializable< PrivateKey<$(cxx_ns)> > { -private: -/** @cond internal */ - typedef $(c_ns)_TOY_private_key_t Wrapped; - Wrapped wrapped; - template friend class PublicKey; -/** @endcond */ -public: - /** Underlying group */ - typedef $(cxx_ns) Group; - - /** Signature size. */ - static const size_t SIG_BYTES = sizeof($(c_ns)_TOY_signature_t); - - /** Serialization size. */ - static const size_t SER_BYTES = sizeof(Wrapped); - - /** Compressed size. */ - static const size_t SYM_BYTES = $(C_NS)_SYMMETRIC_KEY_BYTES; - - /** Create but don't initialize */ - inline explicit PrivateKey(const NOINIT&) NOEXCEPT { } - - /** Read a private key from a string*/ - inline explicit PrivateKey(const FixedBlock &b) NOEXCEPT { - memcpy(wrapped,b.data(),sizeof(wrapped)); - } - - /** Read a private key from a string*/ - inline explicit PrivateKey(const FixedBlock &b) NOEXCEPT { - $(c_ns)_TOY_derive_private_key(wrapped, b.data()); - } - - /** Create at random */ - inline explicit PrivateKey(Rng &r) NOEXCEPT { - FixedArrayBuffer tmp(r); - $(c_ns)_TOY_derive_private_key(wrapped, tmp.data()); - } - - /** Secure destructor */ - inline ~PrivateKey() NOEXCEPT { - $(c_ns)_TOY_destroy_private_key(wrapped); - } - - /** Serialization size. */ - inline size_t ser_size() const NOEXCEPT { return SER_BYTES; } - - /** Serialize into a buffer. */ - inline void serialize_into(unsigned char *x) const NOEXCEPT { - memcpy(x,wrapped,sizeof(wrapped)); - } - - /** Compressed serialize. */ - inline SecureBuffer compress() const throw(std::bad_alloc) { - SecureBuffer ret(sizeof(wrapped->sym)); - memcpy(ret.data(),wrapped->sym,sizeof(wrapped->sym)); - return ret; - } - - /** Get the public key */ - inline PublicKey<$(cxx_ns)> pub() const NOEXCEPT { - PublicKey<$(cxx_ns)> ret(*this); return ret; - } - - /** Derive a shared secret */ - inline SecureBuffer shared_secret( - const PublicKey<$(cxx_ns)> &pub, - size_t bytes, - bool me_first - ) const throw(CryptoException,std::bad_alloc) { - SecureBuffer ret(bytes); - if (DECAF_SUCCESS != $(c_ns)_TOY_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) { - throw(CryptoException()); - } - return ret; - } - - /** Derive a shared secret */ - inline decaf_error_t __attribute__((warn_unused_result)) - shared_secret_noexcept( - Buffer ret, - const PublicKey<$(cxx_ns)> &pub, - bool me_first - ) const NOEXCEPT { - return $(c_ns)_TOY_shared_secret(ret.data(),ret.size(),wrapped,pub.wrapped,me_first); - } - - /** Sign a message. */ - inline SecureBuffer sign(const Block &message) const { - SecureBuffer sig(SIG_BYTES); - $(c_ns)_TOY_sign(sig.data(), wrapped, message.data(), message.size()); - return sig; - } - - /** Sign a message. */ - inline SecureBuffer verify(Strobe &context) const { - SecureBuffer sig(SIG_BYTES); - $(c_ns)_TOY_sign_strobe(context.wrapped, sig.data(), wrapped); - return sig; - } -}; - -/** @cond internal */ -PublicKey<$(cxx_ns)>::PublicKey(const PrivateKey<$(cxx_ns)> &b) NOEXCEPT { - $(c_ns)_TOY_private_to_public(wrapped,b.wrapped); -} -/** @endcond */ - -#undef NOEXCEPT -}} /* namespace decaf::TOY */ \ No newline at end of file diff --git a/src/shake.c b/src/shake.c index 560e657..009f4da 100644 --- a/src/shake.c +++ b/src/shake.c @@ -119,10 +119,10 @@ decaf_error_t decaf_sha3_output ( assert(decaf_sponge->params->rate < sizeof(decaf_sponge->state)); if (decaf_sponge->params->max_out != 0xFF) { - if (decaf_sponge->params->client >= len) { - decaf_sponge->params->client -= len; + if (decaf_sponge->params->remaining >= len) { + decaf_sponge->params->remaining -= len; } else { - decaf_sponge->params->client = 0; + decaf_sponge->params->remaining = 0; ret = DECAF_FAILURE; } } @@ -172,7 +172,7 @@ void decaf_sha3_reset ( decaf_keccak_sponge_t decaf_sponge ) { decaf_sponge_init(decaf_sponge, decaf_sponge->params); - decaf_sponge->params->client = decaf_sponge->params->max_out; + decaf_sponge->params->remaining = decaf_sponge->params->max_out; } void decaf_sponge_destroy (decaf_keccak_sponge_t decaf_sponge) { decaf_bzero(decaf_sponge, sizeof(decaf_keccak_sponge_t)); } diff --git a/src/spongerng.c b/src/spongerng.c new file mode 100644 index 0000000..d604b1c --- /dev/null +++ b/src/spongerng.c @@ -0,0 +1,164 @@ +/** + * @cond internal + * @file spongerng.c + * @copyright + * Copyright (c) 2015-2017 Cryptography Research, Inc. \n + * Released under the MIT License. See LICENSE.txt for license information. + * @author Mike Hamburg + * @brief Spongerng instances (STROBE removed) + * @warning The SpongeRNG code isn't stable. Future versions are likely to + * have different outputs. Of course, this only matters in deterministic mode. + */ + +#define __STDC_WANT_LIB_EXT1__ 1 /* for memset_s */ +#include +#include +#include + +#include "keccak_internal.h" +#include + +/* to open and read from /dev/urandom */ +#include +#include +#include +#include + +/** Get entropy from a CPU, preferably in the form of RDRAND, but possibly instead from RDTSC. */ +static void get_cpu_entropy(uint8_t *entropy, size_t len) { +# if (defined(__i386__) || defined(__x86_64__)) + static char tested = 0, have_rdrand = 0; + if (!tested) { + uint32_t a,b,c,d; + a=1; __asm__("cpuid" : "+a"(a), "=b"(b), "=c"(c), "=d"(d)); + have_rdrand = (c>>30)&1; + tested = 1; + } + + if (have_rdrand) { + # if defined(__x86_64__) + uint64_t out, a=0, *eo = (uint64_t *)entropy; + # elif defined(__i386__) + uint32_t out, a=0, *eo = (uint32_t *)entropy; + #endif + len /= sizeof(out); + + uint32_t tries; + for (tries = 100+len; tries && len; len--, eo++) { + for (a = 0; tries && !a; tries--) { + __asm__ __volatile__ ("rdrand %0\n\tsetc %%al" : "=r"(out), "+a"(a) :: "cc" ); + } + *eo ^= out; + } + } else if (len>=8) { +#ifndef __has_builtin +#define __has_builtin(X) 0 +#endif +#if defined(__clang__) && __has_builtin(__builtin_readcyclecounter) + *(uint64_t*) entropy ^= __builtin_readcyclecounter(); +#elif defined(__x86_64__) + uint32_t lobits, hibits; + __asm__ __volatile__ ("rdtsc" : "=a"(lobits), "=d"(hibits)); + *(uint64_t*) entropy ^= (lobits | ((uint64_t)(hibits) << 32)); +#elif defined(__i386__) + uint64_t __value; + __asm__ __volatile__ ("rdtsc" : "=A"(__value)); + *(uint64_t*) entropy ^= __value; +#endif + } + +#else + (void) entropy; + (void) len; +#endif +} + +void decaf_spongerng_next ( + decaf_keccak_prng_t prng, + uint8_t * __restrict__ out, + size_t len +) { + if (prng->sponge->params->remaining) { + /* nondet */ + uint8_t cpu_entropy[32]; + get_cpu_entropy(cpu_entropy, sizeof(cpu_entropy)); + decaf_spongerng_stir(prng,cpu_entropy,sizeof(cpu_entropy)); + decaf_bzero(cpu_entropy,sizeof(cpu_entropy)); + } + + uint8_t lenx[8]; + size_t len1 = len; + for (unsigned i=0; i>= 8; + } + decaf_sha3_update(prng->sponge,lenx,sizeof(lenx)); + decaf_sha3_output(prng->sponge,out,len); + + const uint8_t nope; + decaf_spongerng_stir(prng,&nope,0); +} + +void decaf_spongerng_stir ( + decaf_keccak_prng_t prng, + const uint8_t * __restrict__ in, + size_t len +) { + uint8_t seed[32]; + decaf_sha3_output(prng->sponge,seed,sizeof(seed)); + uint8_t nondet = prng->sponge->params->remaining; + + decaf_sha3_reset(prng->sponge); + decaf_sha3_update(prng->sponge,seed,sizeof(seed)); + decaf_sha3_update(prng->sponge,in,len); + + prng->sponge->params->remaining = nondet; + decaf_bzero(seed,sizeof(seed)); +} + +void decaf_spongerng_init_from_buffer ( + decaf_keccak_prng_t prng, + const uint8_t * __restrict__ in, + size_t len, + int deterministic +) { + decaf_sponge_init(prng->sponge,&DECAF_SHAKE256_params_s); + prng->sponge->params->remaining = !deterministic; /* A bit of a hack; this param is ignored for SHAKE */ + decaf_spongerng_stir(prng, in, len); +} + +decaf_error_t decaf_spongerng_init_from_file ( + decaf_keccak_prng_t prng, + const char *file, + size_t len, + int deterministic +) { + decaf_sponge_init(prng->sponge,&DECAF_SHAKE256_params_s); + prng->sponge->params->remaining = !deterministic; /* A bit of a hack; this param is ignored for SHAKE */ + if (!len) return DECAF_FAILURE; + + int fd = open(file, O_RDONLY); + if (fd < 0) return DECAF_FAILURE; + + uint8_t buffer[128]; + while (len) { + ssize_t red = read(fd, buffer, (len > sizeof(buffer)) ? sizeof(buffer) : len); + if (red <= 0) { + close(fd); + return DECAF_FAILURE; + } + decaf_sha3_update(prng->sponge,buffer,red); + len -= red; + }; + close(fd); + const uint8_t nope; + decaf_spongerng_stir(prng,&nope,0); + + return DECAF_SUCCESS; +} + +decaf_error_t decaf_spongerng_init_from_dev_urandom ( + decaf_keccak_prng_t decaf_sponge +) { + return decaf_spongerng_init_from_file(decaf_sponge, "/dev/urandom", 64, 0); +} diff --git a/src/strobe.c b/src/strobe.c deleted file mode 100644 index 76ab574..0000000 --- a/src/strobe.c +++ /dev/null @@ -1,412 +0,0 @@ -/** - * @cond internal - * @file strobe.c - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * @author Mike Hamburg - * @brief STROBE and spongerng instances. - * @warning All APIs in here are toys. They will change behavior and probably also API. - * Do not use them for anything serious. - */ - -#define __STDC_WANT_LIB_EXT1__ 1 /* for memset_s */ -#include -#include -#include - -#include "keccak_internal.h" -#include -#include - -/* to open and read from /dev/urandom */ -#include -#include -#include -#include - -/** Get entropy from a CPU, preferably in the form of RDRAND, but possibly instead from RDTSC. */ -static void get_cpu_entropy(uint8_t *entropy, size_t len) { -# if (defined(__i386__) || defined(__x86_64__)) - static char tested = 0, have_rdrand = 0; - if (!tested) { - uint32_t a,b,c,d; - a=1; __asm__("cpuid" : "+a"(a), "=b"(b), "=c"(c), "=d"(d)); - have_rdrand = (c>>30)&1; - tested = 1; - } - - if (have_rdrand) { - # if defined(__x86_64__) - uint64_t out, a=0, *eo = (uint64_t *)entropy; - # elif defined(__i386__) - uint32_t out, a=0, *eo = (uint32_t *)entropy; - #endif - len /= sizeof(out); - - uint32_t tries; - for (tries = 100+len; tries && len; len--, eo++) { - for (a = 0; tries && !a; tries--) { - __asm__ __volatile__ ("rdrand %0\n\tsetc %%al" : "=r"(out), "+a"(a) :: "cc" ); - } - *eo ^= out; - } - } else if (len>=8) { -#ifndef __has_builtin -#define __has_builtin(X) 0 -#endif -#if defined(__clang__) && __has_builtin(__builtin_readcyclecounter) - *(uint64_t*) entropy ^= __builtin_readcyclecounter(); -#elif defined(__x86_64__) - uint32_t lobits, hibits; - __asm__ __volatile__ ("rdtsc" : "=a"(lobits), "=d"(hibits)); - *(uint64_t*) entropy ^= (lobits | ((uint64_t)(hibits) << 32)); -#elif defined(__i386__) - uint64_t __value; - __asm__ __volatile__ ("rdtsc" : "=A"(__value)); - *(uint64_t*) entropy ^= __value; -#endif - } - -#else - (void) entropy; - (void) len; -#endif -} - -static const char *SPONGERNG_NAME = "strobe::decaf_spongerng"; /* TODO: canonicalize name */ - -void decaf_spongerng_next ( - decaf_keccak_prng_t prng, - uint8_t * __restrict__ out, - size_t len -) { - decaf_keccak_sponge_s *decaf_sponge = prng->sponge; - if (decaf_sponge->params->client) { - /* nondet */ - uint8_t cpu_entropy[32]; - get_cpu_entropy(cpu_entropy, sizeof(cpu_entropy)); - decaf_TOY_strobe_transact((keccak_decaf_TOY_strobe_s*)decaf_sponge,NULL,cpu_entropy,sizeof(cpu_entropy),STROBE_CW_PRNG_CPU_SEED); - } - - decaf_TOY_strobe_transact((keccak_decaf_TOY_strobe_s*)decaf_sponge,out,NULL,len,STROBE_CW_PRNG); -} - -void decaf_spongerng_stir ( - decaf_keccak_prng_t decaf_sponge, - const uint8_t * __restrict__ in, - size_t len -) { - decaf_TOY_strobe_transact((keccak_decaf_TOY_strobe_s*)decaf_sponge,NULL,in,len,STROBE_CW_PRNG_USER_SEED); -} - -static const struct decaf_kparams_s decaf_spongerng_params = { - 0, 0, 200-256/4, 0, 0x06, 0x80, 0xFF, 0 -}; - -void decaf_spongerng_init_from_buffer ( - decaf_keccak_prng_t prng, - const uint8_t * __restrict__ in, - size_t len, - int deterministic -) { - decaf_keccak_sponge_s *decaf_sponge = prng->sponge; - decaf_TOY_strobe_init((keccak_decaf_TOY_strobe_s*)decaf_sponge, &decaf_spongerng_params, SPONGERNG_NAME, !deterministic); - decaf_spongerng_stir(prng, in, len); -} - -decaf_error_t decaf_spongerng_init_from_file ( - decaf_keccak_prng_t prng, - const char *file, - size_t len, - int deterministic -) { - decaf_keccak_sponge_s *decaf_sponge = prng->sponge; - decaf_TOY_strobe_init((keccak_decaf_TOY_strobe_s*)decaf_sponge, &decaf_spongerng_params, SPONGERNG_NAME, !deterministic); - if (!len) return DECAF_FAILURE; - - int fd = open(file, O_RDONLY); - if (fd < 0) return DECAF_FAILURE; - - uint8_t buffer[128]; - int first = 1; - while (len) { - ssize_t red = read(fd, buffer, (len > sizeof(buffer)) ? sizeof(buffer) : len); - if (red <= 0) { - close(fd); - return DECAF_FAILURE; - } - decaf_TOY_strobe_transact((keccak_decaf_TOY_strobe_s*)decaf_sponge,NULL,buffer,red, - first ? STROBE_CW_PRNG_USER_SEED : (STROBE_CW_PRNG_USER_SEED | STROBE_FLAG_MORE)); - len -= red; - first = 0; - }; - close(fd); - - return DECAF_SUCCESS; -} - -decaf_error_t decaf_spongerng_init_from_dev_urandom ( - decaf_keccak_prng_t decaf_sponge -) { - return decaf_spongerng_init_from_file(decaf_sponge, "/dev/urandom", 64, 0); -} - -const struct decaf_kparams_s STROBE_128 = { 0, 0, 200-128/4, 0, 0, 0, 0, 0 }; -const struct decaf_kparams_s STROBE_256 = { 0, 0, 200-256/4, 0, 0, 0, 0, 0 }; -const struct decaf_kparams_s STROBE_KEYED_256 = { 0, 0, 200-256/4, 12, 0, 0, 0, 0 }; -const struct decaf_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 decaf_TOY_strobe_init( - keccak_decaf_TOY_strobe_t strobe, - const struct decaf_kparams_s *params, - const char *proto, - uint8_t am_client -) { - decaf_keccak_sponge_s *decaf_sponge = strobe->sponge; - decaf_sponge_init(decaf_sponge,params); - - const char *a_string = "STROBE full v0.2"; - unsigned len = strlen(a_string); - memcpy ( - &decaf_sponge->state->b[sizeof(decaf_sponge->state)-len], - a_string, - len - ); - - decaf_TOY_strobe_transact(strobe, NULL, (const unsigned char *)proto, strlen(proto), STROBE_CW_INIT); - - decaf_sponge->state->b[decaf_sponge->params->rate+1] = 1; - decaf_sponge->params->client = !!am_client; -} - -static const uint8_t EXCEEDED_RATE_PAD = 0x2; -static __inline__ uint8_t CONTROL_WORD_PAD(int cw_size) { - assert(cw_size >= 0 && cw_size <= 31); - return 0xC0 | cw_size; -} - -/* PERF vectorize */ -static void decaf_TOY_strobe_duplex ( - struct decaf_keccak_sponge_s *__restrict__ decaf_sponge, - unsigned char *out, - const unsigned char *in, - size_t len, - mode_t mode -) { - unsigned int j, r = decaf_sponge->params->rate, p = decaf_sponge->params->position; - uint8_t* __restrict__ state = &decaf_sponge->state->b[0]; - - /* sanity */ - assert(r < sizeof(decaf_sponge->state) && r >= p); - switch (mode) { - case STROBE_MODE_PLAINTEXT: - assert(in || len==0); - break; - case STROBE_MODE_ABSORB: - case STROBE_MODE_ABSORB_R: - assert((in||len==0) && !out); - break; - case STROBE_MODE_DUPLEX: - case STROBE_MODE_DUPLEX_R: - assert((in && out) || len==0); - break; - case STROBE_MODE_SQUEEZE: - case STROBE_MODE_SQUEEZE_R: - assert((out || len==0) && !in); - break; - case STROBE_MODE_FORGET: - assert(!in && !out); - break; - default: - assert(0); - } - - while(1) { - unsigned int cando = r - p; - unsigned int last = (cando >= len); - if (last) { - cando = len; - } - - if (cando) { - - switch (mode) { - case STROBE_MODE_PLAINTEXT: - for (j=0; jparams->position = p+len; - return; - } else { - state[r] ^= EXCEEDED_RATE_PAD; - keccakf(decaf_sponge->state, decaf_sponge->params->start_round); - len -= cando; - p = 0; - } - } -} - -static inline mode_t get_mode ( uint32_t cw_flags ) { - return (mode_t)((cw_flags >> 29) & 7); -} - -static const int STROBE_FORGET_BYTES = 32; - -static const uint8_t FLAG_NOPARSE = 1; - -void decaf_TOY_strobe_transact ( - keccak_decaf_TOY_strobe_t strobe, - unsigned char *out, - const unsigned char *in, - size_t len, - uint32_t cw_flags -) { - decaf_keccak_sponge_s *decaf_sponge = strobe->sponge; - if ( (cw_flags & STROBE_FLAG_NONDIR) == 0 - /* extraneous nots to change ints to bools :-/ */ - && !(cw_flags & STROBE_FLAG_RECV) != !(decaf_sponge->params->client) ) { - cw_flags ^= STROBE_FLAG_CLIENT_SENT; - } - - uint64_t my_len = len, len_cw = (cw_flags & STROBE_FLAG_LENGTH_64) ? 10 : 4; - if (cw_flags & STROBE_FLAG_NO_LENGTH) { - my_len = 0; - } else if ((cw_flags & STROBE_FLAG_LENGTH_64)==0) { - assert(my_len < 1<<16); - } - - if (cw_flags & STROBE_FLAG_MORE) { - assert(cw_flags & STROBE_FLAG_NO_LENGTH); /* FUTURE */ - } else { - uint8_t cwb[10] = { - cw_flags, - cw_flags>>8, - my_len, - my_len>>8, - my_len>>16, - my_len>>24, - my_len>>32, - my_len>>40, - my_len>>48, - my_len>>56 - }; - decaf_TOY_strobe_duplex(decaf_sponge, NULL, cwb, len_cw, STROBE_MODE_ABSORB_R); - if ((cw_flags & STROBE_FLAG_RUN_F) || (decaf_sponge->params->flags & FLAG_NOPARSE)) { - decaf_sponge->state->b[decaf_sponge->params->position] ^= CONTROL_WORD_PAD(len_cw); - dokeccak(decaf_sponge); - } - - decaf_sponge->params->flags &= ~FLAG_NOPARSE; - if (cw_flags & STROBE_FLAG_NO_LENGTH) { - decaf_sponge->params->flags |= FLAG_NOPARSE; - } - } - - decaf_TOY_strobe_duplex(decaf_sponge, out, in, len, get_mode(cw_flags)); - if (cw_flags & STROBE_FLAG_FORGET) { - - uint32_t len = decaf_sponge->params->rate - decaf_sponge->params->position; - if (len < STROBE_FORGET_BYTES + len_cw) len += decaf_sponge->params->rate; - len -= len_cw; /* HACK */ - - if (cw_flags & STROBE_FLAG_NO_LENGTH) len = 2*STROBE_FORGET_BYTES; - assert(!(cw_flags & STROBE_FLAG_MORE)); - - decaf_TOY_strobe_duplex( - decaf_sponge, NULL, NULL, len, - STROBE_MODE_FORGET - ); - } -} - -decaf_error_t decaf_TOY_strobe_verify_auth ( - keccak_decaf_TOY_strobe_t strobe, - const unsigned char *in, - uint16_t len -) { - decaf_keccak_sponge_s *decaf_sponge = strobe->sponge; - if (len > decaf_sponge->params->rate) return DECAF_FAILURE; - decaf_TOY_strobe_transact(strobe, NULL, in, len, decaf_TOY_strobe_cw_recv(STROBE_CW_MAC)); - - int32_t residue = 0; - int i; - for (i=0; istate->b[i]; - } - - return decaf_succeed_if((residue-1)>>8); -} - -void decaf_TOY_strobe_respec ( - keccak_decaf_TOY_strobe_t strobe, - const struct decaf_kparams_s *params -) { - decaf_keccak_sponge_s *decaf_sponge = strobe->sponge; - uint8_t in[] = { params->rate, params->start_round }; - decaf_TOY_strobe_transact( strobe, NULL, in, sizeof(in), STROBE_CW_RESPEC_INFO ); - decaf_TOY_strobe_transact( strobe, NULL, NULL, 0, STROBE_CW_RESPEC ); - assert(decaf_sponge->params->position == 0); - decaf_sponge->params->rate = params->rate; - decaf_sponge->params->start_round = params->start_round; -} diff --git a/test/bench_decaf.cxx b/test/bench_decaf.cxx index 8ae7508..ed77640 100644 --- a/test/bench_decaf.cxx +++ b/test/bench_decaf.cxx @@ -12,11 +12,7 @@ #include #include #include -#include #include -#include -#include -#include #include #include #include @@ -26,7 +22,6 @@ #include using namespace decaf; -using namespace decaf::TOY; static __inline__ void __attribute__((unused)) ignore_result ( int result ) { (void)result; } @@ -157,146 +152,6 @@ typedef typename Group::Scalar Scalar; typedef typename Group::Point Point; typedef typename Group::Precomputed Precomputed; -static void tdh ( - SpongeRng &clientRng, - SpongeRng &serverRng, - Scalar x, const Block &gx, - Scalar y, const Block &gy -) { - /* "TripleDH". A bit of a hack, really: the real TripleDH - * sends gx and gy and certs over the channel, but its goal - * is actually the opposite of STROBE in this case: it doesn't - * hash gx and gy into the session secret (only into the MAC - * and AD) because of IPR concerns. - */ - Strobe client("example::tripleDH",Strobe::CLIENT), server("example::tripleDH",Strobe::SERVER); - - Scalar xe(clientRng); - SecureBuffer gxe((Precomputed::base() * xe).serialize()); - client.send_plaintext(gxe); - server.recv_plaintext(gxe); - - Scalar ye(serverRng); - SecureBuffer gye((Precomputed::base() * ye).serialize()); - server.send_plaintext(gye); - client.recv_plaintext(gye); - - Point pgxe(gxe); - server.dh_key(pgxe*ye); - SecureBuffer tag1 = server.produce_auth(); - //SecureBuffer ct = server.encrypt(gy); - server.dh_key(pgxe*y); - SecureBuffer tag2 = server.produce_auth(); - - Point pgye(gye); - client.dh_key(pgye*xe); - client.verify_auth(tag1); - client.dh_key(Point(gy) * xe); - client.verify_auth(tag2); - // ct = client.encrypt(gx); - client.dh_key(pgye * x); - tag1 = client.produce_auth(); - client.respec(STROBE_KEYED_128); - - server.dh_key(Point(gx) * ye); - server.verify_auth(tag1); - server.respec(STROBE_KEYED_128); -} - -static void fhmqv ( - SpongeRng &clientRng, - SpongeRng &serverRng, - Scalar x, const Block &gx, - Scalar y, const Block &gy -) { - /* Don't use this, it's probably patented */ - Strobe client("example::fhmqv",Strobe::CLIENT), server("example::fhmqv",Strobe::SERVER); - - Scalar xe(clientRng); - client.send_plaintext(gx); - server.recv_plaintext(gx); - SecureBuffer gxe((Precomputed::base() * xe).serialize()); - server.send_plaintext(gxe); - client.recv_plaintext(gxe); - - Scalar ye(serverRng); - server.send_plaintext(gy); - client.recv_plaintext(gy); - SecureBuffer gye((Precomputed::base() * ye).serialize()); - server.send_plaintext(gye); - - Scalar schx(server.prng(Scalar::SER_BYTES)); - Scalar schy(server.prng(Scalar::SER_BYTES)); - Scalar yec = y + ye*schy; - server.dh_key(Point::double_scalarmul(Point(gx),yec,Point(gxe),yec*schx)); - SecureBuffer as = server.produce_auth(); - - client.recv_plaintext(gye); - Scalar cchx(client.prng(Scalar::SER_BYTES)); - Scalar cchy(client.prng(Scalar::SER_BYTES)); - Scalar xec = x + xe*schx; - client.dh_key(Point::double_scalarmul(Point(gy),xec,Point(gye),xec*schy)); - client.verify_auth(as); - SecureBuffer ac = client.produce_auth(); - client.respec(STROBE_KEYED_128); - - server.verify_auth(ac); - server.respec(STROBE_KEYED_128); -} - -static void spake2ee( - SpongeRng &clientRng, - SpongeRng &serverRng, - const Block &hashed_password, - bool aug -) { - Strobe client("example::spake2ee",Strobe::CLIENT), server("example::spake2ee",Strobe::SERVER); - - Scalar x(clientRng); - - SHAKE<256> shake; - shake.update(hashed_password); - SecureBuffer h0 = shake.output(Point::HASH_BYTES); - SecureBuffer h1 = shake.output(Point::HASH_BYTES); - SecureBuffer h2 = shake.output(Scalar::SER_BYTES); - Scalar gs(h2); - - Point hc = Point::from_hash(h0); - hc = Point::from_hash(h0); // double-count - Point hs = Point::from_hash(h1); - hs = Point::from_hash(h1); // double-count - - SecureBuffer gx((Precomputed::base() * x + hc).serialize()); - client.send_plaintext(gx); - server.recv_plaintext(gx); - - Scalar y(serverRng); - SecureBuffer gy((Precomputed::base() * y + hs).serialize()); - server.send_plaintext(gy); - client.recv_plaintext(gy); - - server.dh_key(h1); - server.dh_key((Point(gx) - hc)*y); - if(aug) { - /* This step isn't actually online but whatever, it's fastish */ - SecureBuffer serverAug((Precomputed::base() * gs).serialize()); - server.dh_key(Point(serverAug)*y); - } - SecureBuffer tag = server.produce_auth(); - - client.dh_key(h1); - Point pgy(gy); pgy -= hs; - client.dh_key(pgy*x); - if (aug) client.dh_key(pgy * gs); - client.verify_auth(tag); - tag = client.produce_auth(); - client.respec(STROBE_KEYED_128); - /* A real protocol would continue with fork etc here... */ - - server.verify_auth(tag); - server.respec(STROBE_KEYED_128); -} - static void cfrg() { SpongeRng rng(Block("bench_cfrg_crypto"),SpongeRng::DETERMINISTIC); FixedArrayBuffer base(rng); @@ -318,57 +173,6 @@ static void macro() { printf("\nMacro-benchmarks for %s:\n", Group::name()); printf("CFRG crypto benchmarks:\n"); cfrg(); - - printf("\nToy crypto benchmarks:\n"); - SpongeRng rng(Block("macro rng seed"),SpongeRng::DETERMINISTIC); - PrivateKey s1((NOINIT())), s2(rng); - PublicKey p1((NOINIT())), p2(s2); - - SecureBuffer message = rng.read(5), sig, ss; - - for (Benchmark b("Create private key",1); b.iter(); ) { - s1 = PrivateKey(rng); - SecureBuffer bb = s1.serialize(); - } - - for (Benchmark b("Sign",1); b.iter(); ) { - sig = s1.sign(message); - } - - p1 = s1.pub(); - for (Benchmark b("Verify",1); b.iter(); ) { - rng.read(Buffer(message)); - try { p1.verify(message, sig); } catch (CryptoException) {} - } - - for (Benchmark b("SharedSecret",1); b.iter(); ) { - ss = s1.shared_secret(p2,32,true); - } - - printf("\nToy protocol benchmarks:\n"); - SpongeRng clientRng(Block("client rng seed"),SpongeRng::DETERMINISTIC); - SpongeRng serverRng(Block("server rng seed"),SpongeRng::DETERMINISTIC); - SecureBuffer hashedPassword(Block("hello world")); - for (Benchmark b("Spake2ee c+s",0.1); b.iter(); ) { - spake2ee(clientRng, serverRng, hashedPassword,false); - } - - for (Benchmark b("Spake2ee c+s aug",0.1); b.iter(); ) { - spake2ee(clientRng, serverRng, hashedPassword,true); - } - - Scalar x(clientRng); - SecureBuffer gx((Precomputed::base() * x).serialize()); - Scalar y(serverRng); - SecureBuffer gy((Precomputed::base() * y).serialize()); - - for (Benchmark b("FHMQV c+s",0.1); b.iter(); ) { - fhmqv(clientRng, serverRng,x,gx,y,gy); - } - - for (Benchmark b("TripleDH anon c+s",0.1); b.iter(); ) { - tdh(clientRng, serverRng, x,gx,y,gy); - } } static void micro() { @@ -421,29 +225,11 @@ int main(int argc, char **argv) { SHAKE<256> shake2; SHA3<512> sha5; SHA512 sha2; - Strobe strobe("example::bench",Strobe::CLIENT); unsigned char b1024[1024] = {1}; for (Benchmark b("SHAKE128 1kiB", 30); b.iter(); ) { shake1 += Buffer(b1024,1024); } for (Benchmark b("SHAKE256 1kiB", 30); b.iter(); ) { shake2 += Buffer(b1024,1024); } for (Benchmark b("SHA3-512 1kiB", 30); b.iter(); ) { sha5 += Buffer(b1024,1024); } for (Benchmark b("SHA512 1kiB", 30); b.iter(); ) { sha2 += Buffer(b1024,1024); } - strobe.dh_key(Buffer(b1024,1024)); - strobe.respec(STROBE_128); - for (Benchmark b("STROBE128 1kiB", 10); b.iter(); ) { - strobe.encrypt_no_auth(Buffer(b1024,1024),Buffer(b1024,1024)); - } - strobe.respec(STROBE_256); - for (Benchmark b("STROBE256 1kiB", 10); b.iter(); ) { - strobe.encrypt_no_auth(Buffer(b1024,1024),Buffer(b1024,1024)); - } - strobe.respec(STROBE_KEYED_128); - for (Benchmark b("STROBEk128 1kiB", 10); b.iter(); ) { - strobe.encrypt_no_auth(Buffer(b1024,1024),Buffer(b1024,1024)); - } - strobe.respec(STROBE_KEYED_256); - for (Benchmark b("STROBEk256 1kiB", 10); b.iter(); ) { - strobe.encrypt_no_auth(Buffer(b1024,1024),Buffer(b1024,1024)); - } run_for_all_curves(); } diff --git a/test/test_decaf.cxx b/test/test_decaf.cxx index 996c879..085db58 100644 --- a/test/test_decaf.cxx +++ b/test/test_decaf.cxx @@ -11,13 +11,10 @@ #include #include -#include -#include #include #include using namespace decaf; -using namespace decaf::TOY; static bool passing = true; static const long NTESTS = 10000; @@ -410,33 +407,6 @@ static void test_ec() { } } -static void test_toy_crypto() { - Test test("Toy crypto"); - SpongeRng rng(Block("test_decaf_crypto"),SpongeRng::DETERMINISTIC); - - for (int i=0; i priv1(rng), priv2(rng); - PublicKey pub1(priv1), pub2(priv2); - - SecureBuffer message = rng.read(i); - SecureBuffer sig(priv1.sign(message)); - - pub1.verify(message, sig); - - SecureBuffer s1(priv1.shared_secret(pub2,32,true)); - SecureBuffer s2(priv2.shared_secret(pub1,32,false)); - if (!memeq(s1,s2)) { - test.fail(); - printf(" Shared secrets disagree on iteration %d.\n",i); - } - } catch (CryptoException) { - test.fail(); - printf(" Threw CryptoException.\n"); - } - } -} - static const uint8_t rfc7748_1[DhLadder::PUBLIC_BYTES]; static const uint8_t rfc7748_1000[DhLadder::PUBLIC_BYTES]; static const uint8_t rfc7748_1000000[DhLadder::PUBLIC_BYTES]; @@ -572,16 +542,63 @@ static void run() { test_eddsa(); test_cfrg_crypto(); test_cfrg_vectors(); - test_toy_crypto(); printf("\n"); } }; /* template struct Tests */ +static void test_rng() { + Test test("RNG"); + SpongeRng rng_d1(Block("test_rng"),SpongeRng::DETERMINISTIC); + SpongeRng rng_d2(Block("test_rng"),SpongeRng::DETERMINISTIC); + SpongeRng rng_d3(Block("best_rng"),SpongeRng::DETERMINISTIC); + SpongeRng rng_n1; + SpongeRng rng_n2; + SecureBuffer s1,s2,s3; + + for (int i=0; i<5; i++) { + s1 = rng_d1.read(16<(); if (passing) printf("Passed all tests.\n"); return passing ? 0 : 1;