@@ -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 | |||
@@ -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 */ |
@@ -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 */ |
@@ -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 <decaf/crypto.h> | |||
#include <string.h> | |||
#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; | |||
} |
@@ -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 <decaf/crypto_255.h> | |||
#include <string.h> | |||
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; | |||
} |
@@ -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 <decaf/crypto_448.h> | |||
#include <string.h> | |||
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; | |||
} |
@@ -10,6 +10,8 @@ | |||
#include "arch_config.h" | |||
#include <decaf/common.h> | |||
#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__ | |||
@@ -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. | |||
@@ -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 <decaf/crypto_255.h> | |||
#include <decaf/crypto_448.h> | |||
#endif /* __DECAF_CRYPTO_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" */ | |||
@@ -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" */ | |||
@@ -18,17 +18,6 @@ | |||
#include <decaf/common.h> | |||
/** @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__ */ |