diff --git a/.gitignore b/.gitignore index 94d6982..5754812 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,8 @@ vain b33address offlinekeys regaddr_3ld +verifyhost +x25519 *.exe # private key files diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 index 2ec136b..6af1fe0 --- a/Makefile +++ b/Makefile @@ -5,82 +5,88 @@ I2PD_LIB = libi2pd.a LIBI2PD_PATH = $(I2PD_PATH)/libi2pd LIBI2PD_CLIENT_PATH = $(I2PD_PATH)/libi2pd_client + CXX ?= g++ -FLAGS = -Wall -std=c++11 -Wno-misleading-indentation +CXXFLAGS = -Wall -std=c++17 -O2 +INCFLAGS = -I$(LIBI2PD_PATH) -I$(LIBI2PD_CLIENT_PATH) +DEFINES = -DOPENSSL_SUPPRESS_DEPRECATED + +LDFLAGS = +LDLIBS = $(I2PD_PATH)/$(I2PD_LIB) -lboost_system$(BOOST_SUFFIX) -lboost_program_options$(BOOST_SUFFIX) -lssl -lcrypto -lz + ifeq ($(UNAME),Linux) - FLAGS += -g + CXXFLAGS += -g else ifeq ($(UNAME),Darwin) - FLAGS += -g + CXXFLAGS += -g else ifeq ($(UNAME),FreeBSD) - FLAGS += -g + CXXFLAGS += -g else # Win32 - FLAGS += -Os -D_MT -DWIN32 -D_WINDOWS -DWIN32_LEAN_AND_MEAN + CXXFLAGS += -Os -fPIC -msse + DEFINES += -DWIN32_LEAN_AND_MEAN BOOST_SUFFIX = -mt endif -INCFLAGS = -I$(LIBI2PD_PATH) -I$(LIBI2PD_CLIENT_PATH) -CXXFLAGS = $(FLAGS) -LDFLAGS = -LIBS = $(I2PD_PATH)/$(I2PD_LIB) -lboost_system$(BOOST_SUFFIX) -lboost_date_time$(BOOST_SUFFIX) -lboost_filesystem$(BOOST_SUFFIX) -lboost_program_options$(BOOST_SUFFIX) -lssl -lcrypto -lz - ifeq ($(UNAME),Linux) - LIBS += -lrt -lpthread + LDLIBS += -lrt -lpthread else ifeq ($(UNAME),Darwin) - LIBS += -lpthread + LDLIBS += -lpthread LDFLAGS += -L/usr/local/opt/openssl@1.1/lib -L/usr/local/lib INCFLAGS += -I/usr/local/opt/openssl@1.1/include -I/usr/local/include else ifeq ($(UNAME),FreeBSD) - LIBS += -lthr -lpthread - LDFLAGS += -L/usr/local/lib + LDLIBS += -lthr -lpthread + LDFLAGS += -L/usr/local/lib INCFLAGS += -I/usr/local/include else # Win32 - LIBS += -lws2_32 -lwsock32 -lgdi32 -liphlpapi -lstdc++ -lpthread - LDFLAGS += -s -Wl,-Bstatic -static-libgcc -static-libstdc++ + LDLIBS += -lwsock32 -lws2_32 -liphlpapi -lpthread + LDFLAGS += -s -static endif -all: $(I2PD_LIB) keygen keyinfo famtool routerinfo regaddr regaddr_3ld vain i2pbase64 offlinekeys b33address regaddralias x25519 verifyhost + +all: $(I2PD_LIB) vain keygen keyinfo famtool routerinfo regaddr regaddr_3ld i2pbase64 offlinekeys b33address regaddralias x25519 verifyhost autoconf +vain: vain.o $(I2PD_LIB) + $(CXX) -o vain $(LDFLAGS) vain.o $(LDLIBS) + +autoconf: autoconf.o $(I2PD_LIB) + $(CXX) -o autoconf $(DEFINES) $(LDFLAGS) autoconf.o $(LDLIBS) routerinfo: routerinfo.o $(I2PD_LIB) - $(CXX) -o routerinfo routerinfo.o $(LDFLAGS) $(LIBS) + $(CXX) -o routerinfo $(LDFLAGS) routerinfo.o $(LDLIBS) -latomic keygen: keygen.o $(I2PD_LIB) - $(CXX) -o keygen keygen.o $(LDFLAGS) $(LIBS) + $(CXX) -o keygen $(DEFINES) $(LDFLAGS) keygen.o $(LDLIBS) keyinfo: keyinfo.o $(I2PD_LIB) - $(CXX) -o keyinfo keyinfo.o $(LDFLAGS) $(LIBS) + $(CXX) -o keyinfo $(DEFINES) $(LDFLAGS) keyinfo.o $(LDLIBS) famtool: famtool.o $(I2PD_LIB) - $(CXX) -o famtool famtool.o $(LDFLAGS) $(LIBS) + $(CXX) -o famtool $(DEFINES) $(LDFLAGS) famtool.o $(LDLIBS) -latomic regaddr: regaddr.o $(I2PD_LIB) - $(CXX) -o regaddr regaddr.o $(LDFLAGS) $(LIBS) + $(CXX) -o regaddr $(DEFINES) $(LDFLAGS) regaddr.o $(LDLIBS) regaddr_3ld: regaddr_3ld.o $(I2PD_LIB) - $(CXX) -o regaddr_3ld regaddr_3ld.o $(LDFLAGS) $(LIBS) - -vain: vanitygen.o $(I2PD_LIB) - $(CXX) -o vain vanitygen.o $(LDFLAGS) $(LIBS) + $(CXX) -o regaddr_3ld $(DEFINES) $(LDFLAGS) regaddr_3ld.o $(LDLIBS) i2pbase64: i2pbase64.o $(I2PD_LIB) - $(CXX) -o i2pbase64 i2pbase64.o $(LDFLAGS) $(LIBS) + $(CXX) -o i2pbase64 $(DEFINES) $(LDFLAGS) i2pbase64.o $(LDLIBS) offlinekeys: offlinekeys.o $(I2PD_LIB) - $(CXX) -o offlinekeys offlinekeys.o $(LDFLAGS) $(LIBS) + $(CXX) -o offlinekeys $(DEFINES) $(LDFLAGS) offlinekeys.o $(LDLIBS) b33address: b33address.o $(I2PD_LIB) - $(CXX) -o b33address b33address.o $(LDFLAGS) $(LIBS) + $(CXX) -o b33address $(DEFINES) $(LDFLAGS) b33address.o $(LDLIBS) regaddralias: regaddralias.o $(I2PD_LIB) - $(CXX) -o regaddralias regaddralias.o $(LDFLAGS) $(LIBS) - + $(CXX) -o regaddralias $(DEFINES) $(LDFLAGS) regaddralias.o $(LDLIBS) + x25519: x25519.o $(I2PD_LIB) - $(CXX) -o x25519 x25519.o $(LDFLAGS) $(LIBS) + $(CXX) -o x25519 $(DEFINES) $(LDFLAGS) x25519.o $(LDLIBS) verifyhost: verifyhost.o $(I2PD_LIB) - $(CXX) -o verifyhost verifyhost.o $(LDFLAGS) $(LIBS) + $(CXX) -o verifyhost $(DEFINES) $(LDFLAGS) verifyhost.o $(LDLIBS) .SUFFIXES: .SUFFIXES: .c .cc .C .cpp .o @@ -89,7 +95,7 @@ $(I2PD_LIB): $(MAKE) -C $(I2PD_PATH) mk_obj_dir $(I2PD_LIB) %.o: %.cpp $(I2PD_LIB) - $(CXX) -o $@ -c $(CXXFLAGS) $(INCFLAGS) $< + $(CXX) $(CXXFLAGS) $(DEFINES) $(INCFLAGS) -c -o $@ $< count: wc *.c *.cc *.C *.cpp *.h *.hpp @@ -101,7 +107,7 @@ clean-obj: rm -f $(wildcard *.o) clean-bin: - rm -f b33address famtool i2pbase64 keygen keyinfo offlinekeys regaddr regaddr_3ld regaddralias routerinfo vain x25519 verifyhost + rm -f b33address famtool i2pbase64 keygen keyinfo offlinekeys regaddr regaddr_3ld regaddralias routerinfo x25519 verifyhost vain autoconf clean: clean-i2pd clean-obj clean-bin diff --git a/README.md b/README.md old mode 100644 new mode 100755 index b434ce0..8fcaa27 --- a/README.md +++ b/README.md @@ -11,40 +11,27 @@ Notice: git submodules are used so make sure to clone this repository recursivel ### Dependencies * boost chrono + * boost date-time + * boost filesystem + * boost program-options + * libssl + * zlib1g -```bash - -depend="libboost-chrono-dev \ - libboost-date-time-dev \ - libboost-filesystem-dev \ - libboost-program-options-dev \ - libboost-system-dev \ - libboost-thread-dev \ - libssl-dev \ - zlib1g-dev" -kernel=`uname -a` - -case "$kernel" in -*Ubuntu*) - sudo apt install $depend;; -*debian*) - sudo aptitude install $depend;; -*gentoo*) - sudo emerge --deep --newuse dev-libs/boost dev-libs/openssl;; - -*) - echo "Just install libboost and libopenssl dev packages on your pc";; -esac -``` + (run `dependencies.sh`) ### Building - make +```sh +git submodule init && git submodule update +git submodule update --init +git pull --recurse-submodules +make +``` ## Tools included @@ -65,7 +52,7 @@ print iptables firewall rules to allow 1 nodes in netdb through firewall includi ### keygen -Generate an i2p private key +Generate an I2P private key #### Usage @@ -94,7 +81,9 @@ or | EDDSA-SHA512-ED25519 | 7 | | GOSTR3410_CRYPTO_PRO_A-GOSTR3411-256 | 9 | | GOSTR3410_TC26_A_512-GOSTR3411-512 | 10 | +| RED25519-SHA512 | 11 | +For more information on the types of signatures, see the [documentation](https://i2pd.readthedocs.io/en/latest/user-guide/tunnels/#signature-types). ### vain Vanity generation address. @@ -106,17 +95,17 @@ Vanity generation address. #### Time to Generate on a 2.70GHz Processor | characters| time to generate (approx.) | | -------------------- | --------------- | -| 1 | ~0.082s | -| 2 | ~0.075s | -| 3 | ~0.100s | -| 4 | ~0.394s | -| 5 | ~6.343s | -| 6 | ~1m-5m | -| 7 | ~30m | +| 1 | ~0.082s | +| 2 | ~0.075s | +| 3 | ~0.100s | +| 4 | ~0.394s | +| 5 | ~6.343s | +| 6 | ~1m-5m | +| 7 | ~30m | ### keyinfo -Prints information about an i2p private key +Prints information about an I2P private key #### Usage @@ -162,3 +151,51 @@ Generate authentication string to register an alias address for existing domain cat auth_string.txt Send output of auth_string to http://reg.i2p/add and http://stats.i2p/i2p/addkey.html + +### x25519 + +Generate key pair with output in base64 encoding. Now the x25519 keys are used for authentication with an encrypted LeaseSet. + +### famtool +[this is program for works with family of routers in i2p-network. ](https://i2pd.readthedocs.io/en/latest/user-guide/family/) + +usage: ```./famtool [-h] [-v] [-g -n family -c family.crt -k family.pem] [-s -n family -k family.pem -i router.keys -f router.info] [-V -c family.crt -f router.info]``` + +generate a new family signing key for family called ``i2pfam'' +```./famtool -g -n i2pfam -c myfam.crt -k myfam.pem``` + +sign a router info with family signing key +```./famtool -s -n i2pfam -k myfam.pem -i router.keys -f router.info``` + +verify signed router.info +```./famtool -V -n i2pfam -c myfam.pem -f router.info``` +#### Example of usage + $ ./famtool -g -n i2pfam -c myfam.crt -k myfam.pem + family i2pfam made + $ cat myfam.crt + -----BEGIN CERTIFICATE----- + MIIB3TCCAYOgAwIBAgIBADAKBggqhkjOPQQDAjB4MQswCQYDVQQGEwJYWDELMAkG + A1UECAwCWFgxCzAJBgNVBAcMAlhYMR4wHAYDVQQKDBVJMlAgQW5vbnltb3VzIE5l + dHdvcmsxDzANBgNVBAsMBmZhbWlseTEeMBwGA1UEAwwVaTJwZmFtLmZhbWlseS5p + MnAubmV0MB4XDTIzMDczMTE5MjQ1MFoXDTMzMDcyODE5MjQ1MFoweDELMAkGA1UE + BhMCWFgxCzAJBgNVBAgMAlhYMQswCQYDVQQHDAJYWDEeMBwGA1UECgwVSTJQIEFu + b255bW91cyBOZXR3b3JrMQ8wDQYDVQQLDAZmYW1pbHkxHjAcBgNVBAMMFWkycGZh + bS5mYW1pbHkuaTJwLm5ldDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLejNp1Y + 1tnMGFaUIuzNpNL8B9KvaeSSh+OWhRcHn2x1D8TPCVA4IMS0jiMIodCcdyTmz0Qg + SXsWDqT2CbBMENQwCgYIKoZIzj0EAwIDSAAwRQIgU58CeHXlluPZNxpmxb7HSHsJ + STCA8C946oas+8uLU+MCIQDe6Km/h8w+oCh+j6UHobN0EAVtQPQGwkq2XXs1jqX2 + bQ== + -----END CERTIFICATE----- + $ cat myfam.pem + -----BEGIN EC PRIVATE KEY----- + MHcCAQEEIAFA82vZzZN8nZIOVnadSS73G2NNc5pUsh4qmpK2M0nsoAoGCCqGSM49 + AwEHoUQDQgAEt6M2nVjW2cwYVpQi7M2k0vwH0q9p5JKH45aFFwefbHUPxM8JUDgg + xLSOIwih0Jx3JObPRCBJexYOpPYJsEwQ1A== + -----END EC PRIVATE KEY----- + +#### AutoConf +A program for help create the config file for i2pd + +For a now a better way to manual write the config file + +For usage just run ./AutoConf or AutoConf.exe diff --git a/autoconf.cpp b/autoconf.cpp new file mode 100644 index 0000000..c687ab5 --- /dev/null +++ b/autoconf.cpp @@ -0,0 +1,248 @@ +#ifndef AUTOCONFC +#define AUTOCONFC +#include +#include +#include +#include +#include +#include +#include + +#define CIN_CLEAR std::cin.clear(); std::cin.ignore(std::numeric_limits::max(), '\n'); +#define HTTP_SUPPORTS_LANGUAGE "german, italian, polish, portuguese, russian, spanish, turkish, turkmen, ukrainian, uzbek" +namespace AutoConf { + // + namespace Regexps { + //const std::regex port("\\d{1,5}"); + std::regex path(R"([a-zA-Z0-9_\.\/\\]+)"); // (\w|\.|\\|\/)+ + //std::regex proxy("\\w+:\\/\\/(\\w|\\d|\\.|\\-)+\\:\\d+"); + std::regex any(".*"); + + } +namespace PreInitConfigs { + constexpr const char * yggOnlyConf = "ipv4=false\r\n" + "ipv6=false\r\n" + "ssu=false\r\n" + "ntcp2.enabled=false\r\n" + "ssu2.enabled=false\r\n" + "meshnets.yggdrasil=true\r\n"; +} + +// Texts +using AsksT = std::map; +const std::map Texts = // maybe vector better + { + {"ru", { + {"WelcomeText","Привет. Выбери тип конфига\r\n1 - клирнет\r\n2 - только yggdrasil"}, + // Without section + {"TunConfYN", "Использовать другой путь для туннелей?"}, + {"TunConf", "Введите путь для туннелей"}, + {"TunnelsDirYN", "Использовать другой путь для папки туннелей?"}, + {"TunnelsDir","Введите путь для папки с туннелями"}, + {"certsdirYN", "Использовать другой путь для папки с сертификатами?"}, + {"certsdir", "Введите путь для папки с сертификатами"}, + {"pidfileYN","использовать другой путь для PID файла?"}, + {"pidfile", "Введите путь для pidfile"}, + {"logYN","Нужно ли изменить путь лога?"}, + {"log", "Введите тип лога(file,stdout,syslog)"}, + {"logfileYN","Нужно ли изменить путь logfile?"}, + {"logfile", "Введите путь logfile"}, + {"loglevelYN","Нужно ли изменить стандартный уровень логирования?"}, + {"loglevel","Введите уровень лога(warn,info,none,critical,error,debug)"}, + {"logCFLYN", "Использовать полный CFL-форму даты в логах? ПО умолчанию только время"}, + {"daemonYN", "Использовать режим демона?"}, + {"FamilyUsing", "Введите название фамилии или -"}, + //TODO: an another + {"UseIPv6", "Использовать ipv6?"}, + {"UseIPv4", "Использовать ipv4?"}, + {"BeFloodfillYN", "Быть флудфиллом?"}, + {"NoTransitYN", "Отключить транзит? (это уменьшит анонимность)"}, + {"Bandwidth", "Напиши пропускную способность (- для по умолчанию) [L-32kbs,O-256kbs,P-2048kbs,X-unlimited]"}, + {"Share", "Процент шары (- для по умолчанию) [0-100]"}, + // + {"NTCPEnabledYN", "Использовать NTCP?"}, + {"NTCPPublishedYN", "Опубликовать IP В NTCP?"}, + {"NTCPPPort", "NTCP Порт. Либо - для пропуска"}, + {"NTCPPProxy", "NTCP Proxy, пример (socks://localhost:4545) или - для по умолчанию (неиспользуется)"}, + {"SSUEnabledYN", "Использовать SSU?"}, + {"SSUPPort", "SSU Порт. Либо - для пропуска"}, + {"SSUProxy", "SSU Proxy, пример (socks://localhost:4545) или - для по умолчанию (неиспользуется)"}, + {"HTTPLang", "Выбрите язык веб-интерфейса, либо - для опции по умолчанию (" HTTP_SUPPORTS_LANGUAGE ")" } + }}, + {"en", { + {"WelcomeText","Hello. Select type of config\r\n1 - clearnet\r\n2 - only yggdrasil"}, + {"TunConfYN", "Use a different path for tunnels?"}, + {"TunConf", "Enter path for tunnels"}, + {"TunnelsDirYN", "Use a different path for the tunnels folder?"}, + {"TunnelsDir", "Enter path for the tunnels folder"}, + {"certsdirYN", "Use a different path for the certificates folder?"}, + {"certsdir", "Enter path for the certificates folder"}, + {"pidfileYN", "Use a different path for the PID file?"}, + {"pidfile", "Enter path for pidfile"}, + {"logYN", "Do you need to change the log path?"}, + {"log", "Enter log type (file, stdout, syslog)"}, + {"logfileYN", "Do you need to change the logfile path?"}, + {"logfile", "Enter path for logfile"}, + {"loglevelYN", "Do you need to change the default log level?"}, + {"loglevel", "Enter log level (warn, info, none, critical, error, debug)"}, + {"logCFLYN", "Use full CFL format for date in logs? Default is only time."}, + {"daemonYN", "Use daemon mode?"}, + {"FamilyUsing", "Enter your netfamily or just hit -."}, + //TODO: an another + {"UseIPv6", "Use ipv6?"}, + {"UseIPv4", "Use ipv4?"}, + {"BeFloodfillYN", "Be a floodfill?"}, + {"NoTransitYN", "Disable transit? (this will reduce anonymity)"}, + {"Bandwidth", "Write bandwidth (- for default) [L-32kbs,O-256kbs,P-2048kbs,X-unlimited]"}, + {"Share", "Share percents (- for default) [0-100]"}, + {"HTTPLang", "Select Web-interface language or - for default (" HTTP_SUPPORTS_LANGUAGE ")" }, + // + {"NTCPEnabledYN", "Use NTCP?"}, + {"NTCPPublishedYN", "Publish IP in NTCP?"}, + {"NTCPPPort", "NTCP Port or - for auto port (random)"}, + {"NTCPPProxy", "NTCP Proxy, example (socks://localhost:4545) or - for default"}, + {"SSUEnabledYN", "Use SSU?"}, + {"SSUPPort", "SSU Port or - for auto port (random)"}, + {"SSUProxy", "SSU Proxy, example (socks://localhost:4545) or - for default"} + + }} + }; + +// Functions +bool AskYN(void) noexcept { + char answ; + std::cout << " ? (y/n) "; + std::cin >> answ; + CIN_CLEAR; + switch(answ) { + case 'y': + case 'Y': + return true; + case 'n': + case 'N': + return false; + default: + return AskYN(); // stack overflow, would use while(true) + } +} +std::string GetLanguage(void) noexcept { + std::string lang; + std::cout << "Language/Язык:\r\nru - русский\r\nen - английский\r\n"; + std::cin >> lang; + CIN_CLEAR; + if (Texts.find(lang) != Texts.end()) { + return lang; + } else { + std::cerr << "Not correct language, try again" << std::endl; + return GetLanguage(); // stack overflow + } +} + +bool IsOnlyYggdrasil(const std::string & lang) noexcept { + unsigned short answ; + std::cout << AutoConf::Texts.at(lang).at("WelcomeText") << std::endl; + std::cin >> answ; + CIN_CLEAR; + switch(answ) { + case 1: + return false; + case 2: + return true; + default: + return IsOnlyYggdrasil(lang); + } +} + +} + +int +main(void) { + std::cout << "https://i2pd.readthedocs.io/en/latest/user-guide/configuration/\r\nhttps://github.com/PurpleI2P/i2pd/blob/openssl/contrib/i2pd.conf\r\n"; + std::ostringstream conf; + auto lang = AutoConf::GetLanguage(); + auto isOnlyYgg = AutoConf::IsOnlyYggdrasil(lang); + if (isOnlyYgg) { + #ifndef _WIN32 + conf << "daemon=true\r\n"; + #endif + conf << AutoConf::PreInitConfigs::yggOnlyConf; + } else { + // Asks + using namespace AutoConf; + [](std::ostringstream &conf, const std::string &lang) { + #define ASKYN_MACRO(A,B,C, REGEX) { \ + std::cout << AutoConf::Texts.at(lang).at(A); \ + if(AskYN()) { \ + while(1) {\ + std::cout << AutoConf::Texts.at(lang).at(B) << "\r\n"; \ + std::string inp; \ + std::cin >> inp;\ + CIN_CLEAR; \ + std::smatch bmatch;\ + std::regex_match(inp, bmatch, REGEX);\ + if (bmatch.length() > 0) {\ + conf << C "=" << inp << "\r\n"; \ + break;\ + }else {std::cerr<<"No correct input"<> inp;CIN_CLEAR; if (inp != "-") {\ + conf << B "=" << inp << "\r\n";\ + }\ + } + ASK_TEXT("FamilyUsing","family"); + ASK_BOOL("BeFloodfillYN", "floodfill"); + ASK_BOOL("NoTransitYN", "notransit"); + ASK_TEXT("Bandwidth","bandwidth"); + ASK_TEXT("Share","share"); + ///// With sections + conf << "[ntcp2]\r\n"; + ASK_BOOL("NTCPEnabledYN", "enabled"); + ASK_BOOL("NTCPPublishedYN", "published"); + ASK_TEXT("NTCPPPort", "port"); + ASK_TEXT("NTCPPProxy", "proxy"); + conf << "[ssu2]\r\n"; + ASK_BOOL("SSUEnabledYN", "enabled"); + ASK_TEXT("SSUPPort", "port"); + ASK_TEXT("SSUProxy", "proxy"); + conf << "[http]\r\n"; + ASK_TEXT("HTTPLang", "lang"); + #undef ASK_TEXT + #undef ASK_BOOL + #undef ASKYN_MACRO + + }(conf, lang); + } + std::cout << "Config: " << std::endl; + std::cout << conf.str() << std::endl; + //TODO: To Constexpr + std::cout << "Save File: (\"i2pd_.conf\"):"; + std::string outFileName; + std::cin.clear(); + std::getline(std::cin, outFileName); + //TODO: to constxpr + if (outFileName.length() == 0) outFileName = "i2pd_.conf"; + std::ofstream confFile(outFileName); + confFile << conf.str(); + confFile.close(); +} +#endif diff --git a/b33address.cpp b/b33address.cpp index e239526..59dd96f 100644 --- a/b33address.cpp +++ b/b33address.cpp @@ -14,7 +14,8 @@ int main(int argc, char * argv[]) auto ident = std::make_shared(); if (ident->FromBase64 (base64)) { - if (ident->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519) + if (ident->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519 || + ident->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519) { i2p::data::BlindedPublicKey blindedKey (ident); std::cout << "b33 address: " << blindedKey.ToB33 () << ".b32.i2p" << std::endl; diff --git a/dependencies.sh b/dependencies.sh new file mode 100755 index 0000000..aaddcaf --- /dev/null +++ b/dependencies.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +dependNix="libboost-chrono-dev \ + libboost-date-time-dev \ + libboost-filesystem-dev \ + libboost-program-options-dev \ + libboost-system-dev \ + libboost-thread-dev \ + libssl-dev \ + zlib1g-dev" +dependWin="mingw-w64-x86_64-boost \ + mingw-w64-x86_64-openssl \ + mingw-w64-x86_64-zlib" + +kernel=$(uname -a) + +function anotherDistr() { + echo "Just install libboost and libopenssl dev packages on your pc" + return 0 +} + +function installDnf() { + sudo dnf install boost-devel g++ +} + +function installDeb() { + sudo apt-get install $dependNix + return 0 +} + +function installOnGentoo() { + sudo emerge --deep --newuse dev-libs/boost dev-libs/openssl + return 0 +} + +function installOnWin() { + pacman -S $dependWin + return 0 +} + +function doInstallDepencies() { + case "$1" in + *Ubuntu* | *Debian*) + installDeb + ;; + *gentoo*) + installOnGentoo + ;; + *MINGW64*) + installOnWin + ;; + *dnf*) + installDnf + ;; + *) + anotherDistr + ;; + esac +} + +isLsbReleaseExists=$(which lsb_release > /dev/null 2>&1; echo $?) +if [ $isLsbReleaseExists -eq 0 ]; then + distr=$(lsb_release -i) + doInstallDepencies "$distr" +elif test -e /etc/fedora-release || which dnf > /dev/null; then + printf "Like you use fedora/redhat distr\n" + doInstallDepencies "dnf" +else + doInstallDepencies "$kernel" +fi + diff --git a/famtool.cpp b/famtool.cpp index cbd0bfb..0a40689 100644 --- a/famtool.cpp +++ b/famtool.cpp @@ -197,7 +197,7 @@ int main(int argc, char * argv[]) return 0; } - InitCrypto(false, true, true, false); + InitCrypto(false); if(!fam.size()) { // no family name @@ -319,7 +319,10 @@ int main(int argc, char * argv[]) delete [] k; } - RouterInfo ri(infofile); + RouterInfo routerInfo(infofile); + LocalRouterInfo ri; + ri.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ()); + auto ident = ri.GetIdentHash(); @@ -365,7 +368,9 @@ int main(int argc, char * argv[]) if (verbose) std::cout << "load " << infofile << std::endl; - RouterInfo ri(infofile); + RouterInfo routerInfo(infofile); + LocalRouterInfo ri; + ri.Update (routerInfo.GetBuffer (), routerInfo.GetBufferLen ()); auto sig = ri.GetProperty(ROUTER_INFO_PROPERTY_FAMILY_SIG); if (ri.GetProperty(ROUTER_INFO_PROPERTY_FAMILY) != fam) { std::cout << infofile << " does not belong to " << fam << std::endl; diff --git a/i2pd b/i2pd index f22eaa6..dcd15cc 160000 --- a/i2pd +++ b/i2pd @@ -1 +1 @@ -Subproject commit f22eaa6db51e36d0a064c56907589164752035c5 +Subproject commit dcd15cc2449d6320de6351054e61ef2ee7ebee40 diff --git a/keygen.cpp b/keygen.cpp index 9105d92..a9f72cf 100644 --- a/keygen.cpp +++ b/keygen.cpp @@ -12,11 +12,12 @@ int main (int argc, char * argv[]) std::cout << "Usage: keygen filename " << std::endl; return -1; } - i2p::crypto::InitCrypto (false, true, true, false); + i2p::crypto::InitCrypto (false); i2p::data::SigningKeyType type = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519; if (argc > 2) { std::string str(argv[2]); type = NameToSigType(str); + if (SigTypeToName(type).find("unknown") != std::string::npos) { std::cerr << "Incorrect signature type" << std::endl; return -2; } } auto keys = i2p::data::PrivateKeys::CreateRandomKeys (type); std::ofstream f (argv[1], std::ofstream::binary | std::ofstream::out); @@ -28,6 +29,7 @@ int main (int argc, char * argv[]) f.write ((char *)buf, len); delete[] buf; std::cout << "Destination " << keys.GetPublic ()->GetIdentHash ().ToBase32 () << " created" << std::endl; + std::cout << "Signature type: " << SigTypeToName(type) << " (" << type << ")" << std::endl; } else std::cout << "Can't create file " << argv[1] << std::endl; diff --git a/keyinfo.cpp b/keyinfo.cpp index 4a8d19e..2f79bb8 100644 --- a/keyinfo.cpp +++ b/keyinfo.cpp @@ -12,7 +12,7 @@ static int printHelp(const char * exe, int exitcode) { - std::cout << "usage: " << exe << " [-v] [-d] [-b] privatekey.dat" << std::endl; + std::cout << "usage: " << exe << " [-v] [-d] [-p] [-b] privatekey.dat" << std::endl; return exitcode; } @@ -31,10 +31,11 @@ int main(int argc, char * argv[]) } int opt; - bool print_full = false; + bool print_dest = false; + bool print_private = false; bool print_blinded = false; bool verbose = false; - while((opt = getopt(argc, argv, "hvdb")) != -1) { + while((opt = getopt(argc, argv, "hvdpb")) != -1) { switch(opt){ case 'h': return printHelp(argv[0], 0); @@ -42,7 +43,10 @@ int main(int argc, char * argv[]) verbose = true; break; case 'd': - print_full = true; + print_dest = true; + break; + case 'p': + print_private = true; break; case 'b': print_blinded = true; @@ -54,23 +58,22 @@ int main(int argc, char * argv[]) std::string fname(argv[optind]); i2p::data::PrivateKeys keys; - { - std::vector buff; - std::ifstream inf; - inf.open(fname); - if (!inf.is_open()) { - std::cout << "cannot open private key file " << fname << std::endl; - return 2; - } - inf.seekg(0, std::ios::end); - const std::size_t len = inf.tellg(); - inf.seekg(0, std::ios::beg); - buff.resize(len); - inf.read((char*)buff.data(), buff.size()); - if (!keys.FromBuffer(buff.data(), buff.size())) { - std::cout << "bad key file format" << std::endl; - return 3; - } + std::ifstream s(fname, std::ifstream::binary); + + if (!s.is_open()) { + std::cout << "cannot open private key file " << fname << std::endl; + return 2; + } + + s.seekg(0, std::ios::end); + size_t len = s.tellg(); + s.seekg(0, std::ios::beg); + uint8_t * buf = new uint8_t[len]; + s.read((char*)buf, len); + + if (!keys.FromBuffer(buf, len)) { + std::cout << "bad key file format" << std::endl; + return 3; } auto dest = keys.GetPublic(); @@ -94,7 +97,9 @@ int main(int argc, char * argv[]) std::cout << "Transient Signature Type: " << SigTypeToName(bufbe16toh(offlineSignature.data () + 4)) << std::endl; } } else { - if(print_full) { + if(print_private) { + std::cout << keys.ToBase64() << std::endl; + } else if(print_dest) { std::cout << dest->ToBase64() << std::endl; } else { std::cout << ident.ToBase32() << ".b32.i2p" << std::endl; @@ -112,4 +117,7 @@ int main(int argc, char * argv[]) else std::cout << "Invalid signature type " << SigTypeToName (dest->GetSigningKeyType ()) << std::endl; } + + i2p::crypto::TerminateCrypto (); + return 0; } diff --git a/offlinekeys.cpp b/offlinekeys.cpp index 473c703..c290465 100644 --- a/offlinekeys.cpp +++ b/offlinekeys.cpp @@ -14,7 +14,7 @@ int main (int argc, char * argv[]) std::cout << "Usage: offlinekeys " << std::endl; return -1; } - i2p::crypto::InitCrypto (false, true, true, false); + i2p::crypto::InitCrypto (false); std::string fname(argv[2]); i2p::data::PrivateKeys keys; diff --git a/regaddr.cpp b/regaddr.cpp index 9890830..6dbf1fd 100644 --- a/regaddr.cpp +++ b/regaddr.cpp @@ -12,10 +12,11 @@ int main (int argc, char * argv[]) return -1; } - i2p::crypto::InitCrypto (false, true, true, false); + i2p::crypto::InitCrypto (false); i2p::data::PrivateKeys keys; std::ifstream s(argv[1], std::ifstream::binary); + if (s.is_open ()) { s.seekg (0, std::ios::end); @@ -23,6 +24,7 @@ int main (int argc, char * argv[]) s.seekg (0, std::ios::beg); uint8_t * buf = new uint8_t[len]; s.read ((char *)buf, len); + if(keys.FromBuffer (buf, len)) { auto signatureLen = keys.GetPublic ()->GetSignatureLen (); @@ -41,10 +43,10 @@ int main (int argc, char * argv[]) } else std::cout << "Failed to load keyfile " << argv[1] << std::endl; + delete[] buf; } i2p::crypto::TerminateCrypto (); - return 0; } diff --git a/regaddr_3ld.cpp b/regaddr_3ld.cpp index bb1c703..4c94b09 100644 --- a/regaddr_3ld.cpp +++ b/regaddr_3ld.cpp @@ -18,7 +18,7 @@ int main (int argc, char * argv[]) if (argc < 3) { help(); return -1;} std::string arg = argv[1]; - i2p::crypto::InitCrypto (false, true, true, false); + i2p::crypto::InitCrypto (false); i2p::data::PrivateKeys keys; if (arg == "step1") { diff --git a/regaddralias.cpp b/regaddralias.cpp index 921847e..cc56bc0 100644 --- a/regaddralias.cpp +++ b/regaddralias.cpp @@ -12,7 +12,7 @@ int main (int argc, char * argv[]) return -1; } - i2p::crypto::InitCrypto (false, true, true, false); + i2p::crypto::InitCrypto (false); i2p::data::PrivateKeys oldkeys, newkeys; { diff --git a/routerinfo.cpp b/routerinfo.cpp index aeb51f6..5391e39 100644 --- a/routerinfo.cpp +++ b/routerinfo.cpp @@ -6,16 +6,16 @@ static void usage(const char * argv) { - std::cout << "usage: " << argv << " [-6|-f|-p] routerinfo.dat" << std::endl; + std::cout << "usage: " << argv << " [-6|-f|-p|-y] routerinfo.dat" << std::endl; } template static std::string address_style_string(Addr addr) { - if(addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP) { - return "NTCP"; - } else if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU) { - return "SSU"; + if(addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP2) { + return "NTCP2"; + } else if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU2) { + return "SSU2"; } return "???"; @@ -26,9 +26,9 @@ static void write_firewall_entry(std::ostream & o, Addr addr) { std::string proto; - if(addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP) { + if(addr->transportStyle == i2p::data::RouterInfo::eTransportNTCP2) { proto = "tcp"; - } else if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU) { + } else if (addr->transportStyle == i2p::data::RouterInfo::eTransportSSU2) { proto = "udp"; } else { // bail @@ -46,12 +46,13 @@ int main(int argc, char * argv[]) usage(argv[0]); return 1; } - i2p::crypto::InitCrypto(false, true, true, false); + i2p::crypto::InitCrypto(false); int opt; bool ipv6 = false; bool firewall = false; bool port = false; - while((opt = getopt(argc, argv, "6fp")) != -1) { + bool yggdrasil = false; + while((opt = getopt(argc, argv, "6fpy")) != -1) { switch(opt) { case '6': ipv6 = true; @@ -62,6 +63,9 @@ int main(int argc, char * argv[]) case 'p': port = true; break; + case 'y': + yggdrasil = true; + break; default: usage(argv[0]); return 1; @@ -76,6 +80,9 @@ int main(int argc, char * argv[]) std::vector > addrs; auto a = ri.GetPublishedNTCP2V4Address(); + if(a) + addrs.push_back(a); + a = ri.GetSSU2V4Address(); if(a) addrs.push_back(a); if (ipv6) @@ -83,10 +90,16 @@ int main(int argc, char * argv[]) a = ri.GetPublishedNTCP2V6Address(); if(a) addrs.push_back(a); - } - a = ri.GetSSUAddress(!ipv6); - if(a) - addrs.push_back(a); + a = ri.GetSSU2V6Address(); + if(a) + addrs.push_back(a); + } + + if(yggdrasil){ + a = ri.GetYggdrasilAddress(); + if(a) + addrs.push_back(a); + } if(firewall) std::cout << "# "; diff --git a/vain.cpp b/vain.cpp new file mode 100755 index 0000000..91227b9 --- /dev/null +++ b/vain.cpp @@ -0,0 +1,468 @@ +#include "vanity.hpp" +#include +#include +#include +#include +//#include +//#include // is not supports for me + +// some global vars in vanitygen.hpp +static unsigned short fKeyId = 0; +static struct{ + bool reg=false; + int threads=-1; + i2p::data::SigningKeyType signature; + std::string outputpath=""; + std::regex regex; + +}options; +static unsigned short attempts = 0;// it can be disabled, it's just for a statistic. For CPU this is a trash? + +static void inline CalculateW (const uint8_t block[64], uint32_t W[64]) +{ +/* +implementation of orignal +*/ + for (int i = 0; i < 16; i++) +#ifdef _WIN32 + W[i] = htobe32(((uint32_t *)(block))[i]); +#else // from big endian to little endian ( swap ) + W[i] = be32toh(((uint32_t *)(block))[i]); +#endif + + for (int i = 16; i < 64; i++) + W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; +} + +static void inline TransformBlock (uint32_t state[8], const uint32_t W[64]) +{ +/* +implementation of orignal +*/ + uint32_t S[8]; + memcpy(S, state, 32); + + uint32_t t0, t1; + RNDr(S, W, 0, 0x428a2f98); RNDr(S, W, 1, 0x71374491); RNDr(S, W, 2, 0xb5c0fbcf); RNDr(S, W, 3, 0xe9b5dba5); + RNDr(S, W, 4, 0x3956c25b); RNDr(S, W, 5, 0x59f111f1); RNDr(S, W, 6, 0x923f82a4); RNDr(S, W, 7, 0xab1c5ed5); + RNDr(S, W, 8, 0xd807aa98); RNDr(S, W, 9, 0x12835b01); RNDr(S, W, 10, 0x243185be); RNDr(S, W, 11, 0x550c7dc3); + RNDr(S, W, 12, 0x72be5d74); RNDr(S, W, 13, 0x80deb1fe); RNDr(S, W, 14, 0x9bdc06a7); RNDr(S, W, 15, 0xc19bf174); + RNDr(S, W, 16, 0xe49b69c1); RNDr(S, W, 17, 0xefbe4786); RNDr(S, W, 18, 0x0fc19dc6); RNDr(S, W, 19, 0x240ca1cc); + RNDr(S, W, 20, 0x2de92c6f); RNDr(S, W, 21, 0x4a7484aa); RNDr(S, W, 22, 0x5cb0a9dc); RNDr(S, W, 23, 0x76f988da); + RNDr(S, W, 24, 0x983e5152); RNDr(S, W, 25, 0xa831c66d); RNDr(S, W, 26, 0xb00327c8); RNDr(S, W, 27, 0xbf597fc7); + RNDr(S, W, 28, 0xc6e00bf3); RNDr(S, W, 29, 0xd5a79147); RNDr(S, W, 30, 0x06ca6351); RNDr(S, W, 31, 0x14292967); + RNDr(S, W, 32, 0x27b70a85); RNDr(S, W, 33, 0x2e1b2138); RNDr(S, W, 34, 0x4d2c6dfc); RNDr(S, W, 35, 0x53380d13); + RNDr(S, W, 36, 0x650a7354); RNDr(S, W, 37, 0x766a0abb); RNDr(S, W, 38, 0x81c2c92e); RNDr(S, W, 39, 0x92722c85); + RNDr(S, W, 40, 0xa2bfe8a1); RNDr(S, W, 41, 0xa81a664b); RNDr(S, W, 42, 0xc24b8b70); RNDr(S, W, 43, 0xc76c51a3); + RNDr(S, W, 44, 0xd192e819); RNDr(S, W, 45, 0xd6990624); RNDr(S, W, 46, 0xf40e3585); RNDr(S, W, 47, 0x106aa070); + RNDr(S, W, 48, 0x19a4c116); RNDr(S, W, 49, 0x1e376c08); RNDr(S, W, 50, 0x2748774c); RNDr(S, W, 51, 0x34b0bcb5); + RNDr(S, W, 52, 0x391c0cb3); RNDr(S, W, 53, 0x4ed8aa4a); RNDr(S, W, 54, 0x5b9cca4f); RNDr(S, W, 55, 0x682e6ff3); + RNDr(S, W, 56, 0x748f82ee); RNDr(S, W, 57, 0x78a5636f); RNDr(S, W, 58, 0x84c87814); RNDr(S, W, 59, 0x8cc70208); + RNDr(S, W, 60, 0x90befffa); RNDr(S, W, 61, 0xa4506ceb); RNDr(S, W, 62, 0xbef9a3f7); RNDr(S, W, 63, 0xc67178f2); + + for (int i = 0; i < 8; i++) state[i] += S[i]; +} + +void inline HashNextBlock (uint32_t state[8], const uint8_t * block) +{ +/* +implementation of orignal +*/ + uint32_t W[64]; + CalculateW (block, W); + TransformBlock (state, W); +} + +static bool check_prefix(const char * buf) +{ + unsigned short size_str=0; + while(*buf) + { + if(*buf < 48 || (*buf > 57 && *buf < 65) || (*buf > 64 && *buf < 94) || *buf > 125 || size_str > 52) + return false; + size_str++; + buf++; + } + return true; +} + +static inline size_t ByteStreamToBase32 (const uint8_t * inBuf, size_t len, char * outBuf, size_t outLen) +{ + size_t ret = 0, pos = 1; + int bits = 8, tmp = inBuf[0]; + while (ret < outLen && (bits > 0 || pos < len)) + { + if (bits < 5) + { + if (pos < len) + { + tmp <<= 8; + tmp |= inBuf[pos] & 0xFF; + pos++; + bits += 8; + } + else // last byte + { + tmp <<= (5 - bits); + bits = 5; + } + } + + bits -= 5; + int ind = (tmp >> bits) & 0x1F; + outBuf[ret] = (ind < 26) ? (ind + 'a') : ((ind - 26) + '2'); + ret++; + } + outBuf[ret]='\0'; + return ret; +} + +static inline bool NotThat(const char * what, const std::regex & reg){ + return std::regex_match(what,reg) == 1 ? false : true; +} + +static inline bool NotThat(const char * a, const char *b) +{ + while(*b) + if(*a++!=*b++) + return true; + return false; +} + +static inline bool thread_find(uint8_t * buf, const char * prefix, int id_thread, unsigned long long throughput) +{ +/* +Thanks to orignal ^-^ +For idea and example ^-^ +Orignal is sensei of crypto ;) +*/ + std::cout << "Thread " << id_thread << " binded" << std::endl; +/* + union + { + uint8_t b[391]; + uint32_t ll; + } local; + union + { + uint8_t b[32]; + uint32_t ll[8]; + } hash; +*/ + uint8_t b[391]; // b length is 391. + uint32_t hash[8]; + + memcpy (b, buf, 391); // we copy in b our buf, that we give in function. + + auto len = strlen (prefix); + // precalculate first 5 blocks (320 bytes) + uint32_t state[8] = { 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 }; + HashNextBlock (state, b); + HashNextBlock (state, b + 64); + HashNextBlock (state, b + 128); + HashNextBlock (state, b + 192); + HashNextBlock (state, b + 256); + + // pre-calculate last W + uint32_t lastW[64]; + CalculateW (lastBlock, lastW); + + uint32_t * nonce = (uint32_t *)(b+320); // our nonce is place in memory, where is b after 320 bytes (characters) + (*nonce) += id_thread*throughput; + + char addr[53]; + uint32_t state1[8]; + + while(throughput-- and !found) + { + memcpy (state1, state, 32); + // calculate hash of block with nonce + HashNextBlock (state1, b + 320); + // apply last block + TransformBlock (state1, lastW); + // get final hash + for (int j = 8; j--;) + hash[j] = htobe32(state1[j]); + ByteStreamToBase32 ((uint8_t*)hash, 32, addr, len); + // std::cout << addr << std::endl; + + //bool result = options.reg ? !NotThat(addr, &options.regex) : !NotThat(addr,prefix); + + if( ( options.reg ? !NotThat(addr, options.regex) : !NotThat(addr,prefix) ) ) + { + ByteStreamToBase32 ((uint8_t*)hash, 32, addr, 52); + std::cout << "Address found " << addr << " in " << id_thread << std::endl; + found=true; + FoundNonce=*nonce; + // From there place we get a nonce, for some one a byte. + fKeyId = id_thread; + return true; + } + + + (*nonce)++; + hashescounter++; + if (found) // for another threads (?) + { + break; + } + }//while + return true; +} + + + + + +void usage(void){ + constexpr auto help="vain pattern [options]\n" + "-h --help help menu\n" + "-r --reg regexp instead just text pattern\n" + "--threads -t (default count of system)\n" +//"--signature -s (signature type)\n" + "-o --output output file(default " DEF_OUT_FILE ")\n" + "--multiplymode -m - multiple addresses search" + ""; + puts(help); +} + + +void parsing(int argc, char ** args){ + int option_index; + static struct option long_options[]={ + {"help",no_argument,0,'h'}, + {"reg", no_argument,0,'r'}, + {"threads", required_argument, 0, 't'}, + {"signature", required_argument,0,'s'}, + {"output", required_argument,0,'o'}, + {"multiplymode", no_argument, 0, 'm'}, + {0,0,0,0} + }; + + int c; + while( (c=getopt_long(argc,args, "hrt:s:o:m", long_options, &option_index))!=-1){ + switch(c){ + case 'm': + multipleSearchMode=true; + break; + case 'h': + usage(); + exit(0); + break; + case 'r': + options.reg=true; + break; + case 't': + options.threads=atoi(optarg); + break; + case 's': + options.signature = NameToSigType(std::string(optarg)); + break; + case 'o': + options.outputpath=optarg; + break; + case '?': + std::cerr << "Undefined argument" << std::endl; + default: + std::cerr << args[0] << "--help" << std::endl; + exit(1); + break; + } + } +} + +int main (int argc, char * argv[]) +{ + + + + + if ( argc < 2 ) + { + usage(); + return 0; + } + parsing( argc > 2 ? argc-1 : argc, argc > 2 ? argv+1 : argv); // parsing is was there. + // if argc size more than 2. nameprogram is 1. and 2 is prefix. if not there is will be flags like regex + // TODO: ? + if(!options.reg && !check_prefix( argv[1] )) + { + std::cout << "Not correct prefix(just string)" << std::endl; + return 1; + }else{ + options.regex=std::regex(argv[1]); + } +// https://github.com/PurpleI2P/i2pd/blob/ae5239de435e1dcdff342961af9b506f60a494d4/libi2pd/Crypto.h#L310 +//// init and terminate +// void InitCrypto (bool precomputation); +// By default false + i2p::crypto::InitCrypto (PRECOMPUTATION_CRYPTO); + options.signature = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519; +/////////////// +//For while + if(options.signature != i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519) + { + std::cout << "For a while only ED25519-SHA512" << std::endl; + return 0; + } +/////////////// +// if threads less than 0, then we get from system count of CPUs cores + if(options.threads <= 0) + { + options.threads = std::thread::hardware_concurrency(); // thx for acetone. lol + } + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Isntead proccess flipper? + if ( !std::regex_match( std::string(argv[1]), std::regex("[a-zA-Z0-9\\.]{1,}")) ) { + std::cerr << "Please, change the outputfile name" << std::endl; + } + // + if ( options . outputpath . empty () ) options . outputpath . assign ( DEF_OUT_FILE ) ; + static std::string outPutFileName = options.outputpath; + auto doSearch = [argc,argv] () { + found = false; + // TODO: create libi2pd_tools + // If file not exists we create a dump file. (a bug was found in issues) + switch(options.signature) + { + case i2p::data::SIGNING_KEY_TYPE_DSA_SHA1: + case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: + case i2p::data::SIGNING_KEY_TYPE_RSA_SHA256_2048: + case i2p::data::SIGNING_KEY_TYPE_RSA_SHA384_3072: + case i2p::data::SIGNING_KEY_TYPE_RSA_SHA512_4096: + case i2p::data::SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512: + std::cout << "Sorry, i don't can generate adress for this signature type" << std::endl; + return 0; + break; + } + + //TODO: for other types. + switch(options.signature) + { + case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256: + break; + case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384: + break; + case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: + break; + case i2p::data::SIGNING_KEY_TYPE_RSA_SHA256_2048: + break; + case i2p::data::SIGNING_KEY_TYPE_RSA_SHA384_3072: + break; + case i2p::data::SIGNING_KEY_TYPE_RSA_SHA512_4096: + break; + case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: + MutateByte=320; + break; + case i2p::data::SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256: + break; + } + // there we gen key to buffer. That we mem allocate... + const auto keys_len = i2p::data::PrivateKeys::CreateRandomKeys (options.signature).GetFullLen(); // is will be constant. so calculate every time is a bad way + auto KeyBufs = new uint8_t*[options.threads];//[keys_len]; + for(auto i = options.threads-1; i--;) { + KeyBufs[i] = new uint8_t[keys_len]; + auto keys = i2p::data::PrivateKeys::CreateRandomKeys (options.signature); + keys.ToBuffer (KeyBufs[i], keys_len); + } + + /// there was some things for cpu 665% usage, but is not helpful even + std::cout << "Start vanity generator in " << options.threads << " threads" << std::endl; + // there we start to change byte in our private key. we can change another bytes too + // but we just change 1 byte in all key. So. TODO: change all bytes not one? + while(!found) + {//while + {//stack(for destructors(vector/thread)) + + std::vector threads(options.threads); + unsigned long long thoughtput = 0x4F4B5A37; // is a magic number. + + for ( unsigned int j = options.threads;j--;) + { + // our buf is our key, but in uint8 type, unsigned integ... another argument + // is our prefix that we search in address + // and j is magic number, is thread id. + // thoughtput is our magic number that we increment on 1000 everytime + // so we just change a one a byte in key and convert private key to address + // after we check it. + auto n = j != 0 ? j-1 : 0 ; + std::cout << "Use " << n << " key" << std::endl; + + threads[j] = std::thread(thread_find,KeyBufs[ n ],argv[1],j,thoughtput); + thoughtput+=1000; + }//for + + //There will be proccessFlipper by accetone + // if I correctly understand it's drop a payload things in a prefix/search data + // or simmilar. We can just use regex. I would to use regex + + // So I put it ^^^ + for(unsigned int j = 0; j < (unsigned int)options.threads;j++) + threads[j].join(); + if(FoundNonce == 0) + { + //keys = i2p::data::PrivateKeys::CreateRandomKeys (options.signature); + //RAND_bytes( KeyBuf+MutateByte , 90 ); // FoundNonce is + DELKEYBUFS(options.threads); + std::cout << "(Generate a new keypair) Attempts #" << ++attempts << std::endl; + return 1; + } + + }//stack + }//while + // before we write result we would to create private.dat a file. dump file. we can use for it keygen + // so. + // std::cout << fKeyId << std::endl; + auto KeyBuf = KeyBufs[fKeyId - 1 < 0 ? 0 : fKeyId - 1]; + memcpy (KeyBuf + MutateByte, &FoundNonce, 4); + std::cout << "Hashes: " << hashescounter << std::endl; + + // IDK. what for acetone change this line to if (options.output...empty() ... assign + // cplusplus.com/reference/string/string/assign yes we can. but I would don't change this + //if(options.outputpath.size() == 0) options.outputpath = DEF_OUT_FILE; + options.outputpath = options.outputpath + std::to_string(foundKeys) + std::string(".dat"); + do + { + options.outputpath.assign(outPutFileName); + options.outputpath = options.outputpath + std::to_string(foundKeys) + std::string(".dat"); + foundKeys++; + //printf("foundKeys = %d\n", foundKeys); + }while( std::filesystem::exists(options.outputpath) ); + //puts("do while cycle break"); + //if ( ! boost::algorithm::ends_with(options.outputpath, ".dat") ) + // options.outputpath = options.outputpath + ".dat"; + + // there we generate a key, like as in keygen.cpp + // before a mining we would to create a dump file + + std::cout << "outpath for a now: " << options.outputpath << std::endl; + + std::ofstream f (options.outputpath, std::ofstream::binary | std::ofstream::out); + if (f) + { + f.write ((char *)KeyBuf, keys_len); + DELKEYBUFS(options.threads); + } + else + std::cout << "Can't create file " << options.outputpath << std::endl; + return 0; + }; // void doSearch lamda + + do { + doSearch(); + if(found) + { + //TODO: an another variable for file count and found keys as found keys by one runs + //foundKeys++; + } + options.outputpath.assign(outPutFileName); + FoundNonce = 0; + } while(multipleSearchMode || !found); + + i2p::crypto::TerminateCrypto (); + return 0; +} + + +// diff --git a/vanity.hpp b/vanity.hpp old mode 100644 new mode 100755 index 84c8e0f..6ba379e --- a/vanity.hpp +++ b/vanity.hpp @@ -41,27 +41,51 @@ //static i2p::data::SigningKeyType type; //static i2p::data::PrivateKeys keys; -static bool found=false; + +// for InitCrypto. TODO: to makefile/another place get the macro +#ifndef PRECOMPUTATION_CRYPTO +#define PRECOMPUTATION_CRYPTO false +#endif +#ifndef AESNI_CRYPTO +#define AESNI_CRYPTO false +#endif +#ifndef AVX_CRYPTO +#define AVX_CRYPTO false +#endif +#ifndef FORCE_CRYPTO +#define FORCE_CRYPTO false +#endif +// def out file name +#define DEF_OUT_FILE "private" +// Global vars +static bool found=false; +static bool multipleSearchMode = false; +//TODO: an another variable for file count and found keys as found keys by one runs +static unsigned int foundKeys = 0; static size_t MutateByte; static uint32_t FoundNonce=0; -static uint8_t * KeyBuf; +//static uint8_t ** KeyBufs; //static uint8_t * PaddingBuf; static unsigned long long hashescounter; unsigned int count_cpu; const uint8_t lastBlock[64] = -{ - 0x05, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x80, // 7 bytes EdDSA certificate - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x38 // 3128 bits (391 bytes) -}; + { + 0x05, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x80, // 7 bytes EdDSA certificate + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x38 // 3128 bits (391 bytes) + }; +#define DELKEYBUFS(S) {\ +for (unsigned i = S-1;i--;) \ + delete [] KeyBufs[i];\ +delete [] KeyBufs;} diff --git a/vanitygen.cpp b/vanitygen.cpp deleted file mode 100644 index 982d09d..0000000 --- a/vanitygen.cpp +++ /dev/null @@ -1,406 +0,0 @@ -#include "vanity.hpp" -#include -#include - - -static struct -{ - bool reg=false; - int threads=-1; - i2p::data::SigningKeyType signature; - std::string outputpath=""; - std::regex regex; -} options; - - -static void inline CalculateW (const uint8_t block[64], uint32_t W[64]) -{ -/** - * implementation of orignal - */ - for (int i = 0; i < 16; i++) -#ifdef _WIN32 - W[i] = htobe32(((uint32_t *)(block))[i]); -#else // from big endian to little endian ( swap ) - W[i] = be32toh(((uint32_t *)(block))[i]); -#endif - - for (int i = 16; i < 64; i++) - W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; -} - -static void inline TransformBlock (uint32_t state[8], const uint32_t W[64]) -{ -/** - * implementation of orignal - */ - uint32_t S[8]; - memcpy(S, state, 32); - - uint32_t t0, t1; - RNDr(S, W, 0, 0x428a2f98); RNDr(S, W, 1, 0x71374491); RNDr(S, W, 2, 0xb5c0fbcf); RNDr(S, W, 3, 0xe9b5dba5); - RNDr(S, W, 4, 0x3956c25b); RNDr(S, W, 5, 0x59f111f1); RNDr(S, W, 6, 0x923f82a4); RNDr(S, W, 7, 0xab1c5ed5); - RNDr(S, W, 8, 0xd807aa98); RNDr(S, W, 9, 0x12835b01); RNDr(S, W, 10, 0x243185be); RNDr(S, W, 11, 0x550c7dc3); - RNDr(S, W, 12, 0x72be5d74); RNDr(S, W, 13, 0x80deb1fe); RNDr(S, W, 14, 0x9bdc06a7); RNDr(S, W, 15, 0xc19bf174); - RNDr(S, W, 16, 0xe49b69c1); RNDr(S, W, 17, 0xefbe4786); RNDr(S, W, 18, 0x0fc19dc6); RNDr(S, W, 19, 0x240ca1cc); - RNDr(S, W, 20, 0x2de92c6f); RNDr(S, W, 21, 0x4a7484aa); RNDr(S, W, 22, 0x5cb0a9dc); RNDr(S, W, 23, 0x76f988da); - RNDr(S, W, 24, 0x983e5152); RNDr(S, W, 25, 0xa831c66d); RNDr(S, W, 26, 0xb00327c8); RNDr(S, W, 27, 0xbf597fc7); - RNDr(S, W, 28, 0xc6e00bf3); RNDr(S, W, 29, 0xd5a79147); RNDr(S, W, 30, 0x06ca6351); RNDr(S, W, 31, 0x14292967); - RNDr(S, W, 32, 0x27b70a85); RNDr(S, W, 33, 0x2e1b2138); RNDr(S, W, 34, 0x4d2c6dfc); RNDr(S, W, 35, 0x53380d13); - RNDr(S, W, 36, 0x650a7354); RNDr(S, W, 37, 0x766a0abb); RNDr(S, W, 38, 0x81c2c92e); RNDr(S, W, 39, 0x92722c85); - RNDr(S, W, 40, 0xa2bfe8a1); RNDr(S, W, 41, 0xa81a664b); RNDr(S, W, 42, 0xc24b8b70); RNDr(S, W, 43, 0xc76c51a3); - RNDr(S, W, 44, 0xd192e819); RNDr(S, W, 45, 0xd6990624); RNDr(S, W, 46, 0xf40e3585); RNDr(S, W, 47, 0x106aa070); - RNDr(S, W, 48, 0x19a4c116); RNDr(S, W, 49, 0x1e376c08); RNDr(S, W, 50, 0x2748774c); RNDr(S, W, 51, 0x34b0bcb5); - RNDr(S, W, 52, 0x391c0cb3); RNDr(S, W, 53, 0x4ed8aa4a); RNDr(S, W, 54, 0x5b9cca4f); RNDr(S, W, 55, 0x682e6ff3); - RNDr(S, W, 56, 0x748f82ee); RNDr(S, W, 57, 0x78a5636f); RNDr(S, W, 58, 0x84c87814); RNDr(S, W, 59, 0x8cc70208); - RNDr(S, W, 60, 0x90befffa); RNDr(S, W, 61, 0xa4506ceb); RNDr(S, W, 62, 0xbef9a3f7); RNDr(S, W, 63, 0xc67178f2); - - for (int i = 0; i < 8; i++) state[i] += S[i]; -} - -void inline HashNextBlock (uint32_t state[8], const uint8_t * block) -{ -/** - * implementation of orignal - */ - uint32_t W[64]; - CalculateW (block, W); - TransformBlock (state, W); -} - -static bool check_prefix(const char * buf) -{ - unsigned short size_str=0; - while(*buf) - { - if(!((*buf > 49 && *buf < 56) || (*buf > 96 && *buf < 123)) || size_str > 52) - return false; - size_str++; - buf++; - } - return true; -} - -static inline size_t ByteStreamToBase32 (const uint8_t * inBuf, size_t len, char * outBuf, size_t outLen) -{ - size_t ret = 0, pos = 1; - int bits = 8, tmp = inBuf[0]; - while (ret < outLen && (bits > 0 || pos < len)) - { - if (bits < 5) - { - if (pos < len) - { - tmp <<= 8; - tmp |= inBuf[pos] & 0xFF; - pos++; - bits += 8; - } - else // last byte - { - tmp <<= (5 - bits); - bits = 5; - } - } - - bits -= 5; - int ind = (tmp >> bits) & 0x1F; - outBuf[ret] = (ind < 26) ? (ind + 'a') : ((ind - 26) + '2'); - ret++; - } - outBuf[ret]='\0'; - return ret; -} - -static inline bool NotThat(const char * what, const std::regex & reg){ - return std::regex_match(what,reg) == 1 ? false : true; -} - -static inline bool NotThat(const char * a, const char *b) -{ - while(*b) - if(*a++!=*b++) - return true; - return false; -} - -static inline bool thread_find(uint8_t * buf, const char * prefix, int id_thread, unsigned long long throughput) -{ -/** - * Thanks to orignal ^-^ - * For idea and example ^-^ - * Orignal is sensei of crypto ;) - */ - std::cout << "Thread " << id_thread << " binded" << std::endl; -/* - union - { - uint8_t b[391]; - uint32_t ll; - } local; - union - { - uint8_t b[32]; - uint32_t ll[8]; - } hash; -*/ - uint8_t b[391]; - uint32_t hash[8]; - - memcpy (b, buf, 391); - - auto len = strlen (prefix); - // precalculate first 5 blocks (320 bytes) - uint32_t state[8] = { 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 }; - HashNextBlock (state, b); - HashNextBlock (state, b + 64); - HashNextBlock (state, b + 128); - HashNextBlock (state, b + 192); - HashNextBlock (state, b + 256); - - // pre-calculate last W - uint32_t lastW[64]; - CalculateW (lastBlock, lastW); - - uint32_t * nonce = (uint32_t *)(b+320); - (*nonce) += id_thread*throughput; - - char addr[53]; - uint32_t state1[8]; - - while(throughput-- and !found) - { - memcpy (state1, state, 32); - // calculate hash of block with nonce - HashNextBlock (state1, b + 320); - // apply last block - TransformBlock (state1, lastW); - // get final hash - for (int j = 8; j--;) - hash[j] = htobe32(state1[j]); - ByteStreamToBase32 ((uint8_t*)hash, 32, addr, len); - // std::cout << addr << std::endl; - - // bool result = options.reg ? !NotThat(addr, &options.regex) : !NotThat(addr,prefix); - - if( ( options.reg ? !NotThat(addr, options.regex) : !NotThat(addr,prefix) ) ) - // if(result) - { - ByteStreamToBase32 ((uint8_t*)hash, 32, addr, 52); - std::cout << "Address found " << addr << " in " << id_thread << std::endl; - found=true; - FoundNonce=*nonce; - // free(hash); - // free(b); - return true; - } - - - (*nonce)++; - hashescounter++; - if (found) - { - // free(hash); - // free(b); - break; - } - } // while - return true; -} - -void usage(void){ - const constexpr char * help="vain [text-pattern|regex-pattern] [options]\n" - "-h --help, help menu\n" - "-r --reg, regexp instead just text pattern (e.g. '(one|two).*')\n" - "--threads -t, (default count of system)\n" - "--signature -s, (signature type)\n" - "-o --output output file (default private.dat)\n" - "--usage usage\n" - // "--prefix -p\n" - ""; - puts(help); -} - -void parsing(int argc, char ** args){ - int option_index; - static struct option long_options[]={ - {"help",no_argument,0,'h'}, - {"reg", no_argument,0,'r'}, - {"threads", required_argument, 0, 't'}, - {"signature", required_argument,0,'s'}, - {"output", required_argument,0,'o'}, - {"usage", no_argument,0,0}, - {0,0,0,0} - }; - - int c; - while( (c=getopt_long(argc,args, "hrt:s:o:", long_options, &option_index))!=-1){ - switch(c){ - case 0: - if ( std::string(long_options[option_index].name) == std::string("usage") ){ - usage(); - exit(1); - } - case 'h': - usage(); - exit(0); - break; - case 'r': - options.reg=true; - break; - case 't': - options.threads=atoi(optarg); - break; - case 's': - options.signature = NameToSigType(std::string(optarg)); - break; - case 'o': - options.outputpath=optarg; - break; - case '?': - std::cerr << "Undefined argument" << std::endl; - default: - std::cerr << args[0] << " --usage / --help" << std::endl; - exit(1); - break; - } - } -} - -int main (int argc, char * argv[]) -{ - if ( argc < 2 ) - { - usage(); - return 0; - } - parsing( argc > 2 ? argc-1 : argc, argc > 2 ? argv+1 : argv); - // - if(!options.reg && !check_prefix( argv[1] )) - { - std::cout << "Invalid pattern." << std::endl; - usage(); - return 1; - }else{ - options.regex=std::regex(argv[1]); -// int ret = regcomp( &options.regex, argv[1], REG_EXTENDED ); -// if( ret != 0 ){ -// std::cerr << "Can't create regexp pattern from " << argv[1] << std::endl; -// return 1; -// } - } - - i2p::crypto::InitCrypto (false, true, true, false); - options.signature = i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519; -/////////////// -//For while - if(options.signature != i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519) - { - std::cout << "For a while only ED25519-SHA512" << std::endl; - return 0; - } -/////////////// - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - auto keys = i2p::data::PrivateKeys::CreateRandomKeys (options.signature); - switch(options.signature) - { - case i2p::data::SIGNING_KEY_TYPE_DSA_SHA1: - case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: - case i2p::data::SIGNING_KEY_TYPE_RSA_SHA256_2048: - case i2p::data::SIGNING_KEY_TYPE_RSA_SHA384_3072: - case i2p::data::SIGNING_KEY_TYPE_RSA_SHA512_4096: - case i2p::data::SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512: - std::cout << "Sorry, i don't can generate address for this signature type" << std::endl; - return 0; - break; - } - -//TODO: for other types. - switch(options.signature) - { - case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA256_P256: - break; - case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA384_P384: - break; - case i2p::data::SIGNING_KEY_TYPE_ECDSA_SHA512_P521: - break; - case i2p::data::SIGNING_KEY_TYPE_RSA_SHA256_2048: - break; - case i2p::data::SIGNING_KEY_TYPE_RSA_SHA384_3072: - break; - case i2p::data::SIGNING_KEY_TYPE_RSA_SHA512_4096: - break; - case i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519: - MutateByte=320; - break; - case i2p::data::SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256: - break; - } - - KeyBuf = new uint8_t[keys.GetFullLen()]; - keys.ToBuffer (KeyBuf, keys.GetFullLen ()); - - if(options.threads <= 0) - { -#if defined(WIN32) - SYSTEM_INFO siSysInfo; - GetSystemInfo(&siSysInfo); - options.threads = siSysInfo.dwNumberOfProcessors; -#elif defined(_SC_NPROCESSORS_CONF) - options.threads = sysconf(_SC_NPROCESSORS_CONF); -#elif defined(HW_NCPU) - int req[] = { CTL_HW, HW_NCPU }; - size_t len = sizeof(options.threads); - v = sysctl(req, 2, &options.threads, &len, NULL, 0); -#else - options.threads = 1; -#endif - } - - std::cout << "Start vanity generator in " << options.threads << " threads" << std::endl; - - unsigned short attempts = 0; - while(!found) - { // while - { // stack(for destructors(vector/thread)) - - std::vector threads(options.threads); - unsigned long long thoughtput = 0x4F4B5A37; - - for ( unsigned int j = options.threads;j--;) - { - threads[j] = std::thread(thread_find,KeyBuf,argv[1],j,thoughtput); - thoughtput+=1000; - } // for - - for(unsigned int j = 0; j < (unsigned int)options.threads;j++) - threads[j].join(); - - if(FoundNonce == 0) - { - RAND_bytes( KeyBuf+MutateByte , 90 ); - std::cout << "Attempts #" << ++attempts << std::endl; - } - - } // stack - } // while - - memcpy (KeyBuf + MutateByte, &FoundNonce, 4); - std::cout << "Hashes: " << hashescounter << std::endl; - - if(options.outputpath.size() == 0) options.outputpath="private.dat"; - - std::ofstream f (options.outputpath, std::ofstream::binary | std::ofstream::out); - if (f) - { - f.write ((char *)KeyBuf, keys.GetFullLen ()); - delete [] KeyBuf; - } - else - std::cout << "Can't create file " << options.outputpath << std::endl; - - i2p::crypto::TerminateCrypto (); - - return 0; -} diff --git a/verifyhost.cpp b/verifyhost.cpp index 59779ac..52c4cff 100644 --- a/verifyhost.cpp +++ b/verifyhost.cpp @@ -12,7 +12,7 @@ int main (int argc, char * argv[]) return -1; } - i2p::crypto::InitCrypto (false, true, true, false); + i2p::crypto::InitCrypto (false); i2p::data::IdentityEx Identity, OldIdentity; diff --git a/x25519.cpp b/x25519.cpp index faf2ad3..4a93b1e 100644 --- a/x25519.cpp +++ b/x25519.cpp @@ -38,7 +38,7 @@ int main(int argc, char * argv[]) { if (argc > 1) { - std::string arg = static_cast(argv[1]); + std::string arg (argv[1]); if (arg == "--usage" || arg == "--help" || arg == "-h") { std::cout << "The x25519 keys are used for authentication with an encrypted LeaseSet.\n" @@ -57,7 +57,7 @@ int main(int argc, char * argv[]) BoxKeys newKeys = getKeyPair(); - size_t len_out = 50; + const size_t len_out = 50; char b64Public[len_out] = {0}; char b64Private[len_out] = {0};