Browse Source

move strobe and crypto to TOY areas

master
Michael Hamburg 8 years ago
parent
commit
a01e875d4a
27 changed files with 894 additions and 1606 deletions
  1. +17
    -29
      Makefile
  2. +65
    -68
      src/GENERATED/c/curve25519/crypto.c
  3. +0
    -0
      src/GENERATED/c/decaf/crypto.h
  4. +0
    -0
      src/GENERATED/c/decaf/crypto.hxx
  5. +36
    -36
      src/GENERATED/c/decaf/crypto_255.h
  6. +20
    -20
      src/GENERATED/c/decaf/crypto_255.hxx
  7. +36
    -36
      src/GENERATED/c/decaf/crypto_448.h
  8. +20
    -20
      src/GENERATED/c/decaf/crypto_448.hxx
  9. +65
    -68
      src/GENERATED/c/ed448goldilocks/crypto.c
  10. +0
    -24
      src/bat/api_dh.h
  11. +0
    -24
      src/bat/api_sign.h
  12. +0
    -35
      src/bat/dh.c
  13. +0
    -64
      src/bat/sign.c
  14. +0
    -0
      src/include/decaf/crypto.tmpl.h
  15. +0
    -0
      src/include/decaf/crypto.tmpl.hxx
  16. +53
    -53
      src/include/decaf/strobe.h
  17. +15
    -15
      src/include/decaf/strobe.hxx
  18. +38
    -0
      src/include/keccak_internal.h
  19. +65
    -68
      src/per_curve/crypto.tmpl.c
  20. +32
    -32
      src/per_curve/crypto.tmpl.h
  21. +16
    -16
      src/per_curve/crypto.tmpl.hxx
  22. +0
    -341
      src/public_include/decaf/strobe.h
  23. +0
    -239
      src/public_include/decaf/strobe.hxx
  24. +2
    -418
      src/shake.c
  25. +412
    -0
      src/strobe.c
  26. +1
    -0
      test/bench_decaf.cxx
  27. +1
    -0
      test/test_decaf.cxx

+ 17
- 29
Makefile View File

@@ -57,7 +57,7 @@ endif
ARCHFLAGS += $(XARCHFLAGS)
CFLAGS = $(LANGFLAGS) $(WARNFLAGS) $(INCFLAGS) $(OFLAGS) $(ARCHFLAGS) $(GENFLAGS) $(XCFLAGS)
PUB_CFLAGS = $(LANGFLAGS) $(WARNFLAGS) $(PUB_INCFLAGS) $(OFLAGS) $(ARCHFLAGS) $(GENFLAGS) $(XCFLAGS)
CXXFLAGS = $(LANGXXFLAGS) $(WARNFLAGS) $(PUB_INCFLAGS) $(OFLAGS) $(ARCHFLAGS) $(GENFLAGS) $(XCXXFLAGS)
CXXFLAGS = $(LANGXXFLAGS) $(WARNFLAGS) $(INCFLAGS) $(OFLAGS) $(ARCHFLAGS) $(GENFLAGS) $(XCXXFLAGS)
LDFLAGS = $(XLDFLAGS)
ASFLAGS = $(ARCHFLAGS) $(XASFLAGS)

@@ -66,18 +66,20 @@ SAGES= $(shell ls test/*.sage)
BUILDPYS= $(SAGES:test/%.sage=$(BUILD_PY)/%.py)

.PHONY: clean all test test_ct bench todo doc lib bat sage sagetest gen_code
.PRECIOUS: $(BUILD_C)/*/%.c $(BUILD_H)/*/%.h $(BUILD_IBIN)/%
.PRECIOUS: $(BUILD_C)/*/%.c $(BUILD_H)/*/%.h $(BUILD_H)/%.h $(BUILD_H)/%.hxx $(BUILD_H)/*/%.hxx $(BUILD_IBIN)/%

HEADER_SRCS= $(shell find src/public_include -name "*.h*")
HEADER_PRIVATE_SRCS= $(shell find src/include -name "*.tmpl.h*")
GEN_CODE_0= $(HEADER_SRCS:src/public_include/%=$(BUILD_INC)/%)
GEN_CODE_0+= $(HEADER_PRIVATE_SRCS:src/include/%=$(BUILD_C)/%)
GEN_CODE_1= $(GEN_CODE_0:%.tmpl.h=%.h)
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)/sha512.o # and per-field components
LIBCOMPONENTS = $(BUILD_OBJ)/utils.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/strobe.o $(BUILD_OBJ)/sha512.o # and per-field components

BENCHCOMPONENTS = $(BUILD_OBJ)/bench.o $(BUILD_OBJ)/shake.o
BENCHCOMPONENTS = $(BUILD_OBJ)/bench.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/strobe.o

all: lib $(BUILD_IBIN)/test $(BUILD_IBIN)/bench $(BUILD_BIN)/shakesum

@@ -114,7 +116,7 @@ endif
$(BUILD_OBJ)/timestamp:
mkdir -p $(BUILD_OBJ) $(BUILD_C) $(BUILD_PY) \
$(BUILD_LIB) $(BUILD_INC) $(BUILD_BIN) $(BUILD_IBIN) $(BUILD_H) $(BUILD_INC)/decaf \
$(PER_OBJ_DIRS)
$(PER_OBJ_DIRS) $(BUILD_C)/decaf
touch $@

gen_code: $(GEN_CODE)
@@ -125,8 +127,14 @@ $(BUILD_INC)/%: src/public_include/% $(BUILD_OBJ)/timestamp
$(BUILD_INC)/%.h: src/public_include/%.tmpl.h src/generator/*
python -B src/generator/template.py --per=global --guard=$(@:$(BUILD_INC)/%=%) -o $@ $<
$(BUILD_C)/%.h: src/include/%.tmpl.h src/generator/*
python -B src/generator/template.py --per=global --guard=$(@:$(BUILD_C)/%=%) -o $@ $<
$(BUILD_INC)/%.hxx: src/public_include/%.tmpl.hxx src/generator/*
python -B src/generator/template.py --per=global --guard=$(@:$(BUILD_INC)/%=%) -o $@ $<
$(BUILD_C)/%.hxx: src/include/%.tmpl.hxx src/generator/*
python -B src/generator/template.py --per=global --guard=$(@:$(BUILD_C)/%=%) -o $@ $<

################################################################
# Per-field code: call with field, arch
@@ -169,7 +177,7 @@ LIBCOMPONENTS += $$(BUILD_OBJ)/$(1)/decaf.o $$(BUILD_OBJ)/$(1)/elligator.o $$(BU
$$(BUILD_OBJ)/$(1)/crypto.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/decaf_$(3).h $(BUILD_INC)/decaf/decaf_$(3).hxx \
$(BUILD_INC)/decaf/crypto_$(3).h $(BUILD_INC)/decaf/crypto_$(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))
@@ -192,7 +200,7 @@ $$(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_INC)/decaf/crypto_$(3).%: src/per_curve/crypto.tmpl.% src/generator/* Makefile
$$(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 \
@@ -279,30 +287,10 @@ $(BUILD_DOC)/timestamp:
#
doc: Doxyfile $(BUILD_OBJ)/timestamp $(HEADERS)
doxygen > /dev/null

# # The eBATS benchmarking script
# bat: $(BATNAME)
#
# $(BATNAME): include/* src/* src/*/* test/batarch.map $(BUILD_C)/decaf_tables.c # TODO tables some other way
# rm -fr $@
# for prim in dh sign; do \
# targ="$@/crypto_$$prim/ed448goldilocks_decaf"; \
# (while read arch where; do \
# mkdir -p $$targ/`basename $$arch`; \
# cp include/*.h $(BUILD_C)/decaf_tables.c src/decaf.c src/decaf_crypto.c src/shake.c src/include/*.h src/bat/$$prim.c src/p448/$$where/*.c src/p448/$$where/*.h src/p448/*.c src/p448/*.h $$targ/`basename $$arch`; \
# cp src/bat/api_$$prim.h $$targ/`basename $$arch`/api.h; \
# perl -p -i -e 's/SYSNAME/'`basename $(BATNAME)`_`basename $$arch`'/g' $$targ/`basename $$arch`/api.h; \
# perl -p -i -e 's/__TODAY__/'$(TODAY)'/g' $$targ/`basename $$arch`/api.h; \
# done \
# ) < test/batarch.map; \
# echo 'Mike Hamburg' > $$targ/designers; \
# echo 'Ed448-Goldilocks Decaf sign and dh' > $$targ/description; \
# done
# (cd $(BATNAME)/.. && tar czf $(BATBASE).tgz $(BATBASE) )
# Finds todo items in .h and .c files
TODO_TYPES ?= HACK TODO @todo FIXME BUG XXX PERF FUTURE REMOVE MAGIC UNIFY
TODO_LOCATIONS ?= src test Makefile Doxyfile
TODO_LOCATIONS ?= src/*.c src/include src/p* src/generator test Makefile Doxyfile
todo::
@(find $(TODO_LOCATIONS) -name '*.h' -or -name '*.c' -or -name '*.cxx' -or -name '*.hxx' -or -name '*.py') | xargs egrep --color=auto -w \
`echo $(TODO_TYPES) | tr ' ' '|'`
@@ -324,7 +312,7 @@ test: $(BUILD_IBIN)/test
./$<

test_ct: $(BUILD_IBIN)/test_ct
# NB: you must compile with XCFLAGS=-DNDEBUG or you will get lots of extra warnings.
# NB: you must compile with XCFLAGS=-DNDEBUG or you will get lots of extra warnings due to assert(thing that is always true).
valgrind ./$<
microbench: $(BUILD_IBIN)/bench


+ 65
- 68
src/GENERATED/c/curve25519/crypto.c View File

@@ -17,6 +17,7 @@

#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
@@ -30,20 +31,20 @@ 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(derive_private_key) (
API_NS(private_key_t) priv,
const API_NS(symmetric_key_t) proto
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_strobe_t strobe;
strobe_init(strobe, &STROBE_256, DERIVE_MAGIC, 0);
strobe_fixed_key(strobe, proto, sizeof(API_NS(symmetric_key_t)));
strobe_prng(strobe, encoded_scalar, sizeof(encoded_scalar));
strobe_destroy(strobe);
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(symmetric_key_t)));
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);
@@ -52,18 +53,17 @@ void API_NS(derive_private_key) (
decaf_bzero(encoded_scalar, sizeof(encoded_scalar));
}

void
API_NS(destroy_private_key) (
API_NS(private_key_t) priv
void API_NS_TOY(destroy_private_key) (
API_NS_TOY(private_key_t) priv
) {
decaf_bzero((void*)priv, sizeof(API_NS(private_key_t)));
decaf_bzero((void*)priv, sizeof(API_NS_TOY(private_key_t)));
}

void API_NS(private_to_public) (
API_NS(public_key_t) pub,
const API_NS(private_key_t) priv
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(public_key_t)));
memcpy(pub, priv->pub, sizeof(API_NS_TOY(public_key_t)));
}

/* Performance vs consttime tuning.
@@ -74,66 +74,64 @@ void API_NS(private_to_public) (
#define DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT DECAF_FALSE
#endif

decaf_error_t
API_NS(shared_secret) (
decaf_error_t API_NS_TOY(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,
const API_NS_TOY(private_key_t) my_privkey,
const API_NS_TOY(public_key_t) your_pubkey,
int me_first
) {
keccak_strobe_t strobe;
strobe_init(strobe, &STROBE_256, SHARED_SECRET_MAGIC, 0);
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) {
strobe_ad(strobe,my_privkey->pub,sizeof(API_NS(public_key_t)));
strobe_ad(strobe,your_pubkey,sizeof(API_NS(public_key_t)));
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 {
strobe_ad(strobe,your_pubkey,sizeof(API_NS(public_key_t)));
strobe_ad(strobe,my_privkey->pub,sizeof(API_NS(public_key_t)));
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
);
strobe_transact(strobe,NULL,ss_ser,sizeof(ss_ser),STROBE_CW_DH_KEY);
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;
strobe_prng(strobe,shared,cando);
decaf_TOY_strobe_prng(strobe,shared,cando);
shared_bytes -= cando;
shared += cando;
}

strobe_destroy(strobe);
decaf_TOY_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
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 */
strobe_transact(strobe,NULL,priv->pub,sizeof(API_NS(public_key_t)),STROBE_CW_SIG_PK);
decaf_TOY_strobe_transact(strobe,NULL,priv->pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK);
/* Derive nonce */
keccak_strobe_t strobe2;
keccak_decaf_TOY_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);
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);
@@ -141,8 +139,8 @@ API_NS(sign_strobe) (

/* Derive challenge */
strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH);
strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL);
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 */
@@ -151,7 +149,7 @@ API_NS(sign_strobe) (
/* Save results */
API_NS(scalar_encode)(overkill, nonce);
strobe_transact(strobe,&sig[SER_BYTES],overkill,SCALAR_BYTES,STROBE_CW_SIG_RESP);
decaf_TOY_strobe_transact(strobe,&sig[SER_BYTES],overkill,SCALAR_BYTES,STROBE_CW_SIG_RESP);
/* Clean up */
API_NS(scalar_destroy)(nonce);
@@ -159,11 +157,10 @@ API_NS(sign_strobe) (
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_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;
@@ -172,18 +169,18 @@ API_NS(verify_strobe) (
API_NS(scalar_t) challenge, response;
/* Stir pubkey */
strobe_transact(strobe,NULL,pub,sizeof(API_NS(public_key_t)),STROBE_CW_SIG_PK);
decaf_TOY_strobe_transact(strobe,NULL,pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK);
/* Derive nonce */
strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH);
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 */
strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL);
decaf_TOY_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);
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) );

