From c4518e9ab6b26cbe1a3cee8504f67a9cb405f6a1 Mon Sep 17 00:00:00 2001 From: Benson Muite Date: Sun, 6 Nov 2022 12:55:26 +0300 Subject: [PATCH 1/6] Check tweetnacl C version --- README.md | 4 ++- results.md | 1 + scripts/tweetnacl/Makefile | 2 ++ scripts/tweetnacl/README.md | 14 ++++++++ scripts/tweetnacl/main.c | 71 +++++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 scripts/tweetnacl/Makefile create mode 100644 scripts/tweetnacl/README.md create mode 100644 scripts/tweetnacl/main.c diff --git a/README.md b/README.md index 151f3bf..75ed296 100644 --- a/README.md +++ b/README.md @@ -83,7 +83,8 @@ For a total of 12 test vectors. - [Pyca](https://cryptography.io/en/latest/) using OpenSSL 1.1.1g as default backend : in `scripts/pyca-openssl` - [python-ed25519](https://github.com/warner/python-ed25519)) : in `scripts/python-ed25519` - [ref10 from SUPERCOP through Python bindings](https://github.com/warner/python-ed25519) : in `scripts/python-ed25519.py` -- [tweetnacl](https://www.npmjs.com/package/tweetnacl) version 1.0.3 : in `scripts/tweetnacl` +- [tweetnacl](https://tweetnacl.cr.yp.to/software.html) version 20140427 +- [tweetnacl.js](https://www.npmjs.com/package/tweetnacl) version 1.0.3 : in `scripts/tweetnacl` - [Zebra](https://github.com/ZcashFoundation/ed25519-zebra) : in unit tests ## Results @@ -107,6 +108,7 @@ For a total of 12 test vectors. |PyCA | V | V | V | V | X | X | X | X | X | X | X | V | |python-ed25519 | V | V | V | V | X | X | V | V | X | X | X | V | |ref10 | V | V | V | V | X | X | V | X | X | X | X | V | +|TweetNaCl | V | V | V | V | X | X | V | V | X | X | X | V | |TweetNaCl-js | V | V | V | V | X | X | V | V | X | X | X | V | |Zebra | V | V | V | V | V | V | X | X | X | V | V | V | --------------------------------------------------------------- diff --git a/results.md b/results.md index 8b68b34..a3d3b90 100644 --- a/results.md +++ b/results.md @@ -14,5 +14,6 @@ |PyCA | V | V | V | V | X | X | X | X | X | X | X | V | |python-ed25519 | V | V | V | V | X | X | V | V | X | X | X | V | |ref10 | V | V | V | V | X | X | V | X | X | X | X | V | +|TweetNaCl | V | V | V | V | X | X | V | V | X | X | X | V | |TweetNaCl-js | V | V | V | V | X | X | V | V | X | X | X | V | |Zebra | V | V | V | V | V | V | X | X | X | V | V | V | diff --git a/scripts/tweetnacl/Makefile b/scripts/tweetnacl/Makefile new file mode 100644 index 0000000..a0db599 --- /dev/null +++ b/scripts/tweetnacl/Makefile @@ -0,0 +1,2 @@ +main: main.c + gcc -o main randombytes.c tweetnacl.c main.c -I$(PWD) diff --git a/scripts/tweetnacl/README.md b/scripts/tweetnacl/README.md new file mode 100644 index 0000000..92a778b --- /dev/null +++ b/scripts/tweetnacl/README.md @@ -0,0 +1,14 @@ +TweetNaCl is in the Public Domain and is available at +https://tweetnacl.cr.yp.to/software.html + +Randombytes is available under MIT License and is available at +https://github.com/dsprenkels/randombytes + +``` +> wget https://tweetnacl.cr.yp.to/20140427/tweetnacl.c +> wget https://tweetnacl.cr.yp.to/20140427/tweetnacl.h +> wget https://raw.githubusercontent.com/dsprenkels/randombytes/4ca4200730d3d5e8f18a1728663287792ad5e227/randombytes.c +> wget https://raw.githubusercontent.com/dsprenkels/randombytes/4ca4200730d3d5e8f18a1728663287792ad5e227/randombytes.h +> make +> ./main +``` diff --git a/scripts/tweetnacl/main.c b/scripts/tweetnacl/main.c new file mode 100644 index 0000000..f2ce08f --- /dev/null +++ b/scripts/tweetnacl/main.c @@ -0,0 +1,71 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +// Copyright (c) Benson Muite +// +// This source code is licensed under the APACHE 2.0 license found in +// the LICENSE file in the root directory of this source tree. + +#include "tweetnacl.h" +#include + +#define MESSAGE_LEN 32 + +int main(void) { + + unsigned char pk[crypto_sign_PUBLICKEYBYTES]; + // Array message is larger than MESSAGE_LEN because + // verification in TweetNACL uses the additional space + unsigned char message[crypto_sign_BYTES + MESSAGE_LEN]; + unsigned long long message_len = MESSAGE_LEN; + unsigned char signed_message[crypto_sign_BYTES + MESSAGE_LEN]; + unsigned long long signed_message_len = crypto_sign_BYTES + MESSAGE_LEN; + + FILE *fp; + int number_of_test_vectors = 0; + char buff[255]; + int pos; + + fp = fopen("../../cases.txt", "r+"); + fscanf(fp, "%i", &number_of_test_vectors); + printf("Number of test vectors: %i\n", number_of_test_vectors); + printf("\n|TweetNaCl |"); + for (int i = 0; i < number_of_test_vectors; i++) { + // reading the message + fscanf(fp, "%s", buff); + pos = 0; + for (size_t count = 0; count < 32; count++) { + sscanf(buff + 4 + pos, "%2hhx", &message[count]); + sscanf(buff + 4 + pos, "%2hhx", &signed_message[count+64]); + pos += 2; + } + + // reading the public key + fscanf(fp, "%s", buff); // message 32 bytes + pos = 0; + for (size_t count = 0; count < 32; count++) { + sscanf(buff + 4 + pos, "%2hhx", &pk[count]); + pos += 2; + } + + // reading the signature + fscanf(fp, "%s", buff); + pos = 0; + for (size_t count = 0; count < 64; count++) { + sscanf(buff + 4 + pos, "%2hhx", &signed_message[count]); + pos += 2; + } + + int result = crypto_sign_open(message, &message_len, + signed_message, signed_message_len, &pk[0]); + if (result == -1) { + printf(" X |"); + // Incorrect signature! + } else { + printf(" V |"); + } + + } + + printf("\n"); + fclose(fp); + return 0; +} From 4cad4caf3a72d4122fb9090d1d000491c142a009 Mon Sep 17 00:00:00 2001 From: Benson Muite Date: Mon, 7 Nov 2022 21:59:05 +0300 Subject: [PATCH 2/6] Monocypher results --- README.md | 6 ++- results.md | 1 + scripts/monocypher/Makefile | 2 + scripts/monocypher/README.md | 13 +++++++ scripts/monocypher/main.c | 71 ++++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 scripts/monocypher/Makefile create mode 100644 scripts/monocypher/README.md create mode 100644 scripts/monocypher/main.c diff --git a/README.md b/README.md index 75ed296..38ccfc6 100644 --- a/README.md +++ b/README.md @@ -77,14 +77,15 @@ For a total of 12 test vectors. - [Go-ed25519](https://golang.org/pkg/crypto/ed25519/) : in `scripts/ed25519_test.go` - [libra-crypto](https://github.com/libra/libra/tree/master/crypto/crypto) : in unit tests - LibSodium, through [pynacl](https://github.com/pyca/pynacl) : in `scripts/pynacl_test.py` +- [Monocypher](https://monocypher.org) : in `scripts/monocypher` - nCipher's ed25519, by Rob Starkey - [npm's ed25519](https://www.npmjs.com/package/ed25519) : in `scripts/eddsa_test` - [OpenSSL](https://github.com/openssl/openssl) : in `scripts openssl_3/test_script.sh` - [Pyca](https://cryptography.io/en/latest/) using OpenSSL 1.1.1g as default backend : in `scripts/pyca-openssl` - [python-ed25519](https://github.com/warner/python-ed25519)) : in `scripts/python-ed25519` - [ref10 from SUPERCOP through Python bindings](https://github.com/warner/python-ed25519) : in `scripts/python-ed25519.py` -- [tweetnacl](https://tweetnacl.cr.yp.to/software.html) version 20140427 -- [tweetnacl.js](https://www.npmjs.com/package/tweetnacl) version 1.0.3 : in `scripts/tweetnacl` +- [tweetnacl](https://tweetnacl.cr.yp.to/software.html) version 20140427 : in `scripts/tweetnacl` +- [tweetnacl.js](https://www.npmjs.com/package/tweetnacl) version 1.0.3 : in `scripts/tweetnacl-js` - [Zebra](https://github.com/ZcashFoundation/ed25519-zebra) : in unit tests ## Results @@ -103,6 +104,7 @@ For a total of 12 test vectors. |Go | V | V | V | V | X | X | X | X | X | X | X | V | |libra-crypto | X | X | X | V | X | X | X | X | X | X | X | X | |LibSodium | X | X | X | V | X | X | X | X | X | X | X | X | +|Monocypher | V | V | V | V | X | X | X | X | X | X | X | V | |npm | V | V | V | V | X | X | X | X | X | X | X | V | |OpenSSL-3.0 | V | V | V | V | X | X | X | X | X | X | X | V | |PyCA | V | V | V | V | X | X | X | X | X | X | X | V | diff --git a/results.md b/results.md index a3d3b90..380ddb2 100644 --- a/results.md +++ b/results.md @@ -9,6 +9,7 @@ |Hacl* | V | V | V | V | X | X | X | X | X | X | X | X | |libra-crypto | X | X | X | V | X | X | X | X | X | X | X | X | |LibSodium | X | X | X | V | X | X | X | X | X | X | X | X | +|Monocypher | V | V | V | V | X | X | X | X | X | X | X | V | |npm | V | V | V | V | X | X | X | X | X | X | X | V | |OpenSSL-3.0 | V | V | V | V | X | X | X | X | X | X | X | V | |PyCA | V | V | V | V | X | X | X | X | X | X | X | V | diff --git a/scripts/monocypher/Makefile b/scripts/monocypher/Makefile new file mode 100644 index 0000000..5bd8bc7 --- /dev/null +++ b/scripts/monocypher/Makefile @@ -0,0 +1,2 @@ +main: main.c + gcc -o main monocypher-ed25519.c monocypher.c main.c -I$(PWD) diff --git a/scripts/monocypher/README.md b/scripts/monocypher/README.md new file mode 100644 index 0000000..f58007b --- /dev/null +++ b/scripts/monocypher/README.md @@ -0,0 +1,13 @@ +Monocypher is can be in the Public Domain or under a BSD 2 Clause +license. It is available at +https://monocypher.org + + +``` +> wget https://monocypher.org/download/monocypher-3.1.3.tar.gz +> tar -xf monocypher-3.1.3.tar.gz +> cp monocypher-3.1.3/src/monocypher.* . +> cp monocypher-3.1.3/src/optional/monocypher-ed25519.* . +> make +> ./main +``` diff --git a/scripts/monocypher/main.c b/scripts/monocypher/main.c new file mode 100644 index 0000000..32bbe69 --- /dev/null +++ b/scripts/monocypher/main.c @@ -0,0 +1,71 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +// Copyright (c) Benson Muite +// +// This source code is licensed under the APACHE 2.0 license found in +// the LICENSE file in the root directory of this source tree. + +#include "monocypher.h" +#include "monocypher-ed25519.h" +#include + +#define MESSAGE_LEN 32 +#define crypto_sign_PUBLICKEYBYTES 32 +#define crypto_sign_BYTES 64 + +int main(void) { + + unsigned char public_key[crypto_sign_PUBLICKEYBYTES]; + unsigned char message[MESSAGE_LEN]; + unsigned long long message_len = MESSAGE_LEN; + unsigned char signature[crypto_sign_BYTES]; + unsigned long long signature_len = crypto_sign_BYTES; + + FILE *fp; + int number_of_test_vectors = 0; + char buff[255]; + int pos; + + fp = fopen("../../cases.txt", "r+"); + fscanf(fp, "%i", &number_of_test_vectors); + printf("Number of test vectors: %i\n", number_of_test_vectors); + printf("\n|Monocypher |"); + for (int i = 0; i < number_of_test_vectors; i++) { + // reading the message + fscanf(fp, "%s", buff); + pos = 0; + for (size_t count = 0; count < 32; count++) { + sscanf(buff + 4 + pos, "%2hhx", &message[count]); + pos += 2; + } + + // reading the public key + fscanf(fp, "%s", buff); // message 32 bytes + pos = 0; + for (size_t count = 0; count < 32; count++) { + sscanf(buff + 4 + pos, "%2hhx", &public_key[count]); + pos += 2; + } + + // reading the signature + fscanf(fp, "%s", buff); + pos = 0; + for (size_t count = 0; count < 64; count++) { + sscanf(buff + 4 + pos, "%2hhx", &signature[count]); + pos += 2; + } + + int result = crypto_ed25519_check(signature, public_key, &message, message_len); + + if (result != 0) { + printf(" X |"); + // Incorrect signature! + } else { + printf(" V |"); + } + + } + + printf("\n"); + fclose(fp); + return 0; +} From 1c9efc4f5b5cf1bd2cb0865f5a4a892ccf75368f Mon Sep 17 00:00:00 2001 From: Benson Muite Date: Mon, 7 Nov 2022 22:47:12 +0300 Subject: [PATCH 3/6] Add wolfSSL --- README.md | 4 ++ results.md | 1 + scripts/wolfssl/Makefile | 5 +++ scripts/wolfssl/README.md | 17 ++++++++ scripts/wolfssl/main.c | 91 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 118 insertions(+) create mode 100644 scripts/wolfssl/Makefile create mode 100644 scripts/wolfssl/README.md create mode 100644 scripts/wolfssl/main.c diff --git a/README.md b/README.md index 38ccfc6..c6c7370 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,7 @@ For a total of 12 test vectors. - [ref10 from SUPERCOP through Python bindings](https://github.com/warner/python-ed25519) : in `scripts/python-ed25519.py` - [tweetnacl](https://tweetnacl.cr.yp.to/software.html) version 20140427 : in `scripts/tweetnacl` - [tweetnacl.js](https://www.npmjs.com/package/tweetnacl) version 1.0.3 : in `scripts/tweetnacl-js` +- [wolfSSL](https://github.com/wolfSSL/wolfssl) version 5.5.3 : in `scripts/wolfssl` - [Zebra](https://github.com/ZcashFoundation/ed25519-zebra) : in unit tests ## Results @@ -112,9 +113,12 @@ For a total of 12 test vectors. |ref10 | V | V | V | V | X | X | V | X | X | X | X | V | |TweetNaCl | V | V | V | V | X | X | V | V | X | X | X | V | |TweetNaCl-js | V | V | V | V | X | X | V | V | X | X | X | V | +|WOLFSSL 5.5.3 | V | V | V | V | E | E | E | E | E | E | E | V | |Zebra | V | V | V | V | V | V | X | X | X | V | V | V | --------------------------------------------------------------- ``` +Note that wolfSSL can return three options, verified (V), not verfied +(X) and error in verification procedure (E). Contributors ------------ diff --git a/results.md b/results.md index 380ddb2..b7c5785 100644 --- a/results.md +++ b/results.md @@ -17,4 +17,5 @@ |ref10 | V | V | V | V | X | X | V | X | X | X | X | V | |TweetNaCl | V | V | V | V | X | X | V | V | X | X | X | V | |TweetNaCl-js | V | V | V | V | X | X | V | V | X | X | X | V | +|WOLFSSL 5.5.3 | V | V | V | V | E | E | E | E | E | E | E | V | |Zebra | V | V | V | V | V | V | X | X | X | V | V | V | diff --git a/scripts/wolfssl/Makefile b/scripts/wolfssl/Makefile new file mode 100644 index 0000000..7c99881 --- /dev/null +++ b/scripts/wolfssl/Makefile @@ -0,0 +1,5 @@ + + +LIBWOLFSSL_INSTALL_DIR=./wolfssl-install +main: main.c + gcc -o main main.c -I$(LIBWOLFSSL_INSTALL_DIR)/include -L$(LIBWOLFSSL_INSTALL_DIR)/lib -lwolfssl diff --git a/scripts/wolfssl/README.md b/scripts/wolfssl/README.md new file mode 100644 index 0000000..28a7e3f --- /dev/null +++ b/scripts/wolfssl/README.md @@ -0,0 +1,17 @@ +wolfSSL is available under GPLv2 license as well as under +commercial/custom licenses. + +``` +> wget https://github.com/wolfSSL/wolfssl/archive/refs/tags/v5.5.3-stable.tar.gz +> tar -xf v5.5.3-stable.tar.gz +> export LIBWOLFSSL_INSTALL_PATH=$(pwd)/wolfssl-install +> cd wolfssl-5.5.3-stable/ +> ./autogen.sh +> ./configure --prefix=$(LIBWOLFSSL_INSTALL_PATH) --enable-opensslextra --enable-opensslall --enable-curve25519 --enable-ed25519 +> make +> make install +> cd .. +> export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LIBWOLFSSL_INSTALL_PATH/lib +> make +> ./main +``` diff --git a/scripts/wolfssl/main.c b/scripts/wolfssl/main.c new file mode 100644 index 0000000..7574896 --- /dev/null +++ b/scripts/wolfssl/main.c @@ -0,0 +1,91 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +// Copyright (c) Benson Muite +// +// This source code is licensed under the APACHE 2.0 license found in +// the LICENSE file in the root directory of this source tree. + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MESSAGE_LEN 32 +#define crypto_sign_PUBLICKEYBYTES 32 +#define crypto_sign_BYTES 64 + +int main(int argc, char **argv) { + int num_test_vectors = 0; + FILE *fp; + char buff[255]; + byte pk[crypto_sign_PUBLICKEYBYTES]; + byte message[MESSAGE_LEN]; + unsigned long long message_len = MESSAGE_LEN; + byte signature[crypto_sign_BYTES]; + + ed25519_key ed_pkey; + byte pub[32]; + word32 pubSz = sizeof(pub); + int ret; + int verified; + int pos; + word32 sigSz = sizeof(signature); + + fp = fopen("../../cases.txt", "r"); + fscanf(fp, "%i", &num_test_vectors); + printf("|WOLFSSL 5.5.3 |"); + for (int i = 0; i < num_test_vectors; i++) { + // reading the message 32 bytes + fscanf(fp, "%s", buff); + pos = 0; + for (size_t count = 0; count < 32; count++) { + sscanf(buff + 4 + pos, "%2hhx", &message[count]); + pos += 2; + } + + // reading the public key 32 bytes + fscanf(fp, "%s", buff); + pos = 0; + for (size_t count = 0; count < 32; count++) { + sscanf(buff + 4 + pos, "%2hhx", &pk[count]); + pos += 2; + } + + // reading the signature 64 bytes + fscanf(fp, "%s", buff); + pos = 0; + for (size_t count = 0; count < 64; count++) { + sscanf(buff + 4 + pos, "%2hhx", &signature[count]); + pos += 2; + } + + ret = wc_ed25519_init(&ed_pkey); + if (ret !=0) { + printf("Error initializing key\n"); + break; + } + + ret = wc_ed25519_import_public(pk,sizeof(pk),&ed_pkey); + if (ret != 0) { + printf("Error importing public key\n"); + break; + } + + verified = 0; + ret = wc_ed25519_verify_msg(signature, sizeof(signature), + message, sizeof(message), + &verified, &ed_pkey); + if (ret < 0 ) { + printf(" E |"); + }else{ + printf(verified ? " V |" : " X |"); + } + wc_ed25519_free(&ed_pkey); + } + printf("\n"); + fclose(fp); + return 1; +} From 67258372c89c9d2f8c78a0912f26878e8c84976a Mon Sep 17 00:00:00 2001 From: Benson Muite Date: Tue, 8 Nov 2022 12:18:10 +0300 Subject: [PATCH 4/6] Add Botan --- README.md | 2 ++ results.md | 1 + scripts/botan/Makefile | 6 ++++ scripts/botan/README.md | 17 ++++++++++ scripts/botan/main.cpp | 71 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+) create mode 100644 scripts/botan/Makefile create mode 100644 scripts/botan/README.md create mode 100644 scripts/botan/main.cpp diff --git a/README.md b/README.md index c6c7370..5dcb306 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ For a total of 12 test vectors. - [Apple CryptoKit](https://developer.apple.com/documentation/cryptokit) : in `scripts/ed25519-ios` - BoringSSL, through [Ring](https://github.com/briansmith/ring) : in unit tests +- [Botan](https://github.com/randombit/botan) : `scripts/botan` - [Bouncy Castle (Java)](https://www.bouncycastle.org/java.html) version 1.66 : in `scripts/ed25519-java` - [Dalek](https://github.com/dalek-cryptography/ed25519-dalek) : in unit tests - [ed25519-donna from Signal](https://github.com/signalapp/libsignal-protocol-c.git): in `scripts/ed25519-signal-donna` @@ -96,6 +97,7 @@ For a total of 12 test vectors. |Library | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| |---------------+---+---+---+---+---+---+---+---+---+---+---+---| |BoringSSL | V | V | V | V | X | X | X | X | X | X | X | V | +|Botan | V | V | V | V | X | X | V | X | X | X | X | V | |BouncyCastle | V | V | V | V | X | X | X | X | X | X | X | X | |CryptoKit | V | V | V | V | X | X | X | X | X | X | X | V | |Dalek | V | V | V | V | X | X | X | X | X | X | X | V | diff --git a/results.md b/results.md index b7c5785..42291a0 100644 --- a/results.md +++ b/results.md @@ -1,4 +1,5 @@ |BoringSSL | V | V | V | V | X | X | X | X | X | X | X | V | +|Botan | V | V | V | V | X | X | V | X | X | X | X | V | |BouncyCastle | V | V | V | V | X | X | X | X | X | X | X | X | |CryptoKit | V | V | V | V | X | X | X | X | X | X | X | V | |Dalek | V | V | V | V | X | X | X | X | X | X | X | V | diff --git a/scripts/botan/Makefile b/scripts/botan/Makefile new file mode 100644 index 0000000..806c247 --- /dev/null +++ b/scripts/botan/Makefile @@ -0,0 +1,6 @@ +LIBBOTAN_INSTALL_DIR=$(pwd)/libbotan-build +main: main.o + g++ -o main main.o -L$(LIBBOTAN_INSTALL_DIR)/lib64 -lbotan-2 + +main.o: main.cpp + g++ -c -I$(LIBBOTAN_INSTALL_DIR)/include/botan-2 main.cpp -o main.o diff --git a/scripts/botan/README.md b/scripts/botan/README.md new file mode 100644 index 0000000..df2dbb5 --- /dev/null +++ b/scripts/botan/README.md @@ -0,0 +1,17 @@ +[Botan](https://botan.randombit.net) is available under a BSD-2-Clause license + +``` +> wget https://botan.randombit.net/releases/Botan-2.19.2.tar.xz +> tar -xf Botan-2.19.2.tar.xz +> mkdir libbotan-build +> export LIBBOTAN_INSTALL_DIR=$(pwd)/libbotan-build +> cd Botan-2.19.2 +> ./configure --prefix=$(LIBBOTAN_INSTALL_DIR) +> make +> make check +> make install +> cd .. +> export LD_LIBRARY_PATH=$(pwd)/libbotan-build/lib64:$LD_LIBRARY_PATH +> make +> ./main +``` diff --git a/scripts/botan/main.cpp b/scripts/botan/main.cpp new file mode 100644 index 0000000..582ceba --- /dev/null +++ b/scripts/botan/main.cpp @@ -0,0 +1,71 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +// Copyright (c) Benson Muite +// +// This source code is licensed under the APACHE 2.0 license found in +// the LICENSE file in the root directory of this source tree. + +#include +#include + +#define MESSAGE_LEN 32 + +using namespace Botan::Sodium; +int main(void) { + if (sodium_init() < 0) { + /* panic! the library couldn't be initialized, it is not safe to use */ + printf("PANIC \n"); + return 0; + } + + unsigned char pk[crypto_sign_PUBLICKEYBYTES]; + unsigned char message[MESSAGE_LEN]; + uint8_t message_len = MESSAGE_LEN; + unsigned char signature[crypto_sign_BYTES]; + + FILE *fp; + int number_of_test_vectors = 0; + char buff[255]; + int pos; + + fp = fopen("../../cases.txt", "r+"); + fscanf(fp, "%i", &number_of_test_vectors); + // printf("Number of test vectors: %i\n", number_of_test_vectors); + printf("\n|Botan |"); + for (int i = 0; i < number_of_test_vectors; i++) { + // reading the message + fscanf(fp, "%s", buff); + pos = 0; + for (size_t count = 0; count < 32; count++) { + sscanf(buff + 4 + pos, "%2hhx", &message[count]); + pos += 2; + } + + // reading the public key + fscanf(fp, "%s", buff); // message 32 bytes + pos = 0; + for (size_t count = 0; count < 32; count++) { + sscanf(buff + 4 + pos, "%2hhx", &pk[count]); + pos += 2; + } + + // reading the signature + fscanf(fp, "%s", buff); + pos = 0; + for (size_t count = 0; count < 64; count++) { + sscanf(buff + 4 + pos, "%2hhx", &signature[count]); + pos += 2; + } + + int result = crypto_sign_ed25519_verify_detached(signature, message, message_len, pk); + + if (result == -1) { + printf(" X |"); + /* Incorrect signature! */ + } else { + printf(" V |"); + } + } + printf("\n"); + fclose(fp); + return 0; +} From 755b49f995e503dda97b345fc70f0efee2c6d855 Mon Sep 17 00:00:00 2001 From: Benson Muite Date: Sun, 13 Nov 2022 07:47:00 +0300 Subject: [PATCH 5/6] Add libgcrypt Also use only X and V following review --- README.md | 6 +- results.md | 3 +- scripts/libgcrypt/Makefile | 5 ++ scripts/libgcrypt/README.md | 45 +++++++++++++ scripts/libgcrypt/main.c | 126 ++++++++++++++++++++++++++++++++++++ 5 files changed, 181 insertions(+), 4 deletions(-) create mode 100644 scripts/libgcrypt/Makefile create mode 100644 scripts/libgcrypt/README.md create mode 100644 scripts/libgcrypt/main.c diff --git a/README.md b/README.md index 5dcb306..0b31e5f 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,7 @@ For a total of 12 test vectors. - [ed25519-donna from Signal](https://github.com/signalapp/libsignal-protocol-c.git): in `scripts/ed25519-signal-donna` - [ed25519-java](https://github.com/str4d/ed25519-java) version 0.3.0 : in `scripts/ed25519-java` - [Go-ed25519](https://golang.org/pkg/crypto/ed25519/) : in `scripts/ed25519_test.go` +- [Libgcrypt](https://www.gnupg.org/software/libgcrypt/index.html) version 1.10.1 : in `scripts/libgcrypt` - [libra-crypto](https://github.com/libra/libra/tree/master/crypto/crypto) : in unit tests - LibSodium, through [pynacl](https://github.com/pyca/pynacl) : in `scripts/pynacl_test.py` - [Monocypher](https://monocypher.org) : in `scripts/monocypher` @@ -105,6 +106,7 @@ For a total of 12 test vectors. |ed25519-donna | V | V | V | V | X | X | V | X | X | X | X | V | |ed25519-java | V | V | V | V | X | X | V | V | X | X | V | X | |Go | V | V | V | V | X | X | X | X | X | X | X | V | +|Libgcyrpt | X | X | V | X | X | X | V | V | X | X | X | X | |libra-crypto | X | X | X | V | X | X | X | X | X | X | X | X | |LibSodium | X | X | X | V | X | X | X | X | X | X | X | X | |Monocypher | V | V | V | V | X | X | X | X | X | X | X | V | @@ -115,12 +117,10 @@ For a total of 12 test vectors. |ref10 | V | V | V | V | X | X | V | X | X | X | X | V | |TweetNaCl | V | V | V | V | X | X | V | V | X | X | X | V | |TweetNaCl-js | V | V | V | V | X | X | V | V | X | X | X | V | -|WOLFSSL 5.5.3 | V | V | V | V | E | E | E | E | E | E | E | V | +|WOLFSSL 5.5.3 | V | V | V | V | X | X | X | X | X | X | X | V | |Zebra | V | V | V | V | V | V | X | X | X | V | V | V | --------------------------------------------------------------- ``` -Note that wolfSSL can return three options, verified (V), not verfied -(X) and error in verification procedure (E). Contributors ------------ diff --git a/results.md b/results.md index 42291a0..626b779 100644 --- a/results.md +++ b/results.md @@ -8,6 +8,7 @@ |ed25519-java | V | V | V | V | X | X | V | V | X | X | V | X | |Go | V | V | V | V | X | X | X | X | X | X | X | V | |Hacl* | V | V | V | V | X | X | X | X | X | X | X | X | +|Libgcyrpt | X | X | V | X | X | X | V | V | X | X | X | X | |libra-crypto | X | X | X | V | X | X | X | X | X | X | X | X | |LibSodium | X | X | X | V | X | X | X | X | X | X | X | X | |Monocypher | V | V | V | V | X | X | X | X | X | X | X | V | @@ -18,5 +19,5 @@ |ref10 | V | V | V | V | X | X | V | X | X | X | X | V | |TweetNaCl | V | V | V | V | X | X | V | V | X | X | X | V | |TweetNaCl-js | V | V | V | V | X | X | V | V | X | X | X | V | -|WOLFSSL 5.5.3 | V | V | V | V | E | E | E | E | E | E | E | V | +|WOLFSSL 5.5.3 | V | V | V | V | X | X | X | X | X | X | X | V | |Zebra | V | V | V | V | V | V | X | X | X | V | V | V | diff --git a/scripts/libgcrypt/Makefile b/scripts/libgcrypt/Makefile new file mode 100644 index 0000000..81b3d24 --- /dev/null +++ b/scripts/libgcrypt/Makefile @@ -0,0 +1,5 @@ +LIBGCRYPT_INSTALL_DIR=./libgcrypt-install +LIBPTH_INSTALL_DIR=./libpth-install +LIBGPG_ERROR_INSTALL_DIR=./libgpg-error-install +main: main.c + gcc -o main main.c -I$(LIBGCRYPT_INSTALL_DIR)/include -L$(LIBGCRYPT_INSTALL_DIR)/lib -lgcrypt -L$(LIBGPG_ERROR_INSTALL_DIR)/lib -lgpg-error -L$(LIBPTH_INSTALL_DIR)/lib -lpth diff --git a/scripts/libgcrypt/README.md b/scripts/libgcrypt/README.md new file mode 100644 index 0000000..1ac1e59 --- /dev/null +++ b/scripts/libgcrypt/README.md @@ -0,0 +1,45 @@ +[Libgcrypt](https://www.gnupg.org/software/libgcrypt/index.html) is +available under LGPLv2.1+ with the documentation and some helper +programs are available under GPLv2+. + +[Libgpg-error](https://www.gnupg.org/software/libgpg-error/index.html) +is available under LGPLv2.1+ + +[Pth](https://www.gnupg.org/software/npth/index.html) is available under +LGPLv2.1+ + +Note that if some of these libraries are already installed on your system, +it may be easier to use them rather than update paths to a new installation. + +``` +> wget ftp://ftp.gnu.org/gnu/pth/pth-2.0.7.tar.gz +> tar -xf pth-2.0.7.tar.gz +> export PTH_INSTALL_DIR=$(pwd)/pth-install +> cd pth-2.0.7 +> ./configure --prefix=$(PTH_INSTALL_DIR) +> make +> make check +> make install +> cd .. +> wget https://www.gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.46.tar.bz2 +> tar -xf libgpg-error-1.46.tar.bz2 +> export LIBGPG_ERROR_INSTALL_DIR=$(pwd)/libgpg-error-install +> cd libgpg-error-1.46/ +> ./configure --prefix=$(LIBGPG_ERROR_INSTALL_DIR) +> make +> make check +> make install +> cd .. +> wget https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.10.1.tar.bz2 +> tar -xf libgcrypt-1.10.1.tar.bz2 +> export LIBGCRYPT_INSTALL_DIR=$(pwd)/libgcrypt-install +> cd libgcrypt-1.10.1/ +> ./configure --prefix=$(LIBGCRYPT_INSTALL_DIR) --with-libgpg-error-prefix=$(LIBGPG_ERROR_INSTALL_DIR) --with-pth-prefix=$(PTH_INSTALL_DIR) +> make +> make check +> make install +> cd .. +> export LD_LIBRARY_PATH=$(LIBGPG_ERROR_INSTALL_DIR)/lib:$(PTH_INSTALL_DIR)/lib:$(LIBGCRYPT_INSTALL_DIR)/lib:$LD_LIBRARY_PATH +> make +> ./main +``` diff --git a/scripts/libgcrypt/main.c b/scripts/libgcrypt/main.c new file mode 100644 index 0000000..8a2e001 --- /dev/null +++ b/scripts/libgcrypt/main.c @@ -0,0 +1,126 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +// Copyright (c) Benson Muite +// +// This source code is licensed under the APACHE 2.0 license found in +// the LICENSE file in the root directory of this source tree. + +#include +#include +#include + +#define MESSAGE_LEN 32 +#define crypto_sign_PUBLICKEYBYTES 32 +#define crypto_sign_BYTES 64 +int main(void) { + + unsigned char pk[crypto_sign_PUBLICKEYBYTES]; + unsigned char message[MESSAGE_LEN]; + unsigned long long message_len = MESSAGE_LEN; + unsigned char sig_r[crypto_sign_BYTES/2]; + unsigned char sig_s[crypto_sign_BYTES/2]; + unsigned long long signature_len = crypto_sign_BYTES; + gpg_error_t err; + + FILE *fp; + int number_of_test_vectors = 0; + char buff[255]; + int pos; + int res; + + if (!gcry_check_version(GCRYPT_VERSION)) + { + fputs("libgcrypt version mismatch\n", stderr); + exit(2); + } + + gcry_control(GCRYCTL_DISABLE_SECMEM, 0); + + gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); + + if(!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P)) + { + fputs("libgcrypt has not been initialized\n", stderr); + abort(); + } + + fp = fopen("../../cases.txt", "r+"); + fscanf(fp, "%i", &number_of_test_vectors); + // printf("Number of test vectors: %i\n", number_of_test_vectors); + printf("\n|Libgcyrpt |"); + for (int i = 0; i < number_of_test_vectors; i++) { + gcry_sexp_t s_pk = NULL; + gcry_sexp_t s_msg= NULL; + gcry_sexp_t s_sig= NULL; + + // reading the message + fscanf(fp, "%s", buff); + pos = 0; + for (size_t count = 0; count < 32; count++) { + sscanf(buff + 4 + pos, "%2hhx", &message[count]); + pos += 2; + } + + // reading the public key + fscanf(fp, "%s", buff); // message 32 bytes + pos = 0; + for (size_t count = 0; count < 32; count++) { + sscanf(buff + 4 + pos, "%2hhx", &pk[count]); + pos += 2; + } + + // reading the signature + fscanf(fp, "%s", buff); + pos = 0; + for (size_t count = 0; count < 32; count++) { + sscanf(buff + 4 + pos, "%2hhx", &sig_r[count]); + pos += 2; + } + for (size_t count = 0; count < 32; count++) { + sscanf(buff + 4 + pos, "%2hhx", &sig_s[count]); + pos += 2; + } + + err = gcry_sexp_build (&s_sig, NULL, + "(sig-val" + " (eddsa" + " (r %b)" + " (s %b)))", + (int)sizeof(sig_r), sig_r, + (int)sizeof(sig_s), sig_s); + + err = gcry_sexp_build (&s_pk, NULL, + "(public-key" + " (ecc" + " (curve \"Ed25519\")" + " (flags eddsa)" + " (q %b)))", + (int)sizeof(pk), pk); + if (err) + printf ("gcry_sexp_build failed: %s\n", gpg_strerror (err)); + + err = gcry_sexp_build (&s_msg, NULL, + "(data" + " (flags eddsa)" + " (raw)" + " (value %b))", + (int)sizeof(message), message); + if (err) + printf ("gcry_sexp_build failed: %s\n", gpg_strerror (err)); + + gpg_error_t result = gcry_pk_verify (s_sig, s_msg, s_pk); +// printf(" %s \n",gpg_strerror (result)); + if (result != 0) { + printf(" X |"); + /* Incorrect signature! */ + } else { + printf(" V |"); + } + gcry_sexp_release (s_sig); + gcry_sexp_release (s_pk); + gcry_sexp_release (s_msg); + } + printf("\n"); + fclose(fp); + + return 0; +} From 28a036797ce5552e019982fb2a002167b0a17d26 Mon Sep 17 00:00:00 2001 From: Benson Muite Date: Sun, 13 Nov 2022 19:09:58 +0300 Subject: [PATCH 6/6] Add patched Libressl --- README.md | 2 + results.md | 1 + scripts/libressl/Makefile | 4 + scripts/libressl/README.md | 22 +++++ scripts/libressl/main.c | 50 +++++++++++ scripts/libressl/try_ed25519.patch | 131 +++++++++++++++++++++++++++++ 6 files changed, 210 insertions(+) create mode 100644 scripts/libressl/Makefile create mode 100644 scripts/libressl/README.md create mode 100644 scripts/libressl/main.c create mode 100644 scripts/libressl/try_ed25519.patch diff --git a/README.md b/README.md index 0b31e5f..ba43509 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ For a total of 12 test vectors. - [Go-ed25519](https://golang.org/pkg/crypto/ed25519/) : in `scripts/ed25519_test.go` - [Libgcrypt](https://www.gnupg.org/software/libgcrypt/index.html) version 1.10.1 : in `scripts/libgcrypt` - [libra-crypto](https://github.com/libra/libra/tree/master/crypto/crypto) : in unit tests +- [Libressl](https://www.libressl.org/) patched version 3.6.1 : in `scripts/libressl` - LibSodium, through [pynacl](https://github.com/pyca/pynacl) : in `scripts/pynacl_test.py` - [Monocypher](https://monocypher.org) : in `scripts/monocypher` - nCipher's ed25519, by Rob Starkey @@ -108,6 +109,7 @@ For a total of 12 test vectors. |Go | V | V | V | V | X | X | X | X | X | X | X | V | |Libgcyrpt | X | X | V | X | X | X | V | V | X | X | X | X | |libra-crypto | X | X | X | V | X | X | X | X | X | X | X | X | +|LibreSSL-3.6.1 | V | V | V | V | X | X | V | X | X | X | X | V | |LibSodium | X | X | X | V | X | X | X | X | X | X | X | X | |Monocypher | V | V | V | V | X | X | X | X | X | X | X | V | |npm | V | V | V | V | X | X | X | X | X | X | X | V | diff --git a/results.md b/results.md index 626b779..43b9830 100644 --- a/results.md +++ b/results.md @@ -10,6 +10,7 @@ |Hacl* | V | V | V | V | X | X | X | X | X | X | X | X | |Libgcyrpt | X | X | V | X | X | X | V | V | X | X | X | X | |libra-crypto | X | X | X | V | X | X | X | X | X | X | X | X | +|LibreSSL-3.6.1 | V | V | V | V | X | X | V | X | X | X | X | V | |LibSodium | X | X | X | V | X | X | X | X | X | X | X | X | |Monocypher | V | V | V | V | X | X | X | X | X | X | X | V | |npm | V | V | V | V | X | X | X | X | X | X | X | V | diff --git a/scripts/libressl/Makefile b/scripts/libressl/Makefile new file mode 100644 index 0000000..43fc76c --- /dev/null +++ b/scripts/libressl/Makefile @@ -0,0 +1,4 @@ +LIBRESSL_INSTALL_DIR=./libressl-install +main: main.c + g++ -o main main.c -I$(LIBRESSL_INSTALL_DIR)/include -L$(LIBRESSL_INSTALL_DIR)/lib -lcrypto -lssl -ltls + diff --git a/scripts/libressl/README.md b/scripts/libressl/README.md new file mode 100644 index 0000000..0322874 --- /dev/null +++ b/scripts/libressl/README.md @@ -0,0 +1,22 @@ +[Libressl](https://www.libressl.org/) is available under a combination +of several licenses, including ISC, OpenSSL, SSLeay and public domain. +Examine the source files to determine the ones that are appropriate. + +At present ED25519 support is not enabled by default. A patch is applied +to enable it. + +``` +> wget https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-3.6.1.tar.gz +> tar -xf libressl-3.6.1.tar.gz +> export LIBRESSL_INSTALL_DIR=$(pwd)/libressl-install +> patch -p0 < try_ed25519.patch +> cd libressl-3.6.1 +> ./configure --prefix=$(LIBRESSL_INSTALL_DIR) +> make +> make check +> make install +> cd .. +> make +> export LD_LIBRARY_PATH=$(LIBRESSL_INSTALL_DIR)/lib:$LD_LIBRARY_PATH +> ./main +``` diff --git a/scripts/libressl/main.c b/scripts/libressl/main.c new file mode 100644 index 0000000..4a0559a --- /dev/null +++ b/scripts/libressl/main.c @@ -0,0 +1,50 @@ +// Copyright (c) Facebook, Inc. and its affiliates. +// Copyright (c) Benson Muite +// +// This source code is licensed under the APACHE 2.0 license found in +// the LICENSE file in the root directory of this source tree. + +#include +#include +#include +#include +#include "openssl/curve25519.h" +#include "openssl/sha.h" + +void hex_string_to_byte_array(char *buff, int buf_len, unsigned char *res) { + char *pos = buff; + + for (int i = 0; i < buf_len; i++) { + sscanf(pos, "%2hhx", &res[i]); + pos += 2; + } +} + +int main(int argc, char **argv) { + int num_test_vectors = 0; + + FILE *fp; + char buff[255]; + unsigned char msg[32]; + unsigned char pk[32]; + unsigned char sig[64]; + + fp = fopen("../../cases.txt", "r"); + fscanf(fp, "%i", &num_test_vectors); + printf("|LibreSSL-3.6.1 |"); + for (int i = 0; i < num_test_vectors; i++) { + fscanf(fp, "%s", buff); + hex_string_to_byte_array(buff + 4, 32, msg); + fscanf(fp, "%s", buff); + hex_string_to_byte_array(buff + 4, 32, pk); + fscanf(fp, "%s", buff); + hex_string_to_byte_array(buff + 4, 64, sig); + + int result = ED25519_verify(msg, (size_t)sizeof(msg), + sig, pk); + printf(result ? " V |" : " X |"); + } + printf("\n"); + fclose(fp); + return 1; +} diff --git a/scripts/libressl/try_ed25519.patch b/scripts/libressl/try_ed25519.patch new file mode 100644 index 0000000..e2dba54 --- /dev/null +++ b/scripts/libressl/try_ed25519.patch @@ -0,0 +1,131 @@ +diff -ruN libressl-3.6.1/crypto/crypto.sym libressl-3.6.1-mod/crypto/crypto.sym +--- libressl-3.6.1/crypto/crypto.sym 2022-10-25 03:57:46.000000000 +0300 ++++ libressl-3.6.1-mod/crypto/crypto.sym 2022-11-13 19:00:17.733448120 +0300 +@@ -1242,6 +1242,9 @@ + EC_curve_nid2nist + EC_curve_nist2nid + EC_get_builtin_curves ++ED25519_keypair ++ED25519_sign ++ED25519_verify + EDIPARTYNAME_free + EDIPARTYNAME_it + EDIPARTYNAME_new +diff -ruN libressl-3.6.1/crypto/curve25519/curve25519.c libressl-3.6.1-mod/crypto/curve25519/curve25519.c +--- libressl-3.6.1/crypto/curve25519/curve25519.c 2022-03-15 19:37:03.000000000 +0300 ++++ libressl-3.6.1-mod/crypto/curve25519/curve25519.c 2022-11-13 18:59:23.019622207 +0300 +@@ -29,9 +29,7 @@ + + #include + +-#ifdef ED25519 + #include +-#endif + + #include "curve25519_internal.h" + +@@ -979,7 +977,6 @@ + s[31] ^= fe_isnegative(x) << 7; + } + +-#ifdef ED25519 + static void ge_p3_tobytes(uint8_t *s, const ge_p3 *h) { + fe recip; + fe x; +@@ -991,7 +988,6 @@ + fe_tobytes(s, y); + s[31] ^= fe_isnegative(x) << 7; + } +-#endif + + static const fe d = {-10913610, 13857413, -15372611, 6949391, 114729, + -8787816, -6275908, -3247719, -18696448, -12055116}; +@@ -1146,7 +1142,6 @@ + fe_sub(r->T, t0, r->T); + } + +-#ifdef ED25519 + /* r = p - q */ + static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe t0; +@@ -1162,7 +1157,6 @@ + fe_sub(r->Z, t0, r->T); + fe_add(r->T, t0, r->T); + } +-#endif + + /* r = p + q */ + void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { +@@ -3624,7 +3618,6 @@ + } + } + +-#ifdef ED25519 + static void slide(signed char *r, const uint8_t *a) { + int i; + int b; +@@ -3799,7 +3792,6 @@ + x25519_ge_p1p1_to_p2(r, &t); + } + } +-#endif + + /* The set of scalars is \Z/l + * where l = 2^252 + 27742317777372353535851937790883648493. */ +@@ -4145,7 +4137,6 @@ + s[31] = s11 >> 17; + } + +-#ifdef ED25519 + /* Input: + * a[0]+256*a[1]+...+256^31*a[31] = a + * b[0]+256*b[1]+...+256^31*b[31] = b +@@ -4636,9 +4627,7 @@ + s[30] = s11 >> 9; + s[31] = s11 >> 17; + } +-#endif + +-#ifdef ED25519 + void ED25519_keypair(uint8_t out_public_key[32], uint8_t out_private_key[64]) { + uint8_t seed[32]; + arc4random_buf(seed, 32); +@@ -4728,7 +4717,6 @@ + + return timingsafe_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0; + } +-#endif + + /* Replace (f,g) with (g,f) if b == 1; + * replace (f,g) with (f,g) if b == 0. +diff -ruN libressl-3.6.1/include/openssl/curve25519.h libressl-3.6.1-mod/include/openssl/curve25519.h +--- libressl-3.6.1/include/openssl/curve25519.h 2022-02-19 01:30:39.000000000 +0300 ++++ libressl-3.6.1-mod/include/openssl/curve25519.h 2022-11-13 18:58:20.692820519 +0300 +@@ -61,6 +61,27 @@ + const uint8_t private_key[X25519_KEY_LENGTH], + const uint8_t peers_public_value[X25519_KEY_LENGTH]); + ++/* ++ * ED25519. ++ * ++ * ED25519 is the public key signature scheme from curve25519. ++ * See http://ed25519.cr.yp.to/ and https://tools.ietf.org/html/rfc8032. ++ */ ++ ++void ED25519_keypair(uint8_t out_public_key[32], ++ uint8_t out_private_key[64]); ++ ++int ED25519_sign(uint8_t *out_sig, ++ const uint8_t *message, ++ size_t message_len, ++ const uint8_t private_key[64]); ++ ++int ED25519_verify(const uint8_t *message, ++ size_t message_len, ++ const uint8_t signature[64], ++ const uint8_t public_key[32]); ++ ++ + #if defined(__cplusplus) + } /* extern C */ + #endif