34 #define EXTRA_CHECKS 0
59 #define CURVE "Ed25519"
61 #define LOG(kind, ...) GNUNET_log_from (kind, "util-crypto-ecc", __VA_ARGS__)
63 #define LOG_STRERROR(kind, syscall) \
64 GNUNET_log_from_strerror (kind, "util-crypto-ecc", syscall)
66 #define LOG_STRERROR_FILE(kind, syscall, filename) \
67 GNUNET_log_from_strerror_file (kind, "util-crypto-ecc", syscall, filename)
74 #define LOG_GCRY(level, cmd, rc) \
78 _ ("`%s' failed at %s:%d with error: %s\n"), \
82 gcry_strerror (rc)); \
105 list = gcry_sexp_find_token (sexp, topname, 0);
108 l2 = gcry_sexp_cadr (
list);
109 gcry_sexp_release (
list);
115 for (
const char *s = elems; *s; s++, idx++)
117 l2 = gcry_sexp_find_token (
list, s, 1);
120 for (
unsigned int i = 0; i < idx; i++)
122 gcry_free (array[i]);
125 gcry_sexp_release (
list);
128 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
129 gcry_sexp_release (l2);
132 for (
unsigned int i = 0; i < idx; i++)
134 gcry_free (array[i]);
137 gcry_sexp_release (
list);
141 gcry_sexp_release (
list);
160 for (
size_t i = 0; i<32; i++)
161 d[i] = priv->
d[31 - i];
163 rc = gcry_sexp_build (&
result,
165 "(private-key(ecc(curve \"" CURVE "\")"
175 if (0 != (rc = gcry_pk_testkey (
result)))
191 crypto_scalarmult_ed25519_base_noclamp (
pub->
q_y, priv->
d);
201 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
202 unsigned char sk[crypto_sign_SECRETKEYBYTES];
207 sodium_memzero (sk, crypto_sign_SECRETKEYBYTES);
232 keylen += 5 - keylen % 5;
259 keylen += 5 - keylen % 5;
286 keylen += 5 - keylen % 5;
313 keylen += 5 - keylen % 5;
340 keylen += 5 - keylen % 5;
342 if (enclen != keylen)
365 keylen += 5 - keylen % 5;
367 if (enclen != keylen)
390 keylen += 5 - keylen % 5;
392 if (enclen != keylen)
495 anonymous.
d[0] &= 248;
496 anonymous.
d[31] &= 127;
497 anonymous.
d[31] |= 64;
522 if (0 != (rc = gcry_sexp_build (&
data,
524 "(data(flags rfc6979)(hash %s %b))",
533 if (0 != (rc = gcry_sexp_build (&
data,
535 "(data(flags rfc6979)(hash %s %b))",
537 ntohl (purpose->
size),
554 gcry_sexp_t priv_sexp;
555 gcry_sexp_t sig_sexp;
564 if (0 != (rc = gcry_pk_sign (&sig_sexp,
data, priv_sexp)))
567 _ (
"ECC signing failed at %s:%d: %s\n"),
571 gcry_sexp_release (
data);
572 gcry_sexp_release (priv_sexp);
575 gcry_sexp_release (priv_sexp);
576 gcry_sexp_release (
data);
580 if (0 != (rc =
key_from_sexp (rs, sig_sexp,
"sig-val",
"rs")))
583 gcry_sexp_release (sig_sexp);
586 gcry_sexp_release (sig_sexp);
589 gcry_mpi_release (rs[0]);
590 gcry_mpi_release (rs[1]);
604 unsigned char sk[crypto_sign_SECRETKEYBYTES];
605 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
609 res = crypto_sign_detached ((uint8_t *) sig,
625 size_t mlen = ntohl (purpose->
size);
626 unsigned char sk[crypto_sign_SECRETKEYBYTES];
627 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
632 res = crypto_sign_detached ((uint8_t *) sig,
650 gcry_sexp_t sig_sexpr;
651 gcry_sexp_t pub_sexpr;
656 if (purpose != ntohl (validate->
purpose))
660 if (0 != (rc = gcry_sexp_build (&sig_sexpr,
662 "(sig-val(ecdsa(r %b)(s %b)))",
663 (
int)
sizeof(sig->
r),
665 (
int)
sizeof(sig->
s),
672 if (0 != (rc = gcry_sexp_build (&pub_sexpr,
674 "(public-key(ecc(curve " CURVE ")(q %b)))",
678 gcry_sexp_release (
data);
679 gcry_sexp_release (sig_sexpr);
682 rc = gcry_pk_verify (sig_sexpr,
data, pub_sexpr);
683 gcry_sexp_release (pub_sexpr);
684 gcry_sexp_release (
data);
685 gcry_sexp_release (sig_sexpr);
689 _ (
"ECDSA signature verification failed at %s:%d: %s\n"),
708 const unsigned char *
m = (
const void *) validate;
709 size_t mlen = ntohl (validate->
size);
710 const unsigned char *s = (
const void *) sig;
714 if (purpose != ntohl (validate->
purpose))
719 res = crypto_sign_verify_detached (s,
m, mlen,
pub->
q_y);
730 uint8_t
p[crypto_scalarmult_BYTES];
731 if (0 != crypto_scalarmult (
p, priv->
d,
pub->
q_y))
744 uint8_t a[crypto_scalarmult_SCALARBYTES];
745 uint8_t
p[crypto_scalarmult_BYTES];
751 if (0 != crypto_scalarmult (
p, a,
pub->
q_y))
754 crypto_scalarmult_BYTES,
765 uint8_t
p[crypto_scalarmult_BYTES];
768 if (0 != crypto_scalarmult (
p, priv->
d,
pub->
q_y))
771 crypto_scalarmult_BYTES,
783 uint8_t
p[crypto_scalarmult_BYTES];
784 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
786 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk,
pub->
q_y))
788 if (0 != crypto_scalarmult (
p, priv->
d, curve25510_pk))
800 uint8_t
p[crypto_scalarmult_BYTES];
801 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
803 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk,
pub->
q_y))
805 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:
#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 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 OpusEncoder * enc
OPUS encoder.
uint32_t data
The data value.
struct GNUNET_IDENTITY_PrivateKey pk
Private key from command line option, or NULL.
static int result
Global testing status.
static struct GNUNET_CRYPTO_EddsaPublicKey pub
static struct GNUNET_OS_Process * p
Helper process we started.
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.
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)
Derive key material from a ECDH public key and a private ECDSA key.
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.
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_CRYPTO_ecdsa_key_get_anonymous()
Get the shared private key we use for anonymous users.
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.
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.
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.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_raw(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, void *data, size_t size, struct GNUNET_CRYPTO_EddsaSignature *sig)
char * GNUNET_CRYPTO_ecdsa_public_key_to_string(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a public key to a string.
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.
#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.
GNUNET_GenericReturnValue
Named constants for return values.
char * GNUNET_CRYPTO_ecdsa_private_key_to_string(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
Convert a private key to a string.
char * GNUNET_CRYPTO_eddsa_private_key_to_string(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
Convert a private key to a string.
#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...
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.