@@ -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); | |||
} |