From bc80c744bff7b02c6ac42d9fb52da37e2a5c1c34 Mon Sep 17 00:00:00 2001 From: Michael Hamburg Date: Thu, 10 Mar 2016 11:34:35 -0800 Subject: [PATCH] decaf/decaf_[field].h[xx] -> decaf/point_[field].h[xx] --- Makefile | 6 +- src/GENERATED/c/curve25519/crypto.c | 231 --- src/GENERATED/c/curve25519/decaf_gen_tables.c | 116 -- src/GENERATED/c/curve25519/eddsa.c | 339 ---- src/GENERATED/c/curve25519/scalar.c | 339 ---- src/GENERATED/c/decaf/crypto_255.h | 2 +- src/GENERATED/c/decaf/crypto_255.hxx | 2 +- src/GENERATED/c/decaf/crypto_448.h | 2 +- src/GENERATED/c/decaf/crypto_448.hxx | 2 +- src/GENERATED/c/ed448goldilocks/crypto.c | 231 --- src/GENERATED/c/ed448goldilocks/decaf.c | 1567 ----------------- .../c/ed448goldilocks/decaf_gen_tables.c | 116 -- src/GENERATED/c/ed448goldilocks/eddsa.c | 339 ---- src/GENERATED/c/ed448goldilocks/elligator.c | 199 --- src/GENERATED/c/ed448goldilocks/scalar.c | 339 ---- src/GENERATED/c/p448/f_generic.c | 133 -- src/GENERATED/include/decaf.h | 4 +- src/GENERATED/include/decaf.hxx | 4 +- src/GENERATED/include/decaf/ed255.h | 2 +- src/GENERATED/include/decaf/ed255.hxx | 2 +- src/GENERATED/include/decaf/ed448.h | 2 +- src/GENERATED/include/decaf/ed448.hxx | 2 +- .../decaf/{decaf_255.h => point_255.h} | 8 +- .../decaf/{decaf_255.hxx => point_255.hxx} | 10 +- .../decaf/{decaf_448.h => point_448.h} | 8 +- .../decaf/{decaf_448.hxx => point_448.hxx} | 10 +- src/per_curve/crypto.tmpl.h | 2 +- src/per_curve/crypto.tmpl.hxx | 2 +- src/per_curve/eddsa.tmpl.h | 2 +- src/per_curve/eddsa.tmpl.hxx | 2 +- src/per_curve/{decaf.tmpl.h => point.tmpl.h} | 0 .../{decaf.tmpl.hxx => point.tmpl.hxx} | 2 +- src/public_include/decaf.tmpl.h | 2 +- src/public_include/decaf.tmpl.hxx | 2 +- 34 files changed, 40 insertions(+), 3989 deletions(-) delete mode 100644 src/GENERATED/c/curve25519/crypto.c delete mode 100644 src/GENERATED/c/curve25519/decaf_gen_tables.c delete mode 100644 src/GENERATED/c/curve25519/eddsa.c delete mode 100644 src/GENERATED/c/curve25519/scalar.c delete mode 100644 src/GENERATED/c/ed448goldilocks/crypto.c delete mode 100644 src/GENERATED/c/ed448goldilocks/decaf.c delete mode 100644 src/GENERATED/c/ed448goldilocks/decaf_gen_tables.c delete mode 100644 src/GENERATED/c/ed448goldilocks/eddsa.c delete mode 100644 src/GENERATED/c/ed448goldilocks/elligator.c delete mode 100644 src/GENERATED/c/ed448goldilocks/scalar.c delete mode 100644 src/GENERATED/c/p448/f_generic.c rename src/GENERATED/include/decaf/{decaf_255.h => point_255.h} (99%) rename src/GENERATED/include/decaf/{decaf_255.hxx => point_255.hxx} (99%) rename src/GENERATED/include/decaf/{decaf_448.h => point_448.h} (99%) rename src/GENERATED/include/decaf/{decaf_448.hxx => point_448.hxx} (99%) rename src/per_curve/{decaf.tmpl.h => point.tmpl.h} (100%) rename src/per_curve/{decaf.tmpl.hxx => point.tmpl.hxx} (99%) diff --git a/Makefile b/Makefile index bc22ebe..e0f6769 100644 --- a/Makefile +++ b/Makefile @@ -176,7 +176,7 @@ define define_curve LIBCOMPONENTS += $$(BUILD_OBJ)/$(1)/decaf.o $$(BUILD_OBJ)/$(1)/elligator.o $$(BUILD_OBJ)/$(1)/scalar.o \ $$(BUILD_OBJ)/$(1)/crypto.o $$(BUILD_OBJ)/$(1)/eddsa.o $$(BUILD_OBJ)/$(1)/decaf_tables.o PER_OBJ_DIRS += $$(BUILD_OBJ)/$(1) -GLOBAL_HEADERS_OF_$(1) = $(BUILD_INC)/decaf/decaf_$(3).h $(BUILD_INC)/decaf/decaf_$(3).hxx \ +GLOBAL_HEADERS_OF_$(1) = $(BUILD_INC)/decaf/point_$(3).h $(BUILD_INC)/decaf/point_$(3).hxx \ $(BUILD_C)/decaf/crypto_$(3).h $(BUILD_C)/decaf/crypto_$(3).hxx \ $(BUILD_INC)/decaf/ed$(3).h $(BUILD_INC)/decaf/ed$(3).hxx HEADERS_OF_$(1) = $$(HEADERS_OF_$(2)) $$(GLOBAL_HEADERS_OF_$(1)) @@ -188,7 +188,7 @@ $$(BUILD_C)/$(1)/%.c: src/per_curve/%.tmpl.c src/generator/* Makefile $$(BUILD_H)/$(1)/%.h: src/per_curve/%.tmpl.h src/generator/* Makefile python -B src/generator/template.py --per=curve --item=$(1) --guard=$(1)/`basename $$@` -o $$@ $$< -$$(BUILD_INC)/decaf/decaf_$(3).%: src/per_curve/decaf.tmpl.% src/generator/* Makefile +$$(BUILD_INC)/decaf/point_$(3).%: src/per_curve/point.tmpl.% src/generator/* Makefile python -B src/generator/template.py --per=curve --item=$(1) --guard=$$(@:$(BUILD_INC)/%=%) -o $$@ $$< $$(BUILD_INC)/decaf/ed$(3).%: src/per_curve/eddsa.tmpl.% src/generator/* Makefile @@ -321,5 +321,5 @@ microbench: $(BUILD_IBIN)/bench clean: rm -fr build -clean_generated: +clean_generated: clean rm -fr $(BUILD_C)/* $(BUILD_H)/* $(BUILD_INC)/* diff --git a/src/GENERATED/c/curve25519/crypto.c b/src/GENERATED/c/curve25519/crypto.c deleted file mode 100644 index 5f12270..0000000 --- a/src/GENERATED/c/curve25519/crypto.c +++ /dev/null @@ -1,231 +0,0 @@ -/** - * @file curve25519/crypto.c - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * @cond internal - * @brief Example Decaf crypto routines - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ -#include -#include - -#define API_NAME "decaf_255" -#define API_NS(_id) decaf_255_##_id -#define API_NS_TOY(_id) decaf_255_TOY_##_id -#define SCALAR_BITS DECAF_255_SCALAR_BITS -#define SCALAR_BYTES ((SCALAR_BITS + 7)/8) -#define SER_BYTES DECAF_255_SER_BYTES - - /* TODO: canonicalize and freeze the STROBE constants in this file - * (and STROBE itself for that matter) - */ -static const char *DERIVE_MAGIC = API_NAME"::derive_private_key"; -static const char *SIGN_MAGIC = API_NAME"::sign"; -static const char *SHARED_SECRET_MAGIC = API_NAME"::shared_secret"; -static const uint16_t SHARED_SECRET_MAX_BLOCK_SIZE = 1<<12; -static const unsigned int SCALAR_OVERKILL_BYTES = SCALAR_BYTES + 8; - -void API_NS_TOY(derive_private_key) ( - API_NS_TOY(private_key_t) priv, - const API_NS_TOY(symmetric_key_t) proto -) { - uint8_t encoded_scalar[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) pub; - - keccak_decaf_TOY_strobe_t strobe; - decaf_TOY_strobe_init(strobe, &STROBE_256, DERIVE_MAGIC, 0); - decaf_TOY_strobe_fixed_key(strobe, proto, sizeof(API_NS_TOY(symmetric_key_t))); - decaf_TOY_strobe_prng(strobe, encoded_scalar, sizeof(encoded_scalar)); - decaf_TOY_strobe_destroy(strobe); - - memcpy(priv->sym, proto, sizeof(API_NS_TOY(symmetric_key_t))); - API_NS(scalar_decode_long)(priv->secret_scalar, encoded_scalar, sizeof(encoded_scalar)); - - API_NS(precomputed_scalarmul)(pub, API_NS(precomputed_base), priv->secret_scalar); - API_NS(point_encode)(priv->pub, pub); - - decaf_bzero(encoded_scalar, sizeof(encoded_scalar)); -} - -void API_NS_TOY(destroy_private_key) ( - API_NS_TOY(private_key_t) priv -) { - decaf_bzero((void*)priv, sizeof(API_NS_TOY(private_key_t))); -} - -void API_NS_TOY(private_to_public) ( - API_NS_TOY(public_key_t) pub, - const API_NS_TOY(private_key_t) priv -) { - memcpy(pub, priv->pub, sizeof(API_NS_TOY(public_key_t))); -} - -/* Performance vs consttime tuning. - * Specifying true here might give better DOS resistance in certain corner - * cases. Specifying false gives a tighter result in test_ct. - */ -#ifndef DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT -#define DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT DECAF_FALSE -#endif - -decaf_error_t API_NS_TOY(shared_secret) ( - uint8_t *shared, - size_t shared_bytes, - const API_NS_TOY(private_key_t) my_privkey, - const API_NS_TOY(public_key_t) your_pubkey, - int me_first -) { - keccak_decaf_TOY_strobe_t strobe; - decaf_TOY_strobe_init(strobe, &STROBE_256, SHARED_SECRET_MAGIC, 0); - - uint8_t ss_ser[SER_BYTES]; - - if (me_first) { - decaf_TOY_strobe_ad(strobe,my_privkey->pub,sizeof(API_NS_TOY(public_key_t))); - decaf_TOY_strobe_ad(strobe,your_pubkey,sizeof(API_NS_TOY(public_key_t))); - } else { - decaf_TOY_strobe_ad(strobe,your_pubkey,sizeof(API_NS_TOY(public_key_t))); - decaf_TOY_strobe_ad(strobe,my_privkey->pub,sizeof(API_NS_TOY(public_key_t))); - } - decaf_error_t ret = API_NS(direct_scalarmul)( - ss_ser, your_pubkey, my_privkey->secret_scalar, DECAF_FALSE, - DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT - ); - - decaf_TOY_strobe_transact(strobe,NULL,ss_ser,sizeof(ss_ser),STROBE_CW_DH_KEY); - - while (shared_bytes) { - uint16_t cando = (shared_bytes > SHARED_SECRET_MAX_BLOCK_SIZE) - ? SHARED_SECRET_MAX_BLOCK_SIZE : shared_bytes; - decaf_TOY_strobe_prng(strobe,shared,cando); - shared_bytes -= cando; - shared += cando; - } - - decaf_TOY_strobe_destroy(strobe); - decaf_bzero(ss_ser, sizeof(ss_ser)); - - return ret; -} - -void API_NS_TOY(sign_strobe) ( - keccak_decaf_TOY_strobe_t strobe, - API_NS_TOY(signature_t) sig, - const API_NS_TOY(private_key_t) priv -) { - uint8_t overkill[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) point; - API_NS(scalar_t) nonce, challenge; - - /* Stir pubkey */ - decaf_TOY_strobe_transact(strobe,NULL,priv->pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK); - - /* Derive nonce */ - keccak_decaf_TOY_strobe_t strobe2; - memcpy(strobe2,strobe,sizeof(strobe2)); - decaf_TOY_strobe_fixed_key(strobe2,priv->sym,sizeof(API_NS_TOY(symmetric_key_t))); - decaf_TOY_strobe_prng(strobe2,overkill,sizeof(overkill)); - decaf_TOY_strobe_destroy(strobe2); - - API_NS(scalar_decode_long)(nonce, overkill, sizeof(overkill)); - API_NS(precomputed_scalarmul)(point, API_NS(precomputed_base), nonce); - API_NS(point_encode)(sig, point); - - - /* Derive challenge */ - decaf_TOY_strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH); - decaf_TOY_strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); - API_NS(scalar_decode_long)(challenge, overkill, sizeof(overkill)); - - /* Respond */ - API_NS(scalar_mul)(challenge, challenge, priv->secret_scalar); - API_NS(scalar_sub)(nonce, nonce, challenge); - - /* Save results */ - API_NS(scalar_encode)(overkill, nonce); - decaf_TOY_strobe_transact(strobe,&sig[SER_BYTES],overkill,SCALAR_BYTES,STROBE_CW_SIG_RESP); - - /* Clean up */ - API_NS(scalar_destroy)(nonce); - API_NS(scalar_destroy)(challenge); - decaf_bzero(overkill,sizeof(overkill)); -} - -decaf_error_t API_NS_TOY(verify_strobe) ( - keccak_decaf_TOY_strobe_t strobe, - const API_NS_TOY(signature_t) sig, - const API_NS_TOY(public_key_t) pub -) { - decaf_bool_t ret; - - uint8_t overkill[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) point, pubpoint; - API_NS(scalar_t) challenge, response; - - /* Stir pubkey */ - decaf_TOY_strobe_transact(strobe,NULL,pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK); - - /* Derive nonce */ - decaf_TOY_strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH); - ret = decaf_successful( API_NS(point_decode)(point, sig, DECAF_TRUE) ); - - /* Derive challenge */ - decaf_TOY_strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); - API_NS(scalar_decode_long)(challenge, overkill, sizeof(overkill)); - - /* Decode response */ - decaf_TOY_strobe_transact(strobe,overkill,&sig[SER_BYTES],SCALAR_BYTES,STROBE_CW_SIG_RESP); - ret &= decaf_successful( API_NS(scalar_decode)(response, overkill) ); - ret &= decaf_successful( API_NS(point_decode)(pubpoint, pub, DECAF_FALSE) ); - - API_NS(base_double_scalarmul_non_secret) ( - pubpoint, response, pubpoint, challenge - ); - - ret &= API_NS(point_eq)(pubpoint, point); - - /* Nothing here is secret, so don't do these things: - decaf_bzero(overkill,sizeof(overkill)); - API_NS(point_destroy)(point); - API_NS(point_destroy)(pubpoint); - API_NS(scalar_destroy)(challenge); - API_NS(scalar_destroy)(response); - */ - - return decaf_succeed_if(ret); -} - -void -API_NS_TOY(sign) ( - API_NS_TOY(signature_t) sig, - const API_NS_TOY(private_key_t) priv, - const unsigned char *message, - size_t message_len -) { - keccak_decaf_TOY_strobe_t ctx; - decaf_TOY_strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0); - decaf_TOY_strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); - API_NS_TOY(sign_strobe)(ctx, sig, priv); - decaf_TOY_strobe_destroy(ctx); -} - -decaf_error_t -API_NS_TOY(verify) ( - const API_NS_TOY(signature_t) sig, - const API_NS_TOY(public_key_t) pub, - const unsigned char *message, - size_t message_len -) { - keccak_decaf_TOY_strobe_t ctx; - decaf_TOY_strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0); - decaf_TOY_strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); - decaf_error_t ret = API_NS_TOY(verify_strobe)(ctx, sig, pub); - decaf_TOY_strobe_destroy(ctx); - return ret; -} diff --git a/src/GENERATED/c/curve25519/decaf_gen_tables.c b/src/GENERATED/c/curve25519/decaf_gen_tables.c deleted file mode 100644 index 7cbf5ed..0000000 --- a/src/GENERATED/c/curve25519/decaf_gen_tables.c +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file curve25519/decaf_gen_tables.c - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * @brief Decaf global constant table precomputation. - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ -#define _XOPEN_SOURCE 600 /* for posix_memalign */ -#include -#include - -#include "field.h" -#include "f_field.h" -#include "decaf.h" - -#define API_NS(_id) decaf_255_##_id -static const unsigned char base_point_ser_for_pregen[SER_BYTES] = { - 0x03 -}; - - /* To satisfy linker. */ -const gf API_NS(precomputed_base_as_fe)[1]; -const API_NS(point_t) API_NS(point_base); - -struct niels_s; -const gf_s *API_NS(precomputed_wnaf_as_fe); -extern const size_t API_NS(sizeof_precomputed_wnafs); - -void API_NS(precompute_wnafs) ( - struct niels_s *out, - const API_NS(point_t) base -); -static void field_print(const gf f) { - unsigned char ser[X_SER_BYTES]; - gf_serialize(ser,f,1); - int b=0, i, comma=0; - unsigned long long limb = 0; - printf("{FIELD_LITERAL("); - for (i=0; i= GF_LIT_LIMB_BITS || i == SER_BYTES-1) { - limb &= (1ull<>(8-b); - } - } - printf(")}"); - assert(b<8); -} - -int main(int argc, char **argv) { - (void)argc; (void)argv; - - API_NS(point_t) real_point_base; - int ret = API_NS(point_decode)(real_point_base,base_point_ser_for_pregen,0); - if (ret != DECAF_SUCCESS) return 1; - - API_NS(precomputed_s) *pre; - ret = posix_memalign((void**)&pre, API_NS(alignof_precomputed_s), API_NS(sizeof_precomputed_s)); - if (ret || !pre) return 1; - API_NS(precompute)(pre, real_point_base); - - struct niels_s *pre_wnaf; - ret = posix_memalign((void**)&pre_wnaf, API_NS(alignof_precomputed_s), API_NS(sizeof_precomputed_wnafs)); - if (ret || !pre_wnaf) return 1; - API_NS(precompute_wnafs)(pre_wnaf, real_point_base); - - const gf_s *output; - unsigned i; - - printf("/** @warning: this file was automatically generated. */\n"); - printf("#include \"field.h\"\n\n"); - printf("#include \n\n"); - printf("#define API_NS(_id) decaf_255_##_id\n"); - - output = (const gf_s *)real_point_base; - printf("const API_NS(point_t) API_NS(point_base) = {{\n"); - for (i=0; i < sizeof(API_NS(point_t)); i+=sizeof(gf)) { - if (i) printf(",\n "); - field_print(output++); - } - printf("\n}};\n"); - - output = (const gf_s *)pre; - printf("const gf API_NS(precomputed_base_as_fe)[%d]\n", - (int)(API_NS(sizeof_precomputed_s) / sizeof(gf))); - printf("__attribute__((aligned(%d),visibility(\"hidden\"))) = {\n ", (int)API_NS(alignof_precomputed_s)); - - for (i=0; i < API_NS(sizeof_precomputed_s); i+=sizeof(gf)) { - if (i) printf(",\n "); - field_print(output++); - } - printf("\n};\n"); - - output = (const gf_s *)pre_wnaf; - printf("const gf API_NS(precomputed_wnaf_as_fe)[%d]\n", - (int)(API_NS(sizeof_precomputed_wnafs) / sizeof(gf))); - printf("__attribute__((aligned(%d),visibility(\"hidden\"))) = {\n ", (int)API_NS(alignof_precomputed_s)); - for (i=0; i < API_NS(sizeof_precomputed_wnafs); i+=sizeof(gf)) { - if (i) printf(",\n "); - field_print(output++); - } - printf("\n};\n"); - - return 0; -} diff --git a/src/GENERATED/c/curve25519/eddsa.c b/src/GENERATED/c/curve25519/eddsa.c deleted file mode 100644 index 9277c7c..0000000 --- a/src/GENERATED/c/curve25519/eddsa.c +++ /dev/null @@ -1,339 +0,0 @@ -/** - * @file curve25519/eddsa.c - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * @cond internal - * @brief EdDSA routines. - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ -#include "word.h" -#include -#include -#include -#include - -#define API_NAME "decaf_255" -#define API_NS(_id) decaf_255_##_id - -#define hash_ctx_t decaf_sha512_ctx_t -#define hash_init decaf_sha512_init -#define hash_update decaf_sha512_update -#define hash_final decaf_sha512_final -#define hash_destroy decaf_sha512_destroy -#define hash_hash decaf_sha512_hash - -#define SUPPORTS_CONTEXTS DECAF_EDDSA_25519_SUPPORTS_CONTEXTS -#define EDDSA_USE_SIGMA_ISOGENY 1 -#define COFACTOR 8 - -/* EDDSA_BASE_POINT_RATIO = 1 or 2 - * Because EdDSA25519 is not on E_d but on the isogenous E_sigma_d, - * its base point is twice ours. - */ -#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY) - -static void clamp ( - uint8_t secret_scalar_ser[DECAF_EDDSA_25519_PRIVATE_BYTES] -) { - /* Blarg */ - secret_scalar_ser[0] &= -COFACTOR; - uint8_t hibit = (1<<7)>>1; - if (hibit == 0) { - secret_scalar_ser[DECAF_EDDSA_25519_PRIVATE_BYTES - 1] = 0; - secret_scalar_ser[DECAF_EDDSA_25519_PRIVATE_BYTES - 2] |= 0x80; - } else { - secret_scalar_ser[DECAF_EDDSA_25519_PRIVATE_BYTES - 1] &= hibit-1; - secret_scalar_ser[DECAF_EDDSA_25519_PRIVATE_BYTES - 1] |= hibit; - } -} - -static void hash_init_with_dom( - hash_ctx_t hash, - uint8_t prehashed, - uint8_t for_prehash, - const uint8_t *context, - uint8_t context_len -) { - hash_init(hash); - -#if SUPPORTS_CONTEXTS - const char *dom_s = ""; - const uint8_t dom[2] = {2+word_is_zero(prehashed)+word_is_zero(for_prehash), context_len}; - hash_update(hash,(const unsigned char *)dom_s, strlen(dom_s)); - hash_update(hash,dom,2); - hash_update(hash,context,context_len); -#else - (void)prehashed; - (void)for_prehash; - (void)context; - assert(context==NULL); - (void)context_len; - assert(context_len == 0); -#endif -} - -void decaf_ed25519_prehash_init ( - hash_ctx_t hash -#if DECAF_EDDSA_25519_SUPPORTS_CONTEXTS - , const uint8_t *context, - uint8_t context_len -#endif -) { -#if DECAF_EDDSA_25519_SUPPORTS_CONTEXTS - hash_init_with_dom(hash,1,1,context,context_len); -#else - hash_init_with_dom(hash,1,1,NULL,0); -#endif -} - -void decaf_ed25519_derive_public_key ( - uint8_t pubkey[DECAF_EDDSA_25519_PUBLIC_BYTES], - const uint8_t privkey[DECAF_EDDSA_25519_PRIVATE_BYTES] -) { - /* only this much used for keygen */ - uint8_t secret_scalar_ser[DECAF_EDDSA_25519_PRIVATE_BYTES]; - - hash_hash( - secret_scalar_ser, - sizeof(secret_scalar_ser), - privkey, - DECAF_EDDSA_25519_PRIVATE_BYTES - ); - clamp(secret_scalar_ser); - - API_NS(scalar_t) secret_scalar; - API_NS(scalar_decode_long)(secret_scalar, secret_scalar_ser, sizeof(secret_scalar_ser)); - - /* Since we are going to mul_by_cofactor during encoding, divide by it here. - * However, the EdDSA base point is not the same as the decaf base point if - * the sigma isogeny is in use: the EdDSA base point is on Etwist_d/(1-d) and - * the decaf base point is on Etwist_d, and when converted it effectively - * picks up a factor of 2 from the isogenies. So we might start at 2 instead of 1. - */ - for (unsigned int c = EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) { - API_NS(scalar_halve)(secret_scalar,secret_scalar); - } - - API_NS(point_t) p; - API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),secret_scalar); - - API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(pubkey, p); - - /* Cleanup */ - API_NS(scalar_destroy)(secret_scalar); - API_NS(point_destroy)(p); - decaf_bzero(secret_scalar_ser, sizeof(secret_scalar_ser)); -} - -void decaf_ed25519_sign ( - uint8_t signature[DECAF_EDDSA_25519_SIGNATURE_BYTES], - const uint8_t privkey[DECAF_EDDSA_25519_PRIVATE_BYTES], - const uint8_t pubkey[DECAF_EDDSA_25519_PUBLIC_BYTES], - const uint8_t *message, - size_t message_len, - uint8_t prehashed -#if SUPPORTS_CONTEXTS - , const uint8_t *context, - uint8_t context_len -#endif -) { -#if !SUPPORTS_CONTEXTS - const uint8_t *const context = NULL; - const uint8_t context_len = 0; -#endif - API_NS(scalar_t) secret_scalar; - hash_ctx_t hash; - { - /* Schedule the secret key */ - struct { - uint8_t secret_scalar_ser[DECAF_EDDSA_25519_PRIVATE_BYTES]; - uint8_t seed[DECAF_EDDSA_25519_PRIVATE_BYTES]; - } __attribute__((packed)) expanded; - hash_hash( - (uint8_t *)&expanded, - sizeof(expanded), - privkey, - DECAF_EDDSA_25519_PRIVATE_BYTES - ); - clamp(expanded.secret_scalar_ser); - API_NS(scalar_decode_long)(secret_scalar, expanded.secret_scalar_ser, sizeof(expanded.secret_scalar_ser)); - - /* Hash to create the nonce */ - hash_init_with_dom(hash,prehashed,0,context,context_len); - hash_update(hash,expanded.seed,sizeof(expanded.seed)); - hash_update(hash,message,message_len); - decaf_bzero(&expanded, sizeof(expanded)); - } - - /* Decode the nonce */ - API_NS(scalar_t) nonce_scalar; - { - uint8_t nonce[2*DECAF_EDDSA_25519_PRIVATE_BYTES]; - hash_final(hash,nonce,sizeof(nonce)); - API_NS(scalar_decode_long)(nonce_scalar, nonce, sizeof(nonce)); - decaf_bzero(nonce, sizeof(nonce)); - } - - uint8_t nonce_point[DECAF_EDDSA_25519_PUBLIC_BYTES] = {0}; - { - /* Scalarmul to create the nonce-point */ - API_NS(scalar_t) nonce_scalar_2; - API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar); - for (unsigned int c = 2*EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) { - API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2); - } - - API_NS(point_t) p; - API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2); - API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(nonce_point, p); - API_NS(point_destroy)(p); - API_NS(scalar_destroy)(nonce_scalar_2); - } - - API_NS(scalar_t) challenge_scalar; - { - /* Compute the challenge */ - hash_init_with_dom(hash,prehashed,0,context,context_len); - hash_update(hash,nonce_point,sizeof(nonce_point)); - hash_update(hash,pubkey,DECAF_EDDSA_25519_PUBLIC_BYTES); - hash_update(hash,message,message_len); - uint8_t challenge[2*DECAF_EDDSA_25519_PRIVATE_BYTES]; - hash_final(hash,challenge,sizeof(challenge)); - hash_destroy(hash); - API_NS(scalar_decode_long)(challenge_scalar,challenge,sizeof(challenge)); - decaf_bzero(challenge,sizeof(challenge)); - } - - API_NS(scalar_mul)(challenge_scalar,challenge_scalar,secret_scalar); - API_NS(scalar_add)(challenge_scalar,challenge_scalar,nonce_scalar); - - decaf_bzero(signature,DECAF_EDDSA_25519_SIGNATURE_BYTES); - memcpy(signature,nonce_point,sizeof(nonce_point)); - API_NS(scalar_encode)(&signature[DECAF_EDDSA_25519_PUBLIC_BYTES],challenge_scalar); - - API_NS(scalar_destroy)(secret_scalar); - API_NS(scalar_destroy)(nonce_scalar); - API_NS(scalar_destroy)(challenge_scalar); -} - - -void decaf_ed25519_sign_prehash ( - uint8_t signature[DECAF_EDDSA_25519_SIGNATURE_BYTES], - const uint8_t privkey[DECAF_EDDSA_25519_PRIVATE_BYTES], - const uint8_t pubkey[DECAF_EDDSA_25519_PUBLIC_BYTES], - const decaf_ed25519_prehash_ctx_t hash -#if DECAF_EDDSA_25519_SUPPORTS_CONTEXTS - , const uint8_t *context, - uint8_t context_len -#endif -) { - uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */ - { - decaf_ed25519_prehash_ctx_t hash_too; - memcpy(hash_too,hash,sizeof(hash_too)); - hash_final(hash_too,hash_output,sizeof(hash_output)); - hash_destroy(hash_too); - } - -#if DECAF_EDDSA_25519_SUPPORTS_CONTEXTS - decaf_ed25519_sign(signature,privkey,pubkey,hash_output,sizeof(hash_output),1,context,context_len); -#else - decaf_ed25519_sign(signature,privkey,pubkey,hash_output,sizeof(hash_output),1); -#endif - - decaf_bzero(hash_output,sizeof(hash_output)); -} - -decaf_error_t decaf_ed25519_verify ( - const uint8_t signature[DECAF_EDDSA_25519_SIGNATURE_BYTES], - const uint8_t pubkey[DECAF_EDDSA_25519_PUBLIC_BYTES], - const uint8_t *message, - size_t message_len, - uint8_t prehashed -#if SUPPORTS_CONTEXTS - , const uint8_t *context, - uint8_t context_len -#endif -) { -#if !SUPPORTS_CONTEXTS - const uint8_t *const context = NULL; - const uint8_t context_len = 0; -#endif - API_NS(point_t) pk_point, r_point; - decaf_error_t error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(pk_point,pubkey); - if (DECAF_SUCCESS != error) { return error; } - - error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(r_point,signature); - if (DECAF_SUCCESS != error) { return error; } - - API_NS(scalar_t) challenge_scalar; - { - /* Compute the challenge */ - hash_ctx_t hash; - hash_init_with_dom(hash,prehashed,0,context,context_len); - hash_update(hash,signature,DECAF_EDDSA_25519_PUBLIC_BYTES); - hash_update(hash,pubkey,DECAF_EDDSA_25519_PUBLIC_BYTES); - hash_update(hash,message,message_len); - uint8_t challenge[2*DECAF_EDDSA_25519_PRIVATE_BYTES]; - hash_final(hash,challenge,sizeof(challenge)); - hash_destroy(hash); - API_NS(scalar_decode_long)(challenge_scalar,challenge,sizeof(challenge)); - decaf_bzero(challenge,sizeof(challenge)); - } - API_NS(scalar_sub)(challenge_scalar, API_NS(scalar_zero), challenge_scalar); - - API_NS(scalar_t) response_scalar; - API_NS(scalar_decode_long)( - response_scalar, - &signature[DECAF_EDDSA_25519_PUBLIC_BYTES], - DECAF_EDDSA_25519_PRIVATE_BYTES - ); -#if EDDSA_BASE_POINT_RATIO == 2 - API_NS(scalar_add)(response_scalar,response_scalar,response_scalar); -#endif - - - /* pk_point = -c(x(P)) + (cx + k)G = kG */ - API_NS(base_double_scalarmul_non_secret)( - pk_point, - response_scalar, - pk_point, - challenge_scalar - ); - return decaf_succeed_if(API_NS(point_eq(pk_point,r_point))); -} - - -decaf_error_t decaf_ed25519_verify_prehash ( - const uint8_t signature[DECAF_EDDSA_25519_SIGNATURE_BYTES], - const uint8_t pubkey[DECAF_EDDSA_25519_PUBLIC_BYTES], - const decaf_ed25519_prehash_ctx_t hash -#if DECAF_EDDSA_25519_SUPPORTS_CONTEXTS - , const uint8_t *context, - uint8_t context_len -#endif -) { - decaf_error_t ret; - - uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */ - { - decaf_ed25519_prehash_ctx_t hash_too; - memcpy(hash_too,hash,sizeof(hash_too)); - hash_final(hash_too,hash_output,sizeof(hash_output)); - hash_destroy(hash_too); - } - -#if DECAF_EDDSA_25519_SUPPORTS_CONTEXTS - ret = decaf_ed25519_verify(signature,pubkey,hash_output,sizeof(hash_output),1,context,context_len); -#else - ret = decaf_ed25519_verify(signature,pubkey,hash_output,sizeof(hash_output),1); -#endif - - return ret; -} diff --git a/src/GENERATED/c/curve25519/scalar.c b/src/GENERATED/c/curve25519/scalar.c deleted file mode 100644 index 352158b..0000000 --- a/src/GENERATED/c/curve25519/scalar.c +++ /dev/null @@ -1,339 +0,0 @@ -/** - * @file curve25519/scalar.c - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * @brief Decaf high-level functions. - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ -#include "word.h" -#include "constant_time.h" -#include - -/* Template stuff */ -#define API_NS(_id) decaf_255_##_id -#define SCALAR_BITS DECAF_255_SCALAR_BITS -#define SCALAR_SER_BYTES DECAF_255_SCALAR_BYTES -#define SCALAR_LIMBS DECAF_255_SCALAR_LIMBS -#define scalar_t API_NS(scalar_t) - -static const decaf_word_t MONTGOMERY_FACTOR = (decaf_word_t)0xd2b51da312547e1bull; -static const scalar_t sc_p = {{{ - SC_LIMB(0x5812631a5cf5d3ed), SC_LIMB(0x14def9dea2f79cd6), SC_LIMB(0x0000000000000000), SC_LIMB(0x1000000000000000) -}}}, sc_r2 = {{{ - SC_LIMB(0xa40611e3449c0f01), SC_LIMB(0xd00e1ba768859347), SC_LIMB(0xceec73d217f5be65), SC_LIMB(0x0399411b7c309a3d) -}}}; -/* End of template stuff */ - -#define WBITS DECAF_WORD_BITS /* NB this may be different from ARCH_WORD_BITS */ - -const scalar_t API_NS(scalar_one) = {{{1}}}, API_NS(scalar_zero) = {{{0}}}; - -/** {extra,accum} - sub +? p - * Must have extra <= 1 - */ -static NOINLINE void sc_subx( - scalar_t out, - const decaf_word_t accum[SCALAR_LIMBS], - const scalar_t sub, - const scalar_t p, - decaf_word_t extra -) { - decaf_dsword_t chain = 0; - unsigned int i; - for (i=0; ilimb[i]; - out->limb[i] = chain; - chain >>= WBITS; - } - decaf_word_t borrow = chain+extra; /* = 0 or -1 */ - - chain = 0; - for (i=0; ilimb[i]) + (p->limb[i] & borrow); - out->limb[i] = chain; - chain >>= WBITS; - } -} - -static NOINLINE void sc_montmul ( - scalar_t out, - const scalar_t a, - const scalar_t b -) { - unsigned int i,j; - decaf_word_t accum[SCALAR_LIMBS+1] = {0}; - decaf_word_t hi_carry = 0; - - for (i=0; ilimb[i]; - const decaf_word_t *mier = b->limb; - - decaf_dword_t chain = 0; - for (j=0; j>= WBITS; - } - accum[j] = chain; - - mand = accum[0] * MONTGOMERY_FACTOR; - chain = 0; - mier = sc_p->limb; - for (j=0; j>= WBITS; - } - chain += accum[j]; - chain += hi_carry; - accum[j-1] = chain; - hi_carry = chain >> WBITS; - } - - sc_subx(out, accum, sc_p, sc_p, hi_carry); -} - -void API_NS(scalar_mul) ( - scalar_t out, - const scalar_t a, - const scalar_t b -) { - sc_montmul(out,a,b); - sc_montmul(out,out,sc_r2); -} - -/* PERF: could implement this */ -static INLINE void sc_montsqr (scalar_t out, const scalar_t a) { - sc_montmul(out,a,a); -} - -decaf_error_t API_NS(scalar_invert) ( - scalar_t out, - const scalar_t a -) { - /* Fermat's little theorem, sliding window. - * Sliding window is fine here because the modulus isn't secret. - */ - const int SCALAR_WINDOW_BITS = 3; - scalar_t precmp[1< 0) sc_montmul(precmp[LAST],precmp[0],precmp[0]); - - int i; - for (i=1; i<=LAST; i++) { - sc_montmul(precmp[i],precmp[i-1],precmp[LAST]); - } - - /* Sliding window */ - unsigned residue = 0, trailing = 0, started = 0; - for (i=SCALAR_BITS-1; i>=-SCALAR_WINDOW_BITS; i--) { - - if (started) sc_montsqr(out,out); - - decaf_word_t w = (i>=0) ? sc_p->limb[i/WBITS] : 0; - if (i >= 0 && i= 2); - w-=2; - } - - residue = (residue<<1) | ((w>>(i%WBITS))&1); - if (residue>>SCALAR_WINDOW_BITS != 0) { - assert(trailing == 0); - trailing = residue; - residue = 0; - } - - if (trailing > 0 && (trailing & ((1<>(SCALAR_WINDOW_BITS+1)]); - } else { - API_NS(scalar_copy)(out,precmp[trailing>>(SCALAR_WINDOW_BITS+1)]); - started = 1; - } - trailing = 0; - } - trailing <<= 1; - - } - assert(residue==0); - assert(trailing==0); - - /* Demontgomerize */ - sc_montmul(out,out,API_NS(scalar_one)); - decaf_bzero(precmp, sizeof(precmp)); - return decaf_succeed_if(~API_NS(scalar_eq)(out,API_NS(scalar_zero))); -} - -void API_NS(scalar_sub) ( - scalar_t out, - const scalar_t a, - const scalar_t b -) { - sc_subx(out, a->limb, b, sc_p, 0); -} - -void API_NS(scalar_add) ( - scalar_t out, - const scalar_t a, - const scalar_t b -) { - decaf_dword_t chain = 0; - unsigned int i; - for (i=0; ilimb[i]) + b->limb[i]; - out->limb[i] = chain; - chain >>= WBITS; - } - sc_subx(out, out->limb, sc_p, sc_p, chain); -} - -void -API_NS(scalar_set_unsigned) ( - scalar_t out, - uint64_t w -) { - memset(out,0,sizeof(scalar_t)); - unsigned int i = 0; - for (; ilimb[i] = w; - w >>= (sizeof(uint64_t) > sizeof(decaf_word_t)) ? 8*sizeof(decaf_word_t) : 0; - } -} - -decaf_bool_t -API_NS(scalar_eq) ( - const scalar_t a, - const scalar_t b -) { - decaf_word_t diff = 0; - unsigned int i; - for (i=0; ilimb[i] ^ b->limb[i]; - } - return mask_to_bool(word_is_zero(diff)); -} - -static INLINE void scalar_decode_short ( - scalar_t s, - const unsigned char *ser, - unsigned int nbytes -) { - unsigned int i,j,k=0; - for (i=0; ilimb[i] = out; - } -} - -decaf_error_t API_NS(scalar_decode)( - scalar_t s, - const unsigned char ser[SCALAR_SER_BYTES] -) { - unsigned int i; - scalar_decode_short(s, ser, SCALAR_SER_BYTES); - decaf_dsword_t accum = 0; - for (i=0; ilimb[i] - sc_p->limb[i]) >> WBITS; - } - /* Here accum == 0 or -1 */ - - API_NS(scalar_mul)(s,s,API_NS(scalar_one)); /* ham-handed reduce */ - - return decaf_succeed_if(~word_is_zero(accum)); -} - -void API_NS(scalar_destroy) ( - scalar_t scalar -) { - decaf_bzero(scalar, sizeof(scalar_t)); -} - -void API_NS(scalar_decode_long)( - scalar_t s, - const unsigned char *ser, - size_t ser_len -) { - if (ser_len == 0) { - API_NS(scalar_copy)(s, API_NS(scalar_zero)); - return; - } - - size_t i; - scalar_t t1, t2; - - i = ser_len - (ser_len%SCALAR_SER_BYTES); - if (i==ser_len) i -= SCALAR_SER_BYTES; - - scalar_decode_short(t1, &ser[i], ser_len-i); - - if (ser_len == sizeof(scalar_t)) { - assert(i==0); - /* ham-handed reduce */ - API_NS(scalar_mul)(s,t1,API_NS(scalar_one)); - API_NS(scalar_destroy)(t1); - return; - } - - while (i) { - i -= SCALAR_SER_BYTES; - sc_montmul(t1,t1,sc_r2); - ignore_result( API_NS(scalar_decode)(t2, ser+i) ); - API_NS(scalar_add)(t1, t1, t2); - } - - API_NS(scalar_copy)(s, t1); - API_NS(scalar_destroy)(t1); - API_NS(scalar_destroy)(t2); -} - -void API_NS(scalar_encode)( - unsigned char ser[SCALAR_SER_BYTES], - const scalar_t s -) { - unsigned int i,j,k=0; - for (i=0; ilimb[i] >> (8*j); - } - } -} - -void API_NS(scalar_cond_sel) ( - scalar_t out, - const scalar_t a, - const scalar_t b, - decaf_bool_t pick_b -) { - constant_time_select(out,a,b,sizeof(scalar_t),bool_to_mask(pick_b),sizeof(out->limb[0])); -} - -void API_NS(scalar_halve) ( - scalar_t out, - const scalar_t a -) { - decaf_word_t mask = -(a->limb[0] & 1); - decaf_dword_t chain = 0; - unsigned int i; - for (i=0; ilimb[i]) + (sc_p->limb[i] & mask); - out->limb[i] = chain; - chain >>= DECAF_WORD_BITS; - } - for (i=0; ilimb[i] = out->limb[i]>>1 | out->limb[i+1]<<(WBITS-1); - } - out->limb[i] = out->limb[i]>>1 | chain<<(WBITS-1); -} - diff --git a/src/GENERATED/c/decaf/crypto_255.h b/src/GENERATED/c/decaf/crypto_255.h index e4fbff1..3751f14 100644 --- a/src/GENERATED/c/decaf/crypto_255.h +++ b/src/GENERATED/c/decaf/crypto_255.h @@ -19,7 +19,7 @@ #ifndef __SRC_GENERATED_C_DECAF_CRYPTO_255_H__ #define __SRC_GENERATED_C_DECAF_CRYPTO_255_H__ 1 -#include +#include #include #ifdef __cplusplus diff --git a/src/GENERATED/c/decaf/crypto_255.hxx b/src/GENERATED/c/decaf/crypto_255.hxx index b6ceef8..2e2da39 100644 --- a/src/GENERATED/c/decaf/crypto_255.hxx +++ b/src/GENERATED/c/decaf/crypto_255.hxx @@ -22,7 +22,7 @@ * @warning Experimental! The names, parameter orders etc are likely to change. */ -#include +#include #include #include diff --git a/src/GENERATED/c/decaf/crypto_448.h b/src/GENERATED/c/decaf/crypto_448.h index befa731..43c6f13 100644 --- a/src/GENERATED/c/decaf/crypto_448.h +++ b/src/GENERATED/c/decaf/crypto_448.h @@ -19,7 +19,7 @@ #ifndef __SRC_GENERATED_C_DECAF_CRYPTO_448_H__ #define __SRC_GENERATED_C_DECAF_CRYPTO_448_H__ 1 -#include +#include #include #ifdef __cplusplus diff --git a/src/GENERATED/c/decaf/crypto_448.hxx b/src/GENERATED/c/decaf/crypto_448.hxx index f38b0d7..253c98e 100644 --- a/src/GENERATED/c/decaf/crypto_448.hxx +++ b/src/GENERATED/c/decaf/crypto_448.hxx @@ -22,7 +22,7 @@ * @warning Experimental! The names, parameter orders etc are likely to change. */ -#include +#include #include #include diff --git a/src/GENERATED/c/ed448goldilocks/crypto.c b/src/GENERATED/c/ed448goldilocks/crypto.c deleted file mode 100644 index 7d6aa97..0000000 --- a/src/GENERATED/c/ed448goldilocks/crypto.c +++ /dev/null @@ -1,231 +0,0 @@ -/** - * @file ed448goldilocks/crypto.c - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * @cond internal - * @brief Example Decaf crypto routines - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ -#include -#include - -#define API_NAME "decaf_448" -#define API_NS(_id) decaf_448_##_id -#define API_NS_TOY(_id) decaf_448_TOY_##_id -#define SCALAR_BITS DECAF_448_SCALAR_BITS -#define SCALAR_BYTES ((SCALAR_BITS + 7)/8) -#define SER_BYTES DECAF_448_SER_BYTES - - /* TODO: canonicalize and freeze the STROBE constants in this file - * (and STROBE itself for that matter) - */ -static const char *DERIVE_MAGIC = API_NAME"::derive_private_key"; -static const char *SIGN_MAGIC = API_NAME"::sign"; -static const char *SHARED_SECRET_MAGIC = API_NAME"::shared_secret"; -static const uint16_t SHARED_SECRET_MAX_BLOCK_SIZE = 1<<12; -static const unsigned int SCALAR_OVERKILL_BYTES = SCALAR_BYTES + 8; - -void API_NS_TOY(derive_private_key) ( - API_NS_TOY(private_key_t) priv, - const API_NS_TOY(symmetric_key_t) proto -) { - uint8_t encoded_scalar[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) pub; - - keccak_decaf_TOY_strobe_t strobe; - decaf_TOY_strobe_init(strobe, &STROBE_256, DERIVE_MAGIC, 0); - decaf_TOY_strobe_fixed_key(strobe, proto, sizeof(API_NS_TOY(symmetric_key_t))); - decaf_TOY_strobe_prng(strobe, encoded_scalar, sizeof(encoded_scalar)); - decaf_TOY_strobe_destroy(strobe); - - memcpy(priv->sym, proto, sizeof(API_NS_TOY(symmetric_key_t))); - API_NS(scalar_decode_long)(priv->secret_scalar, encoded_scalar, sizeof(encoded_scalar)); - - API_NS(precomputed_scalarmul)(pub, API_NS(precomputed_base), priv->secret_scalar); - API_NS(point_encode)(priv->pub, pub); - - decaf_bzero(encoded_scalar, sizeof(encoded_scalar)); -} - -void API_NS_TOY(destroy_private_key) ( - API_NS_TOY(private_key_t) priv -) { - decaf_bzero((void*)priv, sizeof(API_NS_TOY(private_key_t))); -} - -void API_NS_TOY(private_to_public) ( - API_NS_TOY(public_key_t) pub, - const API_NS_TOY(private_key_t) priv -) { - memcpy(pub, priv->pub, sizeof(API_NS_TOY(public_key_t))); -} - -/* Performance vs consttime tuning. - * Specifying true here might give better DOS resistance in certain corner - * cases. Specifying false gives a tighter result in test_ct. - */ -#ifndef DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT -#define DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT DECAF_FALSE -#endif - -decaf_error_t API_NS_TOY(shared_secret) ( - uint8_t *shared, - size_t shared_bytes, - const API_NS_TOY(private_key_t) my_privkey, - const API_NS_TOY(public_key_t) your_pubkey, - int me_first -) { - keccak_decaf_TOY_strobe_t strobe; - decaf_TOY_strobe_init(strobe, &STROBE_256, SHARED_SECRET_MAGIC, 0); - - uint8_t ss_ser[SER_BYTES]; - - if (me_first) { - decaf_TOY_strobe_ad(strobe,my_privkey->pub,sizeof(API_NS_TOY(public_key_t))); - decaf_TOY_strobe_ad(strobe,your_pubkey,sizeof(API_NS_TOY(public_key_t))); - } else { - decaf_TOY_strobe_ad(strobe,your_pubkey,sizeof(API_NS_TOY(public_key_t))); - decaf_TOY_strobe_ad(strobe,my_privkey->pub,sizeof(API_NS_TOY(public_key_t))); - } - decaf_error_t ret = API_NS(direct_scalarmul)( - ss_ser, your_pubkey, my_privkey->secret_scalar, DECAF_FALSE, - DECAF_CRYPTO_SHARED_SECRET_SHORT_CIRUIT - ); - - decaf_TOY_strobe_transact(strobe,NULL,ss_ser,sizeof(ss_ser),STROBE_CW_DH_KEY); - - while (shared_bytes) { - uint16_t cando = (shared_bytes > SHARED_SECRET_MAX_BLOCK_SIZE) - ? SHARED_SECRET_MAX_BLOCK_SIZE : shared_bytes; - decaf_TOY_strobe_prng(strobe,shared,cando); - shared_bytes -= cando; - shared += cando; - } - - decaf_TOY_strobe_destroy(strobe); - decaf_bzero(ss_ser, sizeof(ss_ser)); - - return ret; -} - -void API_NS_TOY(sign_strobe) ( - keccak_decaf_TOY_strobe_t strobe, - API_NS_TOY(signature_t) sig, - const API_NS_TOY(private_key_t) priv -) { - uint8_t overkill[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) point; - API_NS(scalar_t) nonce, challenge; - - /* Stir pubkey */ - decaf_TOY_strobe_transact(strobe,NULL,priv->pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK); - - /* Derive nonce */ - keccak_decaf_TOY_strobe_t strobe2; - memcpy(strobe2,strobe,sizeof(strobe2)); - decaf_TOY_strobe_fixed_key(strobe2,priv->sym,sizeof(API_NS_TOY(symmetric_key_t))); - decaf_TOY_strobe_prng(strobe2,overkill,sizeof(overkill)); - decaf_TOY_strobe_destroy(strobe2); - - API_NS(scalar_decode_long)(nonce, overkill, sizeof(overkill)); - API_NS(precomputed_scalarmul)(point, API_NS(precomputed_base), nonce); - API_NS(point_encode)(sig, point); - - - /* Derive challenge */ - decaf_TOY_strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH); - decaf_TOY_strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); - API_NS(scalar_decode_long)(challenge, overkill, sizeof(overkill)); - - /* Respond */ - API_NS(scalar_mul)(challenge, challenge, priv->secret_scalar); - API_NS(scalar_sub)(nonce, nonce, challenge); - - /* Save results */ - API_NS(scalar_encode)(overkill, nonce); - decaf_TOY_strobe_transact(strobe,&sig[SER_BYTES],overkill,SCALAR_BYTES,STROBE_CW_SIG_RESP); - - /* Clean up */ - API_NS(scalar_destroy)(nonce); - API_NS(scalar_destroy)(challenge); - decaf_bzero(overkill,sizeof(overkill)); -} - -decaf_error_t API_NS_TOY(verify_strobe) ( - keccak_decaf_TOY_strobe_t strobe, - const API_NS_TOY(signature_t) sig, - const API_NS_TOY(public_key_t) pub -) { - decaf_bool_t ret; - - uint8_t overkill[SCALAR_OVERKILL_BYTES]; - API_NS(point_t) point, pubpoint; - API_NS(scalar_t) challenge, response; - - /* Stir pubkey */ - decaf_TOY_strobe_transact(strobe,NULL,pub,sizeof(API_NS_TOY(public_key_t)),STROBE_CW_SIG_PK); - - /* Derive nonce */ - decaf_TOY_strobe_transact(strobe,NULL,sig,SER_BYTES,STROBE_CW_SIG_EPH); - ret = decaf_successful( API_NS(point_decode)(point, sig, DECAF_TRUE) ); - - /* Derive challenge */ - decaf_TOY_strobe_transact(strobe,overkill,NULL,sizeof(overkill),STROBE_CW_SIG_CHAL); - API_NS(scalar_decode_long)(challenge, overkill, sizeof(overkill)); - - /* Decode response */ - decaf_TOY_strobe_transact(strobe,overkill,&sig[SER_BYTES],SCALAR_BYTES,STROBE_CW_SIG_RESP); - ret &= decaf_successful( API_NS(scalar_decode)(response, overkill) ); - ret &= decaf_successful( API_NS(point_decode)(pubpoint, pub, DECAF_FALSE) ); - - API_NS(base_double_scalarmul_non_secret) ( - pubpoint, response, pubpoint, challenge - ); - - ret &= API_NS(point_eq)(pubpoint, point); - - /* Nothing here is secret, so don't do these things: - decaf_bzero(overkill,sizeof(overkill)); - API_NS(point_destroy)(point); - API_NS(point_destroy)(pubpoint); - API_NS(scalar_destroy)(challenge); - API_NS(scalar_destroy)(response); - */ - - return decaf_succeed_if(ret); -} - -void -API_NS_TOY(sign) ( - API_NS_TOY(signature_t) sig, - const API_NS_TOY(private_key_t) priv, - const unsigned char *message, - size_t message_len -) { - keccak_decaf_TOY_strobe_t ctx; - decaf_TOY_strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0); - decaf_TOY_strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); - API_NS_TOY(sign_strobe)(ctx, sig, priv); - decaf_TOY_strobe_destroy(ctx); -} - -decaf_error_t -API_NS_TOY(verify) ( - const API_NS_TOY(signature_t) sig, - const API_NS_TOY(public_key_t) pub, - const unsigned char *message, - size_t message_len -) { - keccak_decaf_TOY_strobe_t ctx; - decaf_TOY_strobe_init(ctx,&STROBE_256,SIGN_MAGIC,0); - decaf_TOY_strobe_transact(ctx, NULL, message, message_len, STROBE_CW_STREAMING_PLAINTEXT); - decaf_error_t ret = API_NS_TOY(verify_strobe)(ctx, sig, pub); - decaf_TOY_strobe_destroy(ctx); - return ret; -} diff --git a/src/GENERATED/c/ed448goldilocks/decaf.c b/src/GENERATED/c/ed448goldilocks/decaf.c deleted file mode 100644 index 221c7ff..0000000 --- a/src/GENERATED/c/ed448goldilocks/decaf.c +++ /dev/null @@ -1,1567 +0,0 @@ -/** - * @file ed448goldilocks/decaf.c - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * @brief Decaf high-level functions. - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ -#define _XOPEN_SOURCE 600 /* for posix_memalign */ -#include "word.h" -#include "field.h" - -#include -#include - -/* Template stuff */ -#define API_NS(_id) decaf_448_##_id -#define SCALAR_BITS DECAF_448_SCALAR_BITS -#define SCALAR_SER_BYTES DECAF_448_SCALAR_BYTES -#define SCALAR_LIMBS DECAF_448_SCALAR_LIMBS -#define scalar_t API_NS(scalar_t) -#define point_t API_NS(point_t) -#define precomputed_s API_NS(precomputed_s) -#define IMAGINE_TWIST 0 -#define COFACTOR 4 - -/* Comb config: number of combs, n, t, s. */ -#define COMBS_N 5 -#define COMBS_T 5 -#define COMBS_S 18 -#define DECAF_WINDOW_BITS 5 -#define DECAF_WNAF_FIXED_TABLE_BITS 5 -#define DECAF_WNAF_VAR_TABLE_BITS 3 - -#define EDDSA_USE_SIGMA_ISOGENY 0 - -static const int EDWARDS_D = -39081; -static const scalar_t point_scalarmul_adjustment = {{{ - SC_LIMB(0xc873d6d54a7bb0cf), SC_LIMB(0xe933d8d723a70aad), SC_LIMB(0xbb124b65129c96fd), SC_LIMB(0x00000008335dc163) -}}}, precomputed_scalarmul_adjustment = {{{ - SC_LIMB(0xc873d6d54a7bb0cf), SC_LIMB(0xe933d8d723a70aad), SC_LIMB(0xbb124b65129c96fd), SC_LIMB(0x00000008335dc163) -}}}; - -const uint8_t decaf_x448_base_point[DECAF_X448_PUBLIC_BYTES] = { 0x05 }; - -#if COFACTOR==8 || EDDSA_USE_SIGMA_ISOGENY - static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL( - /* NONE */ - )}; -#endif - -/* End of template stuff */ - -/* Sanity */ -#if (COFACTOR == 8) && !IMAGINE_TWIST -/* FUTURE MAGIC: Curve41417 doesn't have these properties. */ - #error "Currently require IMAGINE_TWIST (and thus p=5 mod 8) for cofactor 8" -#endif - -#if IMAGINE_TWIST && (P_MOD_8 != 5) - #error "Cannot use IMAGINE_TWIST except for p == 5 mod 8" -#endif - -#if (COFACTOR != 8) && (COFACTOR != 4) - #error "COFACTOR must be 4 or 8" -#endif - -#if IMAGINE_TWIST - extern const gf SQRT_MINUS_ONE; -#endif - -#define WBITS DECAF_WORD_BITS /* NB this may be different from ARCH_WORD_BITS */ - -extern const point_t API_NS(point_base); - -/* Projective Niels coordinates */ -typedef struct { gf a, b, c; } niels_s, niels_t[1]; -typedef struct { niels_t n; gf z; } __attribute__((aligned(sizeof(big_register_t)))) - pniels_s, pniels_t[1]; - -/* Precomputed base */ -struct precomputed_s { niels_t table [COMBS_N<<(COMBS_T-1)]; }; - -extern const gf API_NS(precomputed_base_as_fe)[]; -const precomputed_s *API_NS(precomputed_base) = - (const precomputed_s *) &API_NS(precomputed_base_as_fe); - -const size_t API_NS(sizeof_precomputed_s) = sizeof(precomputed_s); -const size_t API_NS(alignof_precomputed_s) = sizeof(big_register_t); - -/** Inverse. */ -static void -gf_invert(gf y, const gf x) { - gf t1, t2; - gf_sqr(t1, x); // o^2 - mask_t ret = gf_isr(t2, t1); // +-1/sqrt(o^2) = +-1/o - (void)ret; assert(ret); - gf_sqr(t1, t2); - gf_mul(t2, t1, x); // not direct to y in case of alias. - gf_copy(y, t2); -} - -/** Return high bit of x = low bit of 2x mod p */ -static mask_t gf_lobit(const gf x) { - gf y; - gf_copy(y,x); - gf_strong_reduce(y); - return -(y->limb[0]&1); -} - -/** identity = (0,1) */ -const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}}; - -void API_NS(deisogenize) ( - gf_s *__restrict__ s, - gf_s *__restrict__ minus_t_over_s, - const point_t p, - mask_t toggle_hibit_s, - mask_t toggle_hibit_t_over_s, - mask_t toggle_rotation -); - -void API_NS(deisogenize) ( - gf_s *__restrict__ s, - gf_s *__restrict__ minus_t_over_s, - const point_t p, - mask_t toggle_hibit_s, - mask_t toggle_hibit_t_over_s, - mask_t toggle_rotation -) { -#if COFACTOR == 4 && !IMAGINE_TWIST - (void) toggle_rotation; - - gf b, d; - gf_s *c = s, *a = minus_t_over_s; - gf_mulw(a, p->y, 1-EDWARDS_D); - gf_mul(c, a, p->t); /* -dYT, with EDWARDS_D = d-1 */ - gf_mul(a, p->x, p->z); - gf_sub(d, c, a); /* aXZ-dYT with a=-1 */ - gf_add(a, p->z, p->y); - gf_sub(b, p->z, p->y); - gf_mul(c, b, a); - gf_mulw(b, c, -EDWARDS_D); /* (a-d)(Z+Y)(Z-Y) */ - mask_t ok = gf_isr (a,b); /* r in the paper */ - (void)ok; assert(ok | gf_eq(b,ZERO)); - gf_mulw (b, a, -EDWARDS_D); /* u in the paper */ - - gf_mul(c,a,d); /* r(aZX-dYT) */ - gf_mul(a,b,p->z); /* uZ */ - gf_add(a,a,a); /* 2uZ */ - - mask_t tg = toggle_hibit_t_over_s ^ ~gf_hibit(minus_t_over_s); - gf_cond_neg(minus_t_over_s, tg); /* t/s <-? -t/s */ - gf_cond_neg(c, tg); /* u <- -u if negative. */ - - gf_add(d,c,p->y); - gf_mul(s,b,d); - gf_cond_neg(s, toggle_hibit_s ^ gf_hibit(s)); -#else - /* More complicated because of rotation */ - /* MAGIC This code is wrong for certain non-Curve25519 curves; - * check if it's because of Cofactor==8 or IMAGINE_ROTATION */ - - gf c, d; - gf_s *b = s, *a = minus_t_over_s; - - #if IMAGINE_TWIST - gf x, t; - gf_div_qnr(x,p->x); - gf_div_qnr(t,p->t); - gf_add ( a, p->z, x ); - gf_sub ( b, p->z, x ); - gf_mul ( c, a, b ); /* "zx" = Z^2 - aX^2 = Z^2 - X^2 */ - #else - const gf_s *x = p->x, *t = p->t; - /* Won't hit the gf_cond_sel below because COFACTOR==8 requires IMAGINE_TWIST for now. */ - gf_sqr ( a, p->z ); - gf_sqr ( b, p->x ); - gf_add ( c, a, b ); /* "zx" = Z^2 - aX^2 = Z^2 + X^2 */ - #endif - - gf_mul ( a, p->z, t ); /* "tz" = T*Z */ - gf_sqr ( b, a ); - gf_mul ( d, b, c ); /* (TZ)^2 * (Z^2-aX^2) */ - mask_t ok = gf_isr(b, d); - (void)ok; assert(ok | gf_eq(d,ZERO)); - gf_mul ( d, b, a ); /* "osx" = 1 / sqrt(z^2-ax^2) */ - gf_mul ( a, b, c ); - gf_mul ( b, a, d ); /* 1/tz */ - - mask_t rotate; - #if (COFACTOR == 8) - gf e; - gf_sqr(e, p->z); - gf_mul(a, e, b); /* z^2 / tz = z/t = 1/xy */ - rotate = gf_hibit(a) ^ toggle_rotation; - /* Curve25519: cond select between zx * 1/tz or sqrt(1-d); y=-x */ - gf_mul ( a, b, c ); - gf_cond_sel ( a, a, SQRT_ONE_MINUS_D, rotate ); - gf_cond_sel ( x, p->y, x, rotate ); - #else - (void)toggle_rotation; - rotate = 0; - #endif - - gf_mul ( c, a, d ); // new "osx" - gf_mul ( a, c, p->z ); - gf_add ( minus_t_over_s, a, a ); // 2 * "osx" * Z - gf_mul ( d, b, p->z ); - - mask_t tg = toggle_hibit_t_over_s ^~ gf_hibit(minus_t_over_s); - gf_cond_neg ( minus_t_over_s, tg ); - gf_cond_neg ( c, rotate ^ tg ); - gf_add ( d, d, c ); - gf_mul ( s, d, x ); /* here "x" = y unless rotate */ - gf_cond_neg ( s, toggle_hibit_s ^ gf_hibit(s) ); -#endif -} - -void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { - gf s, mtos; - API_NS(deisogenize)(s,mtos,p,0,0,0); - gf_serialize(ser,s,0); -} - -decaf_error_t API_NS(point_decode) ( - point_t p, - const unsigned char ser[SER_BYTES], - decaf_bool_t allow_identity -) { - gf s, a, b, c, d, e, f; - mask_t succ = gf_deserialize(s, ser, 0); - mask_t zero = gf_eq(s, ZERO); - succ &= bool_to_mask(allow_identity) | ~zero; - gf_sqr ( a, s ); -#if IMAGINE_TWIST - gf_sub ( f, ONE, a ); /* f = 1-as^2 = 1-s^2*/ -#else - gf_add ( f, ONE, a ); /* f = 1-as^2 = 1+s^2 */ -#endif - succ &= ~ gf_eq( f, ZERO ); - gf_sqr ( b, f ); - gf_mulw ( c, a, 4*IMAGINE_TWIST-4*EDWARDS_D ); - gf_add ( c, c, b ); /* t^2 */ - gf_mul ( d, f, s ); /* s(1-as^2) for denoms */ - gf_sqr ( e, d ); - gf_mul ( b, c, e ); - - succ &= gf_isr(e,b) | gf_eq(b,ZERO); /* e = 1/(t s (1-as^2)) */ - gf_mul ( b, e, d ); /* 1/t */ - gf_mul ( d, e, c ); /* d = t / (s(1-as^2)) */ - gf_mul ( e, d, f ); /* t/s */ - mask_t negtos = gf_hibit(e); - gf_cond_neg(b, negtos); - gf_cond_neg(d, negtos); - -#if IMAGINE_TWIST - gf_add ( p->z, ONE, a); /* Z = 1+as^2 = 1-s^2 */ -#else - gf_sub ( p->z, ONE, a); /* Z = 1+as^2 = 1-s^2 */ -#endif - -#if COFACTOR == 8 - gf_mul ( a, p->z, d); /* t(1+s^2) / s(1-s^2) = 2/xy */ - succ &= ~gf_lobit(a); /* = ~gf_hibit(a/2), since gf_hibit(x) = gf_lobit(2x) */ -#endif - - gf_mul ( a, f, b ); /* y = (1-s^2) / t */ - gf_mul ( p->y, p->z, a ); /* Y = yZ */ -#if IMAGINE_TWIST - gf_add ( b, s, s ); - gf_mul(p->x, b, SQRT_MINUS_ONE); /* Curve25519 */ -#else - gf_add ( p->x, s, s ); -#endif - gf_mul ( p->t, p->x, a ); /* T = 2s (1-as^2)/t */ - - p->y->limb[0] -= zero; - - assert(API_NS(point_valid)(p) | ~succ); - - return decaf_succeed_if(mask_to_bool(succ)); -} - -#if IMAGINE_TWIST -#define TWISTED_D (-(EDWARDS_D)) -#else -#define TWISTED_D ((EDWARDS_D)-1) -#endif - -#if TWISTED_D < 0 -#define EFF_D (-(TWISTED_D)) -#define NEG_D 1 -#else -#define EFF_D TWISTED_D -#define NEG_D 0 -#endif - -void API_NS(point_sub) ( - point_t p, - const point_t q, - const point_t r -) { - gf a, b, c, d; - gf_sub_nr ( b, q->y, q->x ); /* 3+e */ - gf_sub_nr ( d, r->y, r->x ); /* 3+e */ - gf_add_nr ( c, r->y, r->x ); /* 2+e */ - gf_mul ( a, c, b ); - gf_add_nr ( b, q->y, q->x ); /* 2+e */ - gf_mul ( p->y, d, b ); - gf_mul ( b, r->t, q->t ); - gf_mulw ( p->x, b, 2*EFF_D ); - gf_add_nr ( b, a, p->y ); /* 2+e */ - gf_sub_nr ( c, p->y, a ); /* 3+e */ - gf_mul ( a, q->z, r->z ); - gf_add_nr ( a, a, a ); /* 2+e */ - if (GF_HEADROOM <= 3) gf_weak_reduce(a); /* or 1+e */ -#if NEG_D - gf_sub_nr ( p->y, a, p->x ); /* 4+e or 3+e */ - gf_add_nr ( a, a, p->x ); /* 3+e or 2+e */ -#else - gf_add_nr ( p->y, a, p->x ); /* 3+e or 2+e */ - gf_sub_nr ( a, a, p->x ); /* 4+e or 3+e */ -#endif - gf_mul ( p->z, a, p->y ); - gf_mul ( p->x, p->y, c ); - gf_mul ( p->y, a, b ); - gf_mul ( p->t, b, c ); -} - -void API_NS(point_add) ( - point_t p, - const point_t q, - const point_t r -) { - gf a, b, c, d; - gf_sub_nr ( b, q->y, q->x ); /* 3+e */ - gf_sub_nr ( c, r->y, r->x ); /* 3+e */ - gf_add_nr ( d, r->y, r->x ); /* 2+e */ - gf_mul ( a, c, b ); - gf_add_nr ( b, q->y, q->x ); /* 2+e */ - gf_mul ( p->y, d, b ); - gf_mul ( b, r->t, q->t ); - gf_mulw ( p->x, b, 2*EFF_D ); - gf_add_nr ( b, a, p->y ); /* 2+e */ - gf_sub_nr ( c, p->y, a ); /* 3+e */ - gf_mul ( a, q->z, r->z ); - gf_add_nr ( a, a, a ); /* 2+e */ - if (GF_HEADROOM <= 3) gf_weak_reduce(a); /* or 1+e */ -#if NEG_D - gf_add_nr ( p->y, a, p->x ); /* 3+e or 2+e */ - gf_sub_nr ( a, a, p->x ); /* 4+e or 3+e */ -#else - gf_sub_nr ( p->y, a, p->x ); /* 4+e or 3+e */ - gf_add_nr ( a, a, p->x ); /* 3+e or 2+e */ -#endif - gf_mul ( p->z, a, p->y ); - gf_mul ( p->x, p->y, c ); - gf_mul ( p->y, a, b ); - gf_mul ( p->t, b, c ); -} - -static NOINLINE void -point_double_internal ( - point_t p, - const point_t q, - int before_double -) { - gf a, b, c, d; - gf_sqr ( c, q->x ); - gf_sqr ( a, q->y ); - gf_add_nr ( d, c, a ); /* 2+e */ - gf_add_nr ( p->t, q->y, q->x ); /* 2+e */ - gf_sqr ( b, p->t ); - gf_subx_nr ( b, b, d, 3 ); /* 4+e */ - gf_sub_nr ( p->t, a, c ); /* 3+e */ - gf_sqr ( p->x, q->z ); - gf_add_nr ( p->z, p->x, p->x ); /* 2+e */ - gf_subx_nr ( a, p->z, p->t, 4 ); /* 6+e */ - if (GF_HEADROOM == 5) gf_weak_reduce(a); /* or 1+e */ - gf_mul ( p->x, a, b ); - gf_mul ( p->z, p->t, a ); - gf_mul ( p->y, p->t, d ); - if (!before_double) gf_mul ( p->t, b, d ); -} - -void API_NS(point_double)(point_t p, const point_t q) { - point_double_internal(p,q,0); -} - -void API_NS(point_negate) ( - point_t nega, - const point_t a -) { - gf_sub(nega->x, ZERO, a->x); - gf_copy(nega->y, a->y); - gf_copy(nega->z, a->z); - gf_sub(nega->t, ZERO, a->t); -} - -/* Operations on [p]niels */ -static INLINE void -cond_neg_niels ( - niels_t n, - mask_t neg -) { - gf_cond_swap(n->a, n->b, neg); - gf_cond_neg(n->c, neg); -} - -static NOINLINE void pt_to_pniels ( - pniels_t b, - const point_t a -) { - gf_sub ( b->n->a, a->y, a->x ); - gf_add ( b->n->b, a->x, a->y ); - gf_mulw ( b->n->c, a->t, 2*TWISTED_D ); - gf_add ( b->z, a->z, a->z ); -} - -static NOINLINE void pniels_to_pt ( - point_t e, - const pniels_t d -) { - gf eu; - gf_add ( eu, d->n->b, d->n->a ); - gf_sub ( e->y, d->n->b, d->n->a ); - gf_mul ( e->t, e->y, eu); - gf_mul ( e->x, d->z, e->y ); - gf_mul ( e->y, d->z, eu ); - gf_sqr ( e->z, d->z ); -} - -static NOINLINE void -niels_to_pt ( - point_t e, - const niels_t n -) { - gf_add ( e->y, n->b, n->a ); - gf_sub ( e->x, n->b, n->a ); - gf_mul ( e->t, e->y, e->x ); - gf_copy ( e->z, ONE ); -} - -static NOINLINE void -add_niels_to_pt ( - point_t d, - const niels_t e, - int before_double -) { - gf a, b, c; - gf_sub_nr ( b, d->y, d->x ); /* 3+e */ - gf_mul ( a, e->a, b ); - gf_add_nr ( b, d->x, d->y ); /* 2+e */ - gf_mul ( d->y, e->b, b ); - gf_mul ( d->x, e->c, d->t ); - gf_add_nr ( c, a, d->y ); /* 2+e */ - gf_sub_nr ( b, d->y, a ); /* 3+e */ - gf_sub_nr ( d->y, d->z, d->x ); /* 3+e */ - gf_add_nr ( a, d->x, d->z ); /* 2+e */ - gf_mul ( d->z, a, d->y ); - gf_mul ( d->x, d->y, b ); - gf_mul ( d->y, a, c ); - if (!before_double) gf_mul ( d->t, b, c ); -} - -static NOINLINE void -sub_niels_from_pt ( - point_t d, - const niels_t e, - int before_double -) { - gf a, b, c; - gf_sub_nr ( b, d->y, d->x ); /* 3+e */ - gf_mul ( a, e->b, b ); - gf_add_nr ( b, d->x, d->y ); /* 2+e */ - gf_mul ( d->y, e->a, b ); - gf_mul ( d->x, e->c, d->t ); - gf_add_nr ( c, a, d->y ); /* 2+e */ - gf_sub_nr ( b, d->y, a ); /* 3+e */ - gf_add_nr ( d->y, d->z, d->x ); /* 2+e */ - gf_sub_nr ( a, d->z, d->x ); /* 3+e */ - gf_mul ( d->z, a, d->y ); - gf_mul ( d->x, d->y, b ); - gf_mul ( d->y, a, c ); - if (!before_double) gf_mul ( d->t, b, c ); -} - -static void -add_pniels_to_pt ( - point_t p, - const pniels_t pn, - int before_double -) { - gf L0; - gf_mul ( L0, p->z, pn->z ); - gf_copy ( p->z, L0 ); - add_niels_to_pt( p, pn->n, before_double ); -} - -static void -sub_pniels_from_pt ( - point_t p, - const pniels_t pn, - int before_double -) { - gf L0; - gf_mul ( L0, p->z, pn->z ); - gf_copy ( p->z, L0 ); - sub_niels_from_pt( p, pn->n, before_double ); -} - -static NOINLINE void -prepare_fixed_window( - pniels_t *multiples, - const point_t b, - int ntable -) { - point_t tmp; - pniels_t pn; - int i; - - point_double_internal(tmp, b, 0); - pt_to_pniels(pn, tmp); - pt_to_pniels(multiples[0], b); - API_NS(point_copy)(tmp, b); - for (i=1; i> 1, - NTABLE = 1<<(WINDOW-1); - - scalar_t scalar1x; - API_NS(scalar_add)(scalar1x, scalar, point_scalarmul_adjustment); - API_NS(scalar_halve)(scalar1x,scalar1x); - - /* Set up a precomputed table with odd multiples of b. */ - pniels_t pn, multiples[NTABLE]; - point_t tmp; - prepare_fixed_window(multiples, b, NTABLE); - - /* Initialize. */ - int i,j,first=1; - i = SCALAR_BITS - ((SCALAR_BITS-1) % WINDOW) - 1; - - for (; i>=0; i-=WINDOW) { - /* Fetch another block of bits */ - word_t bits = scalar1x->limb[i/WBITS] >> (i%WBITS); - if (i%WBITS >= WBITS-WINDOW && i/WBITSlimb[i/WBITS+1] << (WBITS - (i%WBITS)); - } - bits &= WINDOW_MASK; - mask_t inv = (bits>>(WINDOW-1))-1; - bits ^= inv; - - /* Add in from table. Compute t only on last iteration. */ - constant_time_lookup(pn, multiples, sizeof(pn), NTABLE, bits & WINDOW_T_MASK); - cond_neg_niels(pn->n, inv); - if (first) { - pniels_to_pt(tmp, pn); - first = 0; - } else { - /* Using Hisil et al's lookahead method instead of extensible here - * for no particular reason. Double WINDOW times, but only compute t on - * the last one. - */ - for (j=0; j> 1, - NTABLE = 1<<(WINDOW-1); - - scalar_t scalar1x, scalar2x; - API_NS(scalar_add)(scalar1x, scalarb, point_scalarmul_adjustment); - API_NS(scalar_halve)(scalar1x,scalar1x); - API_NS(scalar_add)(scalar2x, scalarc, point_scalarmul_adjustment); - API_NS(scalar_halve)(scalar2x,scalar2x); - - /* Set up a precomputed table with odd multiples of b. */ - pniels_t pn, multiples1[NTABLE], multiples2[NTABLE]; - point_t tmp; - prepare_fixed_window(multiples1, b, NTABLE); - prepare_fixed_window(multiples2, c, NTABLE); - - /* Initialize. */ - int i,j,first=1; - i = SCALAR_BITS - ((SCALAR_BITS-1) % WINDOW) - 1; - - for (; i>=0; i-=WINDOW) { - /* Fetch another block of bits */ - word_t bits1 = scalar1x->limb[i/WBITS] >> (i%WBITS), - bits2 = scalar2x->limb[i/WBITS] >> (i%WBITS); - if (i%WBITS >= WBITS-WINDOW && i/WBITSlimb[i/WBITS+1] << (WBITS - (i%WBITS)); - bits2 ^= scalar2x->limb[i/WBITS+1] << (WBITS - (i%WBITS)); - } - bits1 &= WINDOW_MASK; - bits2 &= WINDOW_MASK; - mask_t inv1 = (bits1>>(WINDOW-1))-1; - mask_t inv2 = (bits2>>(WINDOW-1))-1; - bits1 ^= inv1; - bits2 ^= inv2; - - /* Add in from table. Compute t only on last iteration. */ - constant_time_lookup(pn, multiples1, sizeof(pn), NTABLE, bits1 & WINDOW_T_MASK); - cond_neg_niels(pn->n, inv1); - if (first) { - pniels_to_pt(tmp, pn); - first = 0; - } else { - /* Using Hisil et al's lookahead method instead of extensible here - * for no particular reason. Double WINDOW times, but only compute t on - * the last one. - */ - for (j=0; jn, inv2); - add_pniels_to_pt(tmp, pn, i?-1:0); - } - - /* Write out the answer */ - API_NS(point_copy)(a,tmp); - - - decaf_bzero(scalar1x,sizeof(scalar1x)); - decaf_bzero(scalar2x,sizeof(scalar2x)); - decaf_bzero(pn,sizeof(pn)); - decaf_bzero(multiples1,sizeof(multiples1)); - decaf_bzero(multiples2,sizeof(multiples2)); - decaf_bzero(tmp,sizeof(tmp)); -} - -void API_NS(point_dual_scalarmul) ( - point_t a1, - point_t a2, - const point_t b, - const scalar_t scalar1, - const scalar_t scalar2 -) { - const int WINDOW = DECAF_WINDOW_BITS, - WINDOW_MASK = (1<> 1, - NTABLE = 1<<(WINDOW-1); - - scalar_t scalar1x, scalar2x; - API_NS(scalar_add)(scalar1x, scalar1, point_scalarmul_adjustment); - API_NS(scalar_halve)(scalar1x,scalar1x); - API_NS(scalar_add)(scalar2x, scalar2, point_scalarmul_adjustment); - API_NS(scalar_halve)(scalar2x,scalar2x); - - /* Set up a precomputed table with odd multiples of b. */ - point_t multiples1[NTABLE], multiples2[NTABLE], working, tmp; - pniels_t pn; - - API_NS(point_copy)(working, b); - - /* Initialize. */ - int i,j; - - for (i=0; ilimb[i/WBITS] >> (i%WBITS), - bits2 = scalar2x->limb[i/WBITS] >> (i%WBITS); - if (i%WBITS >= WBITS-WINDOW && i/WBITSlimb[i/WBITS+1] << (WBITS - (i%WBITS)); - bits2 ^= scalar2x->limb[i/WBITS+1] << (WBITS - (i%WBITS)); - } - bits1 &= WINDOW_MASK; - bits2 &= WINDOW_MASK; - mask_t inv1 = (bits1>>(WINDOW-1))-1; - mask_t inv2 = (bits2>>(WINDOW-1))-1; - bits1 ^= inv1; - bits2 ^= inv2; - - pt_to_pniels(pn, working); - - constant_time_lookup(tmp, multiples1, sizeof(tmp), NTABLE, bits1 & WINDOW_T_MASK); - cond_neg_niels(pn->n, inv1); - /* add_pniels_to_pt(multiples1[bits1 & WINDOW_T_MASK], pn, 0); */ - add_pniels_to_pt(tmp, pn, 0); - constant_time_insert(multiples1, tmp, sizeof(tmp), NTABLE, bits1 & WINDOW_T_MASK); - - - constant_time_lookup(tmp, multiples2, sizeof(tmp), NTABLE, bits2 & WINDOW_T_MASK); - cond_neg_niels(pn->n, inv1^inv2); - /* add_pniels_to_pt(multiples2[bits2 & WINDOW_T_MASK], pn, 0); */ - add_pniels_to_pt(tmp, pn, 0); - constant_time_insert(multiples2, tmp, sizeof(tmp), NTABLE, bits2 & WINDOW_T_MASK); - } - - if (NTABLE > 1) { - API_NS(point_copy)(working, multiples1[NTABLE-1]); - API_NS(point_copy)(tmp , multiples2[NTABLE-1]); - - for (i=NTABLE-1; i>1; i--) { - API_NS(point_add)(multiples1[i-1], multiples1[i-1], multiples1[i]); - API_NS(point_add)(multiples2[i-1], multiples2[i-1], multiples2[i]); - API_NS(point_add)(working, working, multiples1[i-1]); - API_NS(point_add)(tmp, tmp, multiples2[i-1]); - } - - API_NS(point_add)(multiples1[0], multiples1[0], multiples1[1]); - API_NS(point_add)(multiples2[0], multiples2[0], multiples2[1]); - point_double_internal(working, working, 0); - point_double_internal(tmp, tmp, 0); - API_NS(point_add)(a1, working, multiples1[0]); - API_NS(point_add)(a2, tmp, multiples2[0]); - } else { - API_NS(point_copy)(a1, multiples1[0]); - API_NS(point_copy)(a2, multiples2[0]); - } - - decaf_bzero(scalar1x,sizeof(scalar1x)); - decaf_bzero(scalar2x,sizeof(scalar2x)); - decaf_bzero(pn,sizeof(pn)); - decaf_bzero(multiples1,sizeof(multiples1)); - decaf_bzero(multiples2,sizeof(multiples2)); - decaf_bzero(tmp,sizeof(tmp)); - decaf_bzero(working,sizeof(working)); -} - -decaf_bool_t API_NS(point_eq) ( const point_t p, const point_t q ) { - /* equality mod 2-torsion compares x/y */ - gf a, b; - gf_mul ( a, p->y, q->x ); - gf_mul ( b, q->y, p->x ); - mask_t succ = gf_eq(a,b); - - #if (COFACTOR == 8) && IMAGINE_TWIST - gf_mul ( a, p->y, q->y ); - gf_mul ( b, q->x, p->x ); - #if !(IMAGINE_TWIST) - gf_sub ( a, ZERO, a ); - #else - /* Interesting note: the 4tor would normally be rotation. - * But because of the *i twist, it's actually - * (x,y) <-> (iy,ix) - */ - - /* No code, just a comment. */ - #endif - succ |= gf_eq(a,b); - #endif - - return mask_to_bool(succ); -} - -decaf_bool_t API_NS(point_valid) ( - const point_t p -) { - gf a,b,c; - gf_mul(a,p->x,p->y); - gf_mul(b,p->z,p->t); - mask_t out = gf_eq(a,b); - gf_sqr(a,p->x); - gf_sqr(b,p->y); - gf_sub(a,b,a); - gf_sqr(b,p->t); - gf_mulw(c,b,TWISTED_D); - gf_sqr(b,p->z); - gf_add(b,b,c); - out &= gf_eq(a,b); - out &= ~gf_eq(p->z,ZERO); - return mask_to_bool(out); -} - -void API_NS(point_debugging_torque) ( - point_t q, - const point_t p -) { -#if COFACTOR == 8 - gf tmp; - gf_mul(tmp,p->x,SQRT_MINUS_ONE); - gf_mul(q->x,p->y,SQRT_MINUS_ONE); - gf_copy(q->y,tmp); - gf_copy(q->z,p->z); - gf_sub(q->t,ZERO,p->t); -#else - gf_sub(q->x,ZERO,p->x); - gf_sub(q->y,ZERO,p->y); - gf_copy(q->z,p->z); - gf_copy(q->t,p->t); -#endif -} - -void API_NS(point_debugging_pscale) ( - point_t q, - const point_t p, - const uint8_t factor[SER_BYTES] -) { - gf gfac,tmp; - /* NB this means you'll never pscale by negative numbers for p521 */ - ignore_result(gf_deserialize(gfac,factor,0)); - gf_cond_sel(gfac,gfac,ONE,gf_eq(gfac,ZERO)); - gf_mul(tmp,p->x,gfac); - gf_copy(q->x,tmp); - gf_mul(tmp,p->y,gfac); - gf_copy(q->y,tmp); - gf_mul(tmp,p->z,gfac); - gf_copy(q->z,tmp); - gf_mul(tmp,p->t,gfac); - gf_copy(q->t,tmp); -} - -static void gf_batch_invert ( - gf *__restrict__ out, - const gf *in, - unsigned int n -) { - gf t1; - assert(n>1); - - gf_copy(out[1], in[0]); - int i; - for (i=1; i<(int) (n-1); i++) { - gf_mul(out[i+1], out[i], in[i]); - } - gf_mul(out[0], out[n-1], in[n-1]); - - gf_invert(out[0], out[0]); - - for (i=n-1; i>0; i--) { - gf_mul(t1, out[i], out[0]); - gf_copy(out[i], t1); - gf_mul(t1, out[0], in[i]); - gf_copy(out[0], t1); - } -} - -static void batch_normalize_niels ( - niels_t *table, - const gf *zs, - gf *__restrict__ zis, - int n -) { - int i; - gf product; - gf_batch_invert(zis, zs, n); - - for (i=0; ia, zis[i]); - gf_strong_reduce(product); - gf_copy(table[i]->a, product); - - gf_mul(product, table[i]->b, zis[i]); - gf_strong_reduce(product); - gf_copy(table[i]->b, product); - - gf_mul(product, table[i]->c, zis[i]); - gf_strong_reduce(product); - gf_copy(table[i]->c, product); - } - - decaf_bzero(product,sizeof(product)); -} - -void API_NS(precompute) ( - precomputed_s *table, - const point_t base -) { - const unsigned int n = COMBS_N, t = COMBS_T, s = COMBS_S; - assert(n*t*s >= SCALAR_BITS); - - point_t working, start, doubles[t-1]; - API_NS(point_copy)(working, base); - pniels_t pn_tmp; - - gf zs[n<<(t-1)], zis[n<<(t-1)]; - - unsigned int i,j,k; - - /* Compute n tables */ - for (i=0; i>1); - int idx = (((i+1)<<(t-1))-1) ^ gray; - - pt_to_pniels(pn_tmp, start); - memcpy(table->table[idx], pn_tmp->n, sizeof(pn_tmp->n)); - gf_copy(zs[idx], pn_tmp->z); - - if (j >= (1u<<(t-1)) - 1) break; - int delta = (j+1) ^ ((j+1)>>1) ^ gray; - - for (k=0; delta>1; k++) - delta >>=1; - - if (gray & (1<table,(const gf *)zs,zis,n<<(t-1)); - - decaf_bzero(zs,sizeof(zs)); - decaf_bzero(zis,sizeof(zis)); - decaf_bzero(pn_tmp,sizeof(pn_tmp)); - decaf_bzero(working,sizeof(working)); - decaf_bzero(start,sizeof(start)); - decaf_bzero(doubles,sizeof(doubles)); -} - -static INLINE void -constant_time_lookup_niels ( - niels_s *__restrict__ ni, - const niels_t *table, - int nelts, - int idx -) { - constant_time_lookup(ni, table, sizeof(niels_s), nelts, idx); -} - -void API_NS(precomputed_scalarmul) ( - point_t out, - const precomputed_s *table, - const scalar_t scalar -) { - int i; - unsigned j,k; - const unsigned int n = COMBS_N, t = COMBS_T, s = COMBS_S; - - scalar_t scalar1x; - API_NS(scalar_add)(scalar1x, scalar, precomputed_scalarmul_adjustment); - API_NS(scalar_halve)(scalar1x,scalar1x); - - niels_t ni; - - for (i=s-1; i>=0; i--) { - if (i != (int)s-1) point_double_internal(out,out,0); - - for (j=0; jlimb[bit/WBITS] >> (bit%WBITS) & 1) << k; - } - } - - mask_t invert = (tab>>(t-1))-1; - tab ^= invert; - tab &= (1<<(t-1)) - 1; - - constant_time_lookup_niels(ni, &table->table[j<<(t-1)], 1<<(t-1), tab); - - cond_neg_niels(ni, invert); - if ((i!=(int)s-1)||j) { - add_niels_to_pt(out, ni, j==n-1 && i); - } else { - niels_to_pt(out, ni); - } - } - } - - decaf_bzero(ni,sizeof(ni)); - decaf_bzero(scalar1x,sizeof(scalar1x)); -} - -void API_NS(point_cond_sel) ( - point_t out, - const point_t a, - const point_t b, - decaf_bool_t pick_b -) { - constant_time_select(out,a,b,sizeof(point_t),bool_to_mask(pick_b),0); -} - -/* FUTURE: restore Curve25519 Montgomery ladder? */ -decaf_error_t API_NS(direct_scalarmul) ( - uint8_t scaled[SER_BYTES], - const uint8_t base[SER_BYTES], - const scalar_t scalar, - decaf_bool_t allow_identity, - decaf_bool_t short_circuit -) { - point_t basep; - decaf_error_t succ = API_NS(point_decode)(basep, base, allow_identity); - if (short_circuit && succ != DECAF_SUCCESS) return succ; - API_NS(point_cond_sel)(basep, API_NS(point_base), basep, succ); - API_NS(point_scalarmul)(basep, basep, scalar); - API_NS(point_encode)(scaled, basep); - API_NS(point_destroy)(basep); - return succ; -} - -void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) ( - uint8_t enc[DECAF_EDDSA_448_PUBLIC_BYTES], - const point_t p -) { - - /* The point is now on the twisted curve. Move it to untwisted. */ - gf x, y, z, t; - point_t q; -#if COFACTOR == 8 - API_NS(point_double)(q,p); -#else - API_NS(point_copy)(q,p); -#endif - -#if EDDSA_USE_SIGMA_ISOGENY - { - /* Use 4-isogeny like ed25519: - * 2*x*y*sqrt(d/a-1)/(ax^2 + y^2 - 2) - * (y^2 - ax^2)/(y^2 + ax^2) - * with a = -1, d = -EDWARDS_D: - * -2xysqrt(EDWARDS_D-1)/(2z^2-y^2+x^2) - * (y^2+x^2)/(y^2-x^2) - */ - gf u; - gf_sqr ( x, q->x ); // x^2 - gf_sqr ( t, q->y ); // y^2 - gf_add( u, x, t ); // x^2 + y^2 - gf_add( z, q->y, q->x ); - gf_sqr ( y, z); - gf_sub ( y, u, y ); // -2xy - gf_sub ( z, t, x ); // y^2 - x^2 - gf_sqr ( x, q->z ); - gf_add ( t, x, x); - gf_sub ( t, t, z); // 2z^2 - y^2 + x^2 - gf_mul ( x, y, z ); // 2xy(y^2-x^2) - gf_mul ( y, u, t ); // (x^2+y^2)(2z^2-y^2+x^2) - gf_mul ( u, z, t ); - gf_copy( z, u ); - gf_mul ( u, x, SQRT_ONE_MINUS_D ); - gf_copy( x, u ); - decaf_bzero(u,sizeof(u)); - } -#elif IMAGINE_TWIST - { - API_NS(point_double)(q,q); - API_NS(point_double)(q,q); - gf_mul_qnr(x, q->x); - gf_copy(y, q->y); - gf_copy(z, q->z); - } -#else - { - /* 4-isogeny: 2xy/(y^+x^2), (y^2-x^2)/(2z^2-y^2+x^2) */ - gf u; - gf_sqr ( x, q->x ); - gf_sqr ( t, q->y ); - gf_add( u, x, t ); - gf_add( z, q->y, q->x ); - gf_sqr ( y, z); - gf_sub ( y, u, y ); - gf_sub ( z, t, x ); - gf_sqr ( x, q->z ); - gf_add ( t, x, x); - gf_sub ( t, t, z); - gf_mul ( x, t, y ); - gf_mul ( y, z, u ); - gf_mul ( z, u, t ); - decaf_bzero(u,sizeof(u)); - } -#endif - /* Affinize */ - gf_invert(z,z); - gf_mul(t,x,z); - gf_mul(x,y,z); - - /* Encode */ - enc[DECAF_EDDSA_448_PRIVATE_BYTES-1] = 0; - gf_serialize(enc, x, 1); - enc[DECAF_EDDSA_448_PRIVATE_BYTES-1] |= 0x80 & gf_lobit(t); - - decaf_bzero(x,sizeof(x)); - decaf_bzero(y,sizeof(y)); - decaf_bzero(z,sizeof(z)); - decaf_bzero(t,sizeof(t)); - API_NS(point_destroy)(q); -} - - -decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) ( - point_t p, - const uint8_t enc[DECAF_EDDSA_448_PUBLIC_BYTES] -) { - uint8_t enc2[DECAF_EDDSA_448_PUBLIC_BYTES]; - memcpy(enc2,enc,sizeof(enc2)); - - mask_t low = ~word_is_zero(enc2[DECAF_EDDSA_448_PRIVATE_BYTES-1] & 0x80); - enc2[DECAF_EDDSA_448_PRIVATE_BYTES-1] &= ~0x80; - - mask_t succ = DECAF_TRUE; -#if 0 == 0 - succ = word_is_zero(enc2[DECAF_EDDSA_448_PRIVATE_BYTES-1]); -#endif - - succ &= gf_deserialize(p->y, enc2, 1); - - gf_sqr(p->x,p->y); - gf_sub(p->z,ONE,p->x); /* num = 1-y^2 */ - #if EDDSA_USE_SIGMA_ISOGENY - gf_mulw(p->t,p->z,EDWARDS_D); /* d-dy^2 */ - gf_mulw(p->x,p->z,EDWARDS_D-1); /* num = (1-y^2)(d-1) */ - gf_copy(p->z,p->x); - #else - gf_mulw(p->t,p->x,EDWARDS_D); /* dy^2 */ - #endif - gf_sub(p->t,ONE,p->t); /* denom = 1-dy^2 or 1-d + dy^2 */ - - gf_mul(p->x,p->z,p->t); - succ &= gf_isr(p->t,p->x); /* 1/sqrt(num * denom) */ - - gf_mul(p->x,p->t,p->z); /* sqrt(num / denom) */ - gf_cond_neg(p->x,~gf_lobit(p->x)^low); - gf_copy(p->z,ONE); - - #if EDDSA_USE_SIGMA_ISOGENY - { - /* Use 4-isogeny like ed25519: - * 2*x*y/sqrt(1-d/a)/(ax^2 + y^2 - 2) - * (y^2 - ax^2)/(y^2 + ax^2) - * (MAGIC: above formula may be off by a factor of -a - * or something somewhere; check it for other a) - * - * with a = -1, d = -EDWARDS_D: - * -2xy/sqrt(1-EDWARDS_D)/(2z^2-y^2+x^2) - * (y^2+x^2)/(y^2-x^2) - */ - gf a, b, c, d; - gf_sqr ( c, p->x ); - gf_sqr ( a, p->y ); - gf_add ( d, c, a ); // x^2 + y^2 - gf_add ( p->t, p->y, p->x ); - gf_sqr ( b, p->t ); - gf_sub ( b, b, d ); // 2xy - gf_sub ( p->t, a, c ); // y^2 - x^2 - gf_sqr ( p->x, p->z ); - gf_add ( p->z, p->x, p->x ); - gf_sub ( a, p->z, p->t ); // 2z^2 - y^2 + x^2 - gf_mul ( c, a, SQRT_ONE_MINUS_D ); - gf_mul ( p->x, b, p->t); // (2xy)(y^2-x^2) - gf_mul ( p->z, p->t, c ); // (y^2-x^2)sd(2z^2 - y^2 + x^2) - gf_mul ( p->y, d, c ); // (y^2+x^2)sd(2z^2 - y^2 + x^2) - gf_mul ( p->t, d, b ); - decaf_bzero(a,sizeof(a)); - decaf_bzero(b,sizeof(b)); - decaf_bzero(c,sizeof(c)); - decaf_bzero(d,sizeof(d)); - } - #elif IMAGINE_TWIST - { - gf_mul(p->t,p->x,SQRT_MINUS_ONE); - gf_copy(p->x,p->t); - gf_mul(p->t,p->x,p->y); - } - #else - { - /* 4-isogeny 2xy/(y^2-ax^2), (y^2+ax^2)/(2-y^2-ax^2) */ - gf a, b, c, d; - gf_sqr ( c, p->x ); - gf_sqr ( a, p->y ); - gf_add ( d, c, a ); - gf_add ( p->t, p->y, p->x ); - gf_sqr ( b, p->t ); - gf_sub ( b, b, d ); - gf_sub ( p->t, a, c ); - gf_sqr ( p->x, p->z ); - gf_add ( p->z, p->x, p->x ); - gf_sub ( a, p->z, d ); - gf_mul ( p->x, a, b ); - gf_mul ( p->z, p->t, a ); - gf_mul ( p->y, p->t, d ); - gf_mul ( p->t, b, d ); - decaf_bzero(a,sizeof(a)); - decaf_bzero(b,sizeof(b)); - decaf_bzero(c,sizeof(c)); - decaf_bzero(d,sizeof(d)); - } - #endif - - decaf_bzero(enc2,sizeof(enc2)); - assert(API_NS(point_valid)(p) || ~succ); - return decaf_succeed_if(succ); -} - -decaf_error_t decaf_x448 ( - uint8_t out[X_PUBLIC_BYTES], - const uint8_t base[X_PUBLIC_BYTES], - const uint8_t scalar[X_PRIVATE_BYTES] -) { - gf x1, x2, z2, x3, z3, t1, t2; - ignore_result(gf_deserialize(x1,base,1)); - gf_copy(x2,ONE); - gf_copy(z2,ZERO); - gf_copy(x3,x1); - gf_copy(z3,ONE); - - int t; - mask_t swap = 0; - - for (t = X_PRIVATE_BITS-1; t>=0; t--) { - uint8_t sb = scalar[t/8]; - - /* Scalar conditioning */ - if (t/8==0) sb &= -(uint8_t)COFACTOR; - else if (t == X_PRIVATE_BITS-1) sb = -1; - - mask_t k_t = (sb>>(t%8)) & 1; - k_t = -k_t; /* set to all 0s or all 1s */ - - swap ^= k_t; - gf_cond_swap(x2,x3,swap); - gf_cond_swap(z2,z3,swap); - swap = k_t; - - gf_add_nr(t1,x2,z2); /* A = x2 + z2 */ /* 2+e */ - gf_sub_nr(t2,x2,z2); /* B = x2 - z2 */ /* 3+e */ - gf_sub_nr(z2,x3,z3); /* D = x3 - z3 */ /* 3+e */ - gf_mul(x2,t1,z2); /* DA */ - gf_add_nr(z2,z3,x3); /* C = x3 + z3 */ /* 2+e */ - gf_mul(x3,t2,z2); /* CB */ - gf_sub_nr(z3,x2,x3); /* DA-CB */ /* 3+e */ - gf_sqr(z2,z3); /* (DA-CB)^2 */ - gf_mul(z3,x1,z2); /* z3 = x1(DA-CB)^2 */ - gf_add_nr(z2,x2,x3); /* (DA+CB) */ /* 2+e */ - gf_sqr(x3,z2); /* x3 = (DA+CB)^2 */ - - gf_sqr(z2,t1); /* AA = A^2 */ - gf_sqr(t1,t2); /* BB = B^2 */ - gf_mul(x2,z2,t1); /* x2 = AA*BB */ - gf_sub_nr(t2,z2,t1); /* E = AA-BB */ /* 3+e */ - - gf_mulw(t1,t2,-EDWARDS_D); /* E*-d = a24*E */ - gf_add_nr(t1,t1,z2); /* AA + a24*E */ /* 2+e */ - gf_mul(z2,t2,t1); /* z2 = E(AA+a24*E) */ - } - - /* Finish */ - gf_cond_swap(x2,x3,swap); - gf_cond_swap(z2,z3,swap); - gf_invert(z2,z2); - gf_mul(x1,x2,z2); - gf_serialize(out,x1,1); - mask_t nz = ~gf_eq(x1,ZERO); - - decaf_bzero(x1,sizeof(x1)); - decaf_bzero(x2,sizeof(x2)); - decaf_bzero(z2,sizeof(z2)); - decaf_bzero(x3,sizeof(x3)); - decaf_bzero(z3,sizeof(z3)); - decaf_bzero(t1,sizeof(t1)); - decaf_bzero(t2,sizeof(t2)); - - return decaf_succeed_if(mask_to_bool(nz)); -} - -void decaf_x448_generate_key ( - uint8_t out[X_PUBLIC_BYTES], - const uint8_t scalar[X_PRIVATE_BYTES] -) { - /* Scalar conditioning */ - uint8_t scalar2[X_PRIVATE_BYTES]; - memcpy(scalar2,scalar,sizeof(scalar2)); - scalar2[0] &= -(uint8_t)COFACTOR; - - scalar2[X_PRIVATE_BYTES-1] &= ~(-1<<((X_PRIVATE_BITS+7)%8)); - scalar2[X_PRIVATE_BYTES-1] |= 1<<((X_PRIVATE_BITS+7)%8); - - scalar_t the_scalar; - API_NS(scalar_decode_long)(the_scalar,scalar2,sizeof(scalar2)); - - /* We're gonna isogenize by 2, so divide by 2. - * - * Why by 2, even though it's a 4-isogeny? - * - * The isogeny map looks like - * Montgomery <-2-> Jacobi <-2-> Edwards - * - * Since the Jacobi base point is the PREimage of the iso to - * the Montgomery curve, and we're going - * Jacobi -> Edwards -> Jacobi -> Montgomery, - * we pick up only a factor of 2 over Jacobi -> Montgomery. - */ - API_NS(scalar_halve)(the_scalar,the_scalar); - point_t p; - API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),the_scalar); - - /* Isogenize to Montgomery curve */ - gf_invert(p->t,p->x); /* 1/x */ - gf_mul(p->z,p->t,p->y); /* y/x */ - gf_sqr(p->y,p->z); /* (y/x)^2 */ -#if IMAGINE_TWIST - gf_sub(p->y,ZERO,p->y); -#endif - gf_serialize(out,p->y,1); - - decaf_bzero(scalar2,sizeof(scalar2)); - API_NS(scalar_destroy)(the_scalar); - API_NS(point_destroy)(p); -} - -/** - * @cond internal - * Control for variable-time scalar multiply algorithms. - */ -struct smvt_control { - int power, addend; -}; - -static int recode_wnaf ( - struct smvt_control *control, /* [nbits/(table_bits+1) + 3] */ - const scalar_t scalar, - unsigned int table_bits -) { - unsigned int table_size = SCALAR_BITS/(table_bits+1) + 3; - int position = table_size - 1; /* at the end */ - - /* place the end marker */ - control[position].power = -1; - control[position].addend = 0; - position--; - - /* PERF: Could negate scalar if it's large. But then would need more cases - * in the actual code that uses it, all for an expected reduction of like 1/5 op. - * Probably not worth it. - */ - - uint64_t current = scalar->limb[0] & 0xFFFF; - uint32_t mask = (1<<(table_bits+1))-1; - - unsigned int w; - const unsigned int B_OVER_16 = sizeof(scalar->limb[0]) / 2; - for (w = 1; w<(SCALAR_BITS-1)/16+3; w++) { - if (w < (SCALAR_BITS-1)/16+1) { - /* Refill the 16 high bits of current */ - current += (uint32_t)((scalar->limb[w/B_OVER_16]>>(16*(w%B_OVER_16)))<<16); - } - - while (current & 0xFFFF) { - assert(position >= 0); - uint32_t pos = __builtin_ctz((uint32_t)current), odd = (uint32_t)current >> pos; - int32_t delta = odd & mask; - if (odd & 1<<(table_bits+1)) delta -= (1<<(table_bits+1)); - current -= delta << pos; - control[position].power = pos + 16*(w-1); - control[position].addend = delta; - position--; - } - current >>= 16; - } - assert(current==0); - - position++; - unsigned int n = table_size - position; - unsigned int i; - for (i=0; in, sizeof(niels_t)); - gf_copy(zs[i], tmp[i]->z); - } - batch_normalize_niels(out, (const gf *)zs, zis, 1< control_pre[0].power) { - pniels_to_pt(combo, precmp_var[control_var[0].addend >> 1]); - contv++; - } else if (i == control_pre[0].power && i >=0 ) { - pniels_to_pt(combo, precmp_var[control_var[0].addend >> 1]); - add_niels_to_pt(combo, API_NS(wnaf_base)[control_pre[0].addend >> 1], i); - contv++; contp++; - } else { - i = control_pre[0].power; - niels_to_pt(combo, API_NS(wnaf_base)[control_pre[0].addend >> 1]); - contp++; - } - - for (i--; i >= 0; i--) { - int cv = (i==control_var[contv].power), cp = (i==control_pre[contp].power); - point_double_internal(combo,combo,i && !(cv||cp)); - - if (cv) { - assert(control_var[contv].addend); - - if (control_var[contv].addend > 0) { - add_pniels_to_pt(combo, precmp_var[control_var[contv].addend >> 1], i&&!cp); - } else { - sub_pniels_from_pt(combo, precmp_var[(-control_var[contv].addend) >> 1], i&&!cp); - } - contv++; - } - - if (cp) { - assert(control_pre[contp].addend); - - if (control_pre[contp].addend > 0) { - add_niels_to_pt(combo, API_NS(wnaf_base)[control_pre[contp].addend >> 1], i); - } else { - sub_niels_from_pt(combo, API_NS(wnaf_base)[(-control_pre[contp].addend) >> 1], i); - } - contp++; - } - } - - /* This function is non-secret, but whatever this is cheap. */ - decaf_bzero(control_var,sizeof(control_var)); - decaf_bzero(control_pre,sizeof(control_pre)); - decaf_bzero(precmp_var,sizeof(precmp_var)); - - assert(contv == ncb_var); (void)ncb_var; - assert(contp == ncb_pre); (void)ncb_pre; -} - -void API_NS(point_destroy) ( - point_t point -) { - decaf_bzero(point, sizeof(point_t)); -} - -void API_NS(precomputed_destroy) ( - precomputed_s *pre -) { - decaf_bzero(pre, API_NS(sizeof_precomputed_s)); -} diff --git a/src/GENERATED/c/ed448goldilocks/decaf_gen_tables.c b/src/GENERATED/c/ed448goldilocks/decaf_gen_tables.c deleted file mode 100644 index b41c8c5..0000000 --- a/src/GENERATED/c/ed448goldilocks/decaf_gen_tables.c +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file ed448goldilocks/decaf_gen_tables.c - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * @brief Decaf global constant table precomputation. - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ -#define _XOPEN_SOURCE 600 /* for posix_memalign */ -#include -#include - -#include "field.h" -#include "f_field.h" -#include "decaf.h" - -#define API_NS(_id) decaf_448_##_id -static const unsigned char base_point_ser_for_pregen[SER_BYTES] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01 -}; - - /* To satisfy linker. */ -const gf API_NS(precomputed_base_as_fe)[1]; -const API_NS(point_t) API_NS(point_base); - -struct niels_s; -const gf_s *API_NS(precomputed_wnaf_as_fe); -extern const size_t API_NS(sizeof_precomputed_wnafs); - -void API_NS(precompute_wnafs) ( - struct niels_s *out, - const API_NS(point_t) base -); -static void field_print(const gf f) { - unsigned char ser[X_SER_BYTES]; - gf_serialize(ser,f,1); - int b=0, i, comma=0; - unsigned long long limb = 0; - printf("{FIELD_LITERAL("); - for (i=0; i= GF_LIT_LIMB_BITS || i == SER_BYTES-1) { - limb &= (1ull<>(8-b); - } - } - printf(")}"); - assert(b<8); -} - -int main(int argc, char **argv) { - (void)argc; (void)argv; - - API_NS(point_t) real_point_base; - int ret = API_NS(point_decode)(real_point_base,base_point_ser_for_pregen,0); - if (ret != DECAF_SUCCESS) return 1; - - API_NS(precomputed_s) *pre; - ret = posix_memalign((void**)&pre, API_NS(alignof_precomputed_s), API_NS(sizeof_precomputed_s)); - if (ret || !pre) return 1; - API_NS(precompute)(pre, real_point_base); - - struct niels_s *pre_wnaf; - ret = posix_memalign((void**)&pre_wnaf, API_NS(alignof_precomputed_s), API_NS(sizeof_precomputed_wnafs)); - if (ret || !pre_wnaf) return 1; - API_NS(precompute_wnafs)(pre_wnaf, real_point_base); - - const gf_s *output; - unsigned i; - - printf("/** @warning: this file was automatically generated. */\n"); - printf("#include \"field.h\"\n\n"); - printf("#include \n\n"); - printf("#define API_NS(_id) decaf_448_##_id\n"); - - output = (const gf_s *)real_point_base; - printf("const API_NS(point_t) API_NS(point_base) = {{\n"); - for (i=0; i < sizeof(API_NS(point_t)); i+=sizeof(gf)) { - if (i) printf(",\n "); - field_print(output++); - } - printf("\n}};\n"); - - output = (const gf_s *)pre; - printf("const gf API_NS(precomputed_base_as_fe)[%d]\n", - (int)(API_NS(sizeof_precomputed_s) / sizeof(gf))); - printf("__attribute__((aligned(%d),visibility(\"hidden\"))) = {\n ", (int)API_NS(alignof_precomputed_s)); - - for (i=0; i < API_NS(sizeof_precomputed_s); i+=sizeof(gf)) { - if (i) printf(",\n "); - field_print(output++); - } - printf("\n};\n"); - - output = (const gf_s *)pre_wnaf; - printf("const gf API_NS(precomputed_wnaf_as_fe)[%d]\n", - (int)(API_NS(sizeof_precomputed_wnafs) / sizeof(gf))); - printf("__attribute__((aligned(%d),visibility(\"hidden\"))) = {\n ", (int)API_NS(alignof_precomputed_s)); - for (i=0; i < API_NS(sizeof_precomputed_wnafs); i+=sizeof(gf)) { - if (i) printf(",\n "); - field_print(output++); - } - printf("\n};\n"); - - return 0; -} diff --git a/src/GENERATED/c/ed448goldilocks/eddsa.c b/src/GENERATED/c/ed448goldilocks/eddsa.c deleted file mode 100644 index dae9a8c..0000000 --- a/src/GENERATED/c/ed448goldilocks/eddsa.c +++ /dev/null @@ -1,339 +0,0 @@ -/** - * @file ed448goldilocks/eddsa.c - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * @cond internal - * @brief EdDSA routines. - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ -#include "word.h" -#include -#include -#include -#include - -#define API_NAME "decaf_448" -#define API_NS(_id) decaf_448_##_id - -#define hash_ctx_t decaf_shake256_ctx_t -#define hash_init decaf_shake256_init -#define hash_update decaf_shake256_update -#define hash_final decaf_shake256_final -#define hash_destroy decaf_shake256_destroy -#define hash_hash decaf_shake256_hash - -#define SUPPORTS_CONTEXTS DECAF_EDDSA_448_SUPPORTS_CONTEXTS -#define EDDSA_USE_SIGMA_ISOGENY 0 -#define COFACTOR 4 - -/* EDDSA_BASE_POINT_RATIO = 1 or 2 - * Because EdDSA25519 is not on E_d but on the isogenous E_sigma_d, - * its base point is twice ours. - */ -#define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY) - -static void clamp ( - uint8_t secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES] -) { - /* Blarg */ - secret_scalar_ser[0] &= -COFACTOR; - uint8_t hibit = (1<<0)>>1; - if (hibit == 0) { - secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES - 1] = 0; - secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES - 2] |= 0x80; - } else { - secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES - 1] &= hibit-1; - secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES - 1] |= hibit; - } -} - -static void hash_init_with_dom( - hash_ctx_t hash, - uint8_t prehashed, - uint8_t for_prehash, - const uint8_t *context, - uint8_t context_len -) { - hash_init(hash); - -#if SUPPORTS_CONTEXTS - const char *dom_s = "SigEd448"; - const uint8_t dom[2] = {2+word_is_zero(prehashed)+word_is_zero(for_prehash), context_len}; - hash_update(hash,(const unsigned char *)dom_s, strlen(dom_s)); - hash_update(hash,dom,2); - hash_update(hash,context,context_len); -#else - (void)prehashed; - (void)for_prehash; - (void)context; - assert(context==NULL); - (void)context_len; - assert(context_len == 0); -#endif -} - -void decaf_ed448_prehash_init ( - hash_ctx_t hash -#if DECAF_EDDSA_448_SUPPORTS_CONTEXTS - , const uint8_t *context, - uint8_t context_len -#endif -) { -#if DECAF_EDDSA_448_SUPPORTS_CONTEXTS - hash_init_with_dom(hash,1,1,context,context_len); -#else - hash_init_with_dom(hash,1,1,NULL,0); -#endif -} - -void decaf_ed448_derive_public_key ( - uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES], - const uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES] -) { - /* only this much used for keygen */ - uint8_t secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES]; - - hash_hash( - secret_scalar_ser, - sizeof(secret_scalar_ser), - privkey, - DECAF_EDDSA_448_PRIVATE_BYTES - ); - clamp(secret_scalar_ser); - - API_NS(scalar_t) secret_scalar; - API_NS(scalar_decode_long)(secret_scalar, secret_scalar_ser, sizeof(secret_scalar_ser)); - - /* Since we are going to mul_by_cofactor during encoding, divide by it here. - * However, the EdDSA base point is not the same as the decaf base point if - * the sigma isogeny is in use: the EdDSA base point is on Etwist_d/(1-d) and - * the decaf base point is on Etwist_d, and when converted it effectively - * picks up a factor of 2 from the isogenies. So we might start at 2 instead of 1. - */ - for (unsigned int c = EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) { - API_NS(scalar_halve)(secret_scalar,secret_scalar); - } - - API_NS(point_t) p; - API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),secret_scalar); - - API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(pubkey, p); - - /* Cleanup */ - API_NS(scalar_destroy)(secret_scalar); - API_NS(point_destroy)(p); - decaf_bzero(secret_scalar_ser, sizeof(secret_scalar_ser)); -} - -void decaf_ed448_sign ( - uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES], - const uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES], - const uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES], - const uint8_t *message, - size_t message_len, - uint8_t prehashed -#if SUPPORTS_CONTEXTS - , const uint8_t *context, - uint8_t context_len -#endif -) { -#if !SUPPORTS_CONTEXTS - const uint8_t *const context = NULL; - const uint8_t context_len = 0; -#endif - API_NS(scalar_t) secret_scalar; - hash_ctx_t hash; - { - /* Schedule the secret key */ - struct { - uint8_t secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES]; - uint8_t seed[DECAF_EDDSA_448_PRIVATE_BYTES]; - } __attribute__((packed)) expanded; - hash_hash( - (uint8_t *)&expanded, - sizeof(expanded), - privkey, - DECAF_EDDSA_448_PRIVATE_BYTES - ); - clamp(expanded.secret_scalar_ser); - API_NS(scalar_decode_long)(secret_scalar, expanded.secret_scalar_ser, sizeof(expanded.secret_scalar_ser)); - - /* Hash to create the nonce */ - hash_init_with_dom(hash,prehashed,0,context,context_len); - hash_update(hash,expanded.seed,sizeof(expanded.seed)); - hash_update(hash,message,message_len); - decaf_bzero(&expanded, sizeof(expanded)); - } - - /* Decode the nonce */ - API_NS(scalar_t) nonce_scalar; - { - uint8_t nonce[2*DECAF_EDDSA_448_PRIVATE_BYTES]; - hash_final(hash,nonce,sizeof(nonce)); - API_NS(scalar_decode_long)(nonce_scalar, nonce, sizeof(nonce)); - decaf_bzero(nonce, sizeof(nonce)); - } - - uint8_t nonce_point[DECAF_EDDSA_448_PUBLIC_BYTES] = {0}; - { - /* Scalarmul to create the nonce-point */ - API_NS(scalar_t) nonce_scalar_2; - API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar); - for (unsigned int c = 2*EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) { - API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2); - } - - API_NS(point_t) p; - API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2); - API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(nonce_point, p); - API_NS(point_destroy)(p); - API_NS(scalar_destroy)(nonce_scalar_2); - } - - API_NS(scalar_t) challenge_scalar; - { - /* Compute the challenge */ - hash_init_with_dom(hash,prehashed,0,context,context_len); - hash_update(hash,nonce_point,sizeof(nonce_point)); - hash_update(hash,pubkey,DECAF_EDDSA_448_PUBLIC_BYTES); - hash_update(hash,message,message_len); - uint8_t challenge[2*DECAF_EDDSA_448_PRIVATE_BYTES]; - hash_final(hash,challenge,sizeof(challenge)); - hash_destroy(hash); - API_NS(scalar_decode_long)(challenge_scalar,challenge,sizeof(challenge)); - decaf_bzero(challenge,sizeof(challenge)); - } - - API_NS(scalar_mul)(challenge_scalar,challenge_scalar,secret_scalar); - API_NS(scalar_add)(challenge_scalar,challenge_scalar,nonce_scalar); - - decaf_bzero(signature,DECAF_EDDSA_448_SIGNATURE_BYTES); - memcpy(signature,nonce_point,sizeof(nonce_point)); - API_NS(scalar_encode)(&signature[DECAF_EDDSA_448_PUBLIC_BYTES],challenge_scalar); - - API_NS(scalar_destroy)(secret_scalar); - API_NS(scalar_destroy)(nonce_scalar); - API_NS(scalar_destroy)(challenge_scalar); -} - - -void decaf_ed448_sign_prehash ( - uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES], - const uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES], - const uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES], - const decaf_ed448_prehash_ctx_t hash -#if DECAF_EDDSA_448_SUPPORTS_CONTEXTS - , const uint8_t *context, - uint8_t context_len -#endif -) { - uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */ - { - decaf_ed448_prehash_ctx_t hash_too; - memcpy(hash_too,hash,sizeof(hash_too)); - hash_final(hash_too,hash_output,sizeof(hash_output)); - hash_destroy(hash_too); - } - -#if DECAF_EDDSA_448_SUPPORTS_CONTEXTS - decaf_ed448_sign(signature,privkey,pubkey,hash_output,sizeof(hash_output),1,context,context_len); -#else - decaf_ed448_sign(signature,privkey,pubkey,hash_output,sizeof(hash_output),1); -#endif - - decaf_bzero(hash_output,sizeof(hash_output)); -} - -decaf_error_t decaf_ed448_verify ( - const uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES], - const uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES], - const uint8_t *message, - size_t message_len, - uint8_t prehashed -#if SUPPORTS_CONTEXTS - , const uint8_t *context, - uint8_t context_len -#endif -) { -#if !SUPPORTS_CONTEXTS - const uint8_t *const context = NULL; - const uint8_t context_len = 0; -#endif - API_NS(point_t) pk_point, r_point; - decaf_error_t error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(pk_point,pubkey); - if (DECAF_SUCCESS != error) { return error; } - - error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(r_point,signature); - if (DECAF_SUCCESS != error) { return error; } - - API_NS(scalar_t) challenge_scalar; - { - /* Compute the challenge */ - hash_ctx_t hash; - hash_init_with_dom(hash,prehashed,0,context,context_len); - hash_update(hash,signature,DECAF_EDDSA_448_PUBLIC_BYTES); - hash_update(hash,pubkey,DECAF_EDDSA_448_PUBLIC_BYTES); - hash_update(hash,message,message_len); - uint8_t challenge[2*DECAF_EDDSA_448_PRIVATE_BYTES]; - hash_final(hash,challenge,sizeof(challenge)); - hash_destroy(hash); - API_NS(scalar_decode_long)(challenge_scalar,challenge,sizeof(challenge)); - decaf_bzero(challenge,sizeof(challenge)); - } - API_NS(scalar_sub)(challenge_scalar, API_NS(scalar_zero), challenge_scalar); - - API_NS(scalar_t) response_scalar; - API_NS(scalar_decode_long)( - response_scalar, - &signature[DECAF_EDDSA_448_PUBLIC_BYTES], - DECAF_EDDSA_448_PRIVATE_BYTES - ); -#if EDDSA_BASE_POINT_RATIO == 2 - API_NS(scalar_add)(response_scalar,response_scalar,response_scalar); -#endif - - - /* pk_point = -c(x(P)) + (cx + k)G = kG */ - API_NS(base_double_scalarmul_non_secret)( - pk_point, - response_scalar, - pk_point, - challenge_scalar - ); - return decaf_succeed_if(API_NS(point_eq(pk_point,r_point))); -} - - -decaf_error_t decaf_ed448_verify_prehash ( - const uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES], - const uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES], - const decaf_ed448_prehash_ctx_t hash -#if DECAF_EDDSA_448_SUPPORTS_CONTEXTS - , const uint8_t *context, - uint8_t context_len -#endif -) { - decaf_error_t ret; - - uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */ - { - decaf_ed448_prehash_ctx_t hash_too; - memcpy(hash_too,hash,sizeof(hash_too)); - hash_final(hash_too,hash_output,sizeof(hash_output)); - hash_destroy(hash_too); - } - -#if DECAF_EDDSA_448_SUPPORTS_CONTEXTS - ret = decaf_ed448_verify(signature,pubkey,hash_output,sizeof(hash_output),1,context,context_len); -#else - ret = decaf_ed448_verify(signature,pubkey,hash_output,sizeof(hash_output),1); -#endif - - return ret; -} diff --git a/src/GENERATED/c/ed448goldilocks/elligator.c b/src/GENERATED/c/ed448goldilocks/elligator.c deleted file mode 100644 index 66b398f..0000000 --- a/src/GENERATED/c/ed448goldilocks/elligator.c +++ /dev/null @@ -1,199 +0,0 @@ -/** - * @file ed448goldilocks/elligator.c - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * @brief Elligator high-level functions. - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ -#include "word.h" -#include "field.h" -#include - -/* Template stuff */ -#define API_NS(_id) decaf_448_##_id -#define point_t API_NS(point_t) -#define IMAGINE_TWIST 0 -#define COFACTOR 4 -static const int EDWARDS_D = -39081; -/* End of template stuff */ - -extern void API_NS(deisogenize) ( - gf_s *__restrict__ s, - gf_s *__restrict__ minus_t_over_s, - const point_t p, - mask_t toggle_hibit_s, - mask_t toggle_hibit_t_over_s, - mask_t toggle_rotation -); - -void API_NS(point_from_hash_nonuniform) ( - point_t p, - const unsigned char ser[SER_BYTES] -) { - gf r0,r,a,b,c,N,e; - ignore_result(gf_deserialize(r0,ser,0)); - gf_strong_reduce(r0); - gf_sqr(a,r0); - gf_mul_qnr(r,a); - - /* Compute D@c := (dr+a-d)(dr-ar-d) with a=1 */ - gf_sub(a,r,ONE); - gf_mulw(b,a,EDWARDS_D); /* dr-d */ - gf_add(a,b,ONE); - gf_sub(b,b,r); - gf_mul(c,a,b); - - /* compute N := (r+1)(a-2d) */ - gf_add(a,r,ONE); - gf_mulw(N,a,1-2*EDWARDS_D); - - /* e = +-sqrt(1/ND) or +-r0 * sqrt(qnr/ND) */ - gf_mul(a,c,N); - mask_t square = gf_isr(b,a); - gf_cond_sel(c,r0,ONE,square); /* r? = square ? 1 : r0 */ - gf_mul(e,b,c); - - /* s@a = +-|N.e| */ - gf_mul(a,N,e); - gf_cond_neg(a,gf_hibit(a)^square); /* NB this is - what is listen in the paper */ - - /* t@b = -+ cN(r-1)((a-2d)e)^2 - 1 */ - gf_mulw(c,e,1-2*EDWARDS_D); /* (a-2d)e */ - gf_sqr(b,c); - gf_sub(e,r,ONE); - gf_mul(c,b,e); - gf_mul(b,c,N); - gf_cond_neg(b,square); - gf_sub(b,b,ONE); - - /* isogenize */ -#if IMAGINE_TWIST - gf_mul(c,a,SQRT_MINUS_ONE); - gf_copy(a,c); -#endif - - gf_sqr(c,a); /* s^2 */ - gf_add(a,a,a); /* 2s */ - gf_add(e,c,ONE); - gf_mul(p->t,a,e); /* 2s(1+s^2) */ - gf_mul(p->x,a,b); /* 2st */ - gf_sub(a,ONE,c); - gf_mul(p->y,e,a); /* (1+s^2)(1-s^2) */ - gf_mul(p->z,a,b); /* (1-s^2)t */ - - assert(API_NS(point_valid)(p)); -} - -void API_NS(point_from_hash_uniform) ( - point_t pt, - const unsigned char hashed_data[2*SER_BYTES] -) { - point_t pt2; - API_NS(point_from_hash_nonuniform)(pt,hashed_data); - API_NS(point_from_hash_nonuniform)(pt2,&hashed_data[SER_BYTES]); - API_NS(point_add)(pt,pt,pt2); -} - -/* Elligator_onto: - * Make elligator-inverse onto at the cost of roughly halving the success probability. - * Currently no effect for curves with field size 1 bit mod 8 (where the top bit - * is chopped off). FUTURE MAGIC: automatic at least for brainpool-style curves; support - * log p == 1 mod 8 brainpool curves maybe? - */ -#define MAX(A,B) (((A)>(B)) ? (A) : (B)) -#define PKP_MASK ((1<<(MAX(8*SER_BYTES + 0 - 448,0)))-1) -#if PKP_MASK != 0 -static UNUSED mask_t plus_k_p ( - uint8_t x[SER_BYTES], - uint32_t factor_ -) { - uint32_t carry = 0; - uint64_t factor = factor_; - const uint8_t p[SER_BYTES] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - for (unsigned int i=0; i>8; - } - return word_is_zero(carry); -} -#endif - -decaf_error_t -API_NS(invert_elligator_nonuniform) ( - unsigned char recovered_hash[SER_BYTES], - const point_t p, - uint32_t hint_ -) { - mask_t hint = hint_; - mask_t sgn_s = -(hint & 1), - sgn_t_over_s = -(hint>>1 & 1), - sgn_r0 = -(hint>>2 & 1), - /* FUTURE MAGIC: eventually if there's a curve which needs sgn_ed_T but not sgn_r0, - * change this mask extraction. - */ - sgn_ed_T = -(hint>>3 & 1); - gf a, b, c, d; - API_NS(deisogenize)(a,c,p,sgn_s,sgn_t_over_s,sgn_ed_T); - -#if 448 == 8*SER_BYTES + 1 /* p521. */ - sgn_r0 = 0; -#endif - - /* ok, a = s; c = -t/s */ - gf_mul(b,c,a); - gf_sub(b,ONE,b); /* t+1 */ - gf_sqr(c,a); /* s^2 */ - mask_t is_identity = gf_eq(p->t,ZERO); - - /* identity adjustments */ - /* in case of identity, currently c=0, t=0, b=1, will encode to 1 */ - /* if hint is 0, -> 0 */ - /* if hint is to neg t/s, then go to infinity, effectively set s to 1 */ - gf_cond_sel(c,c,ONE,is_identity & sgn_t_over_s); - gf_cond_sel(b,b,ZERO,is_identity & ~sgn_t_over_s & ~sgn_s); - - gf_mulw(d,c,2*EDWARDS_D-1); /* $d = (2d-a)s^2 */ - gf_add(a,b,d); /* num? */ - gf_sub(d,d,b); /* den? */ - gf_mul(b,a,d); /* n*d */ - gf_cond_sel(a,d,a,sgn_s); - gf_mul_qnr(d,b); - mask_t succ = gf_isr(c,d)|gf_eq(d,ZERO); - gf_mul(b,a,c); - gf_cond_neg(b, sgn_r0^gf_hibit(b)); - - succ &= ~(gf_eq(b,ZERO) & sgn_r0); - #if COFACTOR == 8 - succ &= ~(is_identity & sgn_ed_T); /* NB: there are no preimages of rotated identity. */ - #endif - - #if 448 == 8*SER_BYTES + 1 /* p521 */ - gf_serialize(recovered_hash,b,0); - #else - gf_serialize(recovered_hash,b,1); - #if PKP_MASK != 0 - /* Add a multiple of p to make the result either almost-onto or completely onto. */ - succ &= plus_k_p(recovered_hash, (hint >> ((COFACTOR==8)?4:3)) & PKP_MASK); - #endif - #endif - return decaf_succeed_if(mask_to_bool(succ)); -} - -decaf_error_t -API_NS(invert_elligator_uniform) ( - unsigned char partial_hash[2*SER_BYTES], - const point_t p, - uint32_t hint -) { - point_t pt2; - API_NS(point_from_hash_nonuniform)(pt2,&partial_hash[SER_BYTES]); - API_NS(point_sub)(pt2,p,pt2); - return API_NS(invert_elligator_nonuniform)(partial_hash,pt2,hint); -} diff --git a/src/GENERATED/c/ed448goldilocks/scalar.c b/src/GENERATED/c/ed448goldilocks/scalar.c deleted file mode 100644 index d5fd3a2..0000000 --- a/src/GENERATED/c/ed448goldilocks/scalar.c +++ /dev/null @@ -1,339 +0,0 @@ -/** - * @file ed448goldilocks/scalar.c - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * @brief Decaf high-level functions. - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ -#include "word.h" -#include "constant_time.h" -#include - -/* Template stuff */ -#define API_NS(_id) decaf_448_##_id -#define SCALAR_BITS DECAF_448_SCALAR_BITS -#define SCALAR_SER_BYTES DECAF_448_SCALAR_BYTES -#define SCALAR_LIMBS DECAF_448_SCALAR_LIMBS -#define scalar_t API_NS(scalar_t) - -static const decaf_word_t MONTGOMERY_FACTOR = (decaf_word_t)0x3bd440fae918bc5ull; -static const scalar_t sc_p = {{{ - SC_LIMB(0x2378c292ab5844f3), SC_LIMB(0x216cc2728dc58f55), SC_LIMB(0xc44edb49aed63690), SC_LIMB(0xffffffff7cca23e9), SC_LIMB(0xffffffffffffffff), SC_LIMB(0xffffffffffffffff), SC_LIMB(0x3fffffffffffffff) -}}}, sc_r2 = {{{ - SC_LIMB(0xe3539257049b9b60), SC_LIMB(0x7af32c4bc1b195d9), SC_LIMB(0x0d66de2388ea1859), SC_LIMB(0xae17cf725ee4d838), SC_LIMB(0x1a9cc14ba3c47c44), SC_LIMB(0x2052bcb7e4d070af), SC_LIMB(0x3402a939f823b729) -}}}; -/* End of template stuff */ - -#define WBITS DECAF_WORD_BITS /* NB this may be different from ARCH_WORD_BITS */ - -const scalar_t API_NS(scalar_one) = {{{1}}}, API_NS(scalar_zero) = {{{0}}}; - -/** {extra,accum} - sub +? p - * Must have extra <= 1 - */ -static NOINLINE void sc_subx( - scalar_t out, - const decaf_word_t accum[SCALAR_LIMBS], - const scalar_t sub, - const scalar_t p, - decaf_word_t extra -) { - decaf_dsword_t chain = 0; - unsigned int i; - for (i=0; ilimb[i]; - out->limb[i] = chain; - chain >>= WBITS; - } - decaf_word_t borrow = chain+extra; /* = 0 or -1 */ - - chain = 0; - for (i=0; ilimb[i]) + (p->limb[i] & borrow); - out->limb[i] = chain; - chain >>= WBITS; - } -} - -static NOINLINE void sc_montmul ( - scalar_t out, - const scalar_t a, - const scalar_t b -) { - unsigned int i,j; - decaf_word_t accum[SCALAR_LIMBS+1] = {0}; - decaf_word_t hi_carry = 0; - - for (i=0; ilimb[i]; - const decaf_word_t *mier = b->limb; - - decaf_dword_t chain = 0; - for (j=0; j>= WBITS; - } - accum[j] = chain; - - mand = accum[0] * MONTGOMERY_FACTOR; - chain = 0; - mier = sc_p->limb; - for (j=0; j>= WBITS; - } - chain += accum[j]; - chain += hi_carry; - accum[j-1] = chain; - hi_carry = chain >> WBITS; - } - - sc_subx(out, accum, sc_p, sc_p, hi_carry); -} - -void API_NS(scalar_mul) ( - scalar_t out, - const scalar_t a, - const scalar_t b -) { - sc_montmul(out,a,b); - sc_montmul(out,out,sc_r2); -} - -/* PERF: could implement this */ -static INLINE void sc_montsqr (scalar_t out, const scalar_t a) { - sc_montmul(out,a,a); -} - -decaf_error_t API_NS(scalar_invert) ( - scalar_t out, - const scalar_t a -) { - /* Fermat's little theorem, sliding window. - * Sliding window is fine here because the modulus isn't secret. - */ - const int SCALAR_WINDOW_BITS = 3; - scalar_t precmp[1< 0) sc_montmul(precmp[LAST],precmp[0],precmp[0]); - - int i; - for (i=1; i<=LAST; i++) { - sc_montmul(precmp[i],precmp[i-1],precmp[LAST]); - } - - /* Sliding window */ - unsigned residue = 0, trailing = 0, started = 0; - for (i=SCALAR_BITS-1; i>=-SCALAR_WINDOW_BITS; i--) { - - if (started) sc_montsqr(out,out); - - decaf_word_t w = (i>=0) ? sc_p->limb[i/WBITS] : 0; - if (i >= 0 && i= 2); - w-=2; - } - - residue = (residue<<1) | ((w>>(i%WBITS))&1); - if (residue>>SCALAR_WINDOW_BITS != 0) { - assert(trailing == 0); - trailing = residue; - residue = 0; - } - - if (trailing > 0 && (trailing & ((1<>(SCALAR_WINDOW_BITS+1)]); - } else { - API_NS(scalar_copy)(out,precmp[trailing>>(SCALAR_WINDOW_BITS+1)]); - started = 1; - } - trailing = 0; - } - trailing <<= 1; - - } - assert(residue==0); - assert(trailing==0); - - /* Demontgomerize */ - sc_montmul(out,out,API_NS(scalar_one)); - decaf_bzero(precmp, sizeof(precmp)); - return decaf_succeed_if(~API_NS(scalar_eq)(out,API_NS(scalar_zero))); -} - -void API_NS(scalar_sub) ( - scalar_t out, - const scalar_t a, - const scalar_t b -) { - sc_subx(out, a->limb, b, sc_p, 0); -} - -void API_NS(scalar_add) ( - scalar_t out, - const scalar_t a, - const scalar_t b -) { - decaf_dword_t chain = 0; - unsigned int i; - for (i=0; ilimb[i]) + b->limb[i]; - out->limb[i] = chain; - chain >>= WBITS; - } - sc_subx(out, out->limb, sc_p, sc_p, chain); -} - -void -API_NS(scalar_set_unsigned) ( - scalar_t out, - uint64_t w -) { - memset(out,0,sizeof(scalar_t)); - unsigned int i = 0; - for (; ilimb[i] = w; - w >>= (sizeof(uint64_t) > sizeof(decaf_word_t)) ? 8*sizeof(decaf_word_t) : 0; - } -} - -decaf_bool_t -API_NS(scalar_eq) ( - const scalar_t a, - const scalar_t b -) { - decaf_word_t diff = 0; - unsigned int i; - for (i=0; ilimb[i] ^ b->limb[i]; - } - return mask_to_bool(word_is_zero(diff)); -} - -static INLINE void scalar_decode_short ( - scalar_t s, - const unsigned char *ser, - unsigned int nbytes -) { - unsigned int i,j,k=0; - for (i=0; ilimb[i] = out; - } -} - -decaf_error_t API_NS(scalar_decode)( - scalar_t s, - const unsigned char ser[SCALAR_SER_BYTES] -) { - unsigned int i; - scalar_decode_short(s, ser, SCALAR_SER_BYTES); - decaf_dsword_t accum = 0; - for (i=0; ilimb[i] - sc_p->limb[i]) >> WBITS; - } - /* Here accum == 0 or -1 */ - - API_NS(scalar_mul)(s,s,API_NS(scalar_one)); /* ham-handed reduce */ - - return decaf_succeed_if(~word_is_zero(accum)); -} - -void API_NS(scalar_destroy) ( - scalar_t scalar -) { - decaf_bzero(scalar, sizeof(scalar_t)); -} - -void API_NS(scalar_decode_long)( - scalar_t s, - const unsigned char *ser, - size_t ser_len -) { - if (ser_len == 0) { - API_NS(scalar_copy)(s, API_NS(scalar_zero)); - return; - } - - size_t i; - scalar_t t1, t2; - - i = ser_len - (ser_len%SCALAR_SER_BYTES); - if (i==ser_len) i -= SCALAR_SER_BYTES; - - scalar_decode_short(t1, &ser[i], ser_len-i); - - if (ser_len == sizeof(scalar_t)) { - assert(i==0); - /* ham-handed reduce */ - API_NS(scalar_mul)(s,t1,API_NS(scalar_one)); - API_NS(scalar_destroy)(t1); - return; - } - - while (i) { - i -= SCALAR_SER_BYTES; - sc_montmul(t1,t1,sc_r2); - ignore_result( API_NS(scalar_decode)(t2, ser+i) ); - API_NS(scalar_add)(t1, t1, t2); - } - - API_NS(scalar_copy)(s, t1); - API_NS(scalar_destroy)(t1); - API_NS(scalar_destroy)(t2); -} - -void API_NS(scalar_encode)( - unsigned char ser[SCALAR_SER_BYTES], - const scalar_t s -) { - unsigned int i,j,k=0; - for (i=0; ilimb[i] >> (8*j); - } - } -} - -void API_NS(scalar_cond_sel) ( - scalar_t out, - const scalar_t a, - const scalar_t b, - decaf_bool_t pick_b -) { - constant_time_select(out,a,b,sizeof(scalar_t),bool_to_mask(pick_b),sizeof(out->limb[0])); -} - -void API_NS(scalar_halve) ( - scalar_t out, - const scalar_t a -) { - decaf_word_t mask = -(a->limb[0] & 1); - decaf_dword_t chain = 0; - unsigned int i; - for (i=0; ilimb[i]) + (sc_p->limb[i] & mask); - out->limb[i] = chain; - chain >>= DECAF_WORD_BITS; - } - for (i=0; ilimb[i] = out->limb[i]>>1 | out->limb[i+1]<<(WBITS-1); - } - out->limb[i] = out->limb[i]>>1 | chain<<(WBITS-1); -} - diff --git a/src/GENERATED/c/p448/f_generic.c b/src/GENERATED/c/p448/f_generic.c deleted file mode 100644 index 66f9b08..0000000 --- a/src/GENERATED/c/p448/f_generic.c +++ /dev/null @@ -1,133 +0,0 @@ -/** - * @file p448/f_generic.c - * @author Mike Hamburg - * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. - * - * @brief Generic arithmetic which has to be compiled per field. - * - * @warning This file was automatically generated in Python. - * Please do not edit it. - */ -#include "field.h" - -static const gf MODULUS = {FIELD_LITERAL( - 0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff, 0xfffffffffffffe, 0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff -)}; - -#if P_MOD_8 == 5 - const gf SQRT_MINUS_ONE = {FIELD_LITERAL( - /* NOPE */ - )}; -#endif - -/** Serialize to wire format. */ -void gf_serialize (uint8_t serial[SER_BYTES], const gf x, int with_hibit) { - gf red; - gf_copy(red, x); - gf_strong_reduce(red); - if (!with_hibit) { assert(gf_hibit(red) == 0); } - - unsigned int j=0, fill=0; - dword_t buffer = 0; - UNROLL for (unsigned int i=0; i<(with_hibit ? X_SER_BYTES : SER_BYTES); i++) { - if (fill < 8 && j < NLIMBS) { - buffer |= ((dword_t)red->limb[LIMBPERM(j)]) << fill; - fill += LIMB_PLACE_VALUE(LIMBPERM(j)); - j++; - } - serial[i] = buffer; - fill -= 8; - buffer >>= 8; - } -} - -/** Return high bit of x = low bit of 2x mod p */ -mask_t gf_hibit(const gf x) { - gf y; - gf_add(y,x,x); - gf_strong_reduce(y); - return -(y->limb[0]&1); -} - -/** Deserialize from wire format; return -1 on success and 0 on failure. */ -mask_t gf_deserialize (gf x, const uint8_t serial[SER_BYTES], int with_hibit) { - unsigned int j=0, fill=0; - dword_t buffer = 0; - dsword_t scarry = 0; - UNROLL for (unsigned int i=0; ilimb[LIMBPERM(i)] = (i>= LIMB_PLACE_VALUE(LIMBPERM(i)); - scarry = (scarry + x->limb[LIMBPERM(i)] - MODULUS->limb[LIMBPERM(i)]) >> (8*sizeof(word_t)); - } - mask_t succ = with_hibit ? -(mask_t)1 : ~gf_hibit(x); - return succ & word_is_zero(buffer) & ~word_is_zero(scarry); -} - -/** Reduce to canonical form. */ -void gf_strong_reduce (gf a) { - /* first, clear high */ - gf_weak_reduce(a); /* Determined to have negligible perf impact. */ - - /* now the total is less than 2p */ - - /* compute total_value - p. No need to reduce mod p. */ - dsword_t scarry = 0; - for (unsigned int i=0; ilimb[LIMBPERM(i)] - MODULUS->limb[LIMBPERM(i)]; - a->limb[LIMBPERM(i)] = scarry & LIMB_MASK(LIMBPERM(i)); - scarry >>= LIMB_PLACE_VALUE(LIMBPERM(i)); - } - - /* uncommon case: it was >= p, so now scarry = 0 and this = x - * common case: it was < p, so now scarry = -1 and this = x - p + 2^255 - * so let's add back in p. will carry back off the top for 2^255. - */ - assert(word_is_zero(scarry) | word_is_zero(scarry+1)); - - word_t scarry_0 = scarry; - dword_t carry = 0; - - /* add it back */ - for (unsigned int i=0; ilimb[LIMBPERM(i)] + (scarry_0 & MODULUS->limb[LIMBPERM(i)]); - a->limb[LIMBPERM(i)] = carry & LIMB_MASK(LIMBPERM(i)); - carry >>= LIMB_PLACE_VALUE(LIMBPERM(i)); - } - - assert(word_is_zero(carry + scarry_0)); -} - -/** Add two gf elements */ -void gf_sub (gf d, const gf a, const gf b) { - gf_sub_RAW ( d, a, b ); - gf_bias( d, 2 ); - gf_weak_reduce ( d ); -} - -/** Subtract d = a-b */ -void gf_add (gf d, const gf a, const gf b) { - gf_add_RAW ( d, a, b ); - gf_weak_reduce ( d ); -} - -/** Compare a==b */ -mask_t gf_eq(const gf a, const gf b) { - gf c; - gf_sub(c,a,b); - gf_strong_reduce(c); - mask_t ret=0; - for (unsigned int i=0; ilimb[LIMBPERM(i)]; - } - - return word_is_zero(ret); -} diff --git a/src/GENERATED/include/decaf.h b/src/GENERATED/include/decaf.h index 3f716c1..d3cb60c 100644 --- a/src/GENERATED/include/decaf.h +++ b/src/GENERATED/include/decaf.h @@ -26,7 +26,7 @@ #ifndef __DECAF_H__ #define __DECAF_H__ 1 -#include -#include +#include +#include #endif /* __DECAF_H__ */ diff --git a/src/GENERATED/include/decaf.hxx b/src/GENERATED/include/decaf.hxx index b056e02..f83dfbf 100644 --- a/src/GENERATED/include/decaf.hxx +++ b/src/GENERATED/include/decaf.hxx @@ -15,8 +15,8 @@ #ifndef __DECAF_HXX__ #define __DECAF_HXX__ 1 -#include -#include +#include +#include namespace decaf { template class Run> diff --git a/src/GENERATED/include/decaf/ed255.h b/src/GENERATED/include/decaf/ed255.h index 97f78c0..e16196e 100644 --- a/src/GENERATED/include/decaf/ed255.h +++ b/src/GENERATED/include/decaf/ed255.h @@ -15,7 +15,7 @@ #ifndef __DECAF_ED255_H__ #define __DECAF_ED255_H__ 1 -#include +#include #include #include diff --git a/src/GENERATED/include/decaf/ed255.hxx b/src/GENERATED/include/decaf/ed255.hxx index aba868b..df99227 100644 --- a/src/GENERATED/include/decaf/ed255.hxx +++ b/src/GENERATED/include/decaf/ed255.hxx @@ -24,7 +24,7 @@ */ #include -#include +#include #include #include diff --git a/src/GENERATED/include/decaf/ed448.h b/src/GENERATED/include/decaf/ed448.h index 8c95ec9..9a09b6c 100644 --- a/src/GENERATED/include/decaf/ed448.h +++ b/src/GENERATED/include/decaf/ed448.h @@ -15,7 +15,7 @@ #ifndef __DECAF_ED448_H__ #define __DECAF_ED448_H__ 1 -#include +#include #include #include diff --git a/src/GENERATED/include/decaf/ed448.hxx b/src/GENERATED/include/decaf/ed448.hxx index e978516..d1163fe 100644 --- a/src/GENERATED/include/decaf/ed448.hxx +++ b/src/GENERATED/include/decaf/ed448.hxx @@ -24,7 +24,7 @@ */ #include -#include +#include #include #include diff --git a/src/GENERATED/include/decaf/decaf_255.h b/src/GENERATED/include/decaf/point_255.h similarity index 99% rename from src/GENERATED/include/decaf/decaf_255.h rename to src/GENERATED/include/decaf/point_255.h index ba27668..621cdea 100644 --- a/src/GENERATED/include/decaf/decaf_255.h +++ b/src/GENERATED/include/decaf/point_255.h @@ -1,5 +1,5 @@ /** - * @file decaf/decaf_255.h + * @file decaf/point_255.h * @author Mike Hamburg * * @copyright @@ -12,8 +12,8 @@ * Please do not edit it. */ -#ifndef __DECAF_DECAF_255_H__ -#define __DECAF_DECAF_255_H__ 1 +#ifndef __DECAF_POINT_255_H__ +#define __DECAF_POINT_255_H__ 1 #include @@ -703,4 +703,4 @@ void decaf_255_precomputed_destroy ( } /* extern "C" */ #endif -#endif /* __DECAF_DECAF_255_H__ */ +#endif /* __DECAF_POINT_255_H__ */ diff --git a/src/GENERATED/include/decaf/decaf_255.hxx b/src/GENERATED/include/decaf/point_255.hxx similarity index 99% rename from src/GENERATED/include/decaf/decaf_255.hxx rename to src/GENERATED/include/decaf/point_255.hxx index 3782827..b70d57a 100644 --- a/src/GENERATED/include/decaf/decaf_255.hxx +++ b/src/GENERATED/include/decaf/point_255.hxx @@ -1,5 +1,5 @@ /** - * @file decaf/decaf_255.hxx + * @file decaf/point_255.hxx * @author Mike Hamburg * * @copyright @@ -23,8 +23,8 @@ * Please do not edit it. */ -#ifndef __DECAF_DECAF_255_HXX__ -#define __DECAF_DECAF_255_HXX__ 1 +#ifndef __DECAF_POINT_255_HXX__ +#define __DECAF_POINT_255_HXX__ 1 /** This code uses posix_memalign. */ #ifndef _XOPEN_SOURCE @@ -33,7 +33,7 @@ #include #include /* for memcpy */ -#include +#include #include #include #include @@ -711,4 +711,4 @@ inline SecureBuffer IsoEd25519::Scalar::direct_scalarmul ( #undef NOEXCEPT } /* namespace decaf */ -#endif /* __DECAF_DECAF_255_HXX__ */ +#endif /* __DECAF_POINT_255_HXX__ */ diff --git a/src/GENERATED/include/decaf/decaf_448.h b/src/GENERATED/include/decaf/point_448.h similarity index 99% rename from src/GENERATED/include/decaf/decaf_448.h rename to src/GENERATED/include/decaf/point_448.h index 3c9f9ca..65e9057 100644 --- a/src/GENERATED/include/decaf/decaf_448.h +++ b/src/GENERATED/include/decaf/point_448.h @@ -1,5 +1,5 @@ /** - * @file decaf/decaf_448.h + * @file decaf/point_448.h * @author Mike Hamburg * * @copyright @@ -12,8 +12,8 @@ * Please do not edit it. */ -#ifndef __DECAF_DECAF_448_H__ -#define __DECAF_DECAF_448_H__ 1 +#ifndef __DECAF_POINT_448_H__ +#define __DECAF_POINT_448_H__ 1 #include @@ -703,4 +703,4 @@ void decaf_448_precomputed_destroy ( } /* extern "C" */ #endif -#endif /* __DECAF_DECAF_448_H__ */ +#endif /* __DECAF_POINT_448_H__ */ diff --git a/src/GENERATED/include/decaf/decaf_448.hxx b/src/GENERATED/include/decaf/point_448.hxx similarity index 99% rename from src/GENERATED/include/decaf/decaf_448.hxx rename to src/GENERATED/include/decaf/point_448.hxx index 36c7bdd..64e0346 100644 --- a/src/GENERATED/include/decaf/decaf_448.hxx +++ b/src/GENERATED/include/decaf/point_448.hxx @@ -1,5 +1,5 @@ /** - * @file decaf/decaf_448.hxx + * @file decaf/point_448.hxx * @author Mike Hamburg * * @copyright @@ -23,8 +23,8 @@ * Please do not edit it. */ -#ifndef __DECAF_DECAF_448_HXX__ -#define __DECAF_DECAF_448_HXX__ 1 +#ifndef __DECAF_POINT_448_HXX__ +#define __DECAF_POINT_448_HXX__ 1 /** This code uses posix_memalign. */ #ifndef _XOPEN_SOURCE @@ -33,7 +33,7 @@ #include #include /* for memcpy */ -#include +#include #include #include #include @@ -711,4 +711,4 @@ inline SecureBuffer Ed448Goldilocks::Scalar::direct_scalarmul ( #undef NOEXCEPT } /* namespace decaf */ -#endif /* __DECAF_DECAF_448_HXX__ */ +#endif /* __DECAF_POINT_448_HXX__ */ diff --git a/src/per_curve/crypto.tmpl.h b/src/per_curve/crypto.tmpl.h index 712ee1b..71faf57 100644 --- a/src/per_curve/crypto.tmpl.h +++ b/src/per_curve/crypto.tmpl.h @@ -6,7 +6,7 @@ * @warning Experimental! The names, parameter orders etc are likely to change. */ -#include +#include #include #ifdef __cplusplus diff --git a/src/per_curve/crypto.tmpl.hxx b/src/per_curve/crypto.tmpl.hxx index 119dcdd..1afcbff 100644 --- a/src/per_curve/crypto.tmpl.hxx +++ b/src/per_curve/crypto.tmpl.hxx @@ -6,7 +6,7 @@ * @warning Experimental! The names, parameter orders etc are likely to change. */ -#include +#include #include #include diff --git a/src/per_curve/eddsa.tmpl.h b/src/per_curve/eddsa.tmpl.h index 556a2a2..340a068 100644 --- a/src/per_curve/eddsa.tmpl.h +++ b/src/per_curve/eddsa.tmpl.h @@ -1,6 +1,6 @@ /** @brief A group of prime order p, based on $(iso_to). */ -#include +#include #include #include diff --git a/src/per_curve/eddsa.tmpl.hxx b/src/per_curve/eddsa.tmpl.hxx index b5af7bc..a38c045 100644 --- a/src/per_curve/eddsa.tmpl.hxx +++ b/src/per_curve/eddsa.tmpl.hxx @@ -8,7 +8,7 @@ */ #include -#include +#include #include #include diff --git a/src/per_curve/decaf.tmpl.h b/src/per_curve/point.tmpl.h similarity index 100% rename from src/per_curve/decaf.tmpl.h rename to src/per_curve/point.tmpl.h diff --git a/src/per_curve/decaf.tmpl.hxx b/src/per_curve/point.tmpl.hxx similarity index 99% rename from src/per_curve/decaf.tmpl.hxx rename to src/per_curve/point.tmpl.hxx index b48ee41..a793d50 100644 --- a/src/per_curve/decaf.tmpl.hxx +++ b/src/per_curve/point.tmpl.hxx @@ -20,7 +20,7 @@ #include #include /* for memcpy */ -#include +#include #include #include #include diff --git a/src/public_include/decaf.tmpl.h b/src/public_include/decaf.tmpl.h index c4c1fe2..aa85ce7 100644 --- a/src/public_include/decaf.tmpl.h +++ b/src/public_include/decaf.tmpl.h @@ -14,5 +14,5 @@ */ $("\n".join([ - "#include " % g for g in sorted([c["bits"] for _,c in curve.iteritems()]) + "#include " % g for g in sorted([c["bits"] for _,c in curve.iteritems()]) ])) diff --git a/src/public_include/decaf.tmpl.hxx b/src/public_include/decaf.tmpl.hxx index 2da5246..40e95eb 100644 --- a/src/public_include/decaf.tmpl.hxx +++ b/src/public_include/decaf.tmpl.hxx @@ -1,7 +1,7 @@ /** Master header for Decaf library, C++ version. */ $("\n".join([ - "#include " % g for g in sorted([c["bits"] for _,c in curve.iteritems()]) + "#include " % g for g in sorted([c["bits"] for _,c in curve.iteritems()]) ])) namespace decaf {