Blob ConvertFromBase58ShaSquare(RCString s) { BigInteger bi = 0; for (const char *p=s; *p; ++p) { if (const char *q = strchr(s_pszBase58, *p)) { bi = bi*58 + BigInteger(q-s_pszBase58); } else Throw(E_INVALIDARG); } vector<byte> v((bi.Length+7)/8); bi.ToBytes(&v[0], v.size()); if (v.size()>=2 && v.end()[-1]==0 && v.end()[-1]>=0x80) v.resize(v.size()-1); vector<byte> r; for (const char *p=s; *p==s_pszBase58[0]; ++p) r.push_back(0); r.resize(r.size()+v.size()); std::reverse_copy(v.begin(), v.end(), r.end()-v.size()); if (r.size() < 4) Throw(E_FAIL); SHA256 sha; HashValue hash = HashValue(sha.ComputeHash(sha.ComputeHash(ConstBuf(&r[0], r.size()-4)))); if (memcmp(hash.data(), &r.end()[-4], 4)) Throw(HRESULT_FROM_WIN32(ERROR_CRC)); return Blob(&r[0], r.size()-4); }
hashval CalcPbkdf2Hash(const UInt32 *pIhash, const ConstBuf& data, int idx) { SHA256 sha; size_t size = 16*4+data.Size+4; UInt32 *buf = (UInt32*)alloca(size); memset(buf, 0x36, 16*4); for (int i=0; i<8; ++i) buf[i] ^= pIhash[i]; memcpy(buf+16, data.P, data.Size); buf[16+data.Size/4] = htobe32(idx); hashval hv = sha.ComputeHash(ConstBuf(buf, size)); memset(buf, 0x5C, 16*4); for (int i=0; i<8; ++i) buf[i] ^= pIhash[i]; memcpy(buf+16, hv.constData(), hv.size()); return sha.ComputeHash(ConstBuf(buf, 64+hv.size())); }
String ConvertToBase58ShaSquare(const ConstBuf& cbuf) { SHA256 sha; HashValue hash = HashValue(sha.ComputeHash(sha.ComputeHash(cbuf))); Blob v = cbuf + Blob(hash.data(), 4); vector<char> r; vector<byte> tmp(v.Size+1, 0); std::reverse_copy(v.begin(), v.end(), tmp.begin()); for (BigInteger n(&tmp[0], tmp.size()); Sign(n);) { pair<BigInteger, BigInteger> pp = div(n, 58); n = pp.first; r.insert(r.begin(), s_pszBase58[explicit_cast<int>(pp.second)]); } for (int i=0; i<v.Size && !v.constData()[i]; ++i) r.insert(r.begin(), s_pszBase58[0]); return String(&r[0], r.size()); }
CArray8UInt32 CalcSCryptHash(const ConstBuf& password) { ASSERT(password.Size == 80); SHA256 sha; hashval ihash = sha.ComputeHash(password); const UInt32 *pIhash = (UInt32*)ihash.constData(); UInt32 x[32]; for (int i=0; i<4; ++i) { hashval hv = CalcPbkdf2Hash(pIhash, password, i+1); memcpy(x+8*i, hv.constData(), 32); } AlignedMem am((1025*32)*sizeof(UInt32), 128); ScryptCore(x, (UInt32*)am.get()); hashval hv = CalcPbkdf2Hash(pIhash, ConstBuf(x, sizeof x), 1); const UInt32 *p = (UInt32*)hv.constData(); CArray8UInt32 r; for (int i=0; i<8; ++i) r[i] = p[i]; return r; }
HashValue SHA256_SHA256(const ConstBuf& cbuf) { SHA256 sha; return ConstBuf(sha.ComputeHash(sha.ComputeHash(cbuf))); }