From 5f919a45f2d4bd450f8c9ef7aad8fb912cb2859a Mon Sep 17 00:00:00 2001 From: Mike Hamburg Date: Tue, 24 Mar 2015 18:43:52 -0700 Subject: [PATCH] start on c++ wrapper --- Makefile | 2 +- include/decaf.h | 44 ++++++++++++++++++++++-- include/decaf.hxx | 86 +++++++++++++++++++++++++++++++++++++++++++++++ src/decaf.c | 30 +++++++++++++++++ src/decaf_fast.c | 30 +++++++++++++++++ 5 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 include/decaf.hxx diff --git a/Makefile b/Makefile index f6b8379..ad1ed0a 100644 --- a/Makefile +++ b/Makefile @@ -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 \ diff --git a/include/decaf.h b/include/decaf.h index 2647aca..3be5183 100644 --- a/include/decaf.h +++ b/include/decaf.h @@ -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 diff --git a/include/decaf.hxx b/include/decaf.hxx new file mode 100644 index 0000000..0f043ad --- /dev/null +++ b/include/decaf.hxx @@ -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 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__ */ diff --git a/src/decaf.c b/src/decaf.c index 28c224e..2ebb94d 100644 --- a/src/decaf.c +++ b/src/decaf.c @@ -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); +} diff --git a/src/decaf_fast.c b/src/decaf_fast.c index f48300e..2cce6db 100644 --- a/src/decaf_fast.c +++ b/src/decaf_fast.c @@ -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); +}