@@ -88,7 +88,7 @@ HEADERS= Makefile $(shell find src test -name "*.h") $(BUILD_OBJ)/timestamp | |||||
HEADERSXX = $(HEADERS) $(shell find . -name "*.hxx") | HEADERSXX = $(HEADERS) $(shell find . -name "*.hxx") | ||||
# components needed by the lib | # 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 | 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)) \ | -I src/curve_$(1)/ -I src/$(2) -I src/$(2)/$$(ARCH_FOR_$(2)) \ | ||||
-S -c -o $$@ $$< | -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 | LIBCOMPONENTS += $$(BUILD_OBJ)/decaf_fast_$(1).o $$(BUILD_OBJ)/decaf_tables_$(1).o | ||||
endef | endef | ||||
@@ -2,6 +2,7 @@ | |||||
#define API_NS(_id) decaf_255_##_id | #define API_NS(_id) decaf_255_##_id | ||||
#define API_NS2(_pref,_id) _pref##_decaf_255_##_id | #define API_NS2(_pref,_id) _pref##_decaf_255_##_id | ||||
#define SCALAR_LIMBS DECAF_255_SCALAR_LIMBS | #define SCALAR_LIMBS DECAF_255_SCALAR_LIMBS | ||||
#define SCALAR_BITS DECAF_255_SCALAR_BITS | #define SCALAR_BITS DECAF_255_SCALAR_BITS | ||||
#define NLIMBS DECAF_255_LIMBS | #define NLIMBS DECAF_255_LIMBS | ||||
@@ -13,6 +14,7 @@ | |||||
#define P_MOD_8 5 | #define P_MOD_8 5 | ||||
#define COFACTOR 8 | #define COFACTOR 8 | ||||
#ifndef DECAF_JUST_API | |||||
static const int EDWARDS_D = -121665; | static const int EDWARDS_D = -121665; | ||||
static const scalar_t sc_p = {{{ | static const scalar_t sc_p = {{{ | ||||
@@ -36,3 +38,5 @@ static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL( | |||||
0x7540f7816214a, | 0x7540f7816214a, | ||||
0x0a0d85b4032b1 | 0x0a0d85b4032b1 | ||||
)}; | )}; | ||||
#endif /* DECAF_JUST_API */ |
@@ -13,6 +13,7 @@ | |||||
#define P_MOD_8 7 | #define P_MOD_8 7 | ||||
#define COFACTOR 4 | #define COFACTOR 4 | ||||
#ifndef DECAF_JUST_API | |||||
static const int EDWARDS_D = -39081; | static const int EDWARDS_D = -39081; | ||||
static const scalar_t sc_p = {{{ | 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 | -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 | ||||
#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 "arch_config.h" | ||||
#include <decaf/common.h> | |||||
#ifndef __APPLE__ | #ifndef __APPLE__ | ||||
#ifndef _BSD_SOURCE | #ifndef _BSD_SOURCE | ||||
@@ -68,11 +70,6 @@ | |||||
#error "For now, libdecaf only supports 32- and 64-bit architectures." | #error "For now, libdecaf only supports 32- and 64-bit architectures." | ||||
#endif | #endif | ||||
/* General utilities */ | |||||
#define NOINLINE __attribute__((noinline)) | |||||
#define UNUSED __attribute__((unused)) | |||||
#define INLINE __inline__ __attribute__((always_inline)) | |||||
#ifdef __ARM_NEON__ | #ifdef __ARM_NEON__ | ||||
typedef uint32x4_t vecmask_t; | typedef uint32x4_t vecmask_t; | ||||
#elif __clang__ | #elif __clang__ | ||||
@@ -27,8 +27,11 @@ | |||||
#define NONNULL2 __attribute__((nonnull(1,2))) | #define NONNULL2 __attribute__((nonnull(1,2))) | ||||
#define NONNULL3 __attribute__((nonnull(1,2,3))) | #define NONNULL3 __attribute__((nonnull(1,2,3))) | ||||
#define NONNULL13 __attribute__((nonnull(1,3))) | #define NONNULL13 __attribute__((nonnull(1,3))) | ||||
#define NONNULL134 __attribute__((nonnull(1,3,4))) | |||||
#define NONNULL4 __attribute__((nonnull(1,2,3,4))) | #define NONNULL4 __attribute__((nonnull(1,2,3,4))) | ||||
#define NONNULL5 __attribute__((nonnull(1,2,3,4,5))) | #define NONNULL5 __attribute__((nonnull(1,2,3,4,5))) | ||||
#define INLINE inline __attribute__((always_inline)) | |||||
#define UNUSED __attribute__((unused)) | |||||
/** @endcond */ | /** @endcond */ | ||||
/* Internal word types. | /* 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) */ | /** Number of bytes for a symmetric key (expanded to full key) */ | ||||
#define DECAF_255_SYMMETRIC_KEY_BYTES 32 | #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. */ | /** A symmetric key, the compressed point of a private key. */ | ||||
typedef unsigned char decaf_255_symmetric_key_t[DECAF_255_SYMMETRIC_KEY_BYTES]; | typedef unsigned char decaf_255_symmetric_key_t[DECAF_255_SYMMETRIC_KEY_BYTES]; | ||||
@@ -175,14 +165,6 @@ decaf_255_verify ( | |||||
const unsigned char *message, | const unsigned char *message, | ||||
size_t message_len | size_t message_len | ||||
) NONNULL3 API_VIS WARN_UNUSED; | ) NONNULL3 API_VIS WARN_UNUSED; | ||||
#undef API_VIS | |||||
#undef WARN_UNUSED | |||||
#undef NONNULL1 | |||||
#undef NONNULL2 | |||||
#undef NONNULL3 | |||||
#undef NONNULL134 | |||||
#undef NONNULL5 | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} /* extern "C" */ | } /* extern "C" */ | ||||
@@ -20,16 +20,6 @@ | |||||
/** Number of bytes for a symmetric key (expanded to full key) */ | /** Number of bytes for a symmetric key (expanded to full key) */ | ||||
#define DECAF_448_SYMMETRIC_KEY_BYTES 32 | #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. */ | /** A symmetric key, the compressed point of a private key. */ | ||||
typedef unsigned char decaf_448_symmetric_key_t[DECAF_448_SYMMETRIC_KEY_BYTES]; | typedef unsigned char decaf_448_symmetric_key_t[DECAF_448_SYMMETRIC_KEY_BYTES]; | ||||
@@ -175,14 +165,6 @@ decaf_448_verify ( | |||||
const unsigned char *message, | const unsigned char *message, | ||||
size_t message_len | size_t message_len | ||||
) NONNULL3 API_VIS WARN_UNUSED; | ) NONNULL3 API_VIS WARN_UNUSED; | ||||
#undef API_VIS | |||||
#undef WARN_UNUSED | |||||
#undef NONNULL1 | |||||
#undef NONNULL2 | |||||
#undef NONNULL3 | |||||
#undef NONNULL134 | |||||
#undef NONNULL5 | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} /* extern "C" */ | } /* extern "C" */ | ||||
@@ -18,17 +18,6 @@ | |||||
#include <decaf/common.h> | #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 | #ifndef INTERNAL_SPONGE_STRUCT | ||||
/** Sponge container object for the various primitives. */ | /** Sponge container object for the various primitives. */ | ||||
typedef struct keccak_sponge_s { | typedef struct keccak_sponge_s { | ||||
@@ -574,14 +563,5 @@ void strobe_respec ( | |||||
#ifdef __cplusplus | #ifdef __cplusplus | ||||
} /* extern "C" */ | } /* extern "C" */ | ||||
#endif | #endif | ||||
#undef API_VIS | |||||
#undef WARN_UNUSED | |||||
#undef NONNULL1 | |||||
#undef NONNULL13 | |||||
#undef NONNULL2 | |||||
#undef NONNULL3 | |||||
#undef INLINE | |||||
#undef UNUSED | |||||
#endif /* __SHAKE_H__ */ | #endif /* __SHAKE_H__ */ |