mirror of
https://github.com/open-quantum-safe/liboqs.git
synced 2025-10-04 00:02:01 -04:00
Merge remote-tracking branch 'upstream/master' into cp-update-picnic
Merged with upstream master.
This commit is contained in:
commit
38d4c6ad74
2
.gitignore
vendored
2
.gitignore
vendored
@ -36,6 +36,8 @@ include
|
||||
/test_sig
|
||||
/test_rand
|
||||
/test_aes
|
||||
/minimal_kex_oqs
|
||||
/minimal_sig_oqs
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
|
@ -1,15 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [[ $(nm -g liboqs.a | grep ' T ' | grep -E -v -i ' T [_]?[OQS|ntru|picnic|Keccak]') ]];
|
||||
REGEX=' T [_]?(OQS|ntru|picnic|Keccak|.*SIKEp503|.*SIDHp503|.*SIKEp751|.*SIDHp751|.*shake128|.*shake256|rand_bytes|cpu_supports|uint64_from_char_array|uint64_to_char_array|print_hex|ntt_double|rec|aligned_alloc|aligned_free)'
|
||||
|
||||
if [[ $(nm -g liboqs.a | grep ' T ' | grep -E -v -i "$REGEX") ]];
|
||||
then
|
||||
tput setaf 1;
|
||||
echo "Code contains the following non-namespaced global symbols; see https://github.com/open-quantum-safe/liboqs/wiki/Coding-conventions for function naming conventions.";
|
||||
tput sgr 0
|
||||
nm -g liboqs.a | grep ' T ' | grep -E -v -i ' T [_]?[OQS|ntru|picnic|Keccak]'
|
||||
exit 1;
|
||||
tput setaf 1;
|
||||
echo "Code contains the following non-namespaced global symbols; see https://github.com/open-quantum-safe/liboqs/wiki/Coding-conventions for function naming conventions.";
|
||||
tput sgr 0
|
||||
nm -g liboqs.a | grep ' T ' | grep -E -v -i "$REGEX"
|
||||
exit 1;
|
||||
else
|
||||
tput setaf 2;
|
||||
echo "Code adheres to the project standards (global namespace).";
|
||||
tput sgr 0
|
||||
exit 0;
|
||||
tput setaf 2;
|
||||
echo "Code adheres to the project standards (global namespace).";
|
||||
tput sgr 0
|
||||
exit 0;
|
||||
fi;
|
||||
|
60
Makefile.am
60
Makefile.am
@ -92,9 +92,6 @@ if USE_SIDH_IQC
|
||||
cp src/kex_sidh_iqc_ref/kex_sidh_iqc_ref.h $(includedir)/oqs
|
||||
endif
|
||||
|
||||
|
||||
noinst_bin_PROGRAMS = test_rand test_kex test_aes
|
||||
|
||||
libmerge_external.la:
|
||||
if USE_SIG_PICNIC
|
||||
mkdir -p temp && cp liboqs.a temp/ && cp src/sig_picnic/external/build/libpicnic_static.a temp/
|
||||
@ -102,7 +99,13 @@ if USE_SIG_PICNIC
|
||||
cd .. && rm -rf temp
|
||||
endif
|
||||
|
||||
noinst_bin_PROGRAMS = test_rand test_kex test_aes test_sig
|
||||
noinst_bin_PROGRAMS = test_kex test_aes test_rand
|
||||
if USE_KEX_LWE_FRODO
|
||||
noinst_bin_PROGRAMS += minimal_kex_oqs
|
||||
endif
|
||||
if USE_SIG_PICNIC
|
||||
noinst_bin_PROGRAMS += test_sig minimal_sig_oqs
|
||||
endif
|
||||
|
||||
noinst_bindir=$(prefix)/tests
|
||||
test_kex_LDADD = liboqs.la -lm
|
||||
@ -119,6 +122,7 @@ if USE_SIDH_IQC
|
||||
test_kex_LDADD += -L$(GMP_DIR)/lib -lgmp
|
||||
endif
|
||||
|
||||
if USE_SIG_PICNIC
|
||||
test_sig_LDADD = liboqs.la -lm
|
||||
test_sig_SOURCES = src/sig/test_sig.c
|
||||
test_sig_CPPFLAGS = -I./include
|
||||
@ -127,6 +131,33 @@ if USE_OPENSSL
|
||||
test_sig_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
|
||||
endif
|
||||
|
||||
minimal_sig_oqs_LDADD = liboqs.la -lm
|
||||
minimal_sig_oqs_SOURCES = src/sig/minimal_sig_oqs.c
|
||||
minimal_sig_oqs_CPPFLAGS = -I./include
|
||||
minimal_sig_oqs_CPPFLAGS += $(AM_CPPFLAGS)
|
||||
if USE_OPENSSL
|
||||
minimal_sig_oqs_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
|
||||
endif
|
||||
|
||||
endif # USE_SIG_PICNIC
|
||||
|
||||
if USE_KEX_LWE_FRODO
|
||||
minimal_kex_oqs_LDADD = liboqs.la -lm
|
||||
minimal_kex_oqs_SOURCES = src/kex/minimal_kex_oqs.c
|
||||
minimal_kex_oqs_CPPFLAGS = -I./include
|
||||
minimal_kex_oqs_CPPFLAGS += $(AM_CPPFLAGS)
|
||||
if USE_MCBITS
|
||||
minimal_kex_oqs_LDADD += -L${SODIUM_DIR}/lib -lsodium
|
||||
endif
|
||||
if USE_OPENSSL
|
||||
minimal_kex_oqs_LDADD += -L$(OPENSSL_DIR)/lib -lcrypto
|
||||
endif
|
||||
if USE_SIDH_IQC
|
||||
minimal_kex_oqs_LDADD += -L$(GMP_DIR)/lib -lgmp
|
||||
endif
|
||||
|
||||
endif # USE_KEX_LWE_FRODO
|
||||
|
||||
test_aes_LDADD = liboqs.la -lm
|
||||
test_aes_SOURCES = src/crypto/aes/test_aes.c
|
||||
test_aes_CPPFLAGS = -I./include
|
||||
@ -147,15 +178,22 @@ else
|
||||
if USE_AES_NI
|
||||
test_rand_CPPFLAGS += -maes -msse2
|
||||
endif
|
||||
endif
|
||||
endif # USE_OPENSSL
|
||||
|
||||
|
||||
test: clean-tests
|
||||
make
|
||||
./test_kex --quiet
|
||||
./test_rand --quiet
|
||||
./test_aes
|
||||
if USE_SIG_PICNIC
|
||||
./test_sig
|
||||
|
||||
./minimal_sig_oqs
|
||||
endif
|
||||
if USE_KEX_LWE_FRODO
|
||||
./minimal_kex_oqs
|
||||
endif
|
||||
|
||||
links:
|
||||
$(MKDIR_P) include/oqs
|
||||
cp -f config.h include/oqs
|
||||
@ -190,13 +228,19 @@ endif
|
||||
clean-local:
|
||||
rm -f liboqs.a
|
||||
rm -rf include
|
||||
if USE_KEX_LWE_FRODO
|
||||
rm -f minimal_kex_oqs
|
||||
endif
|
||||
if USE_SIG_PICNIC
|
||||
rm -f test_sig
|
||||
rm -f minimal_sig_oqs
|
||||
endif
|
||||
if USE_SIDH_IQC
|
||||
rm -f sample_params
|
||||
endif
|
||||
|
||||
|
||||
clean-tests:
|
||||
rm -f test_kex test_rand test_aes test_sig
|
||||
rm -f test_kex test_rand test_aes
|
||||
|
||||
prettyprint:
|
||||
find src -name '*.c' -o -name '*.h' | grep -v sig_picnic/external* | grep -v "kex_rlwe_newhope/avx2" | grep -v "kex_sidh_msr" | xargs $(CLANGFORMAT) -style=file -i
|
||||
|
@ -69,7 +69,8 @@ This will generate:
|
||||
- `test_aes`: A simple test harness for AES. This will test the correctness of the C implementation (and of the AES-NI implementation, if not disabled) of AES, and will compare the speed of these implementations against OpenSSL's AES implementation.
|
||||
- `test_kex`: A simple test harness for the default key exchange algorithm. This will output key exchange messages; indicate whether the parties agree on the session key or not over a large number of trials; and measure the distance of the sessions keys from uniform using statistical distance.
|
||||
- `test_sig`: A simple test harness for the signature algorithms.
|
||||
|
||||
- `minimal_kex_oqs`: A minimal runnable example showing the usage of KEX API.
|
||||
- `minimal_sig_oqs`: A minimal runnable example showing the usage of SIG API.
|
||||
### Running
|
||||
|
||||
To run the tests, simply type:
|
||||
|
180
src/kex/minimal_kex_oqs.c
Normal file
180
src/kex/minimal_kex_oqs.c
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* minimal_kex_oqs.c
|
||||
*
|
||||
* Minimal example of a Diffie-Hellman post-quantum key exchange method
|
||||
* implemented in liboqs.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <oqs/common.h>
|
||||
#include <oqs/kex.h>
|
||||
#include <oqs/rand.h>
|
||||
|
||||
/* Displays hexadecimal strings */
|
||||
void disp_hex_string(const char *label, uint8_t *str, size_t len);
|
||||
|
||||
/* Partially displays hexadecimal strings */
|
||||
void disp_part_hex_string(const char *label, uint8_t *str, size_t len,
|
||||
size_t sub_len);
|
||||
|
||||
/* Cleaning up memory etc */
|
||||
void cleanup(uint8_t *alice_msg, size_t alice_msg_len, uint8_t *alice_key,
|
||||
size_t alice_key_len, uint8_t *bob_msg, size_t bob_msg_len,
|
||||
uint8_t *bob_key, size_t bob_key_len, void *alice_priv,
|
||||
OQS_KEX *kex, OQS_RAND *rnd);
|
||||
|
||||
int main(void) {
|
||||
/* Key exchange parameters */
|
||||
void *alice_priv = NULL; // Alice's private key
|
||||
uint8_t *alice_msg = NULL; // Alice's message
|
||||
size_t alice_msg_len = 0; // Alice's message length
|
||||
uint8_t *alice_key = NULL; // Alice's final key
|
||||
size_t alice_key_len = 0; // Alice's final key length
|
||||
|
||||
uint8_t *bob_msg = NULL; // Bob's message
|
||||
size_t bob_msg_len = 0; // Bob's message length
|
||||
uint8_t *bob_key = NULL; // Bob's final key
|
||||
size_t bob_key_len = 0; // Bob's final key length
|
||||
|
||||
/* Setup the key exchange protocol */
|
||||
enum OQS_KEX_alg_name alg_name = OQS_KEX_alg_lwe_frodo; // Alg. name
|
||||
const uint8_t *seed = (unsigned char *) "01234567890123456"; // Rand. seed
|
||||
const size_t seed_len = 16; // Seed length
|
||||
const char *named_parameters = "recommended"; // Named params.
|
||||
OQS_RAND *rnd = NULL; // Source of randomness
|
||||
OQS_KEX *kex = NULL; // OQS_KEX structure
|
||||
|
||||
/* Setup the source of randomness */
|
||||
rnd = OQS_RAND_new(OQS_RAND_alg_urandom_chacha20);
|
||||
if (rnd == NULL) {
|
||||
eprintf("ERROR: Setting up the randomness source!\n");
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Populate the OQS_KEX structure, here's where liboqs sets up
|
||||
* the specific details of the selected KEX implementation */
|
||||
kex = OQS_KEX_new(rnd, alg_name, seed, seed_len, named_parameters);
|
||||
if (kex == NULL) {
|
||||
eprintf("ERROR: OQS_KEX_new failed!\n");
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Proceed with the Diffie-Hellman key exchange mechanism */
|
||||
printf("===============================================================\n");
|
||||
printf("Diffie-Hellman post-quantum key exchange: %s\n", kex->method_name);
|
||||
printf("===============================================================\n");
|
||||
|
||||
/* Alice's initial message */
|
||||
int success = OQS_KEX_alice_0(kex, &alice_priv, &alice_msg, &alice_msg_len);
|
||||
if (success != OQS_SUCCESS) {
|
||||
eprintf("ERROR: OQS_KEX_alice_0 failed!\n");
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
disp_part_hex_string("Alice message", alice_msg, alice_msg_len, 20);
|
||||
|
||||
/* Bob's response */
|
||||
success = OQS_KEX_bob(kex, alice_msg, alice_msg_len, &bob_msg, &bob_msg_len,
|
||||
&bob_key, &bob_key_len);
|
||||
if (success != OQS_SUCCESS) {
|
||||
eprintf("ERROR: OQS_KEX_bob failed!\n");
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
disp_part_hex_string("Bob message", bob_msg, bob_msg_len, 20);
|
||||
disp_hex_string("Bob session key", bob_key, bob_key_len);
|
||||
|
||||
/* Alice processes Bob's response */
|
||||
success = OQS_KEX_alice_1(kex, alice_priv, bob_msg, bob_msg_len, &alice_key,
|
||||
&alice_key_len);
|
||||
if (success != OQS_SUCCESS) {
|
||||
eprintf("ERROR: OQS_KEX_alice_1 failed!\n");
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
disp_hex_string("Alice session key", alice_key, alice_key_len);
|
||||
|
||||
/* Compare key lengths */
|
||||
if (alice_key_len != bob_key_len) {
|
||||
eprintf("ERROR: Alice's session key and Bob's session keys "
|
||||
"have different lengths (%zu vs %zu)!\n",
|
||||
alice_key_len, bob_key_len);
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Compare key values */
|
||||
success = memcmp(alice_key, bob_key, alice_key_len);
|
||||
if (success != 0) {
|
||||
eprintf("ERROR: Alice's session key and Bob's session "
|
||||
"key are not equal!\n");
|
||||
disp_hex_string("Alice session key", alice_key, alice_key_len);
|
||||
disp_hex_string("Bob session key", bob_key, bob_key_len);
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Success and clean-up */
|
||||
printf("Alice and Bob's session keys match.\n");
|
||||
cleanup(alice_msg, alice_msg_len, alice_key, alice_key_len, bob_msg,
|
||||
bob_msg_len, bob_key, bob_key_len, alice_priv, kex, rnd);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void disp_hex_string(const char *label, uint8_t *str, size_t len) {
|
||||
printf("%-20s (%4zu bytes): ", label, len);
|
||||
for (size_t i = 0; i < (len); i++) {
|
||||
printf("%02X", ((unsigned char *) (str))[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void disp_part_hex_string(const char *label, uint8_t *str, size_t len,
|
||||
size_t sub_len) {
|
||||
printf("%-20s (%4zu bytes): ", label, len);
|
||||
for (size_t i = 0; i < (sub_len); i++) {
|
||||
printf("%02X", ((unsigned char *) (str))[i]);
|
||||
}
|
||||
printf("...");
|
||||
for (size_t i = 0; i < (sub_len); i++) {
|
||||
printf("%02X", ((unsigned char *) (str))[len - sub_len + i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void cleanup(uint8_t *alice_msg, size_t alice_msg_len, uint8_t *alice_key,
|
||||
size_t alice_key_len, uint8_t *bob_msg, size_t bob_msg_len,
|
||||
uint8_t *bob_key, size_t bob_key_len, void *alice_priv,
|
||||
OQS_KEX *kex, OQS_RAND *rnd) {
|
||||
/* Secure cleaning */
|
||||
OQS_MEM_secure_free(alice_msg, alice_msg_len);
|
||||
OQS_MEM_secure_free(alice_key, alice_key_len);
|
||||
OQS_MEM_secure_free(bob_msg, bob_msg_len);
|
||||
OQS_MEM_secure_free(bob_key, bob_key_len);
|
||||
OQS_KEX_alice_priv_free(kex, alice_priv);
|
||||
OQS_KEX_free(kex);
|
||||
OQS_RAND_free(rnd);
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
/**
|
||||
* \file kex_sike_msr.h
|
||||
* \brief Header for SIKE key exchange protocol from the Microsoft SIDH library
|
||||
*/
|
||||
|
||||
#ifndef __OQS_KEX_SIKE_MSR_H
|
||||
#define __OQS_KEX_SIKE_MSR_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <oqs/kex.h>
|
||||
#include <oqs/rand.h>
|
||||
|
||||
OQS_KEX *OQS_KEX_sike_msr_new(OQS_RAND *rand, const char *named_parameters);
|
||||
|
||||
int OQS_KEX_sike_msr_alice_0(OQS_KEX *k, void **alice_priv, uint8_t **alice_msg, size_t *alice_msg_len);
|
||||
int OQS_KEX_sike_msr_bob(OQS_KEX *k, const uint8_t *alice_msg, const size_t alice_msg_len, uint8_t **bob_msg, size_t *bob_msg_len, uint8_t **key, size_t *key_len);
|
||||
int OQS_KEX_sike_msr_alice_1(OQS_KEX *k, const void *alice_priv, const uint8_t *bob_msg, const size_t bob_msg_len, uint8_t **key, size_t *key_len);
|
||||
|
||||
void OQS_KEX_sike_msr_alice_priv_free(OQS_KEX *k, void *alice_priv);
|
||||
void OQS_KEX_sike_msr_free(OQS_KEX *k);
|
||||
|
||||
#endif
|
177
src/sig/minimal_sig_oqs.c
Normal file
177
src/sig/minimal_sig_oqs.c
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* minimal_sig_oqs.c
|
||||
*
|
||||
* Minimal example of a post-quantum signature method implemented in liboqs.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <oqs/common.h>
|
||||
#include <oqs/rand.h>
|
||||
#include <oqs/sig.h>
|
||||
|
||||
/* Displays hexadecimal strings */
|
||||
void disp_hex_string(const char *label, uint8_t *str, size_t len);
|
||||
|
||||
/* Partially displays hexadecimal strings */
|
||||
void disp_part_hex_string(const char *label, uint8_t *str, size_t len,
|
||||
size_t sub_len);
|
||||
|
||||
/* Cleaning up memory etc */
|
||||
void cleanup(uint8_t *msg, size_t msg_len, uint8_t *sig, size_t sig_len,
|
||||
uint8_t *pub, uint8_t *priv, OQS_SIG *s, OQS_RAND *rnd);
|
||||
|
||||
int main(void) {
|
||||
uint8_t *priv = NULL; // Private key
|
||||
uint8_t *pub = NULL; // Public key
|
||||
uint8_t *msg = NULL; // Message
|
||||
size_t msg_len = 0; // Message's length
|
||||
uint8_t *sig = NULL; // Signature
|
||||
size_t sig_len = 0; // Signature's length
|
||||
|
||||
enum OQS_SIG_algid alg_name = OQS_SIG_picnic_default; // Algorithm name
|
||||
// Equivalent to OQS_SIG_picnic_L1_FS
|
||||
|
||||
OQS_RAND *rnd = NULL; // Source of randomness
|
||||
OQS_SIG *s = NULL; // OQS_SIG structure
|
||||
|
||||
/* Setup the source of randomness */
|
||||
rnd = OQS_RAND_new(OQS_RAND_alg_urandom_chacha20);
|
||||
if (rnd == NULL) {
|
||||
eprintf("ERROR: Setting up the randomness source!\n");
|
||||
cleanup(msg, msg_len, sig, sig_len, pub, priv, s, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Populate the OQS_SIG structure, here's where liboqs sets up
|
||||
* the specific details of the selected SIG implementation */
|
||||
s = OQS_SIG_new(rnd, alg_name);
|
||||
if (s == NULL) {
|
||||
eprintf("ERROR: OQS_SIG_new failed!\n");
|
||||
cleanup(msg, msg_len, sig, sig_len, pub, priv, s, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Proceed with the signature generation */
|
||||
printf("====================================\n");
|
||||
printf("Post-quantum signature: %s\n", s->method_name);
|
||||
printf("====================================\n");
|
||||
|
||||
/* Private key memory allocation */
|
||||
priv = malloc(s->priv_key_len);
|
||||
if (priv == NULL) {
|
||||
eprintf("ERROR: priv malloc failed!\n");
|
||||
cleanup(msg, msg_len, sig, sig_len, pub, priv, s, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Public key memory generation */
|
||||
pub = malloc(s->pub_key_len);
|
||||
if (pub == NULL) {
|
||||
eprintf("ERROR: pub malloc failed!\n");
|
||||
cleanup(msg, msg_len, sig, sig_len, pub, priv, s, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Generates the signature key pair */
|
||||
int success = OQS_SIG_keygen(s, priv, pub);
|
||||
if (success != OQS_SUCCESS) {
|
||||
eprintf("ERROR: OQS_SIG_keygen failed!\n");
|
||||
cleanup(msg, msg_len, sig, sig_len, pub, priv, s, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
disp_hex_string("Private key", priv, s->priv_key_len);
|
||||
disp_hex_string("Public key", pub, s->pub_key_len);
|
||||
|
||||
/* Allocates the memory for the message to sign */
|
||||
msg_len = 64; // TODO: randomize based on scheme's max length
|
||||
msg = malloc(msg_len);
|
||||
if (msg == NULL) {
|
||||
eprintf("ERROR: msg malloc failed!\n");
|
||||
cleanup(msg, msg_len, sig, sig_len, pub, priv, s, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Generates a random message to sign */
|
||||
OQS_RAND_n(rnd, msg, msg_len);
|
||||
disp_hex_string("Message", msg, msg_len);
|
||||
|
||||
/* Allocates memory for the signature */
|
||||
sig_len = s->max_sig_len;
|
||||
sig = malloc(sig_len);
|
||||
if (sig == NULL) {
|
||||
eprintf("ERROR: sig malloc failed!\n");
|
||||
cleanup(msg, msg_len, sig, sig_len, pub, priv, s, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Signs the message */
|
||||
success = OQS_SIG_sign(s, priv, msg, msg_len, sig, &sig_len);
|
||||
if (success != OQS_SUCCESS) {
|
||||
eprintf("ERROR: OQS_SIG_sign failed!\n");
|
||||
cleanup(msg, msg_len, sig, sig_len, pub, priv, s, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (sig_len > 40) {
|
||||
// only print the parts of the sig if too long
|
||||
disp_part_hex_string("Signature", sig, sig_len, 20);
|
||||
}
|
||||
|
||||
/* Verification */
|
||||
success = OQS_SIG_verify(s, pub, msg, msg_len, sig, sig_len);
|
||||
if (success != OQS_SUCCESS) {
|
||||
eprintf("ERROR: OQS_SIG_verify failed!\n");
|
||||
cleanup(msg, msg_len, sig, sig_len, pub, priv, s, rnd);
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* Success and clean-up */
|
||||
printf("Signature is valid.\n");
|
||||
cleanup(msg, msg_len, sig, sig_len, pub, priv, s, rnd);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void disp_hex_string(const char *label, uint8_t *str, size_t len) {
|
||||
printf("%-20s (%4zu bytes): ", label, len);
|
||||
for (size_t i = 0; i < (len); i++) {
|
||||
printf("%02X", ((unsigned char *) (str))[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void disp_part_hex_string(const char *label, uint8_t *str, size_t len,
|
||||
size_t sub_len) {
|
||||
printf("%-20s (%4zu bytes): ", label, len);
|
||||
for (size_t i = 0; i < (sub_len); i++) {
|
||||
printf("%02X", ((unsigned char *) (str))[i]);
|
||||
}
|
||||
printf("...");
|
||||
for (size_t i = 0; i < (sub_len); i++) {
|
||||
printf("%02X", ((unsigned char *) (str))[len - sub_len + i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* Cleaning up memory etc */
|
||||
void cleanup(uint8_t *msg, size_t msg_len, uint8_t *sig, size_t sig_len,
|
||||
uint8_t *pub, uint8_t *priv, OQS_SIG *s, OQS_RAND *rnd) {
|
||||
OQS_MEM_secure_free(msg, msg_len);
|
||||
OQS_MEM_secure_free(sig, sig_len);
|
||||
OQS_MEM_secure_free(pub, s->pub_key_len);
|
||||
OQS_MEM_secure_free(priv, s->priv_key_len);
|
||||
OQS_SIG_free(s);
|
||||
OQS_RAND_free(rnd);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user