X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=crypto%2Fec%2Fcurve448%2Feddsa.c;h=556edf07b91cbf2b3d29e456ea383fbeb2a36e38;hb=9fd3c858b4ceea7ff0b176c7c0a2438475898598;hp=9f68e31177171546787eb29b24d5454f6e4f65bd;hpb=a2039c87f5923b10f148dea8fb725df03b90011b;p=openssl.git diff --git a/crypto/ec/curve448/eddsa.c b/crypto/ec/curve448/eddsa.c index 9f68e31177..556edf07b9 100644 --- a/crypto/ec/curve448/eddsa.c +++ b/crypto/ec/curve448/eddsa.c @@ -1,327 +1,359 @@ -/** - * @file ed448goldilocks/eddsa.c - * @author Mike Hamburg +/* + * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2016 Cryptography Research, Inc. * - * @copyright - * Copyright (c) 2015-2016 Cryptography Research, Inc. \n - * Released under the MIT License. See LICENSE.txt for license information. + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html * - * @cond internal - * @brief EdDSA routines. - * - * @warning This file was automatically generated in Python. - * Please do not edit it. + * Originally written by Mike Hamburg */ +#include +#include + +#include "curve448_lcl.h" #include "word.h" #include "ed448.h" -#include "shake.h" #include +#include "internal/numbers.h" -#define API_NAME "decaf_448" -#define API_NS(_id) decaf_448_##_id +#define COFACTOR 4 -#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 +static c448_error_t oneshot_hash(uint8_t *out, size_t outlen, + const uint8_t *in, size_t inlen) +{ + EVP_MD_CTX *hashctx = EVP_MD_CTX_new(); -#define NO_CONTEXT DECAF_EDDSA_448_SUPPORTS_CONTEXTLESS_SIGS -#define EDDSA_USE_SIGMA_ISOGENY 0 -#define COFACTOR 4 -#define EDDSA_PREHASH_BYTES 64 + if (hashctx == NULL) + return C448_FAILURE; -#if NO_CONTEXT -const uint8_t NO_CONTEXT_POINTS_HERE = 0; -const uint8_t * const DECAF_ED448_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE; -#endif + if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) + || !EVP_DigestUpdate(hashctx, in, inlen) + || !EVP_DigestFinalXOF(hashctx, out, outlen)) { + EVP_MD_CTX_free(hashctx); + return C448_FAILURE; + } -/* 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) /* TODO: remove */ + EVP_MD_CTX_free(hashctx); + return C448_SUCCESS; +} + +static void clamp(uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES]) +{ + uint8_t hibit = (1 << 0) >> 1; -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; + secret_scalar_ser[EDDSA_448_PRIVATE_BYTES - 1] = 0; + secret_scalar_ser[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; + secret_scalar_ser[EDDSA_448_PRIVATE_BYTES - 1] &= hibit - 1; + secret_scalar_ser[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 NO_CONTEXT - if (context_len == 0 && context == DECAF_ED448_NO_CONTEXT) { - (void)prehashed; - (void)for_prehash; - (void)context; - (void)context_len; - return; - } -#endif +static c448_error_t hash_init_with_dom(EVP_MD_CTX *hashctx, uint8_t prehashed, + uint8_t for_prehash, + const uint8_t *context, + size_t context_len) +{ 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); -} + uint8_t dom[2]; + + dom[0] = 2 + word_is_zero(prehashed) + word_is_zero(for_prehash); + dom[1] = (uint8_t)context_len; + + if (context_len > UINT8_MAX) + return C448_FAILURE; + + if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) + || !EVP_DigestUpdate(hashctx, dom_s, strlen(dom_s)) + || !EVP_DigestUpdate(hashctx, dom, sizeof(dom)) + || !EVP_DigestUpdate(hashctx, context, context_len)) + return C448_FAILURE; -void decaf_ed448_prehash_init ( - hash_ctx_t hash -) { - hash_init(hash); + return C448_SUCCESS; } /* In this file because it uses the hash */ -void decaf_ed448_convert_private_key_to_x448 ( - uint8_t x[DECAF_X448_PRIVATE_BYTES], - const uint8_t ed[DECAF_EDDSA_448_PRIVATE_BYTES] -) { - /* pass the private key through hash_hash function */ - /* and keep the first DECAF_X448_PRIVATE_BYTES bytes */ - hash_hash( - x, - DECAF_X448_PRIVATE_BYTES, - ed, - DECAF_EDDSA_448_PRIVATE_BYTES - ); +c448_error_t c448_ed448_convert_private_key_to_x448( + uint8_t x[X448_PRIVATE_BYTES], + const uint8_t ed [EDDSA_448_PRIVATE_BYTES]) +{ + /* pass the private key through oneshot_hash function */ + /* and keep the first X448_PRIVATE_BYTES bytes */ + return oneshot_hash(x, X448_PRIVATE_BYTES, ed, + EDDSA_448_PRIVATE_BYTES); } - -void decaf_ed448_derive_public_key ( - uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES], - const uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES] -) { + +c448_error_t c448_ed448_derive_public_key( + uint8_t pubkey[EDDSA_448_PUBLIC_BYTES], + const uint8_t privkey[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 - ); + uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES]; + curve448_scalar_t secret_scalar; + unsigned int c; + curve448_point_t p; + + if (!oneshot_hash(secret_scalar_ser, sizeof(secret_scalar_ser), privkey, + EDDSA_448_PRIVATE_BYTES)) + return C448_FAILURE; + 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. + + curve448_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=1; c