diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c9435d8..40cb2e6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,6 +124,17 @@ else () endif () +# Check if PIP support cryptographic encryption/decryption by using sodium library +if (DEFINED CRYPT) + message(STATUS "Building with CRYPT") + unset(CRYPT) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPIP_CRYPT") + list(APPEND LIBS sodium) +else () + message(STATUS "Building without CRYPTH, encryption doesn't work") +endif () + + # Add library if (${WIN32}) list(APPEND LIBS ws2_32 Iphlpapi Psapi) diff --git a/main.cpp b/main.cpp index 474f2126..6cf61aa3 100644 --- a/main.cpp +++ b/main.cpp @@ -216,22 +216,45 @@ inline PICout operator <<(PICout s, const FixedPoint & v) { //#include "mpint.h" -#include "unicode/utypes.h" -#include "unicode/stringpiece.h" -#include "unicode/utf8.h" -#include "unicode/ucnv.h" -#include "unicode/uchar.h" +//#include "unicode/utypes.h" +//#include "unicode/stringpiece.h" +//#include "unicode/utf8.h" +//#include "unicode/ucnv.h" +//#include "unicode/uchar.h" + +#include "picrypt.h" int main (int argc, char * argv[]) { - //char uc[] = "←↑→↓АБВ"; - char uc[] = "│─┌┐└┘├┤┬┴┼"; - - PIString us = PIString::fromUTF8(uc); - - //piForeachC (PIChar & c, us) - // piCout << PICoutManipulators::Hex << PIByteArray(&c, 4); - piCout << us << us.toByteArray() << us.size_s(); + PICrypt cr; + PIByteArray k = cr.setKey("pass"); + PIString s("1234567890"); + PIByteArray ba(s.data(),s.size()); + PIByteArray sba = cr.crypt(ba); + piCout << ba.size() << ba; + piCout << k.size() << k; + piCout << cr.getKey().size() << cr.getKey(); + piCout << sba.size() << sba; + piCout << cr.decrypt(sba).size() << cr.decrypt(sba); + sba[random()%sba.size()]++; + piCout << cr.decrypt(sba).size() << cr.decrypt(sba); + + piCout << PICrypt::sizeKey() << PICrypt::sizeCrypt(); + piCout << ba.size() << ba; + PIByteArray ke = PICrypt::hash("pass"); + piCout << ke.size() << ke; + sba = PICrypt::crypt(ba, ke); + piCout << sba.size() << sba; + piCout << ba.size() << PICrypt::decrypt(sba, ke); return 0; +// //char uc[] = "←↑→↓АБВ"; +// char uc[] = "│─┌┐└┘├┤┬┴┼"; + +// PIString us = PIString::fromUTF8(uc); + +// //piForeachC (PIChar & c, us) +// // piCout << PICoutManipulators::Hex << PIByteArray(&c, 4); +// piCout << us << us.toByteArray() << us.size_s(); +// return 0; /*FixedPoint<16, long long> a, b; a = 10; diff --git a/src/math/picrypt.cpp b/src/math/picrypt.cpp new file mode 100644 index 00000000..0f787d0f --- /dev/null +++ b/src/math/picrypt.cpp @@ -0,0 +1,148 @@ +#include "picrypt.h" + +#ifdef PIP_CRYPT +#include "sodium.h" +#endif + +PICrypt::PICrypt() { +#ifdef PIP_CRYPT + sodium_init(); + nonce.resize(crypto_secretbox_NONCEBYTES); + key.resize(crypto_secretbox_KEYBYTES); + randombytes_buf(key.data(), key.size()); + randombytes_buf(nonce.data(), nonce.size()); +#else + piCout << "[PICrypt]" << "Warning: PICrypt is disabled, to enable install sodium library and build pip with -DCRYPT="; +#endif +} + + +bool PICrypt::setKey(const PIByteArray &secret) { + if (secret.size() != key.size()) return false; + key = secret; + return true; +} + + +PIByteArray PICrypt::setKey(const PIString &secret) { + PIByteArray hash; +#ifdef PIP_CRYPT + hash.resize(crypto_generichash_BYTES); + PIByteArray s(secret.data(), secret.size()); + crypto_generichash(hash.data(), hash.size(), s.data(), s.size(), 0, 0); + hash.resize(key.size()); + setKey(hash); +#endif + return hash; +} + + +PIByteArray PICrypt::getKey() { + return key; +} + + +PIByteArray PICrypt::crypt(const PIByteArray &data) { + PIByteArray ret; +#ifdef PIP_CRYPT + ret.resize(data.size() + crypto_secretbox_MACBYTES); + randombytes_buf(nonce.data(), nonce.size()); + crypto_secretbox_easy(ret.data(), data.data(), data.size(), nonce.data(), key.data()); + ret.append(nonce); +#endif + return ret; +} + + +PIByteArray PICrypt::crypt(const PIByteArray &data, const PIByteArray &secret) { + PIByteArray ret; +#ifdef PIP_CRYPT + if (secret.size() != crypto_secretbox_KEYBYTES) return PIByteArray(); + sodium_init(); + PIByteArray n; + ret.resize(data.size() + crypto_secretbox_MACBYTES); + n.resize(crypto_secretbox_NONCEBYTES); + randombytes_buf(n.data(), n.size()); + crypto_secretbox_easy(ret.data(), data.data(), data.size(), n.data(), secret.data()); + ret.append(n); +#endif + return ret; +} + + +PIByteArray PICrypt::decrypt(const PIByteArray &crypt_data, bool *ok) { + PIByteArray ret; +#ifdef PIP_CRYPT + if (crypt_data.size() < nonce.size() + crypto_secretbox_MACBYTES) { + if (ok) *ok = false; + return PIByteArray(); + } + ret.resize(crypt_data.size() - nonce.size() - crypto_secretbox_MACBYTES); + memcpy(nonce.data(), crypt_data.data(crypt_data.size() - nonce.size()), nonce.size()); + if (crypto_secretbox_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - nonce.size(), nonce.data(), key.data()) != 0) { + if (ok) *ok = false; + // piCout << "[PICrypt]" << "bad key"; + return PIByteArray(); + } +#endif + if (ok) *ok = true; + return ret; +} + + +PIByteArray PICrypt::decrypt(const PIByteArray &crypt_data, const PIByteArray &secret, bool *ok) { + PIByteArray ret; +#ifdef PIP_CRYPT + if (secret.size() != crypto_secretbox_KEYBYTES) { + if (ok) *ok = false; + return PIByteArray(); + } + if (crypt_data.size() < crypto_secretbox_NONCEBYTES + crypto_secretbox_MACBYTES) { + if (ok) *ok = false; + return PIByteArray(); + } + sodium_init(); + PIByteArray n; + n.resize(crypto_secretbox_NONCEBYTES); + ret.resize(crypt_data.size() - n.size() - crypto_secretbox_MACBYTES); + memcpy(n.data(), crypt_data.data(crypt_data.size() - n.size()), n.size()); + if (crypto_secretbox_open_easy(ret.data(), crypt_data.data(), crypt_data.size() - n.size(), n.data(), secret.data()) != 0) { + if (ok) *ok = false; + // piCout << "[PICrypt]" << "bad key"; + return PIByteArray(); + } +#endif + if (ok) *ok = true; + return ret; +} + + +PIByteArray PICrypt::hash(const PIString &secret) { + PIByteArray hash; +#ifdef PIP_CRYPT + sodium_init(); + hash.resize(crypto_generichash_BYTES); + PIByteArray s(secret.data(), secret.size()); + crypto_generichash(hash.data(), hash.size(), s.data(), s.size(), 0, 0); +#endif + return hash; +} + + +int PICrypt::sizeKey() { +#ifdef PIP_CRYPT + return crypto_secretbox_KEYBYTES; +#endif + return 0; +} + + +int PICrypt::sizeCrypt() { +#ifdef PIP_CRYPT + return crypto_secretbox_MACBYTES + crypto_secretbox_NONCEBYTES; +#endif + return 0; +} + + + diff --git a/src/math/picrypt.h b/src/math/picrypt.h new file mode 100644 index 00000000..deb9917a --- /dev/null +++ b/src/math/picrypt.h @@ -0,0 +1,34 @@ +#ifndef PICRYPT_H +#define PICRYPT_H + +#include "pistring.h" + +class PICrypt { +public: + PICrypt(); + + bool setKey(const PIByteArray &secret); + PIByteArray setKey(const PIString &secret); + + PIByteArray getKey(); + + PIByteArray crypt(const PIByteArray &data); + + PIByteArray decrypt(const PIByteArray &crypt_data, bool * ok = 0); + + static PIByteArray crypt(const PIByteArray &data, const PIByteArray &secret); + + static PIByteArray decrypt(const PIByteArray &crypt_data, const PIByteArray &secret, bool * ok = 0); + + static PIByteArray hash(const PIString &secret); + + static int sizeKey(); + + static int sizeCrypt(); + +private: + PIByteArray nonce; + PIByteArray key; +}; + +#endif // PICRYPT_H