| @@ -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 */ | |||