// receive coin Coin<FIELD> decrypt(const SecretAddr<FIELD>& secretAddr, const PublicAddr<FIELD>& publicAddr) const { DECRYPTOR DEC(secretAddr.cryptoKey()); RANDPOOL RNG; // recovered text length const std::size_t rtextLen = DEC.MaxPlaintextLength(m_cipherText.size()); if (rtextLen) { // recovered text bytes std::vector<byte> rtext(rtextLen, 0xfb); if (DEC.Decrypt(RNG, m_cipherText.data(), m_cipherText.size(), rtext.data()).isValidCoding) { // convert recovered text to stream std::stringstream ss(std::string(rtext.begin(), rtext.end())); Coin<FIELD> coin; if (coin.marshal_in(ss, false)) { // false means omit public address // set public address of recovered coin coin.addr(publicAddr); // must check: // 1. cm matches pour transaction cm (coin exists in ledger) // 2. serial number is not in ledger (not already spent) if (coin.valid()) return coin; } } } return Coin<FIELD>(); // failed }
// pour new coin EncryptedCoin(const Coin<FIELD>& coin) { ENCRYPTOR ENC(coin.addr().cryptoKey()); RANDPOOL RNG; std::stringstream ss; coin.marshal_out(ss, false); // false means omit public address const std::string& ptext = ss.str(); const std::size_t ptextLen = ptext.length() + 1; // encrypt message m_cipherText = std::vector<byte>(ENC.CiphertextLength(ptextLen), 0xfb); ENC.Encrypt(RNG, reinterpret_cast<const byte*>(ptext.data()), ptextLen, m_cipherText.data()); }