diff --git a/Makefile b/Makefile index c618cbf..e7e7cc4 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ TWEETNACLC=randombytes.c tools.c tweetnacl.c TWEETNACL=$(TWEETNACLC) randombytes.h tools.h tweetnacl.h all: tweetnacl-decrypt tweetnacl-encrypt tweetnacl-keypair \ - tweetnacl-sigpair tweetnacl-sign tweetnacl-verify + tweetnacl-sigpair tweetnacl-sign tweetnacl-verify tweetnacl-derivepubkey bin: ; mkdir bin @@ -36,6 +36,10 @@ tweetnacl-verify: bin $(TWEETNACL) tweetnacl-verify.c $(CC) $(CFLAGS) $(TWEETNACLC) tweetnacl-verify.c \ -o bin/tweetnacl-verify +tweetnacl-derivepubkey: bin $(TWEETNACL) tweetnacl-derivepubkey.c + $(CC) $(CFLAGS) $(TWEETNACLC) tweetnacl-derivepubkey.c \ + -o bin/tweetnacl-derivepubkey + test: ; mkdir tmp bin/tweetnacl-keypair tmp/a.pub tmp/a.sec @@ -47,4 +51,5 @@ test: ; echo 'Verified message!' > tmp/msg02 bin/tweetnacl-sign tmp/s.sec tmp/msg02 tmp/signed bin/tweetnacl-verify tmp/s.pub tmp/signed - + bin/tweetnacl-derivepubkey tmp/a.sec tmp/a.pub2 rm -rf tmp diff --git a/README.md b/README.md index 48afaa6..2b16f96 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,17 @@ $ tweetnacl-verify sign.pub message.signed message.txt The `sign.pub` public signature key is used to verify the signed message in `message.signed`. If the signature is verified, the message is placed into `message.txt` and the program exits with successful status 0. If the signature is not verified, an error message is printed to stderr and the program exists with the unsuccessful status 0. If the signature is verified and the message output file is `-` then the message is printed to stdout. +### tweetnacl-derivepubkey + +Derives the public key for the specified secret key + +Usage: + +```shell +$ tweetnacl-derivepubkey key.sec key.pub +``` + + ## Example Encrypting and decrypting: diff --git a/tweetnacl-derivepubkey.c b/tweetnacl-derivepubkey.c new file mode 100644 index 0000000..4166d18 --- /dev/null +++ b/tweetnacl-derivepubkey.c @@ -0,0 +1,35 @@ +#include +#include +#include + +#include "tools.h" +#include "tweetnacl.h" + +void output_key(char filename[], unsigned char key[], int key_size) { + if (strcmp(filename, "-") != 0) { + FILE *out = create_file(filename); + fwrite(key, key_size, 1, out); + fclose(out); + } else { + fwrite(bytes_to_hex(key, key_size), key_size * 2, 1, stdout); + fputs("\n", stdout); + } +} + +// derives the public key from a given secret key +int main(int argc, char *argv[]) { + if (argc != 3) error(2, + "Usage: tweetnacl-derivepubkey key.sec key.pub"); + + unsigned char public_key[crypto_box_PUBLICKEYBYTES]; + unsigned char secret_key[crypto_box_SECRETKEYBYTES]; + + read_key(argv[1], secret_key, crypto_box_SECRETKEYBYTES); + + crypto_scalarmult_base(public_key, secret_key); + + output_key(argv[2], public_key, crypto_box_SECRETKEYBYTES); + + return 0; +} +