void Secp256k1PP::encrypt(Public const& _k, bytes& io_cipher) { auto& ctx = Secp256k1PPCtx::get(); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" CryptoPP::ECIES<CryptoPP::ECP>::Encryptor e; #pragma GCC diagnostic pop #pragma clang diagnostic pop { Guard l(ctx.x_params); e.AccessKey().Initialize(ctx.m_params, publicToPoint(_k)); } size_t plen = io_cipher.size(); bytes ciphertext; ciphertext.resize(e.CiphertextLength(plen)); { Guard l(ctx.x_rng); e.Encrypt(ctx.m_rng, io_cipher.data(), plen, ciphertext.data()); } memset(io_cipher.data(), 0, io_cipher.size()); io_cipher = std::move(ciphertext); }
bool Secp256k1PP::decryptECIES(Secret const& _k, bytesConstRef _sharedMacData, bytes& io_text) { // interop w/go ecies implementation // io_cipher[0] must be 2, 3, or 4, else invalidpublickey if (io_text.empty() || io_text[0] < 2 || io_text[0] > 4) // invalid message: publickey return false; if (io_text.size() < (1 + Public::size + h128::size + 1 + h256::size)) // invalid message: length return false; Secret z; if (!ecdh::agree(_k, *(Public*)(io_text.data() + 1), z)) return false; // Invalid pubkey or seckey. auto key = ecies::kdf(z, bytes(), 64); bytesConstRef eKey = bytesConstRef(&key).cropped(0, 16); bytesRef mKeyMaterial = bytesRef(&key).cropped(16, 16); bytes mKey(32); CryptoPP::SHA256 ctx; ctx.Update(mKeyMaterial.data(), mKeyMaterial.size()); ctx.Final(mKey.data()); bytes plain; size_t cipherLen = io_text.size() - 1 - Public::size - h128::size - h256::size; bytesConstRef cipherWithIV(io_text.data() + 1 + Public::size, h128::size + cipherLen); bytesConstRef cipherIV = cipherWithIV.cropped(0, h128::size); bytesConstRef cipherNoIV = cipherWithIV.cropped(h128::size, cipherLen); bytesConstRef msgMac(cipherNoIV.data() + cipherLen, h256::size); h128 iv(cipherIV.toBytes()); // verify tag CryptoPP::HMAC<CryptoPP::SHA256> hmacctx(mKey.data(), mKey.size()); hmacctx.Update(cipherWithIV.data(), cipherWithIV.size()); hmacctx.Update(_sharedMacData.data(), _sharedMacData.size()); h256 mac; hmacctx.Final(mac.data()); for (unsigned i = 0; i < h256::size; i++) if (mac[i] != msgMac[i]) return false; plain = decryptSymNoAuth(SecureFixedHash<16>(eKey), iv, cipherNoIV).makeInsecure(); io_text.resize(plain.size()); io_text.swap(plain); return true; }
bytes ecies::kdf(Secret const& _z, bytes const& _s1, unsigned kdByteLen) { auto reps = ((kdByteLen + 7) * 8) / 512; // SEC/ISO/Shoup specify counter size SHOULD be equivalent // to size of hash output, however, it also notes that // the 4 bytes is okay. NIST specifies 4 bytes. std::array<byte, 4> ctr{{0, 0, 0, 1}}; bytes k; secp256k1_sha256_t ctx; for (unsigned i = 0; i <= reps; i++) { secp256k1_sha256_initialize(&ctx); secp256k1_sha256_write(&ctx, ctr.data(), ctr.size()); secp256k1_sha256_write(&ctx, _z.data(), Secret::size); secp256k1_sha256_write(&ctx, _s1.data(), _s1.size()); // append hash to k std::array<byte, 32> digest; secp256k1_sha256_finalize(&ctx, digest.data()); k.reserve(k.size() + h256::size); move(digest.begin(), digest.end(), back_inserter(k)); if (++ctr[3] || ++ctr[2] || ++ctr[1] || ++ctr[0]) continue; } k.resize(kdByteLen); return k; }
bytes Secp256k1PP::eciesKDF(Secret const& _z, bytes _s1, unsigned kdByteLen) { auto reps = ((kdByteLen + 7) * 8) / (CryptoPP::SHA256::BLOCKSIZE * 8); // SEC/ISO/Shoup specify counter size SHOULD be equivalent // to size of hash output, however, it also notes that // the 4 bytes is okay. NIST specifies 4 bytes. bytes ctr({0, 0, 0, 1}); bytes k; CryptoPP::SHA256 ctx; for (unsigned i = 0; i <= reps; i++) { ctx.Update(ctr.data(), ctr.size()); ctx.Update(_z.data(), Secret::size); ctx.Update(_s1.data(), _s1.size()); // append hash to k bytes digest(32); ctx.Final(digest.data()); ctx.Restart(); k.reserve(k.size() + h256::size); move(digest.begin(), digest.end(), back_inserter(k)); if (++ctr[3] || ++ctr[2] || ++ctr[1] || ++ctr[0]) continue; } k.resize(kdByteLen); return k; }
void Secp256k1PP::decrypt(Secret const& _k, bytes& io_text) { CryptoPP::ECIES<CryptoPP::ECP>::Decryptor d; initializeDLScheme(_k, d); if (!io_text.size()) { io_text.resize(1); io_text[0] = 0; } size_t clen = io_text.size(); bytes plain; plain.resize(d.MaxPlaintextLength(io_text.size())); DecodingResult r; { Guard l(x_rng); r = d.Decrypt(m_rng, io_text.data(), clen, plain.data()); } if (!r.isValidCoding) { io_text.clear(); return; } io_text.resize(r.messageLength); io_text = std::move(plain); }
void Secp256k1PP::encrypt(Public const& _k, bytes& io_cipher) { ECIES<ECP>::Encryptor e; initializeDLScheme(_k, e); size_t plen = io_cipher.size(); bytes ciphertext; ciphertext.resize(e.CiphertextLength(plen)); { Guard l(x_rng); e.Encrypt(m_rng, io_cipher.data(), plen, ciphertext.data()); } memset(io_cipher.data(), 0, io_cipher.size()); io_cipher = std::move(ciphertext); }
public_key::public_key( const bytes& d ) :my( std::make_shared<detail::pke_impl>() ) { string pem = "-----BEGIN RSA PUBLIC KEY-----\n"; auto b64 = fc::base64_encode( (const unsigned char*)d.data(), d.size() ); for( size_t i = 0; i < b64.size(); i += 64 ) pem += b64.substr( i, 64 ) + "\n"; pem += "-----END RSA PUBLIC KEY-----\n"; // fc::cerr<<pem; BIO* mem = (BIO*)BIO_new_mem_buf( (void*)pem.c_str(), pem.size() ); my->rsa = PEM_read_bio_RSAPublicKey(mem, NULL, NULL, NULL ); BIO_free(mem); }
bytes public_key::decrypt( const bytes& in )const { FC_ASSERT( my && my->rsa ); bytes out( RSA_size(my->rsa) );//, char(0) ); int rtn = RSA_public_decrypt( in.size(), (unsigned char*)in.data(), (unsigned char*)out.data(), my->rsa, RSA_PKCS1_OAEP_PADDING ); if( rtn >= 0 ) { out.resize(rtn); return out; } FC_THROW_EXCEPTION( exception, "openssl: ${message}", ("message",fc::string(ERR_error_string( ERR_get_error(),NULL))) ); }
bytes private_key::decrypt( const bytes& in )const { if( !my ) FC_THROW_EXCEPTION( assert_exception, "!null" ); bytes out; out.resize( RSA_size(my->rsa) ); int rtn = RSA_private_decrypt( in.size(), (unsigned char*)in.data(), (unsigned char*)out.data(), my->rsa, RSA_PKCS1_OAEP_PADDING ); if( rtn >= 0 ) { out.resize(rtn); return out; } FC_THROW_EXCEPTION( exception, "decrypt failed" ); }
bytesSec dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen) { bytesSec ret(_dkLen); if (PKCS5_PBKDF2_HMAC<SHA256>().DeriveKey( ret.writable().data(), _dkLen, 0, reinterpret_cast<byte const*>(_pass.data()), _pass.size(), _salt.data(), _salt.size(), _iterations ) != _iterations) BOOST_THROW_EXCEPTION(CryptoException() << errinfo_comment("Key derivation failed.")); return ret; }
bytesSec dev::scrypt(std::string const& _pass, bytes const& _salt, uint64_t _n, uint32_t _r, uint32_t _p, unsigned _dkLen) { bytesSec ret(_dkLen); if (libscrypt_scrypt( reinterpret_cast<uint8_t const*>(_pass.data()), _pass.size(), _salt.data(), _salt.size(), _n, _r, _p, ret.writable().data(), _dkLen ) != 0) BOOST_THROW_EXCEPTION(CryptoException() << errinfo_comment("Key derivation failed.")); return ret; }
static bytes zlib_decompress(const bytes& data) { try { bytes out; bio::filtering_ostream decomp; decomp.push(bio::zlib_decompressor()); decomp.push(read_limiter<1*1024*1024>()); // limit to 10 megs decompressed for zip bomb protections decomp.push(bio::back_inserter(out)); bio::write(decomp, data.data(), data.size()); bio::close(decomp); return out; } catch( fc::exception& er ) { throw; } catch( ... ) { fc::unhandled_exception er( FC_LOG_MESSAGE( warn, "internal decompression error"), std::current_exception() ); throw er; } }
void Secp256k1PP::decrypt(Secret const& _k, bytes& io_text) { auto& ctx = Secp256k1PPCtx::get(); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" CryptoPP::ECIES<CryptoPP::ECP>::Decryptor d; #pragma GCC diagnostic pop #pragma clang diagnostic pop { Guard l(ctx.x_params); d.AccessKey().Initialize(ctx.m_params, secretToExponent(_k)); } if (!io_text.size()) { io_text.resize(1); io_text[0] = 0; } size_t clen = io_text.size(); bytes plain; plain.resize(d.MaxPlaintextLength(io_text.size())); CryptoPP::DecodingResult r; { Guard l(ctx.x_rng); r = d.Decrypt(ctx.m_rng, io_text.data(), clen, plain.data()); } if (!r.isValidCoding) { io_text.clear(); return; } io_text.resize(r.messageLength); io_text = std::move(plain); }
void writeFile(std::string const& _file, bytes const& _data) { ofstream(_file, ios::trunc).write((char const*)_data.data(), _data.size()); }