2717 views
# Litecoin MWEB Code Audit ## Objective of review I audited the following code: - Full Audit: https://github.com/litecoin-project/litecoin/pull/738 - Full Audit: https://github.com/ltc-mweb/litecoin/tree/mimblewimble/src/mweb - Focused on Functionality: https://github.com/ltc-mweb/litecoin/tree/mimblewimble/src/libmw I didn't go through every single line of every primitive in `libmw` but I focused on tracing the main functionality that is described in LIP-0002, LIP-0003 and LIP-0004 which we summarized our understanding of [here](https://demo.hedgedoc.org/s/7F9l45zHu#). Namely: - Block construction and validation on LTC and MWEB - Pegins - Pegouts - HogEx construction and validation - Transaction construction and validation including one-sided transactions as described in LIP-0004. ## Observations The code is clean and well structured and overall I found that the logic matched what I expected based on my understanding of the documentation. I didn't really spot any bugs or areas for obvious improvement though I have two small observations: In `/src/libmw/src/wallet/TxBuilder.cpp:67` ```c // Total owner offset is split between raw owner_offset and the owner_sig's key. // sum(output.sender_key) - sum(input.key) = owner_offset + sum(owner_sig.key) std::vector<SecretKey> input_keys = GetKeys(input_coins); BlindingFactor owner_offset = Blinds() .Add(.total_key) .Sub(input_keys) .Sub(owner_sig_key) .Total(); ``` The inclusion of the owner_sig_key in the owner_offset is not documented in LIP-0004. I understand its purpose and the validation handles it correctly but the LIP document should be updated. In `/src/mweb/mweb_wallet.h` ```c class Wallet { public: . . . private: CWallet* m_pWallet; mutable mw::Keychain::Ptr m_keychain; std::map<Commitment, mw::Coin> m_coins; }; ``` The `m_coins` field in this class implies that the unblinded coins for the MW balance in the wallet are stored in memory for an extended period of time. While this will depend on your threat model I believe this is a security risk. I would suggest that the spending keys of these unblinded coins only be read from an encrypted data store when needed and then scrubbed from memory once they have been used.