Commit 538fe688 authored by Mike Hamburg's avatar Mike Hamburg

OwnedOrUnowned as base for Precomputed

parent 6bc7a3db
......@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment