Index: build/test/test.tcl ================================================================== --- build/test/test.tcl +++ build/test/test.tcl @@ -2,11 +2,11 @@ lappend auto_path [file join [file dirname [info script]] .. ..] package require nano -proc test1 {} { +proc test_signatures {} { # Detached signature set data [binary decode hex 0000000000000000000000000000000000000000000000000000000000000000] set key [binary decode hex C4D214F19E706E9C7487CEF00DE8059200C32414F0ED82E5E33B523AEDF719BA] set sig [string toupper [binary encode hex [::nano::internal::signDetached $data $key]]] set sig_expected 1C2DE9B8A71215F949A11BBEA7EFA4ECD67A8C2B5A9AD98AE6B1AB7F7A3D2CFD715F570309148C7B39C346FB9B91B321D7E75BD598F271AF31AB60A99D086709 @@ -48,8 +48,37 @@ if {$verified} { puts "\[FAIL\] Got: $verified" puts "\[FAIL\] Exp: false" return false } + + return true +} + +proc test_hashing {} { + # Basic test + set data [binary decode hex 4451686437A2BF5C4759100DE2ADE0F39B6877275AF997906B71B1A8EF1550A2] + set hash [binary encode hex [::nano::internal::hashData $data]] + set hash_expected "84ac733547d71c312e707508646008a9d8f84f7093e60ca91e4eb376365ac1921fdde6e8ccb3875ea12369d9f6fb02237f51f4c05f3555e57d11800deda7319f" + if {$hash ne $hash_expected} { + puts "\[FAIL\] Got: $hash" + puts "\[FAIL\] Exp: $hash_expected" + + return false + } + + return true +} + +set tests { + signatures + hashing +} + +foreach test $tests { + if {![test_$test]} { + puts "FAILED test $test" + exit 1 + } } -test1 +exit 0 Index: nano.c ================================================================== --- nano.c +++ nano.c @@ -1,10 +1,11 @@ #include #include #include #include #include "tweetnacl.h" +#include "blake2-supercop.h" #if 0 #include void randombytes(uint8_t *buffer, uint64_t length) { @@ -238,10 +239,31 @@ return(TCL_OK); /* NOTREACH */ clientData = clientData; } + +static int nano_tcl_hash_data(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { + unsigned char *data, result[crypto_sign_BYTES]; + int data_length, result_length; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "data"); + + return(TCL_ERROR); + } + + data = Tcl_GetByteArrayFromObj(objv[1], &data_length); + crypto_hash(result, data, data_length); + result_length = sizeof(result); + Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(result, result_length)); + + return(TCL_OK); + + /* NOTREACH */ + clientData = clientData; +} int Nano_Init(Tcl_Interp *interp) { #ifdef USE_TCL_STUBS const char *tclInitStubs_ret; @@ -253,8 +275,9 @@ #endif 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); }