@@ -64,7 +64,7 @@ ASFLAGS = $(ARCHFLAGS) $(XASFLAGS) | |||||
.PHONY: clean all test bench todo doc lib bat | .PHONY: clean all test bench todo doc lib bat | ||||
.PRECIOUS: build/%.s | .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 \ | 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 \ | 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 | const decaf_448_scalar_t a | ||||
) API_VIS NONNULL2; | ) 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. | * @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 | * input points and output point can be pointers to the same | ||||
* memory. | * memory. | ||||
* | * | ||||
* @param [out] sum The difference a-b. | |||||
* @param [out] diff The difference a-b. | |||||
* @param [in] a The minuend. | * @param [in] a The minuend. | ||||
* @param [in] b The subtrahend. | * @param [in] b The subtrahend. | ||||
*/ | */ | ||||
@@ -324,7 +334,19 @@ void decaf_448_point_sub ( | |||||
decaf_448_point_t diff, | decaf_448_point_t diff, | ||||
const decaf_448_point_t a, | const decaf_448_point_t a, | ||||
const decaf_448_point_t b | 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. | * @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 | decaf_448_scalar_t scalar | ||||
) NONNULL1 API_VIS; | ) 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?? */ | /* TODO: functions to invert point_from_hash?? */ | ||||
#undef API_VIS | #undef API_VIS | ||||
#undef WARN_UNUSED | #undef WARN_UNUSED | ||||
#undef NOINLINE | |||||
#undef NONNULL1 | #undef NONNULL1 | ||||
#undef NONNULL2 | #undef NONNULL2 | ||||
#undef NONNULL3 | #undef NONNULL3 | ||||
#undef NONNULL4 | |||||
#undef NONNULL5 | #undef NONNULL5 | ||||
#ifdef __cplusplus | #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 ( | decaf_bool_t decaf_448_scalar_eq ( | ||||
const decaf_448_scalar_t a, | const decaf_448_scalar_t a, | ||||
const decaf_448_scalar_t b | const decaf_448_scalar_t b | ||||
@@ -577,6 +585,16 @@ void decaf_448_point_copy ( | |||||
gf_cpy(a->t, b->t); | 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_bool_t decaf_448_scalar_decode( | ||||
decaf_448_scalar_t s, | decaf_448_scalar_t s, | ||||
const unsigned char ser[DECAF_448_SER_BYTES] | 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); | 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 ( | decaf_bool_t decaf_448_scalar_eq ( | ||||
const decaf_448_scalar_t a, | const decaf_448_scalar_t a, | ||||
const decaf_448_scalar_t b | const decaf_448_scalar_t b | ||||
@@ -673,6 +681,16 @@ void decaf_448_point_copy ( | |||||
gf_cpy(a->t, b->t); | 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 ( | siv decaf_448_scalar_decode_short ( | ||||
decaf_448_scalar_t s, | decaf_448_scalar_t s, | ||||
const unsigned char ser[DECAF_448_SER_BYTES], | 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(contv == ncb_var); (void)ncb_var; | ||||
assert(contp == ncb_pre); (void)ncb_pre; | 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); | |||||
} |