Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_ecc.c

n_ecc regression: X25519 agreement + Ed25519 sign/verify round-trips.

n_ecc regression: X25519 agreement + Ed25519 sign/verify round-trips.

Author
Castagnier Mickael
Version
1.0
/*
* Nilorea Library
* Copyright (C) 2005-2026 Castagnier Mickael
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "nilorea/n_ecc.h"
#include "nilorea/n_log.h"
#include <stdio.h>
#include <string.h>
static int failures = 0;
int main(void) {
#if !N_ECC_AVAILABLE
/* Curve25519 needs OpenSSL 1.1.1. On the OpenSSL 1.0.2 this library still
supports, every n_ecc entry point is a logged failure, so there is
nothing here to exercise. Report the skip and succeed rather than count
an absent primitive as a bug. */
n_log(LOG_NOTICE, "ex_ecc: skipped, this OpenSSL does not provide X25519/Ed25519");
return 0;
#else
/* X25519: the two parties derive the same shared secret */
unsigned char a_priv[N_ECC_KEY_LEN], a_pub[N_ECC_KEY_LEN];
unsigned char b_priv[N_ECC_KEY_LEN], b_pub[N_ECC_KEY_LEN];
unsigned char sh_a[N_ECC_KEY_LEN], sh_b[N_ECC_KEY_LEN];
if (n_x25519_keypair(a_priv, a_pub) != 0 || n_x25519_keypair(b_priv, b_pub) != 0) {
n_log(LOG_ERR, "x25519 keypair failed");
} else if (n_x25519_derive(a_priv, b_pub, sh_a) != 0 || n_x25519_derive(b_priv, a_pub, sh_b) != 0) {
n_log(LOG_ERR, "x25519 derive failed");
} else if (memcmp(sh_a, sh_b, N_ECC_KEY_LEN) != 0) {
n_log(LOG_ERR, "x25519 shared secrets differ");
}
/* two independent keypairs must not collide */
if (memcmp(a_pub, b_pub, N_ECC_KEY_LEN) == 0) {
n_log(LOG_ERR, "x25519 keypairs collided");
}
/* Ed25519: sign then verify; a tampered signature or message must not verify */
unsigned char s_priv[N_ECC_KEY_LEN], s_pub[N_ECC_KEY_LEN];
unsigned char sig[N_ECC_SIG_LEN];
const unsigned char msg[] = "the quick brown fox";
size_t mlen = sizeof(msg) - 1;
if (n_ed25519_keypair(s_priv, s_pub) != 0) {
n_log(LOG_ERR, "ed25519 keypair failed");
} else if (n_ed25519_sign(s_priv, msg, mlen, sig) != 0) {
n_log(LOG_ERR, "ed25519 sign failed");
} else {
if (n_ed25519_verify(s_pub, msg, mlen, sig) != 0) {
n_log(LOG_ERR, "ed25519 verify (good) failed");
}
sig[0] ^= 0x01;
if (n_ed25519_verify(s_pub, msg, mlen, sig) == 0) {
n_log(LOG_ERR, "ed25519 verify accepted a tampered signature");
}
sig[0] ^= 0x01;
unsigned char m2[sizeof(msg) - 1];
memcpy(m2, msg, mlen);
m2[0] ^= 0x01;
if (n_ed25519_verify(s_pub, m2, mlen, sig) == 0) {
n_log(LOG_ERR, "ed25519 verify accepted a tampered message");
}
}
if (failures) {
n_log(LOG_ERR, "ex_ecc: %d failure(s)", failures);
return 1;
}
n_log(LOG_NOTICE, "ex_ecc: all checks passed");
return 0;
#endif
}
static int failures
Definition ex_atlas.c:51
int main(void)
Definition ex_atlas.c:117
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:113
#define LOG_ERR
error conditions
Definition n_log.h:100
void set_log_level(const int log_level)
Set the global log level value ( static int LOG_LEVEL ).
Definition n_log.c:123
#define LOG_NOTICE
normal but significant condition
Definition n_log.h:104
int n_ed25519_keypair(unsigned char *priv, unsigned char *pub)
generate an Ed25519 keypair as N_ECC_KEY_LEN-byte raw private and public keys.
Definition n_ecc.c:197
int n_ed25519_verify(const unsigned char *pub, const unsigned char *msg, size_t len, const unsigned char *sig)
Ed25519 verify the N_ECC_SIG_LEN-byte sig over len bytes of msg under the N_ECC_KEY_LEN-byte raw publ...
Definition n_ecc.c:221
int n_x25519_keypair(unsigned char *priv, unsigned char *pub)
generate an X25519 keypair as N_ECC_KEY_LEN-byte raw private and public keys.
Definition n_ecc.c:190
#define N_ECC_SIG_LEN
Ed25519 signature length in bytes.
Definition n_ecc.h:48
#define N_ECC_KEY_LEN
raw X25519/Ed25519 key length in bytes
Definition n_ecc.h:46
int n_ed25519_sign(const unsigned char *priv, const unsigned char *msg, size_t len, unsigned char *sig)
Ed25519 sign len bytes of msg with the N_ECC_KEY_LEN-byte raw private key into sig (N_ECC_SIG_LEN byt...
Definition n_ecc.c:212
int n_x25519_derive(const unsigned char *priv, const unsigned char *peer_pub, unsigned char *shared)
X25519 ECDH: derive the N_ECC_KEY_LEN-byte shared secret from our raw private key and the peer's raw ...
Definition n_ecc.c:204
Curve25519 primitives: X25519 key agreement and Ed25519 signatures.
Generic log system.