@@ -71,7 +71,7 @@ endif | |||
ARCHFLAGS += $(XARCHFLAGS) | |||
CFLAGS = $(LANGFLAGS) $(WARNFLAGS) $(INCFLAGS) $(OFLAGS) $(ARCHFLAGS) $(GENFLAGS) $(XCFLAGS) | |||
CXXFLAGS = $(LANGXXFLAGS) $(WARNFLAGS) $(INCFLAGS) $(OFLAGS) $(ARCHFLAGS) $(GENFLAGS) $(XCXXFLAGS) | |||
LDFLAGS = $(ARCHFLAGS) $(XLDFLAGS) | |||
LDFLAGS = $(XLDFLAGS) | |||
ASFLAGS = $(ARCHFLAGS) $(XASFLAGS) | |||
SAGE ?= sage | |||
@@ -476,35 +476,17 @@ public: | |||
* Therefore we have to call malloc() or friends, but that's probably for the best, because you don't want to | |||
* stack-allocate a 15kiB object anyway. | |||
*/ | |||
class Precomputed { | |||
private: | |||
/** @cond internal */ | |||
typedef decaf_255_precomputed_s Precomputed_U; | |||
/** @endcond */ | |||
class Precomputed | |||
/** @cond internal */ | |||
union { | |||
decaf_255_precomputed_s *mine; | |||
const decaf_255_precomputed_s *yours; | |||
} ours; | |||
bool isMine; | |||
inline void clear() NOEXCEPT { | |||
if (isMine) { | |||
decaf_255_precomputed_destroy(ours.mine); | |||
free(ours.mine); | |||
ours.yours = decaf_255_precomputed_base; | |||
isMine = false; | |||
} | |||
} | |||
inline void alloc() throw(std::bad_alloc) { | |||
if (isMine) return; | |||
int ret = posix_memalign((void**)&ours.mine, alignof_decaf_255_precomputed_s,sizeof_decaf_255_precomputed_s); | |||
if (ret || !ours.mine) { | |||
isMine = false; | |||
throw std::bad_alloc(); | |||
} | |||
isMine = true; | |||
} | |||
inline const decaf_255_precomputed_s *get() const NOEXCEPT { return isMine ? ours.mine : ours.yours; } | |||
: protected OwnedOrUnowned<Precomputed,Precomputed_U> | |||
/** @endcond */ | |||
{ | |||
public: | |||
/** Destructor securely zeorizes the memory. */ | |||
inline ~Precomputed() NOEXCEPT { clear(); } | |||
@@ -519,28 +501,29 @@ public: | |||
* @warning The empty initializer makes this equal to base, unlike the empty | |||
* initializer for points which makes this equal to the identity. | |||
*/ | |||
inline Precomputed( | |||
const decaf_255_precomputed_s &yours = *decaf_255_precomputed_base | |||
) NOEXCEPT { | |||
ours.yours = &yours; | |||
isMine = false; | |||
inline Precomputed ( | |||
const Precomputed_U &yours = *defaultValue() | |||
) NOEXCEPT : OwnedOrUnowned<Precomputed,Precomputed_U>(yours) {} | |||
#if __cplusplus >= 201103L | |||
/** @brief Move-assign operator */ | |||
inline Precomputed &operator=(Precomputed &&it) NOEXCEPT { | |||
OwnedOrUnowned<Precomputed,Precomputed_U>::operator= (it); | |||
return *this; | |||
} | |||
/** | |||
* @brief Assign. This may require an allocation and memcpy. | |||
*/ | |||
inline Precomputed &operator=(const Precomputed &it) throw(std::bad_alloc) { | |||
if (this == &it) return *this; | |||
if (it.isMine) { | |||
alloc(); | |||
memcpy(ours.mine,it.ours.mine,sizeof_decaf_255_precomputed_s); | |||
} else { | |||
clear(); | |||
ours.yours = it.ours.yours; | |||
} | |||
isMine = it.isMine; | |||
/** @brief Move constructor */ | |||
inline Precomputed(Precomputed &&it) NOEXCEPT : OwnedOrUnowned<Precomputed,Precomputed_U>() { | |||
*this = it; | |||
} | |||
/** @brief Undelete copy operator */ | |||
inline Precomputed &operator=(const Precomputed &it) NOEXCEPT { | |||
OwnedOrUnowned<Precomputed,Precomputed_U>::operator= (it); | |||
return *this; | |||
} | |||
#endif | |||
/** | |||
* @brief Initilaize from point. Must allocate memory, and may throw. | |||
@@ -554,25 +537,14 @@ public: | |||
/** | |||
* @brief Copy constructor. | |||
*/ | |||
inline Precomputed(const Precomputed &it) throw(std::bad_alloc) : isMine(false) { *this = it; } | |||
inline Precomputed(const Precomputed &it) throw(std::bad_alloc) | |||
: OwnedOrUnowned<Precomputed,Precomputed_U>() { *this = it; } | |||
/** | |||
* @brief Constructor which initializes from point. | |||
*/ | |||
inline explicit Precomputed(const Point &it) throw(std::bad_alloc) : isMine(false) { *this = it; } | |||
#if __cplusplus >= 201103L | |||
inline Precomputed &operator=(Precomputed &&it) NOEXCEPT { | |||
if (this == &it) return *this; | |||
clear(); | |||
ours = it.ours; | |||
isMine = it.isMine; | |||
it.isMine = false; | |||
it.ours.yours = decaf_255_precomputed_base; | |||
return *this; | |||
} | |||
inline Precomputed(Precomputed &&it) NOEXCEPT : isMine(false) { *this = it; } | |||
#endif | |||
inline explicit Precomputed(const Point &it) throw(std::bad_alloc) | |||
: OwnedOrUnowned<Precomputed,Precomputed_U>() { *this = it; } | |||
/** @brief Fixed base scalarmul. */ | |||
inline Point operator* (const Scalar &s) const NOEXCEPT { Point r; decaf_255_precomputed_scalarmul(r.p,get(),s.s); return r; } | |||
@@ -581,7 +553,15 @@ public: | |||
inline Point operator/ (const Scalar &s) const NOEXCEPT { return (*this) * s.inverse(); } | |||
/** @brief Return the table for the base point. */ | |||
static inline const Precomputed base() NOEXCEPT { return Precomputed(*decaf_255_precomputed_base); } | |||
static inline const Precomputed base() NOEXCEPT { return Precomputed(); } | |||
public: | |||
/** @cond internal */ | |||
friend class OwnedOrUnowned<Precomputed,Precomputed_U>; | |||
static inline size_t size() NOEXCEPT { return sizeof_decaf_255_precomputed_s; } | |||
static inline size_t alignment() NOEXCEPT { return alignof_decaf_255_precomputed_s; } | |||
static inline const Precomputed_U * defaultValue() NOEXCEPT { return decaf_255_precomputed_base; } | |||
/** @endcond */ | |||
}; | |||
}; /* struct Decaf255 */ | |||
@@ -619,37 +619,17 @@ public: | |||
* Minor difficulties arise here because the decaf API doesn't expose, as a constant, how big such an object is. | |||
* Therefore we have to call malloc() or friends, but that's probably for the best, because you don't want to | |||
* stack-allocate a 15kiB object anyway. | |||
*/ | |||
class Precomputed { | |||
private: | |||
*//** @cond internal */ | |||
typedef decaf_448_precomputed_s Precomputed_U; | |||
/** @endcond */ | |||
class Precomputed | |||
/** @cond internal */ | |||
union { | |||
decaf_448_precomputed_s *mine; | |||
const decaf_448_precomputed_s *yours; | |||
} ours; | |||
bool isMine; | |||
inline void clear() NOEXCEPT { | |||
if (isMine) { | |||
decaf_448_precomputed_destroy(ours.mine); | |||
free(ours.mine); | |||
ours.yours = decaf_448_precomputed_base; | |||
isMine = false; | |||
} | |||
} | |||
inline void alloc() throw(std::bad_alloc) { | |||
if (isMine) return; | |||
int ret = posix_memalign((void**)&ours.mine, alignof_decaf_448_precomputed_s,sizeof_decaf_448_precomputed_s); | |||
if (ret || !ours.mine) { | |||
isMine = false; | |||
throw std::bad_alloc(); | |||
} | |||
isMine = true; | |||
} | |||
inline const decaf_448_precomputed_s *get() const NOEXCEPT { return isMine ? ours.mine : ours.yours; } | |||
: protected OwnedOrUnowned<Precomputed,Precomputed_U> | |||
/** @endcond */ | |||
{ | |||
public: | |||
/** Destructor securely erases the memory. */ | |||
/** Destructor securely zeorizes the memory. */ | |||
inline ~Precomputed() NOEXCEPT { clear(); } | |||
/** | |||
@@ -663,28 +643,29 @@ public: | |||
* @warning The empty initializer makes this equal to base, unlike the empty | |||
* initializer for points which makes this equal to the identity. | |||
*/ | |||
inline Precomputed( | |||
const decaf_448_precomputed_s &yours = *decaf_448_precomputed_base | |||
) NOEXCEPT { | |||
ours.yours = &yours; | |||
isMine = false; | |||
inline Precomputed ( | |||
const Precomputed_U &yours = *defaultValue() | |||
) NOEXCEPT : OwnedOrUnowned<Precomputed,Precomputed_U>(yours) {} | |||
#if __cplusplus >= 201103L | |||
/** @brief Move-assign operator */ | |||
inline Precomputed &operator=(Precomputed &&it) NOEXCEPT { | |||
OwnedOrUnowned<Precomputed,Precomputed_U>::operator= (it); | |||
return *this; | |||
} | |||
/** | |||
* @brief Assign. This may require an allocation and memcpy. | |||
*/ | |||
inline Precomputed &operator=(const Precomputed &it) throw(std::bad_alloc) { | |||
if (this == &it) return *this; | |||
if (it.isMine) { | |||
alloc(); | |||
memcpy(ours.mine,it.ours.mine,sizeof_decaf_448_precomputed_s); | |||
} else { | |||
clear(); | |||
ours.yours = it.ours.yours; | |||
} | |||
isMine = it.isMine; | |||
/** @brief Move constructor */ | |||
inline Precomputed(Precomputed &&it) NOEXCEPT : OwnedOrUnowned<Precomputed,Precomputed_U>() { | |||
*this = it; | |||
} | |||
/** @brief Undelete copy operator */ | |||
inline Precomputed &operator=(const Precomputed &it) NOEXCEPT { | |||
OwnedOrUnowned<Precomputed,Precomputed_U>::operator= (it); | |||
return *this; | |||
} | |||
#endif | |||
/** | |||
* @brief Initilaize from point. Must allocate memory, and may throw. | |||
@@ -698,25 +679,14 @@ public: | |||
/** | |||
* @brief Copy constructor. | |||
*/ | |||
inline Precomputed(const Precomputed &it) throw(std::bad_alloc) : isMine(false) { *this = it; } | |||
inline Precomputed(const Precomputed &it) throw(std::bad_alloc) | |||
: OwnedOrUnowned<Precomputed,Precomputed_U>() { *this = it; } | |||
/** | |||
* @brief Constructor which initializes from point. | |||
*/ | |||
inline explicit Precomputed(const Point &it) throw(std::bad_alloc) : isMine(false) { *this = it; } | |||
#if __cplusplus >= 201103L | |||
inline Precomputed &operator=(Precomputed &&it) NOEXCEPT { | |||
if (this == &it) return *this; | |||
clear(); | |||
ours = it.ours; | |||
isMine = it.isMine; | |||
it.isMine = false; | |||
it.ours.yours = decaf_448_precomputed_base; | |||
return *this; | |||
} | |||
inline Precomputed(Precomputed &&it) NOEXCEPT : isMine(false) { *this = it; } | |||
#endif | |||
inline explicit Precomputed(const Point &it) throw(std::bad_alloc) | |||
: OwnedOrUnowned<Precomputed,Precomputed_U>() { *this = it; } | |||
/** @brief Fixed base scalarmul. */ | |||
inline Point operator* (const Scalar &s) const NOEXCEPT { Point r; decaf_448_precomputed_scalarmul(r.p,get(),s.s); return r; } | |||
@@ -725,7 +695,15 @@ public: | |||
inline Point operator/ (const Scalar &s) const NOEXCEPT { return (*this) * s.inverse(); } | |||
/** @brief Return the table for the base point. */ | |||
static inline const Precomputed base() NOEXCEPT { return Precomputed(*decaf_448_precomputed_base); } | |||
static inline const Precomputed base() NOEXCEPT { return Precomputed(); } | |||
public: | |||
/** @cond internal */ | |||
friend class OwnedOrUnowned<Precomputed,Precomputed_U>; | |||
static inline size_t size() NOEXCEPT { return sizeof_decaf_448_precomputed_s; } | |||
static inline size_t alignment() NOEXCEPT { return alignof_decaf_448_precomputed_s; } | |||
static inline const Precomputed_U * defaultValue() NOEXCEPT { return decaf_448_precomputed_base; } | |||
/** @endcond */ | |||
}; | |||
}; /* struct Decaf448 */ | |||
@@ -76,7 +76,7 @@ public: | |||
}; | |||
/** | |||
* Securely zeorize contents of memory. | |||
* Securely zeroize contents of memory. | |||
*/ | |||
static inline void really_bzero(void *data, size_t size) { decaf_bzero(data,size); } | |||
@@ -173,7 +173,7 @@ public: | |||
inline TmpBuffer slice(size_t off, size_t length) throw(LengthException); | |||
/** Securely set the buffer to 0. */ | |||
inline void zeorize() NOEXCEPT { really_bzero(data(),size()); } | |||
inline void zeroize() NOEXCEPT { really_bzero(data(),size()); } | |||
}; | |||
/** A temporary reference to a writeable buffer, for converting C to C++. */ | |||
@@ -198,7 +198,7 @@ public: | |||
inline StackBuffer(Rng &r) NOEXCEPT : Buffer(storage, Size) { r.read(*this); } | |||
/** Destroy the buffer */ | |||
~StackBuffer() NOEXCEPT { zeorize(); } | |||
~StackBuffer() NOEXCEPT { zeroize(); } | |||
}; | |||
/** @cond internal */ | |||
@@ -250,13 +250,13 @@ public: | |||
return *this; | |||
} | |||
/** Destructor zeorizes data */ | |||
/** Destructor zeroizes data */ | |||
~SecureBuffer() NOEXCEPT { clear(); } | |||
/** Clear data */ | |||
inline void clear() NOEXCEPT { | |||
if (data_ == NULL) return; | |||
zeorize(); | |||
zeroize(); | |||
delete[] data_; | |||
data_ = NULL; | |||
size_ = 0; | |||
@@ -293,6 +293,75 @@ inline SecureBuffer Rng::read(size_t length) throw(std::bad_alloc) { | |||
} | |||
/** @endcond */ | |||
/** @cond internal */ | |||
/** A secure buffer which stores an owned or unowned underlying value. | |||
* If it is owned, it will be securely zeroed. | |||
*/ | |||
template <class T, class Underlying> | |||
class OwnedOrUnowned { | |||
protected: | |||
union { | |||
Underlying *mine; | |||
const Underlying *yours; | |||
} ours; | |||
bool isMine; | |||
inline void clear() NOEXCEPT { | |||
if (isMine) { | |||
really_bzero(ours.mine, T::size()); | |||
free(ours.mine); | |||
ours.yours = T::defaultValue(); | |||
isMine = false; | |||
} | |||
} | |||
inline void alloc() throw(std::bad_alloc) { | |||
if (isMine) return; | |||
int ret = posix_memalign((void**)&ours.mine, T::alignment(), T::size()); | |||
if (ret || !ours.mine) { | |||
isMine = false; | |||
throw std::bad_alloc(); | |||
} | |||
isMine = true; | |||
} | |||
inline const Underlying *get() const NOEXCEPT { return isMine ? ours.mine : ours.yours; } | |||
inline OwnedOrUnowned( | |||
const Underlying &yours = *T::defaultValue() | |||
) NOEXCEPT { | |||
ours.yours = &yours; | |||
isMine = false; | |||
} | |||
/** | |||
* @brief Assign. This may require an allocation and memcpy. | |||
*/ | |||
inline T &operator=(const OwnedOrUnowned &it) throw(std::bad_alloc) { | |||
if (this == &it) return *(T*)this; | |||
if (it.isMine) { | |||
alloc(); | |||
memcpy(ours.mine,it.ours.mine,T::size()); | |||
} else { | |||
clear(); | |||
ours.yours = it.ours.yours; | |||
} | |||
isMine = it.isMine; | |||
return *(T*)this; | |||
} | |||
#if __cplusplus >= 201103L | |||
inline T &operator=(OwnedOrUnowned &&it) NOEXCEPT { | |||
if (this == &it) return *(T*)this; | |||
clear(); | |||
ours = it.ours; | |||
isMine = it.isMine; | |||
it.isMine = false; | |||
it.ours.yours = T::defaultValue; | |||
return *this; | |||
} | |||
#endif | |||
}; | |||
/** @endcond */ | |||
} /* namespace decaf */ | |||