33#include "sodium/crypto_scalarmult.h"
34#include "sodium/crypto_scalarmult_curve25519.h"
35#include "sodium/utils.h"
62#define CURVE "Ed25519"
64#define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-ecc", __VA_ARGS__)
66#define LOG_STRERROR(kind, syscall) \
67 GNUNET_log_from_strerror (kind, "util-crypto-ecc", syscall)
69#define LOG_STRERROR_FILE(kind, syscall, filename) \
70 GNUNET_log_from_strerror_file (kind, "util-crypto-ecc", syscall, \
78#define LOG_GCRY(level, cmd, rc) \
82 _ ("`%s' failed at %s:%d with error: %s\n"), \
86 gcry_strerror (rc)); \
109 list = gcry_sexp_find_token (sexp, topname, 0);
112 l2 = gcry_sexp_cadr (
list);
113 gcry_sexp_release (
list);
119 for (
const char *s = elems; *s; s++, idx++)
121 l2 = gcry_sexp_find_token (
list, s, 1);
124 for (
unsigned int i = 0; i < idx; i++)
126 gcry_free (array[i]);
129 gcry_sexp_release (
list);
132 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
133 gcry_sexp_release (l2);
136 for (
unsigned int i = 0; i < idx; i++)
138 gcry_free (array[i]);
141 gcry_sexp_release (
list);
145 gcry_sexp_release (
list);
164 for (
size_t i = 0; i<32; i++)
165 d[i] = priv->
d[31 - i];
167 rc = gcry_sexp_build (&
result,
169 "(private-key(ecc(curve \"" CURVE "\")"
179 if (0 != (rc = gcry_pk_testkey (
result)))
195 crypto_scalarmult_ed25519_base_noclamp (
pub->
q_y, priv->
d);
205 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
206 unsigned char sk[crypto_sign_SECRETKEYBYTES];
211 sodium_memzero (sk, crypto_sign_SECRETKEYBYTES);
236 keylen += 5 - keylen % 5;
263 keylen += 5 - keylen % 5;
290 keylen += 5 - keylen % 5;
317 keylen += 5 - keylen % 5;
344 keylen += 5 - keylen % 5;
346 if (enclen != keylen)
369 keylen += 5 - keylen % 5;
371 if (enclen != keylen)
394 keylen += 5 - keylen % 5;
396 if (enclen != keylen)
421 memset_s (buf, len, 0, len);
422#elif HAVE_EXPLICIT_BZERO
423 explicit_bzero (buf, len);
425 volatile unsigned char *
p = buf;
514 anonymous.
d[0] &= 248;
515 anonymous.
d[31] &= 127;
516 anonymous.
d[31] |= 64;
539 if (0 != (rc = gcry_sexp_build (&
data,
541 "(data(flags rfc6979)(hash %s %b))",
559 gcry_sexp_t priv_sexp;
560 gcry_sexp_t sig_sexp;
569 if (0 != (rc = gcry_pk_sign (&sig_sexp,
data, priv_sexp)))
572 _ (
"ECC signing failed at %s:%d: %s\n"),
576 gcry_sexp_release (
data);
577 gcry_sexp_release (priv_sexp);
580 gcry_sexp_release (priv_sexp);
581 gcry_sexp_release (
data);
585 if (0 != (rc =
key_from_sexp (rs, sig_sexp,
"sig-val",
"rs")))
588 gcry_sexp_release (sig_sexp);
591 gcry_sexp_release (sig_sexp);
594 gcry_mpi_release (rs[0]);
595 gcry_mpi_release (rs[1]);
610 unsigned char sk[crypto_sign_SECRETKEYBYTES];
611 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
615 res = crypto_sign_detached ((uint8_t *) sig,
631 size_t mlen = ntohl (purpose->
size);
632 unsigned char sk[crypto_sign_SECRETKEYBYTES];
633 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
638 res = crypto_sign_detached ((uint8_t *) sig,
656 gcry_sexp_t sig_sexpr;
657 gcry_sexp_t pub_sexpr;
662 if (purpose != ntohl (validate->
purpose))
666 if (0 != (rc = gcry_sexp_build (&sig_sexpr,
668 "(sig-val(ecdsa(r %b)(s %b)))",
669 (
int)
sizeof(sig->
r),
671 (
int)
sizeof(sig->
s),
678 if (0 != (rc = gcry_sexp_build (&pub_sexpr,
680 "(public-key(ecc(curve " CURVE ")(q %b)))",
684 gcry_sexp_release (
data);
685 gcry_sexp_release (sig_sexpr);
688 rc = gcry_pk_verify (sig_sexpr,
data, pub_sexpr);
689 gcry_sexp_release (pub_sexpr);
690 gcry_sexp_release (
data);
691 gcry_sexp_release (sig_sexpr);
695 _ (
"ECDSA signature verification failed at %s:%d: %s\n"),
714 const unsigned char *
m = (
const void *) validate;
715 size_t mlen = ntohl (validate->
size);
716 const unsigned char *s = (
const void *) sig;
720 if (purpose != ntohl (validate->
purpose))
725 res = crypto_sign_verify_detached (s,
m, mlen,
pub->
q_y);
736 uint8_t
p[crypto_scalarmult_BYTES];
737 if (0 != crypto_scalarmult (
p, priv->
d,
pub->
q_y))
750 uint8_t a[crypto_scalarmult_SCALARBYTES];
751 uint8_t
p[crypto_scalarmult_BYTES];
757 if (0 != crypto_scalarmult (
p, a,
pub->
q_y))
760 crypto_scalarmult_BYTES,
771 uint64_t checkbyte = 0;
772 size_t num_words =
sizeof *dh /
sizeof (uint64_t);
773 if (0 != crypto_scalarmult_curve25519 (dh->
q_y, sk->
d,
pub->
q_y))
776 for (
int i = 0; i < num_words; i++)
777 checkbyte |= ((uint64_t*)dh)[i];
787 uint64_t checkbyte = 0;
788 size_t num_words =
sizeof *dh /
sizeof (uint64_t);
789 if (0 != crypto_scalarmult_curve25519 (dh->
q_y, sk->
d,
pk->q_y))
792 for (
int i = 0; i < num_words; i++)
793 checkbyte |= ((uint64_t*)dh)[i];
797 "HPKE ECDH: X25519 all zero value!\n");
809 uint8_t
p[crypto_scalarmult_BYTES];
812 if (0 != crypto_scalarmult (
p, priv->
d,
pub->
q_y))
815 crypto_scalarmult_BYTES,
827 uint8_t
p[crypto_scalarmult_BYTES];
828 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
830 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk,
pub->
q_y))
832 if (0 != crypto_scalarmult (
p, priv->
d, curve25510_pk))
845 uint8_t
p[crypto_scalarmult_BYTES];
846 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
848 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk,
pub->
q_y))
850 if (0 != crypto_scalarmult (
p, priv->
d, curve25510_pk))
benchmarking for various operations
#define BENCHMARK_START(opname)
#define BENCHMARK_END(opname)
static int key_from_sexp(gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname, const char *elems)
Extract values from an S-expression.
static gcry_sexp_t data_to_ecdsa_value(const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose)
Convert the data specified in the given purpose argument to an S-expression suitable for signature op...
#define CURVE
IMPLEMENTATION NOTICE:
static void buffer_clear(void *buf, size_t len)
#define LOG_GCRY(level, cmd, rc)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
static gcry_sexp_t decode_private_ecdsa_key(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
Convert the given private key from the network format to the S-expression that can be used by libgcry...
static mp_limb_t d[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static int once
Global to mark if we've run the initialization.
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
static int list
Set if we should print a list of currently running services.
static int end
Set if we are to shutdown all services (including ARM).
static char * data
The data to insert into the dht.
static OpusEncoder * enc
OPUS encoder.
struct GNUNET_CRYPTO_PrivateKey pk
Private key from command line option, or NULL.
static char * res
Currently read line or NULL on EOF.
static int result
Global testing status.
static struct GNUNET_CRYPTO_EddsaPublicKey pub
static struct GNUNET_OS_Process * p
Helper process we started.
commonly used definitions; globals in this file are exempt from the rule that the module name ("commo...
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_ecdh(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a public and a private ECC key.
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_x25519_ecdh(const struct GNUNET_CRYPTO_EcdhePrivateKey *sk, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_CRYPTO_EcdhePublicKey *dh)
Derive key material from a ECDH public key and a private X25519 key.
void GNUNET_CRYPTO_random_block(enum GNUNET_CRYPTO_Quality mode, void *buffer, size_t length)
Fill block with a random values.
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_ecdh(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
HPKE END.
void GNUNET_CRYPTO_eddsa_key_clear(struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
Clear memory that was used to store a private key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_sign_(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EcdsaSignature *sig)
ECDSA Sign a given block.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_ecdh(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a ECDH public key and a private EdDSA key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_ecdsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EcDSA public key and a private ECDH key.
void GNUNET_CRYPTO_eddsa_key_create(struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
Create a new private key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_eddsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EdDSA public key and a private ECDH key.
void GNUNET_CRYPTO_ecdsa_key_create(struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
Create a new private key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig)
EdDSA sign a given block.
void GNUNET_CRYPTO_ecdsa_key_clear(struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
Clear memory that was used to store a private key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_verify_(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EcdsaSignature *sig, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Verify ECDSA signature.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_CRYPTO_ecdsa_key_get_anonymous()
Get the shared private key we use for anonymous users.
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_verify_(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Verify EdDSA signature.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_x25519(const struct GNUNET_CRYPTO_EcdhePrivateKey *sk, const struct GNUNET_CRYPTO_EcdhePublicKey *pk, struct GNUNET_CRYPTO_EcdhePublicKey *dh)
Derive key material from a EdDSA public key and a private ECDH key.
void GNUNET_CRYPTO_ecdhe_key_clear(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Clear memory that was used to store a private key.
void GNUNET_CRYPTO_ecdhe_key_get_public(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
Extract the public key for the given private key.
@ GNUNET_CRYPTO_QUALITY_NONCE
Randomness for IVs etc.
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
char * GNUNET_CRYPTO_eddsa_private_key_to_string(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
Convert a private key to a string.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_raw(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, void *data, size_t size, struct GNUNET_CRYPTO_EddsaSignature *sig)
#define GNUNET_log(kind,...)
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a string representing a public key to a public key.
char * GNUNET_CRYPTO_eddsa_public_key_to_string(const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a public key to a string.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a string representing a public key to a public key.
void GNUNET_CRYPTO_mpi_print_unsigned(void *buf, size_t size, gcry_mpi_t val)
Output the given MPI value to the given buffer in network byte order.
char * GNUNET_CRYPTO_ecdsa_public_key_to_string(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a public key to a string.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_private_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
Convert a string representing a private key to a private key.
char * GNUNET_CRYPTO_ecdsa_private_key_to_string(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
Convert a private key to a string.
GNUNET_GenericReturnValue
Named constants for return values.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
enum GNUNET_GenericReturnValue GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
static unsigned int size
Size of the "table".
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
Private ECC key encoded for transmission.
unsigned char d[256/8]
d is a value mod n, where n has at most 256 bits.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
unsigned char q_y[256/8]
Q consists of an x- and a y-value, each mod p (256 bits), given here in affine coordinates and Ed2551...
Private ECC key encoded for transmission.
unsigned char d[256/8]
d is a value mod n, where n has at most 256 bits.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
an ECC signature using ECDSA
unsigned char s[256/8]
S value.
unsigned char r[256/8]
R value.
Private ECC key encoded for transmission.
unsigned char d[256/8]
d is a value mod n, where n has at most 256 bits.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
unsigned char q_y[256/8]
Point Q consists of a y-value mod p (256 bits); the x-value is always positive.
an ECC signature using EdDSA.