#include "stdafx.h" #include "secrets.h" //Derive a Short text Secret from a 256 bit random value and a sixty four bit integer using ristretto255::scalar, ristretto255::hash, ristretto255::hsh; std::array DeriveTextSecret(const scalar & blob, uint_fast64_t i){ static constexpr std::array salt{0}; std::array txt; unsigned int n{ 3 }; unsigned int m{ 3 }; hash rand(blob,i); uint8_t* p{ &rand.blob[0] }; char* q = &txt[0]; while (n || m) { if (*p++ < ((n * 0x100) / (n + m))) { n--; bits2base64(p, 0, 18, std::span(q, 4)); q+=3; } else { m--; bits2base64(p, 0, 24, std::span(q, 5)); q+=4; } *q++ = ' '; p += 3; } assert(q == sizeof(txt) + &txt[0]); assert(p == &rand.blob[24]); txt[sizeof(txt)-1]='\0'; return txt; } //Derive a strong scalar secret from a string with password strengthening. //Net effect is convert one scalar into another by a process that is lengthy and costly. ristretto255::scalar DeriveStrongSecret(const char* const passwd){ static std::array salt{ 0 }; std::array)>randb; int i{ crypto_pwhash( &randb[0], sizeof(randb), passwd, strlen(passwd)+1, &salt[0], 2, 0x10000000, crypto_pwhash_ALG_ARGON2ID13 ) }; static_assert(crypto_pwhash_OPSLIMIT_MODERATE == 0x00000003 && crypto_pwhash_MEMLIMIT_MODERATE == 0x10000000, "Argon changed, likely breaking all passphrases"); assert(i == 0); return scalar(hash<512>(randb)); } //Derive scalar secret from another quickly. ristretto255::scalar DeriveSecret(const scalar &sc, uint_fast64_t i) { return ristretto255::scalar(ristretto255::hash<512>(sc, i)); }