From facad6c2aca47ff302ba305783da01346b2d0606 Mon Sep 17 00:00:00 2001 From: Michael Hamburg Date: Thu, 7 Jan 2016 10:55:13 -0800 Subject: [PATCH] unify decaf_crypto c versions, still need to unify with c++ --- Makefile | 7 +- src/curve_ed25519/curve_data.inc.c | 4 + src/curve_ed448goldilocks/curve_data.inc.c | 3 + src/decaf_crypto.c | 216 +++++++++++++++++++++ src/decaf_crypto_255.c | 212 -------------------- src/decaf_crypto_448.c | 213 -------------------- src/include/word.h | 7 +- src/public_include/decaf/common.h | 3 + src/public_include/decaf/crypto.h | 21 ++ src/public_include/decaf/crypto_255.h | 18 -- src/public_include/decaf/crypto_448.h | 18 -- src/public_include/decaf/shake.h | 20 -- 12 files changed, 255 insertions(+), 487 deletions(-) create mode 100644 src/decaf_crypto.c delete mode 100644 src/decaf_crypto_255.c delete mode 100644 src/decaf_crypto_448.c create mode 100644 src/public_include/decaf/crypto.h diff --git a/Makefile b/Makefile index 858d122..a127944 100644 --- a/Makefile +++ b/Makefile @@ -88,7 +88,7 @@ HEADERS= Makefile $(shell find src test -name "*.h") $(BUILD_OBJ)/timestamp HEADERSXX = $(HEADERS) $(shell find . -name "*.hxx") # components needed by the lib -LIBCOMPONENTS = $(BUILD_OBJ)/utils.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/decaf_crypto_255.o $(BUILD_OBJ)/decaf_crypto_448.o # and per-field components +LIBCOMPONENTS = $(BUILD_OBJ)/utils.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/decaf_crypto_ed25519.o $(BUILD_OBJ)/decaf_crypto_ed448goldilocks.o # and per-field components BENCHCOMPONENTS = $(BUILD_OBJ)/bench.o $(BUILD_OBJ)/shake.o @@ -165,6 +165,11 @@ $$(BUILD_ASM)/decaf_fast_$(1).s: src/decaf_fast.c $$(HEADERS) -I src/curve_$(1)/ -I src/$(2) -I src/$(2)/$$(ARCH_FOR_$(2)) \ -S -c -o $$@ $$< +$$(BUILD_ASM)/decaf_crypto_$(1).s: src/decaf_crypto.c $$(HEADERS) + $$(CC) $$(CFLAGS) \ + -I src/curve_$(1)/ \ + -S -c -o $$@ $$< + LIBCOMPONENTS += $$(BUILD_OBJ)/decaf_fast_$(1).o $$(BUILD_OBJ)/decaf_tables_$(1).o endef diff --git a/src/curve_ed25519/curve_data.inc.c b/src/curve_ed25519/curve_data.inc.c index 8c33457..b3d0c56 100644 --- a/src/curve_ed25519/curve_data.inc.c +++ b/src/curve_ed25519/curve_data.inc.c @@ -2,6 +2,7 @@ #define API_NS(_id) decaf_255_##_id #define API_NS2(_pref,_id) _pref##_decaf_255_##_id + #define SCALAR_LIMBS DECAF_255_SCALAR_LIMBS #define SCALAR_BITS DECAF_255_SCALAR_BITS #define NLIMBS DECAF_255_LIMBS @@ -13,6 +14,7 @@ #define P_MOD_8 5 #define COFACTOR 8 +#ifndef DECAF_JUST_API static const int EDWARDS_D = -121665; static const scalar_t sc_p = {{{ @@ -36,3 +38,5 @@ static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL( 0x7540f7816214a, 0x0a0d85b4032b1 )}; + +#endif /* DECAF_JUST_API */ diff --git a/src/curve_ed448goldilocks/curve_data.inc.c b/src/curve_ed448goldilocks/curve_data.inc.c index b4a619b..b42c944 100644 --- a/src/curve_ed448goldilocks/curve_data.inc.c +++ b/src/curve_ed448goldilocks/curve_data.inc.c @@ -13,6 +13,7 @@ #define P_MOD_8 7 #define COFACTOR 4 +#ifndef DECAF_JUST_API static const int EDWARDS_D = -39081; static const scalar_t sc_p = {{{ @@ -31,3 +32,5 @@ static const unsigned char base_point_ser_for_pregen[SER_BYTES] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,1 }; #endif + +#endif /* DECAF_JUST_API */ diff --git a/src/decaf_crypto.c b/src/decaf_crypto.c new file mode 100644 index 0000000..6ec11f4 --- /dev/null +++ b/src/decaf_crypto.c @@ -0,0 +1,216 @@ +/** + * @cond internal + * @file decaf_crypto.c + * @copyright + * Copyright (c) 2015 Cryptography Research, Inc. \n + * Released under the MIT License. See LICENSE.txt for license information. + * @author Mike Hamburg + * @brief Example Decaf crypto routines + */ + +#include +#include + +#define DECAF_JUST_API +#include "curve_data.inc.c" +#define SCALAR_BYTES ((SCALAR_BITS + 7)/8) + +static const unsigned int SCALAR_OVERKILL_BYTES = SCALAR_BYTES + 8; + +void API_NS(derive_private_key) ( + API_NS(private_key_t) priv, + const API_NS(symmetric_key_t) proto +) { + const char *magic = API_NAME"::derive_private_key"; /* TODO: canonicalize and freeze */ + uint8_t encoded_scalar[SCALAR_OVERKILL_BYTES]; + API_NS(point_t) pub; + + keccak_strobe_t strobe; + strobe_init(strobe, &STROBE_256, magic, 0); + strobe_fixed_key(strobe, proto, sizeof(API_NS(symmetric_key_t))); + strobe_prng(strobe, encoded_scalar, sizeof(encoded_scalar)); + strobe_destroy(strobe); + + memcpy(priv->sym, proto, sizeof(API_NS(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(destroy_private_key) ( + API_NS(private_key_t) priv +) { + decaf_bzero((void*)priv, sizeof(API_NS(private_key_t))); +} + +void API_NS(private_to_public) ( + API_NS(public_key_t) pub, + const API_NS(private_key_t) priv +) { + memcpy(pub, priv->pub, sizeof(API_NS(public_key_t))); +} + +static const uint16_t SHARED_SECRET_MAX_BLOCK_SIZE = 1<<12; /* TODO: standardize and freeze */ + +decaf_error_t +API_NS(shared_secret) ( + uint8_t *shared, + size_t shared_bytes, + const API_NS(private_key_t) my_privkey, + const API_NS(public_key_t) your_pubkey, + int me_first +) { + const char *magic = API_NAME"::shared_secret"; /* TODO: canonicalize and freeze */ + keccak_strobe_t strobe; + strobe_init(strobe, &STROBE_256, magic, 0); + + uint8_t ss_ser[SER_BYTES]; + + if (me_first) { + strobe_ad(strobe,my_privkey->pub,sizeof(API_NS(public_key_t))); + strobe_ad(strobe,your_pubkey,sizeof(API_NS(public_key_t))); + } else { + strobe_ad(strobe,your_pubkey,sizeof(API_NS(public_key_t))); + strobe_ad(strobe,my_privkey->pub,sizeof(API_NS(public_key_t))); + } + decaf_error_t ret = API_NS(direct_scalarmul)( + ss_ser, your_pubkey, my_privkey->secret_scalar, DECAF_FALSE, DECAF_TRUE + ); + + 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; + strobe_prng(strobe,shared,cando); + shared_bytes -= cando; + shared += cando; + } + + strobe_destroy(strobe); + decaf_bzero(ss_ser, sizeof(ss_ser)); + + return ret; +} + +void +API_NS(sign_strobe) ( + keccak_strobe_t strobe, + API_NS(signature_t) sig, + const API_NS(private_key_t) priv +) { + uint8_t overkill[SCALAR_OVERKILL_BYTES]; + API_NS(point_t) point; + API_NS(scalar_t) nonce, challenge; + + /* Stir pubkey */ + strobe_transact(strobe,NULL,priv->pub,sizeof(API_NS(public_key_t)),STROBE_CW_SIG_PK); + + /* Derive nonce */ + keccak_strobe_t strobe2; + memcpy(strobe2,strobe,sizeof(strobe2)); + strobe_fixed_key(strobe2,priv->sym,sizeof(API_NS(symmetric_key_t))); + strobe_prng(strobe2,overkill,sizeof(overkill)); + 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 */ + strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH); + 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); + 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(verify_strobe) ( + keccak_strobe_t strobe, + const API_NS(signature_t) sig, + const API_NS(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 */ + strobe_transact(strobe,NULL,pub,sizeof(API_NS(public_key_t)),STROBE_CW_SIG_PK); + + /* Derive nonce */ + strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH); + ret = decaf_successful( API_NS(point_decode)(point, sig, DECAF_TRUE) ); + + /* Derive challenge */ + strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); + API_NS(scalar_decode_long)(challenge, overkill, sizeof(overkill)); + + /* Decode response */ + 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(sign) ( + API_NS(signature_t) sig, + const API_NS(private_key_t) priv, + const unsigned char *message, + size_t message_len +) { + keccak_strobe_t ctx; + strobe_init(ctx,&STROBE_256,API_NAME"::sign",0); /* TODO: canonicalize and freeze */ + strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); + API_NS(sign_strobe)(ctx, sig, priv); + strobe_destroy(ctx); +} + +decaf_error_t +API_NS(verify) ( + const API_NS(signature_t) sig, + const API_NS(public_key_t) pub, + const unsigned char *message, + size_t message_len +) { + keccak_strobe_t ctx; + strobe_init(ctx,&STROBE_256,API_NAME"::sign",0); /* TODO: canonicalize and freeze */ + strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); + decaf_error_t ret = API_NS(verify_strobe)(ctx, sig, pub); + strobe_destroy(ctx); + return ret; +} diff --git a/src/decaf_crypto_255.c b/src/decaf_crypto_255.c deleted file mode 100644 index 815511e..0000000 --- a/src/decaf_crypto_255.c +++ /dev/null @@ -1,212 +0,0 @@ -/** - * @cond internal - * @file decaf_crypto_255.c - * @copyright - * Copyright (c) 2015 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * @author Mike Hamburg - * @brief Example Decaf crypto routines, 255-bit version. - */ - -#include -#include - -static const unsigned int DECAF_255_SCALAR_OVERKILL_BYTES = DECAF_255_SCALAR_BYTES + 8; - -void decaf_255_derive_private_key ( - decaf_255_private_key_t priv, - const decaf_255_symmetric_key_t proto -) { - const char *magic = "decaf::derive_255_private_key"; /* TODO: canonicalize and freeze */ - uint8_t encoded_scalar[DECAF_255_SCALAR_OVERKILL_BYTES]; - decaf_255_point_t pub; - - keccak_strobe_t strobe; - strobe_init(strobe, &STROBE_256, magic, 0); - strobe_fixed_key(strobe, proto, sizeof(decaf_255_symmetric_key_t)); - strobe_prng(strobe, encoded_scalar, sizeof(encoded_scalar)); - strobe_destroy(strobe); - - memcpy(priv->sym, proto, sizeof(decaf_255_symmetric_key_t)); - decaf_255_scalar_decode_long(priv->secret_scalar, encoded_scalar, sizeof(encoded_scalar)); - - decaf_255_precomputed_scalarmul(pub, decaf_255_precomputed_base, priv->secret_scalar); - decaf_255_point_encode(priv->pub, pub); - - decaf_bzero(encoded_scalar, sizeof(encoded_scalar)); -} - -void -decaf_255_destroy_private_key ( - decaf_255_private_key_t priv -) { - decaf_bzero((void*)priv, sizeof(decaf_255_private_key_t)); -} - -void decaf_255_private_to_public ( - decaf_255_public_key_t pub, - const decaf_255_private_key_t priv -) { - memcpy(pub, priv->pub, sizeof(decaf_255_public_key_t)); -} - -static const uint16_t SHARED_SECRET_MAX_BLOCK_SIZE = 1<<12; /* TODO: standardize and freeze */ - -decaf_error_t -decaf_255_shared_secret ( - uint8_t *shared, - size_t shared_bytes, - const decaf_255_private_key_t my_privkey, - const decaf_255_public_key_t your_pubkey, - int me_first -) { - const char *magic = "decaf::decaf_255_shared_secret"; /* TODO: canonicalize and freeze */ - keccak_strobe_t strobe; - strobe_init(strobe, &STROBE_256, magic, 0); - - uint8_t ss_ser[DECAF_255_SER_BYTES]; - - if (me_first) { - strobe_ad(strobe,my_privkey->pub,sizeof(decaf_255_public_key_t)); - strobe_ad(strobe,your_pubkey,sizeof(decaf_255_public_key_t)); - } else { - strobe_ad(strobe,your_pubkey,sizeof(decaf_255_public_key_t)); - strobe_ad(strobe,my_privkey->pub,sizeof(decaf_255_public_key_t)); - } - decaf_error_t ret = decaf_255_direct_scalarmul( - ss_ser, your_pubkey, my_privkey->secret_scalar, DECAF_FALSE, DECAF_TRUE - ); - - 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; - strobe_prng(strobe,shared,cando); - shared_bytes -= cando; - shared += cando; - } - - strobe_destroy(strobe); - decaf_bzero(ss_ser, sizeof(ss_ser)); - - return ret; -} - -void -decaf_255_sign_strobe ( - keccak_strobe_t strobe, - decaf_255_signature_t sig, - const decaf_255_private_key_t priv -) { - uint8_t overkill[DECAF_255_SCALAR_OVERKILL_BYTES]; - decaf_255_point_t point; - decaf_255_scalar_t nonce, challenge; - - /* Stir pubkey */ - strobe_transact(strobe,NULL,priv->pub,sizeof(decaf_255_public_key_t),STROBE_CW_SIG_PK); - - /* Derive nonce */ - keccak_strobe_t strobe2; - memcpy(strobe2,strobe,sizeof(strobe2)); - strobe_fixed_key(strobe2,priv->sym,sizeof(decaf_255_symmetric_key_t)); - strobe_prng(strobe2,overkill,sizeof(overkill)); - strobe_destroy(strobe2); - - decaf_255_scalar_decode_long(nonce, overkill, sizeof(overkill)); - decaf_255_precomputed_scalarmul(point, decaf_255_precomputed_base, nonce); - decaf_255_point_encode(sig, point); - - - /* Derive challenge */ - strobe_transact(strobe,NULL,sig,DECAF_255_SER_BYTES,STROBE_CW_SIG_EPH); - strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); - decaf_255_scalar_decode_long(challenge, overkill, sizeof(overkill)); - - /* Respond */ - decaf_255_scalar_mul(challenge, challenge, priv->secret_scalar); - decaf_255_scalar_sub(nonce, nonce, challenge); - - /* Save results */ - decaf_255_scalar_encode(overkill, nonce); - strobe_transact(strobe,&sig[DECAF_255_SER_BYTES],overkill,DECAF_255_SCALAR_BYTES,STROBE_CW_SIG_RESP); - - /* Clean up */ - decaf_255_scalar_destroy(nonce); - decaf_255_scalar_destroy(challenge); - decaf_bzero(overkill,sizeof(overkill)); -} - -decaf_error_t -decaf_255_verify_strobe ( - keccak_strobe_t strobe, - const decaf_255_signature_t sig, - const decaf_255_public_key_t pub -) { - decaf_bool_t ret; - - uint8_t overkill[DECAF_255_SCALAR_OVERKILL_BYTES]; - decaf_255_point_t point, pubpoint; - decaf_255_scalar_t challenge, response; - - /* Stir pubkey */ - strobe_transact(strobe,NULL,pub,sizeof(decaf_255_public_key_t),STROBE_CW_SIG_PK); - - /* Derive nonce */ - strobe_transact(strobe,NULL,sig,DECAF_255_SER_BYTES,STROBE_CW_SIG_EPH); - ret = decaf_successful( decaf_255_point_decode(point, sig, DECAF_TRUE) ); - - /* Derive challenge */ - strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); - decaf_255_scalar_decode_long(challenge, overkill, sizeof(overkill)); - - /* Decode response */ - strobe_transact(strobe,overkill,&sig[DECAF_255_SER_BYTES],DECAF_255_SCALAR_BYTES,STROBE_CW_SIG_RESP); - ret &= decaf_successful( decaf_255_scalar_decode(response, overkill) ); - ret &= decaf_successful( decaf_255_point_decode(pubpoint, pub, DECAF_FALSE) ); - - decaf_255_base_double_scalarmul_non_secret ( - pubpoint, response, pubpoint, challenge - ); - - ret &= decaf_255_point_eq(pubpoint, point); - - /* Nothing here is secret, so don't do these things: - decaf_bzero(overkill,sizeof(overkill)); - decaf_255_point_destroy(point); - decaf_255_point_destroy(pubpoint); - decaf_255_scalar_destroy(challenge); - decaf_255_scalar_destroy(response); - */ - - return decaf_succeed_if(ret); -} - -void -decaf_255_sign ( - decaf_255_signature_t sig, - const decaf_255_private_key_t priv, - const unsigned char *message, - size_t message_len -) { - keccak_strobe_t ctx; - strobe_init(ctx,&STROBE_256,"decaf::decaf_255_sign",0); /* TODO: canonicalize and freeze */ - strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); - decaf_255_sign_strobe(ctx, sig, priv); - strobe_destroy(ctx); -} - -decaf_error_t -decaf_255_verify ( - const decaf_255_signature_t sig, - const decaf_255_public_key_t pub, - const unsigned char *message, - size_t message_len -) { - keccak_strobe_t ctx; - strobe_init(ctx,&STROBE_256,"decaf::decaf_255_sign",0); /* TODO: canonicalize and freeze */ - strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); - decaf_error_t ret = decaf_255_verify_strobe(ctx, sig, pub); - strobe_destroy(ctx); - return ret; -} diff --git a/src/decaf_crypto_448.c b/src/decaf_crypto_448.c deleted file mode 100644 index 5a47995..0000000 --- a/src/decaf_crypto_448.c +++ /dev/null @@ -1,213 +0,0 @@ -/** - * @cond internal - * @file decaf_crypto_448.c - * @copyright - * Copyright (c) 2015 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * @author Mike Hamburg - * @brief Example Decaf crypto routines, 448-bit version - * @todo TODO don't copy-paste. - */ - -#include -#include - -static const unsigned int DECAF_448_SCALAR_OVERKILL_BYTES = DECAF_448_SCALAR_BYTES + 8; - -void decaf_448_derive_private_key ( - decaf_448_private_key_t priv, - const decaf_448_symmetric_key_t proto -) { - const char *magic = "decaf::derive_448_private_key"; /* TODO: canonicalize and freeze */ - uint8_t encoded_scalar[DECAF_448_SCALAR_OVERKILL_BYTES]; - decaf_448_point_t pub; - - keccak_strobe_t strobe; - strobe_init(strobe, &STROBE_256, magic, 0); - strobe_fixed_key(strobe, proto, sizeof(decaf_448_symmetric_key_t)); - strobe_prng(strobe, encoded_scalar, sizeof(encoded_scalar)); - strobe_destroy(strobe); - - memcpy(priv->sym, proto, sizeof(decaf_448_symmetric_key_t)); - decaf_448_scalar_decode_long(priv->secret_scalar, encoded_scalar, sizeof(encoded_scalar)); - - decaf_448_precomputed_scalarmul(pub, decaf_448_precomputed_base, priv->secret_scalar); - decaf_448_point_encode(priv->pub, pub); - - decaf_bzero(encoded_scalar, sizeof(encoded_scalar)); -} - -void -decaf_448_destroy_private_key ( - decaf_448_private_key_t priv -) { - decaf_bzero((void*)priv, sizeof(decaf_448_private_key_t)); -} - -void decaf_448_private_to_public ( - decaf_448_public_key_t pub, - const decaf_448_private_key_t priv -) { - memcpy(pub, priv->pub, sizeof(decaf_448_public_key_t)); -} - -static const uint16_t SHARED_SECRET_MAX_BLOCK_SIZE = 1<<12; /* TODO: standardize and freeze */ - -decaf_error_t -decaf_448_shared_secret ( - uint8_t *shared, - size_t shared_bytes, - const decaf_448_private_key_t my_privkey, - const decaf_448_public_key_t your_pubkey, - int me_first -) { - const char *magic = "decaf::decaf_448_shared_secret"; /* TODO: canonicalize and freeze */ - keccak_strobe_t strobe; - strobe_init(strobe, &STROBE_256, magic, 0); - - uint8_t ss_ser[DECAF_448_SER_BYTES]; - - if (me_first) { - strobe_ad(strobe,my_privkey->pub,sizeof(decaf_448_public_key_t)); - strobe_ad(strobe,your_pubkey,sizeof(decaf_448_public_key_t)); - } else { - strobe_ad(strobe,your_pubkey,sizeof(decaf_448_public_key_t)); - strobe_ad(strobe,my_privkey->pub,sizeof(decaf_448_public_key_t)); - } - decaf_error_t ret = decaf_448_direct_scalarmul( - ss_ser, your_pubkey, my_privkey->secret_scalar, DECAF_FALSE, DECAF_TRUE - ); - - 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; - strobe_prng(strobe,shared,cando); - shared_bytes -= cando; - shared += cando; - } - - strobe_destroy(strobe); - decaf_bzero(ss_ser, sizeof(ss_ser)); - - return ret; -} - -void -decaf_448_sign_strobe ( - keccak_strobe_t strobe, - decaf_448_signature_t sig, - const decaf_448_private_key_t priv -) { - uint8_t overkill[DECAF_448_SCALAR_OVERKILL_BYTES]; - decaf_448_point_t point; - decaf_448_scalar_t nonce, challenge; - - /* Stir pubkey */ - strobe_transact(strobe,NULL,priv->pub,sizeof(decaf_448_public_key_t),STROBE_CW_SIG_PK); - - /* Derive nonce */ - keccak_strobe_t strobe2; - memcpy(strobe2,strobe,sizeof(strobe2)); - strobe_fixed_key(strobe2,priv->sym,sizeof(decaf_448_symmetric_key_t)); - strobe_prng(strobe2,overkill,sizeof(overkill)); - strobe_destroy(strobe2); - - decaf_448_scalar_decode_long(nonce, overkill, sizeof(overkill)); - decaf_448_precomputed_scalarmul(point, decaf_448_precomputed_base, nonce); - decaf_448_point_encode(sig, point); - - - /* Derive challenge */ - strobe_transact(strobe,NULL,sig,DECAF_448_SER_BYTES,STROBE_CW_SIG_EPH); - strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); - decaf_448_scalar_decode_long(challenge, overkill, sizeof(overkill)); - - /* Respond */ - decaf_448_scalar_mul(challenge, challenge, priv->secret_scalar); - decaf_448_scalar_sub(nonce, nonce, challenge); - - /* Save results */ - decaf_448_scalar_encode(overkill, nonce); - strobe_transact(strobe,&sig[DECAF_448_SER_BYTES],overkill,DECAF_448_SCALAR_BYTES,STROBE_CW_SIG_RESP); - - /* Clean up */ - decaf_448_scalar_destroy(nonce); - decaf_448_scalar_destroy(challenge); - decaf_bzero(overkill,sizeof(overkill)); -} - -decaf_error_t -decaf_448_verify_strobe ( - keccak_strobe_t strobe, - const decaf_448_signature_t sig, - const decaf_448_public_key_t pub -) { - decaf_bool_t ret; - - uint8_t overkill[DECAF_448_SCALAR_OVERKILL_BYTES]; - decaf_448_point_t point, pubpoint; - decaf_448_scalar_t challenge, response; - - /* Stir pubkey */ - strobe_transact(strobe,NULL,pub,sizeof(decaf_448_public_key_t),STROBE_CW_SIG_PK); - - /* Derive nonce */ - strobe_transact(strobe,NULL,sig,DECAF_448_SER_BYTES,STROBE_CW_SIG_EPH); - ret = decaf_successful( decaf_448_point_decode(point, sig, DECAF_TRUE) ); - - /* Derive challenge */ - strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); - decaf_448_scalar_decode_long(challenge, overkill, sizeof(overkill)); - - /* Decode response */ - strobe_transact(strobe,overkill,&sig[DECAF_448_SER_BYTES],DECAF_448_SCALAR_BYTES,STROBE_CW_SIG_RESP); - ret &= decaf_successful( decaf_448_scalar_decode(response, overkill) ); - ret &= decaf_successful( decaf_448_point_decode(pubpoint, pub, DECAF_FALSE) ); - - decaf_448_base_double_scalarmul_non_secret ( - pubpoint, response, pubpoint, challenge - ); - - ret &= decaf_448_point_eq(pubpoint, point); - - /* Nothing here is secret, so don't do these things: - decaf_bzero(overkill,sizeof(overkill)); - decaf_448_point_destroy(point); - decaf_448_point_destroy(pubpoint); - decaf_448_scalar_destroy(challenge); - decaf_448_scalar_destroy(response); - */ - - return decaf_succeed_if(ret); -} - -void -decaf_448_sign ( - decaf_448_signature_t sig, - const decaf_448_private_key_t priv, - const unsigned char *message, - size_t message_len -) { - keccak_strobe_t ctx; - strobe_init(ctx,&STROBE_256,"decaf::decaf_448_sign",0); /* TODO: canonicalize and freeze */ - strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); - decaf_448_sign_strobe(ctx, sig, priv); - strobe_destroy(ctx); -} - -decaf_error_t -decaf_448_verify ( - const decaf_448_signature_t sig, - const decaf_448_public_key_t pub, - const unsigned char *message, - size_t message_len -) { - keccak_strobe_t ctx; - strobe_init(ctx,&STROBE_256,"decaf::decaf_448_sign",0); /* TODO: canonicalize and freeze */ - strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); - decaf_error_t ret = decaf_448_verify_strobe(ctx, sig, pub); - strobe_destroy(ctx); - return ret; -} diff --git a/src/include/word.h b/src/include/word.h index 489f392..0ba17ee 100644 --- a/src/include/word.h +++ b/src/include/word.h @@ -10,6 +10,8 @@ #include "arch_config.h" +#include + #ifndef __APPLE__ #ifndef _BSD_SOURCE @@ -68,11 +70,6 @@ #error "For now, libdecaf only supports 32- and 64-bit architectures." #endif -/* General utilities */ -#define NOINLINE __attribute__((noinline)) -#define UNUSED __attribute__((unused)) -#define INLINE __inline__ __attribute__((always_inline)) - #ifdef __ARM_NEON__ typedef uint32x4_t vecmask_t; #elif __clang__ diff --git a/src/public_include/decaf/common.h b/src/public_include/decaf/common.h index db49a52..fbd9918 100644 --- a/src/public_include/decaf/common.h +++ b/src/public_include/decaf/common.h @@ -27,8 +27,11 @@ #define NONNULL2 __attribute__((nonnull(1,2))) #define NONNULL3 __attribute__((nonnull(1,2,3))) #define NONNULL13 __attribute__((nonnull(1,3))) +#define NONNULL134 __attribute__((nonnull(1,3,4))) #define NONNULL4 __attribute__((nonnull(1,2,3,4))) #define NONNULL5 __attribute__((nonnull(1,2,3,4,5))) +#define INLINE inline __attribute__((always_inline)) +#define UNUSED __attribute__((unused)) /** @endcond */ /* Internal word types. diff --git a/src/public_include/decaf/crypto.h b/src/public_include/decaf/crypto.h new file mode 100644 index 0000000..bb6af0e --- /dev/null +++ b/src/public_include/decaf/crypto.h @@ -0,0 +1,21 @@ +/** + * @file decaf/crypto.h + * @copyright + * Copyright (c) 2016 Cryptography Research, Inc. \n + * Released under the MIT License. See LICENSE.txt for license information. + * @author Mike Hamburg + * @brief Example Decaf cyrpto 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. + * @todo TODO remove/autogenerate all these headers. + */ + +#ifndef __DECAF_CRYPTO_H__ +#define __DECAF_CRYPTO_H__ 1 + +#include +#include + +#endif /* __DECAF_CRYPTO_H__ */ + diff --git a/src/public_include/decaf/crypto_255.h b/src/public_include/decaf/crypto_255.h index 5f877af..adf891b 100644 --- a/src/public_include/decaf/crypto_255.h +++ b/src/public_include/decaf/crypto_255.h @@ -20,16 +20,6 @@ /** Number of bytes for a symmetric key (expanded to full key) */ #define DECAF_255_SYMMETRIC_KEY_BYTES 32 -/** @cond internal */ -#define API_VIS __attribute__((visibility("default"))) __attribute__((noinline)) // TODO: synergize with decaf.h -#define WARN_UNUSED __attribute__((warn_unused_result)) -#define NONNULL1 __attribute__((nonnull(1))) -#define NONNULL2 __attribute__((nonnull(1,2))) -#define NONNULL3 __attribute__((nonnull(1,2,3))) -#define NONNULL134 __attribute__((nonnull(1,3,4))) -#define NONNULL5 __attribute__((nonnull(1,2,3,4,5))) -/** @endcond */ - /** A symmetric key, the compressed point of a private key. */ typedef unsigned char decaf_255_symmetric_key_t[DECAF_255_SYMMETRIC_KEY_BYTES]; @@ -175,14 +165,6 @@ decaf_255_verify ( const unsigned char *message, size_t message_len ) NONNULL3 API_VIS WARN_UNUSED; - -#undef API_VIS -#undef WARN_UNUSED -#undef NONNULL1 -#undef NONNULL2 -#undef NONNULL3 -#undef NONNULL134 -#undef NONNULL5 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/public_include/decaf/crypto_448.h b/src/public_include/decaf/crypto_448.h index 6890df3..328faa7 100644 --- a/src/public_include/decaf/crypto_448.h +++ b/src/public_include/decaf/crypto_448.h @@ -20,16 +20,6 @@ /** Number of bytes for a symmetric key (expanded to full key) */ #define DECAF_448_SYMMETRIC_KEY_BYTES 32 -/** @cond internal */ -#define API_VIS __attribute__((visibility("default"))) __attribute__((noinline)) // TODO: synergize with decaf.h -#define WARN_UNUSED __attribute__((warn_unused_result)) -#define NONNULL1 __attribute__((nonnull(1))) -#define NONNULL2 __attribute__((nonnull(1,2))) -#define NONNULL3 __attribute__((nonnull(1,2,3))) -#define NONNULL134 __attribute__((nonnull(1,3,4))) -#define NONNULL5 __attribute__((nonnull(1,2,3,4,5))) -/** @endcond */ - /** A symmetric key, the compressed point of a private key. */ typedef unsigned char decaf_448_symmetric_key_t[DECAF_448_SYMMETRIC_KEY_BYTES]; @@ -175,14 +165,6 @@ decaf_448_verify ( const unsigned char *message, size_t message_len ) NONNULL3 API_VIS WARN_UNUSED; - -#undef API_VIS -#undef WARN_UNUSED -#undef NONNULL1 -#undef NONNULL2 -#undef NONNULL3 -#undef NONNULL134 -#undef NONNULL5 #ifdef __cplusplus } /* extern "C" */ diff --git a/src/public_include/decaf/shake.h b/src/public_include/decaf/shake.h index aa1fc4b..527bb21 100644 --- a/src/public_include/decaf/shake.h +++ b/src/public_include/decaf/shake.h @@ -18,17 +18,6 @@ #include -/** @cond internal */ -#define API_VIS __attribute__((visibility("default"))) -#define WARN_UNUSED __attribute__((warn_unused_result)) -#define NONNULL1 __attribute__((nonnull(1))) -#define NONNULL2 __attribute__((nonnull(1,2))) -#define NONNULL13 __attribute__((nonnull(1,3))) -#define NONNULL3 __attribute__((nonnull(1,2,3))) -#define INLINE __inline__ __attribute__((always_inline)) -#define UNUSED __attribute__((unused)) -/** @endcond */ - #ifndef INTERNAL_SPONGE_STRUCT /** Sponge container object for the various primitives. */ typedef struct keccak_sponge_s { @@ -574,14 +563,5 @@ void strobe_respec ( #ifdef __cplusplus } /* extern "C" */ #endif - -#undef API_VIS -#undef WARN_UNUSED -#undef NONNULL1 -#undef NONNULL13 -#undef NONNULL2 -#undef NONNULL3 -#undef INLINE -#undef UNUSED #endif /* __SHAKE_H__ */