@@ -205,30 +202,30 @@ API_NS(verify_strobe) (
}

void
API_NS(sign) (
API_NS(signature_t) sig,
const API_NS(private_key_t) priv,
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_strobe_t ctx;
strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0);
strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT);
API_NS(sign_strobe)(ctx, sig, priv);
strobe_destroy(ctx);
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(verify) (
const API_NS(signature_t) sig,
const API_NS(public_key_t) pub,
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_strobe_t ctx;
strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0);
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);
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;
}

src/GENERATED/include/decaf/crypto.h → src/GENERATED/c/decaf/crypto.h View File


src/GENERATED/include/decaf/crypto.hxx → src/GENERATED/c/decaf/crypto.hxx View File


src/GENERATED/include/decaf/crypto_255.h → src/GENERATED/c/decaf/crypto_255.h View File

@@ -1,5 +1,5 @@
/**
* @file decaf/crypto_255.h
* @file src/GENERATED/c/decaf/crypto_255.h
* @author Mike Hamburg
*
* @copyright
@@ -16,8 +16,8 @@
* Please do not edit it.
*/

#ifndef __DECAF_CRYPTO_255_H__
#define __DECAF_CRYPTO_255_H__ 1
#ifndef __SRC_GENERATED_C_DECAF_CRYPTO_255_H__
#define __SRC_GENERATED_C_DECAF_CRYPTO_255_H__ 1

