Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
ex_ecc.c
Go to the documentation of this file.
1/*
2 * Nilorea Library
3 * Copyright (C) 2005-2026 Castagnier Mickael
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 */
19
26
27#include "nilorea/n_ecc.h"
28#include "nilorea/n_log.h"
29
30#include <stdio.h>
31#include <string.h>
32
33static int failures = 0;
34
35int main(void) {
37
38#if !N_ECC_AVAILABLE
39 /* Curve25519 needs OpenSSL 1.1.1. On the OpenSSL 1.0.2 this library still
40 supports, every n_ecc entry point is a logged failure, so there is
41 nothing here to exercise. Report the skip and succeed rather than count
42 an absent primitive as a bug. */
43 n_log(LOG_NOTICE, "ex_ecc: skipped, this OpenSSL does not provide X25519/Ed25519");
44 return 0;
45#else
46 /* X25519: the two parties derive the same shared secret */
47 unsigned char a_priv[N_ECC_KEY_LEN], a_pub[N_ECC_KEY_LEN];
48 unsigned char b_priv[N_ECC_KEY_LEN], b_pub[N_ECC_KEY_LEN];
49 unsigned char sh_a[N_ECC_KEY_LEN], sh_b[N_ECC_KEY_LEN];
50 if (n_x25519_keypair(a_priv, a_pub) != 0 || n_x25519_keypair(b_priv, b_pub) != 0) {
51 n_log(LOG_ERR, "x25519 keypair failed");
52 failures++;
53 } else if (n_x25519_derive(a_priv, b_pub, sh_a) != 0 || n_x25519_derive(b_priv, a_pub, sh_b) != 0) {
54 n_log(LOG_ERR, "x25519 derive failed");
55 failures++;
56 } else if (memcmp(sh_a, sh_b, N_ECC_KEY_LEN) != 0) {
57 n_log(LOG_ERR, "x25519 shared secrets differ");
58 failures++;
59 }
60 /* two independent keypairs must not collide */
61 if (memcmp(a_pub, b_pub, N_ECC_KEY_LEN) == 0) {
62 n_log(LOG_ERR, "x25519 keypairs collided");
63 failures++;
64 }
65
66 /* Ed25519: sign then verify; a tampered signature or message must not verify */
67 unsigned char s_priv[N_ECC_KEY_LEN], s_pub[N_ECC_KEY_LEN];
68 unsigned char sig[N_ECC_SIG_LEN];
69 const unsigned char msg[] = "the quick brown fox";
70 size_t mlen = sizeof(msg) - 1;
71 if (n_ed25519_keypair(s_priv, s_pub) != 0) {
72 n_log(LOG_ERR, "ed25519 keypair failed");
73 failures++;
74 } else if (n_ed25519_sign(s_priv, msg, mlen, sig) != 0) {
75 n_log(LOG_ERR, "ed25519 sign failed");
76 failures++;
77 } else {
78 if (n_ed25519_verify(s_pub, msg, mlen, sig) != 0) {
79 n_log(LOG_ERR, "ed25519 verify (good) failed");
80 failures++;
81 }
82 sig[0] ^= 0x01;
83 if (n_ed25519_verify(s_pub, msg, mlen, sig) == 0) {
84 n_log(LOG_ERR, "ed25519 verify accepted a tampered signature");
85 failures++;
86 }
87 sig[0] ^= 0x01;
88 unsigned char m2[sizeof(msg) - 1];
89 memcpy(m2, msg, mlen);
90 m2[0] ^= 0x01;
91 if (n_ed25519_verify(s_pub, m2, mlen, sig) == 0) {
92 n_log(LOG_ERR, "ed25519 verify accepted a tampered message");
93 failures++;
94 }
95 }
96
97 if (failures) {
98 n_log(LOG_ERR, "ex_ecc: %d failure(s)", failures);
99 return 1;
100 }
101 n_log(LOG_NOTICE, "ex_ecc: all checks passed");
102 return 0;
103#endif
104}
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.