| @@ -41,7 +41,7 @@ gf_25519_mul ( | |||||
| c[i] = accum & mask; | c[i] = accum & mask; | ||||
| accum >>= 51; | accum >>= 51; | ||||
| } | } | ||||
| /* PERF: parallelize? eh well this is reference */ | |||||
| accum *= 19; | accum *= 19; | ||||
| accum += c[0]; | accum += c[0]; | ||||
| c[0] = accum & mask; | c[0] = accum & mask; | ||||
| @@ -68,7 +68,7 @@ gf_25519_mulw ( | |||||
| c[i] = accum & mask; | c[i] = accum & mask; | ||||
| accum >>= 51; | accum >>= 51; | ||||
| } | } | ||||
| /* PERF: parallelize? eh well this is reference */ | |||||
| accum *= 19; | accum *= 19; | ||||
| accum += c[0]; | accum += c[0]; | ||||
| c[0] = accum & mask; | c[0] = accum & mask; | ||||
| @@ -65,7 +65,6 @@ static const decaf_bool_t DECAF_TRUE = -(decaf_bool_t)1; | |||||
| static const decaf_bool_t DECAF_FALSE = 0; | static const decaf_bool_t DECAF_FALSE = 0; | ||||
| /** Another boolean type used to indicate success or failure. */ | /** Another boolean type used to indicate success or failure. */ | ||||
| // FIXME: deploy project-wide | |||||
| typedef enum { | typedef enum { | ||||
| DECAF_SUCCESS = -1, /**< The operation succeeded. */ | DECAF_SUCCESS = -1, /**< The operation succeeded. */ | ||||
| DECAF_FAILURE = 0 /**< The operation failed. */ | DECAF_FAILURE = 0 /**< The operation failed. */ | ||||
| @@ -87,17 +86,13 @@ decaf_successful(decaf_error_t e) { | |||||
| return (w-1)>>DECAF_WORD_BITS; | return (w-1)>>DECAF_WORD_BITS; | ||||
| } | } | ||||
| /** | |||||
| * @brief Overwrite data with zeros. Uses memset_s if available. | |||||
| */ | |||||
| /** Overwrite data with zeros. Uses memset_s if available. */ | |||||
| void decaf_bzero ( | void decaf_bzero ( | ||||
| void *data, | void *data, | ||||
| size_t size | size_t size | ||||
| ) NONNULL1 API_VIS; | ) NONNULL1 API_VIS; | ||||
| /** | |||||
| * @brief Compare two buffers, returning DECAF_TRUE if they are equal. | |||||
| */ | |||||
| /** Compare two buffers, returning DECAF_TRUE if they are equal. */ | |||||
| decaf_bool_t decaf_memeq ( | decaf_bool_t decaf_memeq ( | ||||
| const void *data1, | const void *data1, | ||||
| const void *data2, | const void *data2, | ||||
| @@ -102,17 +102,25 @@ template<int bits> class SHA3 : public KeccakHash { | |||||
| private: | private: | ||||
| /** Get the parameter template block for this hash */ | /** Get the parameter template block for this hash */ | ||||
| static inline const struct kparams_s *get_params(); | static inline const struct kparams_s *get_params(); | ||||
| public: | public: | ||||
| /** Number of bytes of output */ | |||||
| static const size_t MAX_OUTPUT_BYTES = bits/8; | |||||
| /** Initializer */ | /** Initializer */ | ||||
| inline SHA3() NOEXCEPT : KeccakHash(get_params()) {} | inline SHA3() NOEXCEPT : KeccakHash(get_params()) {} | ||||
| /** Reset the hash to the empty string */ | /** Reset the hash to the empty string */ | ||||
| inline void reset() NOEXCEPT { sponge_init(sp, get_params()); } | inline void reset() NOEXCEPT { sponge_init(sp, get_params()); } | ||||
| /** Hash bytes with this SHA3 instance. TODO: output length? */ | |||||
| static inline SecureBuffer hash(const Block &b) throw(std::bad_alloc) { | |||||
| SHA3 s; s += b; return s.output(); | |||||
| /** Hash bytes with this SHA3 instance. | |||||
| * @throw LengthException if nbytes > MAX_OUTPUT_BYTES | |||||
| */ | |||||
| static inline SecureBuffer hash(const Block &b, size_t nbytes = MAX_OUTPUT_BYTES) throw(std::bad_alloc, LengthException) { | |||||
| if (nbytes > MAX_OUTPUT_BYTES) { | |||||
| throw LengthException(); | |||||
| } | |||||
| SHA3 s; s += b; return s.output(nbytes); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -306,8 +314,8 @@ public: | |||||
| } | } | ||||
| /** Produce an authenticator into a buffer. */ | /** Produce an authenticator into a buffer. */ | ||||
| inline void produce_auth(Buffer out) throw(LengthException,ProtocolException) { | |||||
| if (!keyed) throw ProtocolException(); /* TODO: maybe. Could use for eg sanity or dos protection */ | |||||
| 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(); | if (out.size() > STROBE_MAX_AUTH_BYTES) throw LengthException(); | ||||
| strobe_produce_auth(sp, out.data(), out.size()); | strobe_produce_auth(sp, out.data(), out.size()); | ||||
| } | } | ||||
| @@ -280,7 +280,7 @@ static void spake2ee( | |||||
| client.verify_auth(tag); | client.verify_auth(tag); | ||||
| tag = client.produce_auth(); | tag = client.produce_auth(); | ||||
| client.respec(STROBE_KEYED_128); | client.respec(STROBE_KEYED_128); | ||||
| /* TODO: fork... */ | |||||
| /* A real protocol would continue with fork etc here... */ | |||||
| server.verify_auth(tag); | server.verify_auth(tag); | ||||
| server.respec(STROBE_KEYED_128); | server.respec(STROBE_KEYED_128); | ||||