Commit bb1eef37 authored by Michael Hamburg's avatar Michael Hamburg

tear out STROBE. Probably will re-introduce later

parent 4caefd35
April 22, 2017:
Remove STROBE in preparation for 1.0 release. STROBE has its own
repo now at https://strobe.sourceforge.io. I might re-integrate
it into Decaf once I have produced a version that matches the
STROBE v1 spec, but it's just confusing to keep v0.2 in here.
Change x{25519,448}_generate_key to _derive_public_key.
January 15, 2016:
Lots of changes since the last entry in HISTORY.TXT.
......
# Copyright (c) 2014 Cryptography Research, Inc.
# Copyright (c) 2014-2017 Cryptography Research, Inc.
# Released under the MIT License. See LICENSE.txt for license information.
......@@ -77,9 +77,9 @@ GEN_CODE= $(GEN_CODE_1:%.tmpl.hxx=%.hxx)
HEADERS= Makefile $(shell find src test -name "*.h") $(BUILD_OBJ)/timestamp $(GEN_CODE)
# components needed by the lib
LIBCOMPONENTS = $(BUILD_OBJ)/utils.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/strobe.o $(BUILD_OBJ)/sha512.o # and per-field components
LIBCOMPONENTS = $(BUILD_OBJ)/utils.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/sha512.o $(BUILD_OBJ)/spongerng.o # and per-field components
BENCHCOMPONENTS = $(BUILD_OBJ)/bench.o $(BUILD_OBJ)/shake.o $(BUILD_OBJ)/strobe.o
BENCHCOMPONENTS = $(BUILD_OBJ)/bench.o $(BUILD_OBJ)/shake.o
all: lib $(BUILD_IBIN)/test $(BUILD_IBIN)/bench $(BUILD_BIN)/shakesum
......@@ -174,10 +174,9 @@ endef
define define_curve
LIBCOMPONENTS += $$(BUILD_OBJ)/$(1)/decaf.o $$(BUILD_OBJ)/$(1)/elligator.o $$(BUILD_OBJ)/$(1)/scalar.o \
$$(BUILD_OBJ)/$(1)/crypto.o $$(BUILD_OBJ)/$(1)/eddsa.o $$(BUILD_OBJ)/$(1)/decaf_tables.o
$$(BUILD_OBJ)/$(1)/eddsa.o $$(BUILD_OBJ)/$(1)/decaf_tables.o
PER_OBJ_DIRS += $$(BUILD_OBJ)/$(1)
GLOBAL_HEADERS_OF_$(1) = $(BUILD_INC)/decaf/point_$(3).h $(BUILD_INC)/decaf/point_$(3).hxx \
$(BUILD_C)/decaf/crypto_$(3).h $(BUILD_C)/decaf/crypto_$(3).hxx \
$(BUILD_INC)/decaf/ed$(3).h $(BUILD_INC)/decaf/ed$(3).hxx
HEADERS_OF_$(1) = $$(HEADERS_OF_$(2)) $$(GLOBAL_HEADERS_OF_$(1))
HEADERS += $$(GLOBAL_HEADERS_OF_$(1))
......@@ -200,9 +199,6 @@ $$(BUILD_INC)/decaf/elligator_$(3).%: src/per_curve/elligator.tmpl.% src/generat
$$(BUILD_INC)/decaf/scalar_$(3).%: src/per_curve/scalar.tmpl.% src/generator/* Makefile
python -B src/generator/template.py --per=curve --item=$(1) --guard=$$(@:$(BUILD_INC)/%=%) -o $$@ $$<
$$(BUILD_C)/decaf/crypto_$(3).%: src/per_curve/crypto.tmpl.% src/generator/* Makefile
python -B src/generator/template.py --per=curve --item=$(1) --guard=$$(@:$(BUILD_INC)/%=%) -o $$@ $$<
$$(BUILD_IBIN)/decaf_gen_tables_$(1): $$(BUILD_OBJ)/$(1)/decaf_gen_tables.o \
$$(BUILD_OBJ)/$(1)/decaf.o $$(BUILD_OBJ)/$(1)/scalar.o $$(BUILD_OBJ)/utils.o \
$$(COMPONENTS_OF_$(2))
......
......@@ -60,19 +60,6 @@ The Decaf library doesn't implement much symmetric crypto, but it does
contain the hash functions required by the CFRG cryptosystems: SHA512,
SHA-3 and SHAKE.
The library also includes some work on an experimental protocol framework
called STROBE (based on Markku-Juhani Saarinen's BLINKER). This
framework is incomplete and will change in the future! There's also a
significant chance that it's insecure in its current form. Therefore,
all the STROBE interfaces have been marked as TOY for this version.
Please don't use them for anything serious.
The Decaf library contains a random number generator, SpongeRNG, which
uses STROBE internally. This is used in the test suite to generate
random tests. It's probably secure, but since STROBE is not final,
its internals will almost certainly change. I recommend using your own
RNG instead for now. For example, consider libottery.
## Internals
The "decaf" technique is described in https://eprint.iacr.org/2015/673
......
/**
* @file curve25519/crypto.c
* @author Mike Hamburg
*
* @copyright
* Copyright (c) 2015-2016 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information.
*
* @cond internal
* @brief Example Decaf crypto routines
*
* @warning This file was automatically generated in Python.
* Please do not edit it.
*/
#include <decaf/crypto.h>
#include <string.h>
#define API_NAME "decaf_255"
#define API_NS(_id) decaf_255_##_id
#define API_NS_TOY(_id) decaf_255_TOY_##_id
#define SCALAR_BITS DECAF_255_SCALAR_BITS
#define SCALAR_BYTES ((SCALAR_BITS + 7)/8)
#define SER_BYTES DECAF_255_SER_BYTES
/* TODO: canonicalize and freeze the STROBE constants in this file
* (and STROBE itself for that matter)
*/
static const char *DERIVE_MAGIC = API_NAME"::derive_private_key";
static const char *SIGN_MAGIC = API_NAME"::sign";
static const char *SHARED_SECRET_MAGIC = API_NAME"::shared_secret";
static const uint16_t SHARED_SECRET_MAX_BLOCK_SIZE = 1<<12;
static const unsigned int SCALAR_OVERKILL_BYTES = SCALAR_BYTES + 8;
void API_NS_TOY(derive_private_key) (
API_NS_TOY(private_key_t) priv,
const API_NS_TOY(symmetric_key_t) proto
) {
uint8_t encoded_scalar[SCALAR_OVERKILL_BYTES];
API_NS(point_t) pub;
keccak_decaf_TOY_strobe_t strobe;
decaf_TOY_strobe_init(strobe, &STROBE_256, DERIVE_MAGIC, 0);
decaf_TOY_strobe_fixed_key(strobe, proto, sizeof(API_NS_TOY(symmetric_key_t)));
decaf_TOY_strobe_prng(strobe, encoded_scalar, sizeof(encoded_scalar));
decaf_TOY_strobe_destroy(strobe);
memcpy(priv->sym, proto, sizeof(API_NS_TOY(symmetric_key_t)));
API_NS(scalar_decode_long)(priv->secret_scalar, encoded_scalar, sizeof(encoded_scalar));
API_NS(precomputed_scalarmul)(pub, API_NS(precomputed_base), priv->secret_scalar);
API_NS(point_encode)(priv->pub, pub);
decaf_bzero(encoded_scalar, sizeof(encoded_scalar));
}
void API_NS_TOY(destroy_private_key) (
API_NS_TOY(private_key_t) priv
) {
decaf_bzero((void*)priv, sizeof(API_NS_TOY(private_key_t)));
}
void API_NS_TOY(private_to_public) (
API_NS_TOY(public_key_t) pub,
const API_NS_TOY(private_key_t) priv
) {
memcpy(pub, priv->pub, sizeof(API_NS_TOY(public_key_t)));
}
/* Performance vs consttime tuning.
* Specifying true here might give better DOS resistance in certain corner
* cases. Specifying false gives a tighter result in test_ct.
*/
#ifndef DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT
#define DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT DECAF_FALSE
#endif
decaf_error_t API_NS_TOY(shared_secret) (
uint8_t *shared,
size_t shared_bytes,
const API_NS_TOY(private_key_t) my_privkey,
const API_NS_TOY(public_key_t) your_pubkey,
int me_first
) {
keccak_decaf_TOY_strobe_t strobe;
decaf_TOY_strobe_init(strobe, &STROBE_256, SHARED_SECRET_MAGIC, 0);
uint8_t ss_ser[SER_BYTES];
if (me_first) {
decaf_TOY_strobe_ad(strobe,my_privkey->pub,sizeof(API_NS_TOY(public_key_t)));
decaf_TOY_strobe_ad(strobe,your_pubkey,sizeof(API_NS_TOY(public_key_t)));
} else {
decaf_TOY_strobe_ad(strobe,your_pubkey,sizeof(API_NS_TOY(public_key_t)));
decaf_TOY_strobe_ad(strobe,my_privkey->pub,sizeof(API_NS_TOY(public_key_t)));
}
decaf_error_t ret = API_NS(direct_scalarmul)(
ss_ser, your_pubkey, my_privkey->secret_scalar, DECAF_FALSE,
DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT
);
decaf_TOY_strobe_transact(strobe,NULL,ss_ser,sizeof(ss_ser),STROBE_CW_DH_KEY);
while (shared_bytes) {
uint16_t cando = (shared_bytes > SHARED_SECRET_MAX_BLOCK_SIZE)
? SHARED_SECRET_MAX_BLOCK_SIZE : shared_bytes;
decaf_TOY_strobe_prng(strobe,shared,cando);
shared_bytes -= cando;
shared += cando;
}
decaf_TOY_strobe_destroy(strobe);
decaf_bzero(ss_ser, sizeof(ss_ser));
return ret;
}
void API_NS_TOY(sign_strobe) (
keccak_decaf_TOY_strobe_t strobe,
API_NS_TOY(signature_t) sig,
const API_NS_TOY(private_key_t) priv
) {
uint8_t overkill[SCALAR_OVERKILL_BYTES];
API_NS(point_t) point;
API_NS(scalar_t) nonce, challenge;
/* Stir pubkey */
decaf_TOY_strobe_transact(strobe,NULL,priv->pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK);
/* Derive nonce */
keccak_decaf_TOY_strobe_t strobe2;
memcpy(strobe2,strobe,sizeof(strobe2));
decaf_TOY_strobe_fixed_key(strobe2,priv->sym,sizeof(API_NS_TOY(symmetric_key_t)));
decaf_TOY_strobe_prng(strobe2,overkill,sizeof(overkill));
decaf_TOY_strobe_destroy(strobe2);
API_NS(scalar_decode_long)(nonce, overkill, sizeof(overkill));
API_NS(precomputed_scalarmul)(point, API_NS(precomputed_base), nonce);
API_NS(point_encode)(sig, point);
/* Derive challenge */
decaf_TOY_strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH);
decaf_TOY_strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL);
API_NS(scalar_decode_long)(challenge, overkill, sizeof(overkill));
/* Respond */
API_NS(scalar_mul)(challenge, challenge, priv->secret_scalar);
API_NS(scalar_sub)(nonce, nonce, challenge);
/* Save results */
API_NS(scalar_encode)(overkill, nonce);
decaf_TOY_strobe_transact(strobe,&sig[SER_BYTES],overkill,SCALAR_BYTES,STROBE_CW_SIG_RESP);
/* Clean up */
API_NS(scalar_destroy)(nonce);
API_NS(scalar_destroy)(challenge);
decaf_bzero(overkill,sizeof(overkill));
}
decaf_error_t API_NS_TOY(verify_strobe) (
keccak_decaf_TOY_strobe_t strobe,
const API_NS_TOY(signature_t) sig,
const API_NS_TOY(public_key_t) pub
) {
decaf_bool_t ret;
uint8_t overkill[SCALAR_OVERKILL_BYTES];
API_NS(point_t) point, pubpoint;
API_NS(scalar_t) challenge, response;
/* Stir pubkey */
decaf_TOY_strobe_transact(strobe,NULL,pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK);
/* Derive nonce */
decaf_TOY_strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH);
ret = decaf_successful( API_NS(point_decode)(point, sig, DECAF_TRUE) );
/* Derive challenge */
decaf_TOY_strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL);
API_NS(scalar_decode_long)(challenge, overkill, sizeof(overkill));
/* Decode response */
decaf_TOY_strobe_transact(strobe,overkill,&sig[SER_BYTES],SCALAR_BYTES,STROBE_CW_SIG_RESP);
ret &= decaf_successful( API_NS(scalar_decode)(response, overkill) );
ret &= decaf_successful( API_NS(point_decode)(pubpoint, pub, DECAF_FALSE) );
API_NS(base_double_scalarmul_non_secret) (
pubpoint, response, pubpoint, challenge
);
ret &= API_NS(point_eq)(pubpoint, point);
/* Nothing here is secret, so don't do these things:
decaf_bzero(overkill,sizeof(overkill));
API_NS(point_destroy)(point);
API_NS(point_destroy)(pubpoint);
API_NS(scalar_destroy)(challenge);
API_NS(scalar_destroy)(response);
*/
return decaf_succeed_if(ret);
}
void
API_NS_TOY(sign) (
API_NS_TOY(signature_t) sig,
const API_NS_TOY(private_key_t) priv,
const unsigned char *message,
size_t message_len
) {
keccak_decaf_TOY_strobe_t ctx;
decaf_TOY_strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0);
decaf_TOY_strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT);
API_NS_TOY(sign_strobe)(ctx, sig, priv);
decaf_TOY_strobe_destroy(ctx);
}
decaf_error_t
API_NS_TOY(verify) (
const API_NS_TOY(signature_t) sig,
const API_NS_TOY(public_key_t) pub,
const unsigned char *message,
size_t message_len
) {
keccak_decaf_TOY_strobe_t ctx;
decaf_TOY_strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0);
decaf_TOY_strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT);
decaf_error_t ret = API_NS_TOY(verify_strobe)(ctx, sig, pub);
decaf_TOY_strobe_destroy(ctx);
return ret;
}
/**
* @file decaf/crypto.h
* @author Mike Hamburg
*
* @copyright
* Copyright (c) 2015-2016 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information.
*
* Example Decaf crypto routines, metaheader.
* @warning These are merely examples, though they ought to be secure. But real
* protocols will decide differently on magic numbers, formats, which items to
* hash, etc.
*
* @warning This file was automatically generated in Python.
* Please do not edit it.
*/
#ifndef __DECAF_CRYPTO_H__
#define __DECAF_CRYPTO_H__ 1
#include <decaf/crypto_255.h>
#include <decaf/crypto_448.h>
#endif /* __DECAF_CRYPTO_H__ */
/**
* @file src/GENERATED/c/decaf/crypto_255.h
* @author Mike Hamburg
*
* @copyright
* Copyright (c) 2015-2016 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information.
*
* Example Decaf crypto routines.
* @warning These are merely examples, though they ought to be secure. But real
* protocols will decide differently on magic numbers, formats, which items to
* hash, etc.
* @warning Experimental! The names, parameter orders etc are likely to change.
*
* @warning This file was automatically generated in Python.
* Please do not edit it.
*/
#ifndef __SRC_GENERATED_C_DECAF_CRYPTO_255_H__
#define __SRC_GENERATED_C_DECAF_CRYPTO_255_H__ 1
#include <decaf/point_255.h>
#include <decaf/strobe.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Number of bytes for a symmetric key (expanded to full key) */
#define DECAF_255_SYMMETRIC_KEY_BYTES 32
/** A symmetric key, the compressed point of a private key. */
typedef unsigned char decaf_255_TOY_symmetric_key_t[DECAF_255_SYMMETRIC_KEY_BYTES];
/** An encoded public key. */
typedef unsigned char decaf_255_TOY_public_key_t[DECAF_255_SER_BYTES];
/** A signature. */
typedef unsigned char decaf_255_TOY_signature_t[DECAF_255_SER_BYTES + DECAF_255_SCALAR_BYTES];
typedef struct {
/** @cond internal */
/** The symmetric key from which everything is expanded */
decaf_255_TOY_symmetric_key_t sym;
/** The scalar x */
decaf_255_scalar_t secret_scalar;
/** x*Base */
decaf_255_TOY_public_key_t pub;
/** @endcond */
} /** Private key structure for pointers. */
decaf_255_TOY_private_key_s,
/** A private key (gmp array[1] style). */
decaf_255_TOY_private_key_t[1];
/**
* Derive a key from its compressed form.
* @param [out] priv The derived private key.
* @param [in] proto The compressed or proto-key, which must be 32 random bytes.
*/
void decaf_255_TOY_derive_private_key (
decaf_255_TOY_private_key_t priv,
const decaf_255_TOY_symmetric_key_t proto
) NONNULL API_VIS;
/**
* Destroy a private key.
*/
void decaf_255_TOY_destroy_private_key (
decaf_255_TOY_private_key_t priv
) NONNULL API_VIS;
/**
* Convert a private key to a public one.
* @param [out] pub The extracted private key.
* @param [in] priv The private key.
*/
void decaf_255_TOY_private_to_public (
decaf_255_TOY_public_key_t pub,
const decaf_255_TOY_private_key_t priv
) NONNULL API_VIS;
/**
* Compute a Diffie-Hellman shared secret.
*
* This is an example routine; real protocols would use something
* protocol-specific.
*
* @param [out] shared A buffer to store the shared secret.
* @param [in] shared_bytes The size of the buffer.
* @param [in] my_privkey My private key.
* @param [in] your_pubkey Your public key.
* @param [in] me_first Direction flag to break symmetry.
*
* @retval DECAF_SUCCESS Key exchange was successful.
* @retval DECAF_FAILURE Key exchange failed.
*/
decaf_error_t
decaf_255_TOY_shared_secret (
uint8_t *shared,
size_t shared_bytes,
const decaf_255_TOY_private_key_t my_privkey,
const decaf_255_TOY_public_key_t your_pubkey,
int me_first
) NONNULL WARN_UNUSED API_VIS;
/**
* Sign a message from a STROBE context.
*
* @param [out] sig The signature.
* @param [in] priv Your private key.
* @param [in] strobe A STROBE context with the message.
*/
void
decaf_255_TOY_sign_strobe (
keccak_decaf_TOY_strobe_t strobe,
decaf_255_TOY_signature_t sig,
const decaf_255_TOY_private_key_t priv
) NONNULL API_VIS;
/**
* Sign a message.
*
* @param [out] sig The signature.
* @param [in] priv Your private key.
* @param [in] message The message.
* @param [in] message_len The message's length.
*/
void
decaf_255_TOY_sign (
decaf_255_TOY_signature_t sig,
const decaf_255_TOY_private_key_t priv,
const unsigned char *message,
size_t message_len
) NONNULL API_VIS;
/**
* Verify a signed message from its STROBE context.
*
* @param [in] sig The signature.
* @param [in] pub The public key.
* @param [in] strobe A STROBE context with the message.
*
* @return DECAF_SUCCESS The signature verified successfully.
* @return DECAF_FAILURE The signature did not verify successfully.
*/
decaf_error_t
decaf_255_TOY_verify_strobe (
keccak_decaf_TOY_strobe_t strobe,
const decaf_255_TOY_signature_t sig,
const decaf_255_TOY_public_key_t pub
) NONNULL API_VIS WARN_UNUSED;
/**
* Verify a signed message.
*
* @param [in] sig The signature.
* @param [in] pub The public key.
* @param [in] message The message.
* @param [in] message_len The message's length.
*
* @return DECAF_SUCCESS The signature verified successfully.
* @return DECAF_FAILURE The signature did not verify successfully.
*/
decaf_error_t
decaf_255_TOY_verify (
const decaf_255_TOY_signature_t sig,
const decaf_255_TOY_public_key_t pub,
const unsigned char *message,
size_t message_len
) NONNULL API_VIS WARN_UNUSED;
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __SRC_GENERATED_C_DECAF_CRYPTO_255_H__ */
/**
* @file src/GENERATED/c/decaf/crypto_255.hxx
* @author Mike Hamburg
*
* @copyright
* Copyright (c) 2015-2016 Cryptography Research, Inc. \n
* Released under the MIT License. See LICENSE.txt for license information.
*
*
*
* @warning This file was automatically generated in Python.
* Please do not edit it.
*/
#ifndef __SRC_GENERATED_C_DECAF_CRYPTO_255_HXX__
#define __SRC_GENERATED_C_DECAF_CRYPTO_255_HXX__ 1
/*
* Example Decaf cyrpto routines, C++ wrapper.
* @warning These are merely examples, though they ought to be secure. But real
* protocols will decide differently on magic numbers, formats, which items to
* hash, etc.
* @warning Experimental! The names, parameter orders etc are likely to change.
*/
#include <decaf/point_255.hxx>
#include <decaf/shake.hxx>
#include <decaf/strobe.hxx>
/** @cond internal */
#if __cplusplus >= 201103L
#define NOEXCEPT noexcept
#else
#define NOEXCEPT throw()
#endif
/** @endcond */
namespace decaf { namespace TOY {
/** A public key for crypto over some Group */
template <typename Group> class PublicKey;
/** A private key for crypto over some Group */
template <typename Group> class PrivateKey;
/** A public key for crypto over Iso-Ed25519 */
template<> class PublicKey<IsoEd25519>
: public Serializable< PublicKey<IsoEd25519> > {
private:
/** @cond internal */
typedef decaf_255_TOY_public_key_t Wrapped;
Wrapped wrapped;
template<class Group> friend class PrivateKey;
/** @endcond */
public:
/** Underlying group */
typedef IsoEd25519 Group;
/** Signature size. */
static const size_t SIG_BYTES = sizeof(decaf_255_TOY_signature_t);
/** Serialization size. */
static const size_t SER_BYTES = sizeof(Wrapped);
/** Read a private key from a string*/
inline explicit PublicKey(const FixedBlock<SER_BYTES> &b) NOEXCEPT {
memcpy(wrapped,b.data(),sizeof(wrapped));
}
/** Read a private key from a string*/
inline explicit PublicKey(const PrivateKey<IsoEd25519> &b) NOEXCEPT;
/** Create but don't initialize */
inline explicit PublicKey(const NOINIT&) NOEXCEPT { }
/** Serialize into a buffer. */
inline void serialize_into(unsigned char *x) const NOEXCEPT {
memcpy(x,wrapped,sizeof(wrapped));
}
/** Serialization size. */
inline size_t ser_size() const NOEXCEPT { return SER_BYTES; }
/** Verify a message */
inline void verify(
const Block &message,
const FixedBlock<SIG_BYTES> &sig
) const throw(CryptoException) {
if (DECAF_SUCCESS != decaf_255_TOY_verify(sig.data(),wrapped,message.data(),message.size())) {
throw(CryptoException());
}
}
/** Verify a message */
inline void verify(
Strobe &context,
const FixedBlock<SIG_BYTES> &sig
) const throw(CryptoException) {
if (DECAF_SUCCESS != decaf_255_TOY_verify_strobe(context.wrapped,sig.data(),wrapped)) {
throw(CryptoException());
}
}
};
/** A private key for crypto over Iso-Ed25519 */
template<> class PrivateKey<IsoEd25519>
: public Serializable< PrivateKey<IsoEd25519> > {
private:
/** @cond internal */
typedef decaf_255_TOY_private_key_t Wrapped;
Wrapped wrapped;
template<class Group> friend class PublicKey;
/** @endcond */
public:
/** Underlying group */
typedef IsoEd25519 Group;
/** Signature size. */
static const size_t SIG_BYTES = sizeof(decaf_255_TOY_signature_t);
/** Serialization size. */
static const size_t SER_BYTES = sizeof(Wrapped);
/** Compressed size. */
static const size_t SYM_BYTES = DECAF_255_SYMMETRIC_KEY_BYTES;
/** Create but don't initialize */
inline explicit PrivateKey(const NOINIT&) NOEXCEPT { }
/** Read a private key from a string*/
inline explicit PrivateKey(const FixedBlock<SER_BYTES> &b) NOEXCEPT {
memcpy(wrapped,b.data(),sizeof(wrapped));
}
/** Read a private key from a string*/
inline explicit PrivateKey(const FixedBlock<SYM_BYTES> &b) NOEXCEPT {
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_TOY_derive_private_key(wrapped, tmp.data());
}
/** Secure destructor */
inline ~PrivateKey() NOEXCEPT {
decaf_255_TOY_destroy_private_key(wrapped);
}
/** Serialization size. */
inline size_t ser_size() const NOEXCEPT { return SER_BYTES; }
/** Serialize into a buffer. */
inline void serialize_into(unsigned char *x) const NOEXCEPT {
memcpy(x,wrapped,sizeof(wrapped));
}
/** Compressed serialize. */
inline SecureBuffer compress() const throw(std::bad_alloc) {
SecureBuffer ret(sizeof(wrapped->sym));
memcpy(ret.data(),wrapped->sym,sizeof(wrapped->sym));
return ret;
}
/** Get the public key */
inline PublicKey<IsoEd25519> pub() const NOEXCEPT {
PublicKey<IsoEd25519> ret(*this); return ret;
}
/** Derive a shared secret */
inline SecureBuffer shared_secret(
const PublicKey<IsoEd25519> &pub,
size_t bytes,
bool me_first
) const throw(CryptoException,std::bad_alloc) {
SecureBuffer ret(bytes);
if (DECAF_SUCCESS != decaf_255_TOY_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) {
throw(CryptoException());
}
return ret;
}
/** Derive a shared secret */
inline decaf_error_t __attribute__((warn_unused_result))
shared_secret_noexcept(
Buffer ret,
const PublicKey<IsoEd25519> &pub,
bool me_first
) const NOEXCEPT {
return decaf_255_TOY_shared_secret(ret.data(),ret.size(),wrapped,pub.wrapped,me_first);
}
/** Sign a message. */
inline SecureBuffer sign(const Block &message) const {
SecureBuffer sig(SIG_BYTES);
decaf_255_TOY_sign(sig.data(), wrapped, message.data(), message.size());
return sig;
}
/** Sign a message. */
inline SecureBuffer verify(Strobe &context) const {
SecureBuffer sig(SIG_BYTES);
decaf_255_TOY_sign_strobe(context.wrapped, sig.data(), wrapped);
return sig;
}
};
/** @cond internal */
PublicKey<IsoEd25519>::PublicKey(const PrivateKey<IsoEd25519> &b) NOEXCEPT {
decaf_255_TOY_private_to_public(wrapped,b.wrapped);
}
/** @endcond */
#undef NOEXCEPT
}} /* namespace decaf::TOY */
#endif /* __SRC_GENERATED_C_DECAF_CRYPTO_255_HXX__ */
/**
* @file src/GENERATED/c/decaf/crypto_448.h
* @author Mike Hamburg
*