static void generate_testvectors(const char *type) { #define TEST_OUTLEN 32 #define TEST_PWDLEN 32 #define TEST_SALTLEN 16 #define TEST_SECRETLEN 8 #define TEST_ADLEN 12 argon2_context context; unsigned char out[TEST_OUTLEN]; unsigned char pwd[TEST_PWDLEN]; unsigned char salt[TEST_SALTLEN]; unsigned char secret[TEST_SECRETLEN]; unsigned char ad[TEST_ADLEN]; const allocate_fptr myown_allocator = NULL; const deallocate_fptr myown_deallocator = NULL; unsigned t_cost = 3; unsigned m_cost = 32; unsigned lanes = 4; memset(pwd, 1, TEST_OUTLEN); memset(salt, 2, TEST_SALTLEN); memset(secret, 3, TEST_SECRETLEN); memset(ad, 4, TEST_ADLEN); context.out = out; context.outlen = TEST_OUTLEN; context.pwd = pwd; context.pwdlen = TEST_PWDLEN; context.salt = salt; context.saltlen = TEST_SALTLEN; context.secret = secret; context.secretlen = TEST_SECRETLEN; context.ad = ad; context.adlen = TEST_ADLEN; context.t_cost = t_cost; context.m_cost = m_cost; context.lanes = lanes; context.threads = lanes; context.allocate_cbk = myown_allocator; context.free_cbk = myown_deallocator; context.flags = 0; #undef TEST_OUTLEN #undef TEST_PWDLEN #undef TEST_SALTLEN #undef TEST_SECRETLEN #undef TEST_ADLEN if (!strcmp(type, "d")) { argon2d_ctx(&context); } else if (!strcmp(type, "i")) { argon2i_ctx(&context); } else fatal("wrong Argon2 type"); }
u3_noun u3qe_argon2( // configuration params, u3_atom out, u3_atom type, u3_atom version, u3_atom threads, u3_atom mem_cost, u3_atom time_cost, u3_atom wik, u3_atom key, u3_atom wix, u3_atom extra, // input params u3_atom wid, u3_atom dat, u3_atom wis, u3_atom sat ) { c3_assert( _(u3a_is_cat(out)) && _(u3a_is_cat(type)) && _(u3a_is_cat(version)) && _(u3a_is_cat(threads)) && _(u3a_is_cat(mem_cost)) && _(u3a_is_cat(time_cost)) && _(u3a_is_cat(wik)) && _(u3a_is_cat(wix)) && _(u3a_is_cat(wid)) && _(u3a_is_cat(wis)) ); // flip endianness for argon2 key = u3qc_rev(3, wik, key); extra = u3qc_rev(3, wix, extra); dat = u3qc_rev(3, wid, dat); sat = u3qc_rev(3, wis, sat); // atoms to byte arrays c3_y bytes_key[wik]; u3r_bytes(0, wik, bytes_key, key); c3_y bytes_extra[wix]; u3r_bytes(0, wix, bytes_extra, extra); c3_y bytes_dat[wid]; u3r_bytes(0, wid, bytes_dat, dat); c3_y bytes_sat[wis]; u3r_bytes(0, wis, bytes_sat, sat); c3_y outhash[out]; argon2_context context = { outhash, // output array, at least [digest length] in size out, // digest length bytes_dat, // password array wid, // password length bytes_sat, // salt array wis, // salt length bytes_key, wik, // optional secret data bytes_extra, wix, // optional associated data time_cost, mem_cost, threads, threads, // performance cost configuration version, // algorithm version argon2_alloc, // custom memory allocation function argon2_free, // custom memory deallocation function ARGON2_DEFAULT_FLAGS // by default only internal memory is cleared }; int argon_res; switch ( type ) { default: fprintf(stderr, "\nunjetted argon2 variant %i\n", type); u3m_bail(c3__exit); break; // case c3__d: argon_res = argon2d_ctx(&context); break; // case c3__i: argon_res = argon2i_ctx(&context); break; // case c3__id: argon_res = argon2id_ctx(&context); break; // case c3__u: argon_res = argon2u_ctx(&context); break; } if ( ARGON2_OK != argon_res ) { fprintf(stderr, "\nargon2 error: %s\n", argon2_error_message(argon_res)); u3m_bail(c3__exit); } u3z(key); u3z(extra); u3z(dat); u3z(sat); return u3kc_rev(3, out, u3i_bytes(out, outhash)); }