Index: build/test/test.tcl ================================================================== --- build/test/test.tcl +++ build/test/test.tcl @@ -66,14 +66,20 @@ return false } return true } + +proc test_keygeneration {} { + set key [::nano::internal::generateKey] + puts "key=$key" +} set tests { signatures hashing + keygeneration } foreach test $tests { if {![test_$test]} { puts "FAILED test $test" Index: nano.c ================================================================== --- nano.c +++ nano.c @@ -3,10 +3,13 @@ #include #include #include "tweetnacl.h" #include "blake2-supercop.h" +#define NANO_SECRET_KEY_LENGTH (crypto_sign_SECRETKEYBYTES - crypto_sign_PUBLICKEYBYTES) +#define NANO_PUBLIC_KEY_LENGTH (crypto_sign_PUBLICKEYBYTES) + #if 0 #include void randombytes(uint8_t *buffer, uint64_t length) { ssize_t gr_ret; @@ -60,13 +63,10 @@ } return; } -#define NANO_SECRET_KEY_LENGTH (crypto_sign_SECRETKEYBYTES - crypto_sign_PUBLICKEYBYTES) -#define NANO_PUBLIC_KEY_LENGTH (crypto_sign_PUBLICKEYBYTES) - static unsigned char *nano_parse_secret_key(Tcl_Obj *secret_key_only_obj, int *out_key_length) { unsigned char *secret_key, *public_key, *secret_key_only; int secret_key_length, secret_key_only_length; secret_key_only = Tcl_GetByteArrayFromObj(secret_key_only_obj, &secret_key_only_length); @@ -90,10 +90,34 @@ *out_key_length = secret_key_length; return(secret_key); } +static int nano_tcl_generate_keypair(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { + int csk_ret; + unsigned char secret_key[crypto_sign_SECRETKEYBYTES], public_key[crypto_sign_PUBLICKEYBYTES]; + + if (objc != 1) { + Tcl_WrongNumArgs(interp, 1, objv, ""); + + return(TCL_ERROR); + } + + csk_ret = crypto_sign_keypair(public_key, secret_key, 1); + if (csk_ret != 0) { + Tcl_SetResult(interp, "Internal error", NULL); + + return(TCL_ERROR); + } + + Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(secret_key, NANO_SECRET_KEY_LENGTH)); + + return(TCL_OK); + + /* NOTREACH */ + clientData = clientData; +} static int nano_tcl_secret_key_to_public_key(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { unsigned char *secret_key, *public_key; int secret_key_length, public_key_length; if (objc != 2) { @@ -272,12 +296,13 @@ if (!tclInitStubs_ret) { return(TCL_ERROR); } #endif + Tcl_CreateObjCommand(interp, "::nano::internal::generateKey", nano_tcl_generate_keypair, NULL, NULL); Tcl_CreateObjCommand(interp, "::nano::internal::signDetached", nano_tcl_sign_detached, NULL, NULL); Tcl_CreateObjCommand(interp, "::nano::internal::publicKey", nano_tcl_secret_key_to_public_key, NULL, NULL); Tcl_CreateObjCommand(interp, "::nano::internal::verifyDetached", nano_tcl_verify_detached, NULL, NULL); Tcl_CreateObjCommand(interp, "::nano::internal::hashData", nano_tcl_hash_data, NULL, NULL); return(TCL_OK); }