forked from cheng/wallet
57 lines
1.7 KiB
C++
57 lines
1.7 KiB
C++
#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<char, 27> DeriveTextSecret(const scalar & blob, uint_fast64_t i){
|
|
static constexpr std::array<uint8_t, crypto_pwhash_SALTBYTES> salt{0};
|
|
std::array<char, 27> 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<uint8_t, crypto_pwhash_SALTBYTES> salt{ 0 };
|
|
std::array<uint8_t, sizeof(ristretto255::hash<512>)>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));
|
|
} |