#include <decaf/decaf_255.h>
#include <decaf/strobe.h>
@@ -30,45 +30,45 @@ extern "C" {
#define DECAF_255_SYMMETRIC_KEY_BYTES 32

/** 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_TOY_symmetric_key_t[DECAF_255_SYMMETRIC_KEY_BYTES];

/** An encoded public key. */
typedef unsigned char decaf_255_public_key_t[DECAF_255_SER_BYTES];
typedef unsigned char decaf_255_TOY_public_key_t[DECAF_255_SER_BYTES];

/** A signature. */
typedef unsigned char decaf_255_signature_t[DECAF_255_SER_BYTES + DECAF_255_SCALAR_BYTES];
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_symmetric_key_t sym;
decaf_255_TOY_symmetric_key_t sym;
/** The scalar x */
decaf_255_scalar_t secret_scalar;
/** x*Base */
decaf_255_public_key_t pub;
decaf_255_TOY_public_key_t pub;
/** @endcond */
} /** Private key structure for pointers. */
decaf_255_private_key_s,
decaf_255_TOY_private_key_s,
/** A private key (gmp array[1] style). */
decaf_255_private_key_t[1];
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_derive_private_key (
decaf_255_private_key_t priv,
const decaf_255_symmetric_key_t proto
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_destroy_private_key (
decaf_255_private_key_t priv
void decaf_255_TOY_destroy_private_key (
decaf_255_TOY_private_key_t priv
) NONNULL API_VIS;

/**
@@ -76,9 +76,9 @@ void decaf_255_destroy_private_key (
* @param [out] pub The extracted private key.
* @param [in] priv The private key.
*/
void decaf_255_private_to_public (
decaf_255_public_key_t pub,
const decaf_255_private_key_t priv
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;
/**
@@ -97,11 +97,11 @@ void decaf_255_private_to_public (
* @retval DECAF_FAILURE Key exchange failed.
*/
decaf_error_t
decaf_255_shared_secret (
decaf_255_TOY_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,
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;
@@ -113,10 +113,10 @@ decaf_255_shared_secret (
* @param [in] strobe A STROBE context with the message.
*/
void
decaf_255_sign_strobe (
keccak_strobe_t strobe,
decaf_255_signature_t sig,
const decaf_255_private_key_t priv
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;

/**
@@ -128,9 +128,9 @@ decaf_255_sign_strobe (
* @param [in] message_len The message's length.
*/
void
decaf_255_sign (
decaf_255_signature_t sig,
const decaf_255_private_key_t priv,
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;
@@ -146,10 +146,10 @@ decaf_255_sign (
* @return DECAF_FAILURE The signature did not verify successfully.
*/
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_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;

/**
@@ -164,9 +164,9 @@ decaf_255_verify_strobe (
* @return DECAF_FAILURE The signature did not verify successfully.
*/
decaf_error_t
decaf_255_verify (
const decaf_255_signature_t sig,
const decaf_255_public_key_t pub,
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;
@@ -175,4 +175,4 @@ decaf_255_verify (
} /* extern "C" */
#endif

#endif /* __DECAF_CRYPTO_255_H__ */
#endif /* __SRC_GENERATED_C_DECAF_CRYPTO_255_H__ */

src/GENERATED/include/decaf/crypto_255.hxx → src/GENERATED/c/decaf/crypto_255.hxx View File

@@ -1,5 +1,5 @@
/**
* @file decaf/crypto_255.hxx
* @file src/GENERATED/c/decaf/crypto_255.hxx
* @author Mike Hamburg
*
* @copyright
@@ -12,8 +12,8 @@
* Please do not edit it.
*/

#ifndef __DECAF_CRYPTO_255_HXX__
#define __DECAF_CRYPTO_255_HXX__ 1
#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
@@ -34,7 +34,7 @@
#endif
/** @endcond */

namespace decaf {
namespace decaf { namespace TOY {

/** A public key for crypto over some Group */
template <typename Group> class PublicKey;
@@ -47,7 +47,7 @@ template<> class PublicKey<IsoEd25519>
: public Serializable< PublicKey<IsoEd25519> > {
private:
/** @cond internal */
typedef decaf_255_public_key_t Wrapped;
typedef decaf_255_TOY_public_key_t Wrapped;
Wrapped wrapped;
template<class Group> friend class PrivateKey;
/** @endcond */
@@ -56,7 +56,7 @@ public:
typedef IsoEd25519 Group;
/** Signature size. */
static const size_t SIG_BYTES = sizeof(decaf_255_signature_t);
static const size_t SIG_BYTES = sizeof(decaf_255_TOY_signature_t);
/** Serialization size. */
static const size_t SER_BYTES = sizeof(Wrapped);
@@ -85,7 +85,7 @@ public:
const Block &message,
const FixedBlock<SIG_BYTES> &sig
) const throw(CryptoException) {
if (DECAF_SUCCESS != decaf_255_verify(sig.data(),wrapped,message.data(),message.size())) {
if (DECAF_SUCCESS != decaf_255_TOY_verify(sig.data(),wrapped,message.data(),message.size())) {
throw(CryptoException());
}
}
@@ -95,7 +95,7 @@ public:
Strobe &context,
const FixedBlock<SIG_BYTES> &sig
) const throw(CryptoException) {
if (DECAF_SUCCESS != decaf_255_verify_strobe(context.wrapped,sig.data(),wrapped)) {
if (DECAF_SUCCESS != decaf_255_TOY_verify_strobe(context.wrapped,sig.data(),wrapped)) {
throw(CryptoException());
}
}
@@ -106,7 +106,7 @@ template<> class PrivateKey<IsoEd25519>
: public Serializable< PrivateKey<IsoEd25519> > {
private:
/** @cond internal */
typedef decaf_255_private_key_t Wrapped;
typedef decaf_255_TOY_private_key_t Wrapped;
Wrapped wrapped;
template<class Group> friend class PublicKey;
/** @endcond */
@@ -115,7 +115,7 @@ public:
typedef IsoEd25519 Group;
/** Signature size. */
static const size_t SIG_BYTES = sizeof(decaf_255_signature_t);
static const size_t SIG_BYTES = sizeof(decaf_255_TOY_signature_t);
/** Serialization size. */
static const size_t SER_BYTES = sizeof(Wrapped);
@@ -133,18 +133,18 @@ public:
/** Read a private key from a string*/
inline explicit PrivateKey(const FixedBlock<SYM_BYTES> &b) NOEXCEPT {
decaf_255_derive_private_key(wrapped, b.data());
decaf_255_TOY_derive_private_key(wrapped, b.data());
}
/** Create at random */
inline explicit PrivateKey(Rng &r) NOEXCEPT {
FixedArrayBuffer<SYM_BYTES> tmp(r);
decaf_255_derive_private_key(wrapped, tmp.data());
decaf_255_TOY_derive_private_key(wrapped, tmp.data());
}
/** Secure destructor */
inline ~PrivateKey() NOEXCEPT {
decaf_255_destroy_private_key(wrapped);
decaf_255_TOY_destroy_private_key(wrapped);
}
/** Serialization size. */
@@ -174,7 +174,7 @@ public:
bool me_first
) const throw(CryptoException,std::bad_alloc) {
SecureBuffer ret(bytes);
if (DECAF_SUCCESS != decaf_255_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) {
if (DECAF_SUCCESS != decaf_255_TOY_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) {
throw(CryptoException());
}
return ret;
@@ -187,30 +187,30 @@ public:
const PublicKey<IsoEd25519> &pub,
bool me_first
) const NOEXCEPT {
return decaf_255_shared_secret(ret.data(),ret.size(),wrapped,pub.wrapped,me_first);
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_sign(sig.data(), wrapped, message.data(), message.size());
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_sign_strobe(context.wrapped, sig.data(), wrapped);
decaf_255_TOY_sign_strobe(context.wrapped, sig.data(), wrapped);
return sig;
}
};

/** @cond internal */
PublicKey<IsoEd25519>::PublicKey(const PrivateKey<IsoEd25519> &b) NOEXCEPT {
decaf_255_private_to_public(wrapped,b.wrapped);
decaf_255_TOY_private_to_public(wrapped,b.wrapped);
}
/** @endcond */

#undef NOEXCEPT
} /* namespace decaf */
#endif /* __DECAF_CRYPTO_255_HXX__ */
}} /* namespace decaf::TOY */
#endif /* __SRC_GENERATED_C_DECAF_CRYPTO_255_HXX__ */

src/GENERATED/include/decaf/crypto_448.h → src/GENERATED/c/decaf/crypto_448.h View File

@@ -1,5 +1,5 @@
/**
* @file decaf/crypto_448.h
* @file src/GENERATED/c/decaf/crypto_448.h
* @author Mike Hamburg
*
* @copyright
@@ -16,8 +16,8 @@
* Please do not edit it.
*/

#ifndef __DECAF_CRYPTO_448_H__
#define __DECAF_CRYPTO_448_H__ 1
#ifndef __SRC_GENERATED_C_DECAF_CRYPTO_448_H__
#define __SRC_GENERATED_C_DECAF_CRYPTO_448_H__ 1

#include <decaf/decaf_448.h>
#include <decaf/strobe.h>
@@ -30,45 +30,45 @@ extern "C" {
#define DECAF_448_SYMMETRIC_KEY_BYTES 32

/** 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_TOY_symmetric_key_t[DECAF_448_SYMMETRIC_KEY_BYTES];

/** An encoded public key. */
typedef unsigned char decaf_448_public_key_t[DECAF_448_SER_BYTES];
typedef unsigned char decaf_448_TOY_public_key_t[DECAF_448_SER_BYTES];

/** A signature. */
typedef unsigned char decaf_448_signature_t[DECAF_448_SER_BYTES + DECAF_448_SCALAR_BYTES];
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_symmetric_key_t sym;
decaf_448_TOY_symmetric_key_t sym;
/** The scalar x */
decaf_448_scalar_t secret_scalar;
/** x*Base */
decaf_448_public_key_t pub;
decaf_448_TOY_public_key_t pub;
/** @endcond */
} /** Private key structure for pointers. */
decaf_448_private_key_s,
decaf_448_TOY_private_key_s,
/** A private key (gmp array[1] style). */
decaf_448_private_key_t[1];
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_derive_private_key (
decaf_448_private_key_t priv,
const decaf_448_symmetric_key_t proto
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_destroy_private_key (
decaf_448_private_key_t priv
void decaf_448_TOY_destroy_private_key (
decaf_448_TOY_private_key_t priv
) NONNULL API_VIS;

/**
@@ -76,9 +76,9 @@ void decaf_448_destroy_private_key (
* @param [out] pub The extracted private key.
* @param [in] priv The private key.
*/
void decaf_448_private_to_public (
decaf_448_public_key_t pub,
const decaf_448_private_key_t priv
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;
/**
@@ -97,11 +97,11 @@ void decaf_448_private_to_public (
* @retval DECAF_FAILURE Key exchange failed.
*/
decaf_error_t
decaf_448_shared_secret (
decaf_448_TOY_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,
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;
@@ -113,10 +113,10 @@ decaf_448_shared_secret (
* @param [in] strobe A STROBE context with the message.
*/
void
decaf_448_sign_strobe (
keccak_strobe_t strobe,
decaf_448_signature_t sig,
const decaf_448_private_key_t priv
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;

/**
@@ -128,9 +128,9 @@ decaf_448_sign_strobe (
* @param [in] message_len The message's length.
*/
void
decaf_448_sign (
decaf_448_signature_t sig,
const decaf_448_private_key_t priv,
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;
@@ -146,10 +146,10 @@ decaf_448_sign (
* @return DECAF_FAILURE The signature did not verify successfully.
*/
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_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;

/**
@@ -164,9 +164,9 @@ decaf_448_verify_strobe (
* @return DECAF_FAILURE The signature did not verify successfully.
*/
decaf_error_t
decaf_448_verify (
const decaf_448_signature_t sig,
const decaf_448_public_key_t pub,
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;
@@ -175,4 +175,4 @@ decaf_448_verify (
} /* extern "C" */
#endif

#endif /* __DECAF_CRYPTO_448_H__ */
#endif /* __SRC_GENERATED_C_DECAF_CRYPTO_448_H__ */

src/GENERATED/include/decaf/crypto_448.hxx → src/GENERATED/c/decaf/crypto_448.hxx View File

@@ -1,5 +1,5 @@
/**
* @file decaf/crypto_448.hxx
* @file src/GENERATED/c/decaf/crypto_448.hxx
* @author Mike Hamburg
*
* @copyright
@@ -12,8 +12,8 @@
* Please do not edit it.
*/

#ifndef __DECAF_CRYPTO_448_HXX__
#define __DECAF_CRYPTO_448_HXX__ 1
#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
@@ -34,7 +34,7 @@
#endif
/** @endcond */

namespace decaf {
namespace decaf { namespace TOY {

/** A public key for crypto over some Group */
template <typename Group> class PublicKey;
@@ -47,7 +47,7 @@ template<> class PublicKey<Ed448Goldilocks>
: public Serializable< PublicKey<Ed448Goldilocks> > {
private:
/** @cond internal */
typedef decaf_448_public_key_t Wrapped;
typedef decaf_448_TOY_public_key_t Wrapped;
Wrapped wrapped;
template<class Group> friend class PrivateKey;
/** @endcond */
@@ -56,7 +56,7 @@ public:
typedef Ed448Goldilocks Group;
/** Signature size. */
static const size_t SIG_BYTES = sizeof(decaf_448_signature_t);
static const size_t SIG_BYTES = sizeof(decaf_448_TOY_signature_t);
/** Serialization size. */
static const size_t SER_BYTES = sizeof(Wrapped);
@@ -85,7 +85,7 @@ public:
const Block &message,
const FixedBlock<SIG_BYTES> &sig
) const throw(CryptoException) {
if (DECAF_SUCCESS != decaf_448_verify(sig.data(),wrapped,message.data(),message.size())) {
if (DECAF_SUCCESS != decaf_448_TOY_verify(sig.data(),wrapped,message.data(),message.size())) {
throw(CryptoException());
}
}
@@ -95,7 +95,7 @@ public:
Strobe &context,
const FixedBlock<SIG_BYTES> &sig
) const throw(CryptoException) {
if (DECAF_SUCCESS != decaf_448_verify_strobe(context.wrapped,sig.data(),wrapped)) {
if (DECAF_SUCCESS != decaf_448_TOY_verify_strobe(context.wrapped,sig.data(),wrapped)) {
throw(CryptoException());
}
}
@@ -106,7 +106,7 @@ template<> class PrivateKey<Ed448Goldilocks>
: public Serializable< PrivateKey<Ed448Goldilocks> > {
private:
/** @cond internal */
typedef decaf_448_private_key_t Wrapped;
typedef decaf_448_TOY_private_key_t Wrapped;
Wrapped wrapped;
template<class Group> friend class PublicKey;
/** @endcond */
@@ -115,7 +115,7 @@ public:
typedef Ed448Goldilocks Group;
/** Signature size. */
static const size_t SIG_BYTES = sizeof(decaf_448_signature_t);
static const size_t SIG_BYTES = sizeof(decaf_448_TOY_signature_t);
/** Serialization size. */
static const size_t SER_BYTES = sizeof(Wrapped);
@@ -133,18 +133,18 @@ public:
/** Read a private key from a string*/
inline explicit PrivateKey(const FixedBlock<SYM_BYTES> &b) NOEXCEPT {
decaf_448_derive_private_key(wrapped, b.data());
decaf_448_TOY_derive_private_key(wrapped, b.data());
}
/** Create at random */
inline explicit PrivateKey(Rng &r) NOEXCEPT {
FixedArrayBuffer<SYM_BYTES> tmp(r);
decaf_448_derive_private_key(wrapped, tmp.data());
decaf_448_TOY_derive_private_key(wrapped, tmp.data());
}
/** Secure destructor */
inline ~PrivateKey() NOEXCEPT {
decaf_448_destroy_private_key(wrapped);
decaf_448_TOY_destroy_private_key(wrapped);
}
/** Serialization size. */
@@ -174,7 +174,7 @@ public:
bool me_first
) const throw(CryptoException,std::bad_alloc) {
SecureBuffer ret(bytes);
if (DECAF_SUCCESS != decaf_448_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) {
if (DECAF_SUCCESS != decaf_448_TOY_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) {
throw(CryptoException());
}
return ret;
@@ -187,30 +187,30 @@ public:
const PublicKey<Ed448Goldilocks> &pub,
bool me_first
) const NOEXCEPT {
return decaf_448_shared_secret(ret.data(),ret.size(),wrapped,pub.wrapped,me_first);
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_sign(sig.data(), wrapped, message.data(), message.size());
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_sign_strobe(context.wrapped, sig.data(), wrapped);
decaf_448_TOY_sign_strobe(context.wrapped, sig.data(), wrapped);
return sig;
}
};

/** @cond internal */
PublicKey<Ed448Goldilocks>::PublicKey(const PrivateKey<Ed448Goldilocks> &b) NOEXCEPT {
decaf_448_private_to_public(wrapped,b.wrapped);
decaf_448_TOY_private_to_public(wrapped,b.wrapped);
}
/** @endcond */

#undef NOEXCEPT
} /* namespace decaf */
#endif /* __DECAF_CRYPTO_448_HXX__ */
}} /* namespace decaf::TOY */
#endif /* __SRC_GENERATED_C_DECAF_CRYPTO_448_HXX__ */

+ 65
- 68
src/GENERATED/c/ed448goldilocks/crypto.c View File

@@ -17,6 +17,7 @@

#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
@@ -30,20 +31,20 @@ 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(derive_private_key) (
API_NS(private_key_t) priv,
const API_NS(symmetric_key_t) proto
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_strobe_t strobe;
strobe_init(strobe, &STROBE_256, DERIVE_MAGIC, 0);
strobe_fixed_key(strobe, proto, sizeof(API_NS(symmetric_key_t)));
strobe_prng(strobe, encoded_scalar, sizeof(encoded_scalar));
strobe_destroy(strobe);
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(symmetric_key_t)));
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);
@@ -52,18 +53,17 @@ void API_NS(derive_private_key) (
decaf_bzero(encoded_scalar, sizeof(encoded_scalar));
}

void
API_NS(destroy_private_key) (
API_NS(private_key_t) priv
void API_NS_TOY(destroy_private_key) (
API_NS_TOY(private_key_t) priv
) {
decaf_bzero((void*)priv, sizeof(API_NS(private_key_t)));
decaf_bzero((void*)priv, sizeof(API_NS_TOY(private_key_t)));
}

void API_NS(private_to_public) (
API_NS(public_key_t) pub,
const API_NS(private_key_t) priv
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(public_key_t)));
memcpy(pub, priv->pub, sizeof(API_NS_TOY(public_key_t)));
}

/* Performance vs consttime tuning.
@@ -74,66 +74,64 @@ void API_NS(private_to_public) (
#define DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT DECAF_FALSE
#endif

decaf_error_t
API_NS(shared_secret) (
decaf_error_t API_NS_TOY(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,
const API_NS_TOY(private_key_t) my_privkey,
const API_NS_TOY(public_key_t) your_pubkey,
int me_first
) {
keccak_strobe_t strobe;
strobe_init(strobe, &STROBE_256, SHARED_SECRET_MAGIC, 0);
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) {
strobe_ad(strobe,my_privkey->pub,sizeof(API_NS(public_key_t)));
strobe_ad(strobe,your_pubkey,sizeof(API_NS(public_key_t)));
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 {
strobe_ad(strobe,your_pubkey,sizeof(API_NS(public_key_t)));
strobe_ad(strobe,my_privkey->pub,sizeof(API_NS(public_key_t)));
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
);
strobe_transact(strobe,NULL,ss_ser,sizeof(ss_ser),STROBE_CW_DH_KEY);
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;
strobe_prng(strobe,shared,cando);
decaf_TOY_strobe_prng(strobe,shared,cando);
shared_bytes -= cando;
shared += cando;
}

strobe_destroy(strobe);
decaf_TOY_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
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 */
strobe_transact(strobe,NULL,priv->pub,sizeof(API_NS(public_key_t)),STROBE_CW_SIG_PK);
decaf_TOY_strobe_transact(strobe,NULL,priv->pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK);
/* Derive nonce */
keccak_strobe_t strobe2;
keccak_decaf_TOY_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);
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);
@@ -141,8 +139,8 @@ API_NS(sign_strobe) (

/* Derive challenge */
strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH);
strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL);
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 */
@@ -151,7 +149,7 @@ API_NS(sign_strobe) (
/* Save results */
API_NS(scalar_encode)(overkill, nonce);
strobe_transact(strobe,&sig[SER_BYTES],overkill,SCALAR_BYTES,STROBE_CW_SIG_RESP);
decaf_TOY_strobe_transact(strobe,&sig[SER_BYTES],overkill,SCALAR_BYTES,STROBE_CW_SIG_RESP);
/* Clean up */
API_NS(scalar_destroy)(nonce);
@@ -159,11 +157,10 @@ API_NS(sign_strobe) (
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_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;
@@ -172,18 +169,18 @@ API_NS(verify_strobe) (
API_NS(scalar_t) challenge, response;
/* Stir pubkey */
strobe_transact(strobe,NULL,pub,sizeof(API_NS(public_key_t)),STROBE_CW_SIG_PK);
decaf_TOY_strobe_transact(strobe,NULL,pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK);
/* Derive nonce */
strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH);
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 */
strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL);
decaf_TOY_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);
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) );

@@ -205,30 +202,30 @@ API_NS(verify_strobe) (
}

void
API_NS(sign) (
API_NS(signature_t) sig,
const API_NS(private_key_t) priv,
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_strobe_t ctx;
strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0);
strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT);
API_NS(sign_strobe)(ctx, sig, priv);
strobe_destroy(ctx);
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(verify) (
const API_NS(signature_t) sig,
const API_NS(public_key_t) pub,
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_strobe_t ctx;
strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0);
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);
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;
}

+ 0
- 24
src/bat/api_dh.h View File

@@ -1,24 +0,0 @@
/**
* @file sizes.h
* @copyright
* Copyright (c) 2014 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information.
* @author Mike Hamburg
* @brief BATMAN / SUPERCOP glue for benchmarking.
*/

#include <string.h>
#include "decaf_crypto.h"

#define PUBLICKEY_BYTES (sizeof(decaf_448_public_key_t))
#define SECRETKEY_BYTES (sizeof(decaf_448_private_key_t))
#define SHAREDSECRET_BYTES 32

#define CRYPTO_PUBLICKEYBYTES PUBLICKEY_BYTES
#define CRYPTO_SECRETKEYBYTES SECRETKEY_BYTES
#define CRYPTO_BYTES SHAREDSECRET_BYTES
#define PRIVATEKEY_BYTES SECRETKEY_BYTES
#define CRYPTO_VERSION "__TODAY__"

#define CRYPTO_DETERMINISTIC 1


+ 0
- 24
src/bat/api_sign.h View File

@@ -1,24 +0,0 @@
/**
* @file sizes.h
* @copyright
* Copyright (c) 2014 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information.
* @author Mike Hamburg
* @brief BATMAN / SUPERCOP glue for benchmarking.
*/

#include <string.h>
#include "decaf_crypto.h"

#define PUBLICKEY_BYTES (sizeof(decaf_448_public_key_t))
#define SECRETKEY_BYTES (sizeof(decaf_448_private_key_t))
#define SIGNATURE_BYTES (sizeof(decaf_448_signature_t))

#define CRYPTO_PUBLICKEYBYTES PUBLICKEY_BYTES
#define CRYPTO_SECRETKEYBYTES SECRETKEY_BYTES
#define CRYPTO_BYTES SIGNATURE_BYTES
#define PRIVATEKEY_BYTES SECRETKEY_BYTES
#define CRYPTO_VERSION "__TODAY__"

#define CRYPTO_DETERMINISTIC 1


+ 0
- 35
src/bat/dh.c View File

@@ -1,35 +0,0 @@
/**
* @file sizes.h
* @copyright
* Copyright (c) 2014 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information.
* @author Mike Hamburg
* @brief BATMAN / SUPERCOP glue for benchmarking.
*/

#include <string.h>
#include <stdlib.h>
#include "api.h"
#include "crypto_dh.h"
#include "randombytes.h"

int crypto_dh_keypair (
unsigned char pk[PUBLICKEY_BYTES],
unsigned char sk[SECRETKEY_BYTES]
) {
decaf_448_symmetric_key_t proto;
randombytes(proto,sizeof(proto));
decaf_448_derive_private_key((decaf_448_private_key_s *)sk,proto);
decaf_448_private_to_public(pk,(decaf_448_private_key_s *)sk);
return 0;
}

int crypto_dh (
unsigned char s[SHAREDSECRET_BYTES],
const unsigned char pk[PUBLICKEY_BYTES],
const unsigned char sk[SECRETKEY_BYTES]
) {
return !decaf_448_shared_secret (s,SHAREDSECRET_BYTES,
(const decaf_448_private_key_s *)sk, pk
);
}

+ 0
- 64
src/bat/sign.c View File

@@ -1,64 +0,0 @@
/**
* @file sizes.h
* @copyright
* Copyright (c) 2014 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information.
* @author Mike Hamburg
* @brief BATMAN / SUPERCOP glue for benchmarking.
*/

#include <stdlib.h>
#include <string.h>
#include "api.h"
#include "crypto_sign.h"
#include "randombytes.h"

int crypto_sign_keypair (
unsigned char pk[PUBLICKEY_BYTES],
unsigned char sk[SECRETKEY_BYTES]
) {
decaf_448_symmetric_key_t proto;
randombytes(proto,sizeof(proto));
decaf_448_derive_private_key((decaf_448_private_key_s *)sk,proto);
decaf_448_private_to_public(pk,
(decaf_448_private_key_s *)sk
);
return 0;
}

int crypto_sign (
unsigned char *sm,
unsigned long long *smlen,
const unsigned char *m,
unsigned long long mlen,
const unsigned char sk[SECRETKEY_BYTES]
) {
unsigned char sig[SIGNATURE_BYTES];
decaf_448_sign(
sig,
(const decaf_448_private_key_s *)sk,
m, mlen
);
memmove(sm + SIGNATURE_BYTES, m, mlen);
memcpy(sm, sig, SIGNATURE_BYTES);
*smlen = mlen + SIGNATURE_BYTES;
return 0;
}

int crypto_sign_open (
unsigned char *m,
unsigned long long *mlen,
const unsigned char *sm,
unsigned long long smlen,
const unsigned char pk[PUBLICKEY_BYTES]
) {
int ret = decaf_448_verify(
sm,pk,
sm + SIGNATURE_BYTES, smlen - SIGNATURE_BYTES
);
if (ret) {
*mlen = smlen - SIGNATURE_BYTES;
memmove(m, sm + SIGNATURE_BYTES, *mlen);
}
return ret ? 0 : -1;
}

src/public_include/decaf/crypto.tmpl.h → src/include/decaf/crypto.tmpl.h View File


src/public_include/decaf/crypto.tmpl.hxx → src/include/decaf/crypto.tmpl.hxx View File


src/GENERATED/include/decaf/strobe.h → src/include/decaf/strobe.h View File

@@ -20,10 +20,10 @@ extern "C" {
/** Keccak STROBE structure as struct. */
typedef struct {
decaf_keccak_sponge_t sponge; /**< Internal sponge object. */
} keccak_strobe_s;
} keccak_decaf_TOY_strobe_s;
/** Keccak STROBE structure as one-element array */
typedef keccak_strobe_s keccak_strobe_t[1];
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;
@@ -39,16 +39,16 @@ extern const struct decaf_kparams_s STROBE_KEYED_256 API_VIS;


/** Initialize Strobe protocol context. */
void strobe_init (
keccak_strobe_t strobe, /**< [out] The uninitialized strobe object. */
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 strobe_transact (
keccak_strobe_t strobe, /**< [inout] The initialized STROBE object. */
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. */
@@ -56,8 +56,8 @@ void strobe_transact (
) __attribute__((nonnull(1))) API_VIS;

/** Record a message sent in plaintext */
static INLINE UNUSED NONNULL void strobe_plaintext (
keccak_strobe_t strobe, /**< [inout] The STROBE object */
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. */
@@ -65,43 +65,43 @@ static INLINE UNUSED NONNULL void strobe_plaintext (

/** Report authenticated data in strobe context. */
static INLINE UNUSED NONNULL void
strobe_ad (
keccak_strobe_t strobe, /**< [inout] The strobe object. */
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
strobe_nonce (
keccak_strobe_t strobe, /**< [inout] The initialized strobe object. */
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
strobe_fixed_key (
keccak_strobe_t strobe, /**< [inout] The initialized strobe object. */
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
strobe_dh_key (
keccak_strobe_t strobe, /**< [inout] The initialized strobe object. */
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 strobe_produce_auth can spit out. */
/** 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
strobe_produce_auth (
keccak_strobe_t strobe, /**< [inout] The Strobe protocol context. */
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. */
);
@@ -112,8 +112,8 @@ strobe_produce_auth (
* @retval DECAF_FAILURE The operation failed because of a
* bad validator (or because you aren't keyed)
*/
decaf_error_t strobe_verify_auth (
keccak_strobe_t strobe, /**< [inout] The Strobe protocol context */
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;
@@ -123,8 +123,8 @@ decaf_error_t strobe_verify_auth (
* @warning Doesn't produce an auth tag.
*/
static INLINE UNUSED NONNULL void
strobe_encrypt (
keccak_strobe_t strobe, /**< [inout] strobe The Strobe protocol context. */
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. */
@@ -135,8 +135,8 @@ strobe_encrypt (
* @warning Doesn't check an auth tag.
*/
static INLINE UNUSED NONNULL void
strobe_decrypt (
keccak_strobe_t strobe, /**< [inout] The Strobe protocol context. */
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. */
@@ -149,22 +149,22 @@ strobe_decrypt (
* refreshing forward secrecy! It's to replace things
* like TCP session hash.
*/
static inline void NONNULL strobe_prng (
keccak_strobe_t strobe, /**< [inout] The Strobe protocol context */
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 strobe_respec (
keccak_strobe_t strobe, /**< [inout] The initialized strobe context. */
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
strobe_destroy (
keccak_strobe_t doomed /**< [in] The object to destroy. */
decaf_TOY_strobe_destroy (
keccak_decaf_TOY_strobe_t doomed /**< [in] The object to destroy. */
);

/** @cond internal */
@@ -184,7 +184,7 @@ typedef enum {
STROBE_MODE_SQUEEZE = 5,
STROBE_MODE_FORGET = 6,
STROBE_MODE_SQUEEZE_R = 7
} strobe_mode_t;
} 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. */
@@ -263,7 +263,7 @@ 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
strobe_cw_recv(uint32_t cw) {
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;
@@ -288,47 +288,47 @@ strobe_cw_recv(uint32_t cw) {
/* Implementations of inline functions */
/***************************************/

void strobe_plaintext(keccak_strobe_t strobe, const unsigned char *in, uint16_t len, uint8_t iSent) {
strobe_transact(
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
: strobe_cw_recv(STROBE_CW_PAYLOAD_PLAINTEXT)
: decaf_TOY_strobe_cw_recv(STROBE_CW_PAYLOAD_PLAINTEXT)
);
}

void strobe_ad(keccak_strobe_t strobe, const unsigned char *in, size_t len) {
strobe_transact( strobe, NULL, in, len, STROBE_CW_AD_EXPLICIT );
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 strobe_nonce (keccak_strobe_t strobe, const unsigned char *in, uint16_t len) {
strobe_transact( strobe, NULL, in, len, STROBE_CW_NONCE_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 strobe_fixed_key (keccak_strobe_t strobe, const unsigned char *in, uint16_t len) {
strobe_transact( strobe, NULL, in, len, STROBE_CW_FIXED_KEY );
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 strobe_dh_key (keccak_strobe_t strobe, const unsigned char *in, uint16_t len) {
strobe_transact( strobe, NULL, in, len, STROBE_CW_DH_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 strobe_produce_auth (keccak_strobe_t strobe, unsigned char *out, uint16_t len) {
strobe_transact( strobe, out, NULL, len, STROBE_CW_MAC );
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 strobe_encrypt (keccak_strobe_t strobe, unsigned char *out, const unsigned char *in, uint16_t len) {
strobe_transact(strobe, out, in, len, STROBE_CW_PAYLOAD_CIPHERTEXT);
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 strobe_decrypt(keccak_strobe_t strobe, unsigned char *out, const unsigned char *in, uint16_t len) {
strobe_transact(strobe, out, in, len, strobe_cw_recv(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 strobe_prng(keccak_strobe_t strobe, unsigned char *out, uint16_t len) {
strobe_transact( strobe, out, NULL, len, STROBE_CW_PRNG );
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 strobe_destroy (keccak_strobe_t doomed) {
void decaf_TOY_strobe_destroy (keccak_decaf_TOY_strobe_t doomed) {
decaf_sponge_destroy(doomed->sponge);
}


src/GENERATED/include/decaf/strobe.hxx → src/include/decaf/strobe.hxx View File

@@ -41,7 +41,7 @@ public:
class Strobe {
public:
/** The wrapped object */
keccak_strobe_t wrapped;
keccak_decaf_TOY_strobe_t wrapped;
/** Number of bytes in a default authentication size. */
static const uint16_t DEFAULT_AUTH_SIZE = 16;
@@ -55,18 +55,18 @@ public:
client_or_server whoami, /**< Am I client or server? */
const decaf_kparams_s &params = STROBE_256 /**< Strength parameters */
) NOEXCEPT {
strobe_init(wrapped, &params, description, whoami == CLIENT);
decaf_TOY_strobe_init(wrapped, &params, description, whoami == CLIENT);
keyed = false;
}
/** Securely destroy by overwriting state. */
inline ~Strobe() NOEXCEPT { strobe_destroy(wrapped); }
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) {
strobe_fixed_key(wrapped, data.data(), data.size());
decaf_TOY_strobe_fixed_key(wrapped, data.data(), data.size());
keyed = true;
}

@@ -81,7 +81,7 @@ public:
inline void dh_key (
const Block &data /**< The key. */
) throw(ProtocolException) {
strobe_dh_key(wrapped, data.data(), data.size());
decaf_TOY_strobe_dh_key(wrapped, data.data(), data.size());
keyed = true;
}

@@ -94,12 +94,12 @@ public:

/** Stir in an explicit nonce. */
inline void nonce(const Block &data) NOEXCEPT {
strobe_nonce(wrapped, data.data(), data.size());
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 {
strobe_plaintext(wrapped, data.data(), data.size(), true);
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. */
@@ -109,12 +109,12 @@ public:

/** Stir in data we received as plaintext. NB This doesn't actually receive anything. */
inline void recv_plaintext(const Block &data) NOEXCEPT {
strobe_plaintext(wrapped, data.data(), data.size(), false);
decaf_TOY_strobe_plaintext(wrapped, data.data(), data.size(), false);
}

/** Stir in associated data. */
inline void ad(const Block &data) {
strobe_ad(wrapped, data.data(), data.size());
decaf_TOY_strobe_ad(wrapped, data.data(), data.size());
}

/** Stir in associated serializable data. */
@@ -126,7 +126,7 @@ public:
inline void encrypt_no_auth(Buffer out, const Block &data) throw(LengthException,ProtocolException) {
if (!keyed) throw ProtocolException();
if (out.size() != data.size()) throw LengthException();
strobe_encrypt(wrapped, out.data(), data.data(), data.size());
decaf_TOY_strobe_encrypt(wrapped, out.data(), data.data(), data.size());
}
/** Encrypt, without appending authentication data */
@@ -143,7 +143,7 @@ public:
inline void decrypt_no_auth(Buffer out, const Block &data) throw(LengthException,ProtocolException) {
if (!keyed) throw ProtocolException();
if (out.size() != data.size()) throw LengthException();
strobe_decrypt(wrapped, out.data(), data.data(), data.size());
decaf_TOY_strobe_decrypt(wrapped, out.data(), data.data(), data.size());
}
/** Decrypt, without checking authentication data. */
@@ -155,7 +155,7 @@ public:
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();
strobe_produce_auth(wrapped, out.data(), out.size());
decaf_TOY_strobe_produce_auth(wrapped, out.data(), out.size());
}
/** Produce an authenticator. */
@@ -206,12 +206,12 @@ public:
/** 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 (strobe_verify_auth(wrapped, auth.data(), auth.size()) != DECAF_SUCCESS) throw CryptoException();
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)strobe_prng(wrapped, out.data(), out.size());
(void)decaf_TOY_strobe_prng(wrapped, out.data(), out.size());
}
/** Return pseudorandom data */
@@ -224,7 +224,7 @@ public:
*/
inline void respec(const decaf_kparams_s &params) throw(ProtocolException) {
if (!keyed) throw(ProtocolException());
strobe_respec(wrapped, &params);
decaf_TOY_strobe_respec(wrapped, &params);
}
private:

+ 38
- 0
src/include/keccak_internal.h View File

@@ -0,0 +1,38 @@
/**
* @cond internal
* @file keccak_internal.h
* @copyright
* 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.
*/
#ifndef __DECAF_KECCAK_INTERNAL_H__
#define __DECAF_KECCAK_INTERNAL_H__ 1

#include <stdint.h>

/* The internal, non-opaque definition of the decaf_sponge struct. */
typedef union {
uint64_t w[25]; uint8_t b[25*8];
} 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];

typedef struct decaf_keccak_sponge_s {
kdomain_t state;
decaf_kparams_t params;
} decaf_keccak_sponge_s, decaf_keccak_sponge_t[1];

#define INTERNAL_SPONGE_STRUCT 1

void __attribute__((noinline)) keccakf(kdomain_t state, uint8_t start_round);

static inline void dokeccak (decaf_keccak_sponge_t decaf_sponge) {
keccakf(decaf_sponge->state, decaf_sponge->params->start_round);
decaf_sponge->params->position = 0;
}

#endif /* __DECAF_KECCAK_INTERNAL_H__ */

+ 65
- 68
src/per_curve/crypto.tmpl.c View File

@@ -8,6 +8,7 @@

#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
@@ -21,20 +22,20 @@ 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(derive_private_key) (
API_NS(private_key_t) priv,
const API_NS(symmetric_key_t) proto
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_strobe_t strobe;
strobe_init(strobe, &STROBE_256, DERIVE_MAGIC, 0);
strobe_fixed_key(strobe, proto, sizeof(API_NS(symmetric_key_t)));
strobe_prng(strobe, encoded_scalar, sizeof(encoded_scalar));
strobe_destroy(strobe);
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(symmetric_key_t)));
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);
@@ -43,18 +44,17 @@ void API_NS(derive_private_key) (
decaf_bzero(encoded_scalar, sizeof(encoded_scalar));
}

void
API_NS(destroy_private_key) (
API_NS(private_key_t) priv
void API_NS_TOY(destroy_private_key) (
API_NS_TOY(private_key_t) priv
) {
decaf_bzero((void*)priv, sizeof(API_NS(private_key_t)));
decaf_bzero((void*)priv, sizeof(API_NS_TOY(private_key_t)));
}

void API_NS(private_to_public) (
API_NS(public_key_t) pub,
const API_NS(private_key_t) priv
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(public_key_t)));
memcpy(pub, priv->pub, sizeof(API_NS_TOY(public_key_t)));
}

/* Performance vs consttime tuning.
@@ -65,66 +65,64 @@ void API_NS(private_to_public) (
#define DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT DECAF_FALSE
#endif

decaf_error_t
API_NS(shared_secret) (
decaf_error_t API_NS_TOY(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,
const API_NS_TOY(private_key_t) my_privkey,
const API_NS_TOY(public_key_t) your_pubkey,
int me_first
) {
keccak_strobe_t strobe;
strobe_init(strobe, &STROBE_256, SHARED_SECRET_MAGIC, 0);
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) {
strobe_ad(strobe,my_privkey->pub,sizeof(API_NS(public_key_t)));
strobe_ad(strobe,your_pubkey,sizeof(API_NS(public_key_t)));
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 {
strobe_ad(strobe,your_pubkey,sizeof(API_NS(public_key_t)));
strobe_ad(strobe,my_privkey->pub,sizeof(API_NS(public_key_t)));
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
);
strobe_transact(strobe,NULL,ss_ser,sizeof(ss_ser),STROBE_CW_DH_KEY);
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;
strobe_prng(strobe,shared,cando);
decaf_TOY_strobe_prng(strobe,shared,cando);
shared_bytes -= cando;
shared += cando;
}

strobe_destroy(strobe);
decaf_TOY_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
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 */
strobe_transact(strobe,NULL,priv->pub,sizeof(API_NS(public_key_t)),STROBE_CW_SIG_PK);
decaf_TOY_strobe_transact(strobe,NULL,priv->pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK);
/* Derive nonce */
keccak_strobe_t strobe2;
keccak_decaf_TOY_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);
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);
@@ -132,8 +130,8 @@ API_NS(sign_strobe) (

/* Derive challenge */
strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH);
strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL);
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 */
@@ -142,7 +140,7 @@ API_NS(sign_strobe) (
/* Save results */
API_NS(scalar_encode)(overkill, nonce);
strobe_transact(strobe,&sig[SER_BYTES],overkill,SCALAR_BYTES,STROBE_CW_SIG_RESP);
decaf_TOY_strobe_transact(strobe,&sig[SER_BYTES],overkill,SCALAR_BYTES,STROBE_CW_SIG_RESP);
/* Clean up */
API_NS(scalar_destroy)(nonce);
@@ -150,11 +148,10 @@ API_NS(sign_strobe) (
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_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;
@@ -163,18 +160,18 @@ API_NS(verify_strobe) (
API_NS(scalar_t) challenge, response;
/* Stir pubkey */
strobe_transact(strobe,NULL,pub,sizeof(API_NS(public_key_t)),STROBE_CW_SIG_PK);
decaf_TOY_strobe_transact(strobe,NULL,pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK);
/* Derive nonce */
strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH);
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 */
strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL);
decaf_TOY_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);
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) );

@@ -196,30 +193,30 @@ API_NS(verify_strobe) (
}

void
API_NS(sign) (
API_NS(signature_t) sig,
const API_NS(private_key_t) priv,
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_strobe_t ctx;
strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0);
strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT);
API_NS(sign_strobe)(ctx, sig, priv);
strobe_destroy(ctx);
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(verify) (
const API_NS(signature_t) sig,
const API_NS(public_key_t) pub,
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_strobe_t ctx;
strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0);
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);
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;
}

+ 32
- 32
src/per_curve/crypto.tmpl.h View File

@@ -17,45 +17,45 @@ extern "C" {
#define $(C_NS)_SYMMETRIC_KEY_BYTES 32

/** A symmetric key, the compressed point of a private key. */
typedef unsigned char $(c_ns)_symmetric_key_t[$(C_NS)_SYMMETRIC_KEY_BYTES];
typedef unsigned char $(c_ns)_TOY_symmetric_key_t[$(C_NS)_SYMMETRIC_KEY_BYTES];

/** An encoded public key. */
typedef unsigned char $(c_ns)_public_key_t[$(C_NS)_SER_BYTES];
typedef unsigned char $(c_ns)_TOY_public_key_t[$(C_NS)_SER_BYTES];

/** A signature. */
typedef unsigned char $(c_ns)_signature_t[$(C_NS)_SER_BYTES + $(C_NS)_SCALAR_BYTES];
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)_symmetric_key_t sym;
$(c_ns)_TOY_symmetric_key_t sym;
/** The scalar x */
$(c_ns)_scalar_t secret_scalar;
/** x*Base */
$(c_ns)_public_key_t pub;
$(c_ns)_TOY_public_key_t pub;
/** @endcond */
} /** Private key structure for pointers. */
$(c_ns)_private_key_s,
$(c_ns)_TOY_private_key_s,
/** A private key (gmp array[1] style). */
$(c_ns)_private_key_t[1];
$(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)_derive_private_key (
$(c_ns)_private_key_t priv,
const $(c_ns)_symmetric_key_t proto
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)_destroy_private_key (
$(c_ns)_private_key_t priv
void $(c_ns)_TOY_destroy_private_key (
$(c_ns)_TOY_private_key_t priv
) NONNULL API_VIS;

/**
@@ -63,9 +63,9 @@ void $(c_ns)_destroy_private_key (
* @param [out] pub The extracted private key.
* @param [in] priv The private key.
*/
void $(c_ns)_private_to_public (
$(c_ns)_public_key_t pub,
const $(c_ns)_private_key_t priv
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;
/**
@@ -84,11 +84,11 @@ void $(c_ns)_private_to_public (
* @retval DECAF_FAILURE Key exchange failed.
*/
decaf_error_t
$(c_ns)_shared_secret (
$(c_ns)_TOY_shared_secret (
uint8_t *shared,
size_t shared_bytes,
const $(c_ns)_private_key_t my_privkey,
const $(c_ns)_public_key_t your_pubkey,
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;
@@ -100,10 +100,10 @@ $(c_ns)_shared_secret (
* @param [in] strobe A STROBE context with the message.
*/
void
$(c_ns)_sign_strobe (
keccak_strobe_t strobe,
$(c_ns)_signature_t sig,
const $(c_ns)_private_key_t priv
$(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;

/**
@@ -115,9 +115,9 @@ $(c_ns)_sign_strobe (
* @param [in] message_len The message's length.
*/
void
$(c_ns)_sign (
$(c_ns)_signature_t sig,
const $(c_ns)_private_key_t priv,
$(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;
@@ -133,10 +133,10 @@ $(c_ns)_sign (
* @return DECAF_FAILURE The signature did not verify successfully.
*/
decaf_error_t
$(c_ns)_verify_strobe (
keccak_strobe_t strobe,
const $(c_ns)_signature_t sig,
const $(c_ns)_public_key_t pub
$(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;

/**
@@ -151,9 +151,9 @@ $(c_ns)_verify_strobe (
* @return DECAF_FAILURE The signature did not verify successfully.
*/
decaf_error_t
$(c_ns)_verify (
const $(c_ns)_signature_t sig,
const $(c_ns)_public_key_t pub,
$(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;


+ 16
- 16
src/per_curve/crypto.tmpl.hxx View File

@@ -18,7 +18,7 @@
#endif
/** @endcond */

namespace decaf {
namespace decaf { namespace TOY {

/** A public key for crypto over some Group */
template <typename Group> class PublicKey;
@@ -31,7 +31,7 @@ template<> class PublicKey<$(cxx_ns)>
: public Serializable< PublicKey<$(cxx_ns)> > {
private:
/** @cond internal */
typedef $(c_ns)_public_key_t Wrapped;
typedef $(c_ns)_TOY_public_key_t Wrapped;
Wrapped wrapped;
template<class Group> friend class PrivateKey;
/** @endcond */
@@ -40,7 +40,7 @@ public:
typedef $(cxx_ns) Group;
/** Signature size. */
static const size_t SIG_BYTES = sizeof($(c_ns)_signature_t);
static const size_t SIG_BYTES = sizeof($(c_ns)_TOY_signature_t);
/** Serialization size. */
static const size_t SER_BYTES = sizeof(Wrapped);
@@ -69,7 +69,7 @@ public:
const Block &message,
const FixedBlock<SIG_BYTES> &sig
) const throw(CryptoException) {
if (DECAF_SUCCESS != $(c_ns)_verify(sig.data(),wrapped,message.data(),message.size())) {
if (DECAF_SUCCESS != $(c_ns)_TOY_verify(sig.data(),wrapped,message.data(),message.size())) {
throw(CryptoException());
}
}
@@ -79,7 +79,7 @@ public:
Strobe &context,
const FixedBlock<SIG_BYTES> &sig
) const throw(CryptoException) {
if (DECAF_SUCCESS != $(c_ns)_verify_strobe(context.wrapped,sig.data(),wrapped)) {
if (DECAF_SUCCESS != $(c_ns)_TOY_verify_strobe(context.wrapped,sig.data(),wrapped)) {
throw(CryptoException());
}
}
@@ -90,7 +90,7 @@ template<> class PrivateKey<$(cxx_ns)>
: public Serializable< PrivateKey<$(cxx_ns)> > {
private:
/** @cond internal */
typedef $(c_ns)_private_key_t Wrapped;
typedef $(c_ns)_TOY_private_key_t Wrapped;
Wrapped wrapped;
template<class Group> friend class PublicKey;
/** @endcond */
@@ -99,7 +99,7 @@ public:
typedef $(cxx_ns) Group;
/** Signature size. */
static const size_t SIG_BYTES = sizeof($(c_ns)_signature_t);
static const size_t SIG_BYTES = sizeof($(c_ns)_TOY_signature_t);
/** Serialization size. */
static const size_t SER_BYTES = sizeof(Wrapped);
@@ -117,18 +117,18 @@ public:
/** Read a private key from a string*/
inline explicit PrivateKey(const FixedBlock<SYM_BYTES> &b) NOEXCEPT {
$(c_ns)_derive_private_key(wrapped, b.data());
$(c_ns)_TOY_derive_private_key(wrapped, b.data());
}
/** Create at random */
inline explicit PrivateKey(Rng &r) NOEXCEPT {
FixedArrayBuffer<SYM_BYTES> tmp(r);
$(c_ns)_derive_private_key(wrapped, tmp.data());
$(c_ns)_TOY_derive_private_key(wrapped, tmp.data());
}
/** Secure destructor */
inline ~PrivateKey() NOEXCEPT {
$(c_ns)_destroy_private_key(wrapped);
$(c_ns)_TOY_destroy_private_key(wrapped);
}
/** Serialization size. */
@@ -158,7 +158,7 @@ public:
bool me_first
) const throw(CryptoException,std::bad_alloc) {
SecureBuffer ret(bytes);
if (DECAF_SUCCESS != $(c_ns)_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) {
if (DECAF_SUCCESS != $(c_ns)_TOY_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) {
throw(CryptoException());
}
return ret;
@@ -171,29 +171,29 @@ public:
const PublicKey<$(cxx_ns)> &pub,
bool me_first
) const NOEXCEPT {
return $(c_ns)_shared_secret(ret.data(),ret.size(),wrapped,pub.wrapped,me_first);
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)_sign(sig.data(), wrapped, message.data(), message.size());
$(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)_sign_strobe(context.wrapped, sig.data(), wrapped);
$(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)_private_to_public(wrapped,b.wrapped);
$(c_ns)_TOY_private_to_public(wrapped,b.wrapped);
}
/** @endcond */

#undef NOEXCEPT
} /* namespace decaf */
}} /* namespace decaf::TOY */

+ 0
- 341
src/public_include/decaf/strobe.h View File

@@ -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 <decaf/shake.h>

#ifdef __cplusplus
extern "C" {
#endif
/** Keccak STROBE structure as struct. */
typedef struct {
decaf_keccak_sponge_t sponge; /**< Internal sponge object. */
} keccak_strobe_s;
/** Keccak STROBE structure as one-element array */
typedef keccak_strobe_s keccak_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 strobe_init (
keccak_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 strobe_transact (
keccak_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 strobe_plaintext (
keccak_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
strobe_ad (
keccak_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
strobe_nonce (
keccak_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
strobe_fixed_key (
keccak_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
strobe_dh_key (
keccak_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 strobe_produce_auth can spit out. */
#define STROBE_MAX_AUTH_BYTES 32
/** Produce an authenticator. */
static INLINE UNUSED NONNULL void
strobe_produce_auth (
keccak_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 strobe_verify_auth (
keccak_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
strobe_encrypt (
keccak_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
strobe_decrypt (
keccak_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 strobe_prng (
keccak_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 strobe_respec (
keccak_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
strobe_destroy (
keccak_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
} 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
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 strobe_plaintext(keccak_strobe_t strobe, const unsigned char *in, uint16_t len, uint8_t iSent) {
strobe_transact(
strobe, NULL, in, len,
iSent ? STROBE_CW_PAYLOAD_PLAINTEXT
: strobe_cw_recv(STROBE_CW_PAYLOAD_PLAINTEXT)
);
}

void strobe_ad(keccak_strobe_t strobe, const unsigned char *in, size_t len) {
strobe_transact( strobe, NULL, in, len, STROBE_CW_AD_EXPLICIT );
}

void strobe_nonce (keccak_strobe_t strobe, const unsigned char *in, uint16_t len) {
strobe_transact( strobe, NULL, in, len, STROBE_CW_NONCE_EXPLICIT );
}

void strobe_fixed_key (keccak_strobe_t strobe, const unsigned char *in, uint16_t len) {
strobe_transact( strobe, NULL, in, len, STROBE_CW_FIXED_KEY );
}

void strobe_dh_key (keccak_strobe_t strobe, const unsigned char *in, uint16_t len) {
strobe_transact( strobe, NULL, in, len, STROBE_CW_DH_KEY );
}

void strobe_produce_auth (keccak_strobe_t strobe, unsigned char *out, uint16_t len) {
strobe_transact( strobe, out, NULL, len, STROBE_CW_MAC );
}

void strobe_encrypt (keccak_strobe_t strobe, unsigned char *out, const unsigned char *in, uint16_t len) {
strobe_transact(strobe, out, in, len, STROBE_CW_PAYLOAD_CIPHERTEXT);
}

void strobe_decrypt(keccak_strobe_t strobe, unsigned char *out, const unsigned char *in, uint16_t len) {
strobe_transact(strobe, out, in, len, strobe_cw_recv(STROBE_CW_PAYLOAD_CIPHERTEXT));
}

void strobe_prng(keccak_strobe_t strobe, unsigned char *out, uint16_t len) {
strobe_transact( strobe, out, NULL, len, STROBE_CW_PRNG );
}

void strobe_destroy (keccak_strobe_t doomed) {
decaf_sponge_destroy(doomed->sponge);
}

/** @endcond */ /* internal */

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* __DECAF_STROBE_H__ */

+ 0
- 239
src/public_include/decaf/strobe.hxx View File

@@ -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 <decaf/strobe.h>

#include <sys/types.h>


/** @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_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 &params = STROBE_256 /**< Strength parameters */
) NOEXCEPT {
strobe_init(wrapped, &params, description, whoami == CLIENT);
keyed = false;
}
/** Securely destroy by overwriting state. */
inline ~Strobe() NOEXCEPT { strobe_destroy(wrapped); }

/** Stir in fixed key, from a C++ block. */
inline void fixed_key (
const Block &data /**< The key. */
) throw(ProtocolException) {
strobe_fixed_key(wrapped, data.data(), data.size());
keyed = true;
}

/** Stir in fixed key, from a serializeable object. */
template<class T> inline void fixed_key (
const Serializable<T> &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) {
strobe_dh_key(wrapped, data.data(), data.size());
keyed = true;
}

/** Stir in DH key, from a serializeable object. */
template<class T> inline void dh_key (
const Serializable<T> &data /**< The key. */
) throw(ProtocolException) {
dh_key(data.serialize());
}

/** Stir in an explicit nonce. */
inline void nonce(const Block &data) NOEXCEPT {
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 {
strobe_plaintext(wrapped, data.data(), data.size(), true);
}

/** Stir in serializeable data we sent as plaintext. NB This doesn't actually send anything. */
template<class T> inline void send_plaintext(const Serializable<T> &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 {
strobe_plaintext(wrapped, data.data(), data.size(), false);
}

/** Stir in associated data. */
inline void ad(const Block &data) {
strobe_ad(wrapped, data.data(), data.size());
}

/** Stir in associated serializable data. */
template<class T> inline void ad(const Serializable<T> &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();
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<class T> inline SecureBuffer encrypt_no_auth(const Serializable<T> &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();
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();
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<class T> inline SecureBuffer encrypt (
const Serializable<T> &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 (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)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 &params) throw(ProtocolException) {
if (!keyed) throw(ProtocolException());
strobe_respec(wrapped, &params);
}
private:
bool keyed;
};
} /* namespace decaf */

#undef NOEXCEPT
#undef DELETE

#endif /* __DECAF_STROBE_HXX__ */

+ 2
- 418
src/shake.c View File

@@ -17,32 +17,9 @@
#include <stdint.h>
#include <string.h>

/* to open and read from /dev/urandom */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include "portable_endian.h"

/* The internal, non-opaque definition of the decaf_sponge struct. */
typedef union {
uint64_t w[25]; uint8_t b[25*8];
} 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];

typedef struct decaf_keccak_sponge_s {
kdomain_t state;
decaf_kparams_t params;
} decaf_keccak_sponge_s, decaf_keccak_sponge_t[1];

#define INTERNAL_SPONGE_STRUCT 1
#include "keccak_internal.h"
#include <decaf/shake.h>
#include <decaf/strobe.h>
#include <decaf/spongerng.h>

#define FLAG_ABSORBING 'A'
#define FLAG_SQUEEZING 'Z'
@@ -78,9 +55,7 @@ static inline uint64_t rol(uint64_t x, int s) {
#endif

/*** The Keccak-f[1600] permutation ***/
static void
__attribute__((noinline))
keccakf(kdomain_t state, uint8_t start_round) {
void keccakf(kdomain_t state, uint8_t start_round) {
uint64_t* a = state->w;
uint64_t b[5] = {0}, t, u;
uint8_t x, y, i;
@@ -109,11 +84,6 @@ keccakf(kdomain_t state, uint8_t start_round) {
for (i=0; i<25; i++) a[i] = htole64(a[i]);
}

static inline void dokeccak (decaf_keccak_sponge_t decaf_sponge) {
keccakf(decaf_sponge->state, decaf_sponge->params->start_round);
decaf_sponge->params->position = 0;
}

void decaf_sha3_update (
struct decaf_keccak_sponge_s * __restrict__ decaf_sponge,
const uint8_t *in,
@@ -261,390 +231,4 @@ DEFSHA3(256)
DEFSHA3(384)
DEFSHA3(512)

/** 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 = (uint64_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));
strobe_transact((keccak_strobe_s*)decaf_sponge,NULL,cpu_entropy,sizeof(cpu_entropy),STROBE_CW_PRNG_CPU_SEED);
}
strobe_transact((keccak_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
) {
strobe_transact((keccak_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;
strobe_init((keccak_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;
strobe_init((keccak_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;
}
strobe_transact((keccak_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 strobe_init(
keccak_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
);
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 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; j<cando; j++) state[p+j] ^= in[j];
if (out) {
assert(in != NULL);
memcpy(out, in, cando);
out += cando;
}
in += cando;
break;
case STROBE_MODE_ABSORB:
for (j=0; j<cando; j++) state[p+j] ^= in[j];
in += cando;
break;
case STROBE_MODE_ABSORB_R:
assert(in != NULL);
memcpy(state+p, in, cando);
in += cando;
break;
case STROBE_MODE_SQUEEZE:
assert(out != NULL);
memcpy(out, state+p, cando);
out += cando;
break;
case STROBE_MODE_SQUEEZE_R:
assert(out != NULL);
memcpy(out, state+p, cando);
out += cando;
memset(state+p, 0, cando);
break;
case STROBE_MODE_FORGET:
memset(state+p, 0, cando);
break;
case STROBE_MODE_DUPLEX:
for (j=0; j<cando; j++) {
state[p+j] ^= in[j];
out[j] = state[p+j];
}
in += cando;
out += cando;
break;
case STROBE_MODE_DUPLEX_R:
for (j=0; j<cando; j++) {
unsigned char c = in[j];
out[j] = c ^ state[p+j];
state[p+j] = c;
}
in += cando;
out += cando;
break;

default:
assert(0);
};
}
if (last) {
decaf_sponge->params->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 strobe_transact (
keccak_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
};
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;
}
}
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));
strobe_duplex(
decaf_sponge, NULL, NULL, len,
STROBE_MODE_FORGET
);
}
}

decaf_error_t strobe_verify_auth (
keccak_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;
strobe_transact(strobe, NULL, in, len, strobe_cw_recv(STROBE_CW_MAC));
int32_t residue = 0;
int i;
for (i=0; i<len; i++) {
residue |= decaf_sponge->state->b[i];
}
return decaf_succeed_if((residue-1)>>8);
}

void strobe_respec (
keccak_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 };
strobe_transact( strobe, NULL, in, sizeof(in), STROBE_CW_RESPEC_INFO );
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;
}

/* FUTURE: Keyak instances, etc */

+ 412
- 0
src/strobe.c View File

@@ -0,0 +1,412 @@
/**
* @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 <assert.h>
#include <stdint.h>
#include <string.h>

#include "keccak_internal.h"
#include <decaf/strobe.h>
#include <decaf/spongerng.h>

/* to open and read from /dev/urandom */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

/** 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 = (uint64_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; j<cando; j++) state[p+j] ^= in[j];
if (out) {
assert(in != NULL);
memcpy(out, in, cando);
out += cando;
}
in += cando;
break;
case STROBE_MODE_ABSORB:
for (j=0; j<cando; j++) state[p+j] ^= in[j];
in += cando;
break;
case STROBE_MODE_ABSORB_R:
assert(in != NULL);
memcpy(state+p, in, cando);
in += cando;
break;
case STROBE_MODE_SQUEEZE:
assert(out != NULL);
memcpy(out, state+p, cando);
out += cando;
break;
case STROBE_MODE_SQUEEZE_R:
assert(out != NULL);
memcpy(out, state+p, cando);
out += cando;
memset(state+p, 0, cando);
break;
case STROBE_MODE_FORGET:
memset(state+p, 0, cando);
break;
case STROBE_MODE_DUPLEX:
for (j=0; j<cando; j++) {
state[p+j] ^= in[j];
out[j] = state[p+j];
}
in += cando;
out += cando;
break;
case STROBE_MODE_DUPLEX_R:
for (j=0; j<cando; j++) {
unsigned char c = in[j];
out[j] = c ^ state[p+j];
state[p+j] = c;
}
in += cando;
out += cando;
break;

default:
assert(0);
};
}
if (last) {
decaf_sponge->params->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; i<len; i++) {
residue |= decaf_sponge->state->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;
}

+ 1
- 0
test/bench_decaf.cxx View File

@@ -26,6 +26,7 @@
#include <algorithm>

using namespace decaf;
using namespace decaf::TOY;


static __inline__ void __attribute__((unused)) ignore_result ( int result ) { (void)result; }


+ 1
- 0
test/test_decaf.cxx View File

@@ -17,6 +17,7 @@
#include <stdio.h>

using namespace decaf;
using namespace decaf::TOY;

static bool passing = true;
static const long NTESTS = 10000;


Loading…
Cancel
Save