| @@ -64,7 +64,7 @@ ASFLAGS = $(ARCHFLAGS) $(XASFLAGS) | |||
| .PHONY: clean all test bench todo doc lib bat | |||
| .PRECIOUS: build/%.s | |||
| HEADERS= Makefile $(shell find . -name "*.h") build/timestamp | |||
| HEADERS= Makefile $(shell find . -name "*.h") $(shell find . -name "*.hxx") build/timestamp | |||
| LIBCOMPONENTS= build/goldilocks.o build/barrett_field.o build/crandom.o \ | |||
| build/$(FIELD).o build/ec_point.o build/scalarmul.o build/sha512.o build/magic.o \ | |||
| @@ -228,6 +228,16 @@ void decaf_448_scalar_copy ( | |||
| const decaf_448_scalar_t a | |||
| ) API_VIS NONNULL2; | |||
| /** | |||
| * @brief Set a scalar to an integer. | |||
| * @param [in] a An integer. | |||
| * @param [out] out Will become equal to a. | |||
| */ | |||
| void decaf_448_scalar_set ( | |||
| decaf_448_scalar_t out, | |||
| decaf_word_t w | |||
| ) API_VIS NONNULL1; | |||
| /** | |||
| * @brief Encode a point as a sequence of bytes. | |||
| * | |||
| @@ -316,7 +326,7 @@ void decaf_448_point_double ( | |||
| * input points and output point can be pointers to the same | |||
| * memory. | |||
| * | |||
| * @param [out] sum The difference a-b. | |||
| * @param [out] diff The difference a-b. | |||
| * @param [in] a The minuend. | |||
| * @param [in] b The subtrahend. | |||
| */ | |||
| @@ -324,7 +334,19 @@ void decaf_448_point_sub ( | |||
| decaf_448_point_t diff, | |||
| const decaf_448_point_t a, | |||
| const decaf_448_point_t b | |||
| ) API_VIS NONNULL3; // TODO: NOINLINE? | |||
| ) API_VIS NONNULL3; | |||
| /** | |||
| * @brief Negate a point to produce another point. The input | |||
| * and output points can use the same memory. | |||
| * | |||
| * @param [out] nega The negated input point | |||
| * @param [in] a The input point. | |||
| */ | |||
| void decaf_448_point_negate ( | |||
| decaf_448_point_t nega, | |||
| const decaf_448_point_t a | |||
| ) API_VIS NONNULL2; | |||
| /** | |||
| * @brief Multiply a base point by a scalar: scaled = scalar*base. | |||
| @@ -509,13 +531,31 @@ void decaf_448_scalar_destroy ( | |||
| decaf_448_scalar_t scalar | |||
| ) NONNULL1 API_VIS; | |||
| /** | |||
| * @brief Overwrite point with zeros. | |||
| * @todo Use this internally. | |||
| */ | |||
| void decaf_448_point_destroy ( | |||
| decaf_448_point_t point | |||
| ) NONNULL1 API_VIS; | |||
| /** | |||
| * @brief Overwrite point with zeros. | |||
| * @todo Use this internally. | |||
| */ | |||
| void decaf_448_precomputed_destroy ( | |||
| decaf_448_precomputed_s *pre | |||
| ) NONNULL1 API_VIS; | |||
| /* TODO: functions to invert point_from_hash?? */ | |||
| #undef API_VIS | |||
| #undef WARN_UNUSED | |||
| #undef NOINLINE | |||
| #undef NONNULL1 | |||
| #undef NONNULL2 | |||
| #undef NONNULL3 | |||
| #undef NONNULL4 | |||
| #undef NONNULL5 | |||
| #ifdef __cplusplus | |||
| @@ -0,0 +1,86 @@ | |||
| /** | |||
| * @file decaf.hxx | |||
| * @author Mike Hamburg | |||
| * | |||
| * @copyright | |||
| * Copyright (c) 2015 Cryptography Research, Inc. \n | |||
| * Released under the MIT License. See LICENSE.txt for license information. | |||
| * | |||
| * @brief A group of prime order p, C++ version. | |||
| * | |||
| * The Decaf library implements cryptographic operations on a an elliptic curve | |||
| * group of prime order p. It accomplishes this by using a twisted Edwards | |||
| * curve (isogenous to Ed448-Goldilocks) and wiping out the cofactor. | |||
| * | |||
| * The formulas are all complete and have no special cases, except that | |||
| * decaf_448_decode can fail because not every sequence of bytes is a valid group | |||
| * element. | |||
| * | |||
| * The formulas contain no data-dependent branches, timing or memory accesses, | |||
| * except for decaf_448_base_double_scalarmul_non_secret. | |||
| * | |||
| * This library may support multiple curves eventually. The Ed448-Goldilocks | |||
| * specific identifiers are prefixed with DECAF_448 or decaf_448. | |||
| */ | |||
| #ifndef __DECAF_448_HXX__ | |||
| #define __DECAF_448_HXX__ 1 | |||
| #include "decaf.h" | |||
| template<unsigned int bits = 448> struct decaf; | |||
| /* TODO: document */ | |||
| /* TODO: This is incomplete */ | |||
| template<> struct decaf<448> { | |||
| class Scalar { | |||
| public: | |||
| decaf_448_scalar_t s; | |||
| inline Scalar() {} | |||
| inline Scalar(const decaf_word_t w) { decaf_448_scalar_set(s,w); } | |||
| inline Scalar(const decaf_448_scalar_t &t) { decaf_448_scalar_copy(s,t); } | |||
| inline Scalar(const Scalar &x) { decaf_448_scalar_copy(s,x.s); } | |||
| inline Scalar& operator=(const Scalar &x) { decaf_448_scalar_copy(s,x.s); return *this; } | |||
| inline ~Scalar() { decaf_448_scalar_destroy(s); } | |||
| inline Scalar operator+ (const Scalar &q) { Scalar r; decaf_448_scalar_add(r.s,s,q.s); return r; } | |||
| inline Scalar operator+=(const Scalar &q) { decaf_448_scalar_add(s,s,q.s); return *this; } | |||
| inline Scalar operator- (const Scalar &q) { Scalar r; decaf_448_scalar_sub(r.s,s,q.s); return r; } | |||
| inline Scalar operator-=(const Scalar &q) { decaf_448_scalar_sub(s,s,q.s); return *this; } | |||
| inline Scalar operator* (const Scalar &q) { Scalar r; decaf_448_scalar_mul(r.s,s,q.s); return r; } | |||
| inline Scalar operator*=(const Scalar &q) { decaf_448_scalar_mul(s,s,q.s); return *this; } | |||
| inline Scalar operator-() { Scalar r; decaf_448_scalar_sub(r.s,decaf_448_scalar_zero,s); return r; } | |||
| inline bool operator==(const Scalar &q) { return !!decaf_448_scalar_eq(s,q.s); } | |||
| }; | |||
| class Point { | |||
| public: | |||
| decaf_448_point_t p; | |||
| inline Point() {} | |||
| inline Point(const decaf_448_point_t &q) { decaf_448_point_copy(p,q); } /* TODO: not memcpy? */ | |||
| inline Point(const Point &q) { decaf_448_point_copy(p,q.p); } | |||
| inline Point& operator=(const Point &q) { decaf_448_point_copy(p,q.p); return *this; } | |||
| inline ~Point() { decaf_448_point_destroy(p); } | |||
| inline Point operator+(const Point &q) { Point r; decaf_448_point_add(r.p,p,q.p); return r; } | |||
| inline Point operator+=(const Point &q) { decaf_448_point_add(p,p,q.p); return *this; } | |||
| inline Point operator-(const Point &q) { Point r; decaf_448_point_sub(r.p,p,q.p); return r; } | |||
| inline Point operator-=(const Point &q) { decaf_448_point_sub(p,p,q.p); return *this; } | |||
| inline Point operator-() { Point r; decaf_448_point_negate(r.p,p); return r; } | |||
| inline Point operator*(const Scalar &s) { Point r; decaf_448_point_scalarmul(r.p,p,s.s); return r; } | |||
| inline Point operator*=(const Scalar &s) { decaf_448_point_scalarmul(p,p,s.s); return *this; } | |||
| inline Point times_two() { Point r; decaf_448_point_double(r.p,p); return r; } | |||
| inline Point &double_in_place() { decaf_448_point_double(p,p); return *this; } | |||
| inline bool operator==(const Point &q) { return !!decaf_448_point_eq(p,q.p); } | |||
| static inline Point double_scalar_mul( | |||
| const Point &q, const Scalar &qs, const Point &r, const Scalar &rs | |||
| ) { | |||
| Point p; decaf_448_point_double_scalarmul(p.p,q.p,qs.s,r.p,rs.s); return p; | |||
| } | |||
| }; | |||
| }; /* struct decaf<448> */ | |||
| #endif /* __DECAF_448_HXX__ */ | |||
| @@ -422,6 +422,14 @@ void decaf_448_scalar_copy ( | |||
| } | |||
| } | |||
| void decaf_448_scalar_set ( | |||
| decaf_448_scalar_t out, | |||
| decaf_word_t w | |||
| ) { | |||
| memset(out,0,sizeof(decaf_448_scalar_t)); | |||
| out->limb[0] = w; | |||
| } | |||
| decaf_bool_t decaf_448_scalar_eq ( | |||
| const decaf_448_scalar_t a, | |||
| const decaf_448_scalar_t b | |||
| @@ -577,6 +585,16 @@ void decaf_448_point_copy ( | |||
| gf_cpy(a->t, b->t); | |||
| } | |||
| void decaf_448_point_negate ( | |||
| decaf_448_point_t nega, | |||
| const decaf_448_point_t a | |||
| ) { | |||
| gf_sub(nega->x, ZERO, a->x); | |||
| gf_cpy(nega->y, a->y); | |||
| gf_cpy(nega->z, a->z); | |||
| gf_sub(nega->t, ZERO, a->t); | |||
| } | |||
| decaf_bool_t decaf_448_scalar_decode( | |||
| decaf_448_scalar_t s, | |||
| const unsigned char ser[DECAF_448_SER_BYTES] | |||
| @@ -851,3 +869,15 @@ void decaf_448_base_double_scalarmul_non_secret ( | |||
| ) { | |||
| decaf_448_point_double_scalarmul(combo, decaf_448_point_base, scalar1, base2, scalar2); | |||
| } | |||
| void decaf_448_point_destroy ( | |||
| decaf_448_point_t point | |||
| ) { | |||
| decaf_bzero(point, sizeof(decaf_448_point_t)); | |||
| } | |||
| void decaf_448_precomputed_destroy ( | |||
| decaf_448_precomputed_s *pre | |||
| ) { | |||
| decaf_bzero(pre, sizeof_decaf_448_precomputed_s); | |||
| } | |||
| @@ -450,6 +450,14 @@ void decaf_448_scalar_copy ( | |||
| } | |||
| } | |||
| void decaf_448_scalar_set ( | |||
| decaf_448_scalar_t out, | |||
| decaf_word_t w | |||
| ) { | |||
| memset(out,0,sizeof(decaf_448_scalar_t)); | |||
| out->limb[0] = w; | |||
| } | |||
| decaf_bool_t decaf_448_scalar_eq ( | |||
| const decaf_448_scalar_t a, | |||
| const decaf_448_scalar_t b | |||
| @@ -673,6 +681,16 @@ void decaf_448_point_copy ( | |||
| gf_cpy(a->t, b->t); | |||
| } | |||
| void decaf_448_point_negate ( | |||
| decaf_448_point_t nega, | |||
| const decaf_448_point_t a | |||
| ) { | |||
| gf_sub(nega->x, ZERO, a->x); | |||
| gf_cpy(nega->y, a->y); | |||
| gf_cpy(nega->z, a->z); | |||
| gf_sub(nega->t, ZERO, a->t); | |||
| } | |||
| siv decaf_448_scalar_decode_short ( | |||
| decaf_448_scalar_t s, | |||
| const unsigned char ser[DECAF_448_SER_BYTES], | |||
| @@ -1576,3 +1594,15 @@ void decaf_448_base_double_scalarmul_non_secret ( | |||
| assert(contv == ncb_var); (void)ncb_var; | |||
| assert(contp == ncb_pre); (void)ncb_pre; | |||
| } | |||
| void decaf_448_point_destroy ( | |||
| decaf_448_point_t point | |||
| ) { | |||
| decaf_bzero(point, sizeof(decaf_448_point_t)); | |||
| } | |||
| void decaf_448_precomputed_destroy ( | |||
| decaf_448_precomputed_s *pre | |||
| ) { | |||
| decaf_bzero(pre, sizeof_decaf_448_precomputed_s); | |||
| } | |||