diff --git a/include/fc/crypto/romix.hpp b/include/fc/crypto/romix.hpp deleted file mode 100644 index 21c3bc0..0000000 --- a/include/fc/crypto/romix.hpp +++ /dev/null @@ -1,81 +0,0 @@ -// Most of this file has been ported from EncryptionUtils.cpp from BitcoinArmory: -//////////////////////////////////////////////////////////////////////////////// -// // -// Copyright(C) 2011-2013, Armory Technologies, Inc. // -// Distributed under the GNU Affero General Public License (AGPL v3) // -// See LICENSE or http://www.gnu.org/licenses/agpl.html // -// // -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -// -// For the KDF: -// -// This technique is described in Colin Percival's paper on memory-hard -// key-derivation functions, used to create "scrypt": -// -// http://www.tarsnap.com/scrypt/scrypt.pdf -// -// The goal is to create a key-derivation function that can force a memory -// requirement on the thread applying the KDF. By picking a sequence-length -// of 1,000,000, each thread will require 32 MB of memory to compute the keys, -// which completely disarms GPUs of their massive parallelization capabilities -// (for maximum parallelization, the kernel must use less than 1-2 MB/thread) -// -// Even with less than 1,000,000 hashes, as long as it requires more than 64 -// kB of memory, a GPU will have to store the computed lookup tables in global -// memory, which is extremely slow for random lookup. As a result, GPUs are -// no better (and possibly much worse) than a CPU for brute-forcing the passwd -// -// This KDF is actually the ROMIX algorithm described on page 6 of Colin's -// paper. This was chosen because it is the simplest technique that provably -// achieves the goal of being secure, and memory-hard. -// -// The computeKdfParams method well test the speed of the system it is running -// on, and try to pick the largest memory-size the system can compute in less -// than 0.25s (or specified target). -// -// -// NOTE: If you are getting an error about invalid argument types, from python, -// it is usually because you passed in a BinaryData/Python-string instead -// of a SecureBinaryData object -// -//////////////////////////////////////////////////////////////////////////////// - -#pragma once -#include -#include - -namespace fc { -//////////////////////////////////////////////////////////////////////////////// -// A memory-bound key-derivation function -- uses a variation of Colin -// Percival's ROMix algorithm: http://www.tarsnap.com/scrypt/scrypt.pdf -// -// The computeKdfParams method takes in a target time, T, for computation -// on the computer executing the test. The final KDF should take somewhere -// between T/2 and T seconds. - class romix - { - public: - romix(uint32_t memReqts, uint32_t numIter, std::string salt); - - std::string deriveKey_OneIter(std::string const & password); - std::string deriveKey(std::string const & password); - - private: - uint32_t hashOutputBytes_; - uint32_t kdfOutputBytes_; // size of final key data - - uint32_t memoryReqtBytes_; - uint32_t sequenceCount_; - std::string salt_; // prob not necessary amidst numIter, memReqts - // but I guess it can't hurt - - uint32_t numIterations_; // We set the ROMIX params for a given memory - // req't. Then run it numIter times to meet - // the computation-time req't - }; - -} - - diff --git a/src/crypto/romix.cpp b/src/crypto/romix.cpp deleted file mode 100644 index f9b85a1..0000000 --- a/src/crypto/romix.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// Most of this file has been ported from EncryptionUtils.cpp from BitcoinArmory: -//////////////////////////////////////////////////////////////////////////////// -// // -// Copyright(C) 2011-2013, Armory Technologies, Inc. // -// Distributed under the GNU Affero General Public License (AGPL v3) // -// See LICENSE or http://www.gnu.org/licenses/agpl.html // -// // -//////////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#include - -namespace fc -{ - romix::romix( uint32_t memReqts, uint32_t numIter, std::string salt ) : - hashOutputBytes_( 64 ), - kdfOutputBytes_( 32 ) - { - memoryReqtBytes_ = memReqts; - sequenceCount_ = memoryReqtBytes_ / hashOutputBytes_; - numIterations_ = numIter; - salt_ = salt; - } - - std::string romix::deriveKey_OneIter( std::string const & password ) - { - static fc::sha512 sha512; - - // Concatenate the salt/IV to the password - std::string saltedPassword = password + salt_; - - // Prepare the lookup table - char *lookupTable_ = new char[memoryReqtBytes_]; - uint32_t const HSZ = hashOutputBytes_; - - // First hash to seed the lookup table, input is variable length anyway - fc::sha512 hash = sha512.hash(saltedPassword); - memcpy(lookupTable_, &hash, HSZ); - - // Compute consecutive hashes of the passphrase - // Every iteration is stored in the next 64-bytes in the Lookup table - for( uint32_t nByte = 0; nByte < memoryReqtBytes_ - HSZ; nByte += HSZ ) - { - // Compute hash of slot i, put result in slot i+1 - fc::sha512 hash = sha512.hash(lookupTable_ + nByte, HSZ); - memcpy(lookupTable_ + nByte + HSZ, &hash, HSZ); - } - - // LookupTable should be complete, now start lookup sequence. - // Start with the last hash from the previous step - std::string X(lookupTable_ + memoryReqtBytes_ - HSZ, HSZ); - std::string Y(HSZ, '0'); - - // We "integerize" a hash value by taking the last 4 bytes of - // as a u_int32_t, and take modulo sequenceCount - uint64_t* X64ptr = (uint64_t*)(X.data()); - uint64_t* Y64ptr = (uint64_t*)(Y.data()); - uint64_t* V64ptr = NULL; - uint32_t newIndex; - uint32_t const nXorOps = HSZ / sizeof(uint64_t); - - // Pure ROMix would use sequenceCount_ for the number of lookups. - // We divide by 2 to reduce computation time RELATIVE to the memory usage - // This still provides suffient LUT operations, but allows us to use more - // memory in the same amount of time (and this is the justification for - // the scrypt algorithm -- it is basically ROMix, modified for more - // flexibility in controlling compute-time vs memory-usage). - uint32_t const nLookups = sequenceCount_ / 2; - for(uint32_t nSeq=0; nSeq - V64ptr = (uint64_t*)(lookupTable_ + HSZ * newIndex); - - // xor X with V, and store the result in X - for(uint32_t i = 0; i < nXorOps; i++) - *(Y64ptr + i) = *(X64ptr + i) ^ *(V64ptr + i); - - // Hash the xor'd data to get the next index for lookup - fc::sha512 hash = sha512.hash(Y.data(), HSZ); - X.assign(hash.data(), HSZ); - } - // Truncate the final result to get the final key - delete lookupTable_; - return X.substr(0, kdfOutputBytes_); - } - - std::string romix::deriveKey( std::string const & password ) - { - std::string masterKey(password); - for(uint32_t i=0; i