diff --git a/Dockerfile b/Dockerfile
index b722c370f..e7cb1991b 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -11,7 +11,7 @@ RUN apt-get update && \
libboost-filesystem1.81-dev libssl-dev libc-ares-dev zlib1g-dev \
ca-certificates automake libtool patchelf cmake pkg-config lua5.4 liblua5.4-dev \
libgrpc++-dev libprotobuf-dev protobuf-compiler-grpc \
- luarocks libb64-dev libcrypto++-dev nlohmann-json3-dev && \
+ luarocks libcrypto++-dev nlohmann-json3-dev && \
update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-15 120 && \
update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-15 120 && \
rm -rf /var/lib/apt/lists/*
diff --git a/README.md b/README.md
index d20e28d90..28af0e83e 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,6 @@ Docker targets:
- Cryptopp >= 7.0.0
- GRPC >= 1.45.0
- Lua >= 5.4.4
-- b64 >= 1.2.1
- Boost >= 1.81
- nlohmann JSON >= 3.10
@@ -38,7 +37,7 @@ apt-get install build-essential wget git clang-tidy-15 clang-format-15 \
libboost-filesystem1.81-dev libssl-dev libc-ares-dev zlib1g-dev \
ca-certificates automake libtool patchelf cmake pkg-config lua5.4 liblua5.4-dev \
libgrpc++-dev libprotobuf-dev protobuf-compiler-grpc \
- luarocks libb64-dev libcrypto++-dev nlohmann-json3-dev
+ luarocks libcrypto++-dev nlohmann-json3-dev
sudo luarocks install --lua-version=5.4 lpeg
sudo luarocks install --lua-version=5.4 dkjson
@@ -50,7 +49,7 @@ sudo luarocks install --lua-version=5.4 luaposix
##### MacPorts
```
-sudo port install clang-15 automake boost libtool wget cmake pkgconfig grpc zlib openssl lua libb64 libcryptopp nlohmann-json lua-luarocks
+sudo port install clang-15 automake boost libtool wget cmake pkgconfig grpc zlib openssl lua libcryptopp nlohmann-json lua-luarocks
sudo luarocks install --lua-version=5.4 lpeg
sudo luarocks install --lua-version=5.4 dkjson
@@ -61,7 +60,7 @@ sudo luarocks install --lua-version=5.4 luaposix
##### Homebrew
```
-brew install llvm@15 automake boost libomp wget cmake cryptopp pkg-config grpc zlib openssl lua@5.4 libb64 nlohmann-json luarocks
+brew install llvm@15 automake boost libomp wget cmake cryptopp pkg-config grpc zlib openssl lua@5.4 nlohmann-json luarocks
luarocks --lua-dir=$(brew --prefix)/opt/lua@5.4 install lpeg
luarocks --lua-dir=$(brew --prefix)/opt/lua@5.4 install dkjson
luarocks --lua-dir=$(brew --prefix)/opt/lua@5.4 install luasocket
diff --git a/src/Makefile b/src/Makefile
index 4c1ac7634..571873c50 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -69,8 +69,6 @@ BOOST_INC_Darwin=-I$(BREW_PREFIX)/include
CRYPTOPP_LIB_Darwin:=-L$(BREW_PREFIX)/lib -lcryptopp
CRYPTOPP_INC_Darwin:=-I$(BREW_PREFIX)/include
NLOHMANN_JSON_INC_Darwin:=-I$(BREW_PREFIX)/include
-B64_LIB_Darwin:=-L$(BREW_PREFIX)/lib -lb64
-B64_INC_Darwin:=-I$(BREW_PREFIX)/include
GRPC_INC_Darwin:=$(shell pkg-config --cflags-only-I grpc++)
GRPC_LIB_Darwin:=$(shell pkg-config --libs grpc++)
PROTOBUF_INC_Darwin:=$(shell pkg-config --cflags-only-I protobuf)
@@ -81,8 +79,6 @@ BOOST_LIB_DIR_Darwin=-L$(PORT_PREFIX)/libexec/boost/1.81/lib
BOOST_INC_Darwin=-I$(PORT_PREFIX)/libexec/boost/1.81/include
CRYPTOPP_LIB_Darwin:=-L$(PORT_PREFIX)/lib -lcryptopp
CRYPTOPP_INC_Darwin:=-I$(PORT_PREFIX)/include
-B64_LIB_Darwin:=-L$(PORT_PREFIX)/lib -lb64
-B64_INC_Darwin:=-I$(PORT_PREFIX)/include
GRPC_INC_Darwin:=-I$(PORT_PREFIX)/include
GRPC_LIB_Darwin=-L$(PORT_PREFIX)/lib -lgrpc++ -lgrpc -lgpr -lprotobuf -lpthread -labsl_synchronization
PROTOBUF_INC_Darwin:=-I$(PORT_PREFIX)/include
@@ -115,8 +111,6 @@ FS_LIB_Linux=-lstdc++fs
BOOST_FILESYSTEM_LIB_Linux:=-lboost_system -lboost_filesystem
BOOST_PROCESS_LIB_Linux:=-lpthread
BOOST_INC_Linux=
-B64_LIB_Linux:=-lb64
-B64_INC_Linux:=
CRYPTOPP_LIB_Linux:=-lcryptopp
CRYPTOPP_INC_Linux:=
GRPC_INC_Linux:=$(shell pkg-config --cflags-only-I grpc++)
@@ -141,8 +135,6 @@ SOLDFLAGS:=$(SOLDFLAGS_$(UNAME)) $(GCLDFLAGS)
BOOST_PROCESS_LIB=$(BOOST_PROCESS_LIB_$(UNAME))
BOOST_FILESYSTEM_LIB=$(BOOST_FILESYSTEM_LIB_$(UNAME))
BOOST_INC=$(BOOST_INC_$(UNAME))
-B64_LIB=$(B64_LIB_$(UNAME))
-B64_INC=$(B64_INC_$(UNAME))
CRYPTOPP_LIB=$(CRYPTOPP_LIB_$(UNAME))
CRYPTOPP_INC=$(CRYPTOPP_INC_$(UNAME))
NLOHMANN_JSON_INC=$(NLOHMANN_JSON_INC_$(UNAME))
@@ -162,14 +154,14 @@ LIBCARTESI_GRPC_LDFLAGS=$(LIBCARTESI_GRPC_LDFLAGS_$(UNAME))
LIBCARTESI_GRPC_TESTS_LDFLAGS=$(LIBCARTESI_GRPC_TESTS_LDFLAGS_$(UNAME))
LIBCARTESI_GRPC_LIB=-L. -lcartesi_grpc-$(EMULATOR_VERSION_MAJOR).$(EMULATOR_VERSION_MINOR)
-LIBCARTESI_LIBS:=$(CRYPTOPP_LIB) $(B64_LIB)
+LIBCARTESI_LIBS:=$(CRYPTOPP_LIB)
LIBCARTESI_GRPC_LIBS:=$(CRYPTOPP_LIB) $(GRPC_LIB) $(PROTOBUF_LIB)
LUACARTESI_LIBS:=$(LIBCARTESI_LIB) $(CRYPTOPP_LIB)
LUACARTESI_GRPC_LIBS:=$(LIBCARTESI_LIB) $(CRYPTOPP_LIB) $(LIBCARTESI_GRPC_LIB)
-LUACARTESI_JSONRPC_LIBS:=$(LIBCARTESI_LIB) $(CRYPTOPP_LIB) $(B64_LIB)
-REMOTE_CARTESI_MACHINE_LIBS:=$(CRYPTOPP_LIB) $(GRPC_LIB) $(PROTOBUF_LIB) $(B64_LIB)
-JSONRPC_REMOTE_CARTESI_MACHINE_LIBS:=$(CRYPTOPP_LIB) $(B64_LIB)
-TEST_MACHINE_C_API_LIBS:=$(LIBCARTESI_LIB) $(CRYPTOPP_LIB) $(LIBCARTESI_GRPC_LIB) $(BOOST_PROCESS_LIB) $(BOOST_FILESYSTEM_LIB) $(B64_LIB)
+LUACARTESI_JSONRPC_LIBS:=$(LIBCARTESI_LIB) $(CRYPTOPP_LIB)
+REMOTE_CARTESI_MACHINE_LIBS:=$(CRYPTOPP_LIB) $(GRPC_LIB) $(PROTOBUF_LIB)
+JSONRPC_REMOTE_CARTESI_MACHINE_LIBS:=$(CRYPTOPP_LIB)
+TEST_MACHINE_C_API_LIBS:=$(LIBCARTESI_LIB) $(CRYPTOPP_LIB) $(LIBCARTESI_GRPC_LIB) $(BOOST_PROCESS_LIB) $(BOOST_FILESYSTEM_LIB)
HASH_LIBS:=$(CRYPTOPP_LIB)
#DEFS+= -DMT_ALL_DIRTY
@@ -178,7 +170,7 @@ WARNS=-W -Wall -pedantic
# Place our include directories before the system's
INCS=-I../lib/machine-emulator-defines -I../third-party/llvm-flang-uint128 \
- $(LUA_INC) $(CRYPTOPP_INC) $(NLOHMANN_JSON_INC) $(MONGOOSE_INC) $(B64_INC) $(BOOST_INC) $(PROTOBUF_INC) $(GRPC_INC) $(INCS_$(UNAME))
+ $(LUA_INC) $(CRYPTOPP_INC) $(NLOHMANN_JSON_INC) $(MONGOOSE_INC) $(BOOST_INC) $(PROTOBUF_INC) $(GRPC_INC) $(INCS_$(UNAME))
ifeq ($(dump),yes)
#DEFS+=-DDUMP_ILLEGAL_INSN_EXCEPTIONS
diff --git a/src/base64.cpp b/src/base64.cpp
index 559bcac92..9f49633ad 100644
--- a/src/base64.cpp
+++ b/src/base64.cpp
@@ -14,36 +14,152 @@
// with this program (see COPYING). If not, see .
//
+#include
#include
-#ifndef BUFFERSIZE
-// To fulfill libb64's assumption that the macro BUFFERSIZE is always defined. It is not.
-// bug https://sourceforge.net/p/libb64/bugs/3/
-// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
-#define BUFFERSIZE 1024
-#endif
+#include "base64.h"
-#include
+namespace cartesi {
-#include
+// Base64 globals
+static constexpr uint8_t b64base[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-#include "base64.h"
+static constexpr uint8_t b64unbase[] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 62, 255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 0, 255, 255, 255,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255,
+ 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255};
-namespace cartesi {
+// Acumulates bytes in input buffer until 3 bytes are available.
+// Translate the 3 bytes into Base64 form and append to buffer.
+// Returns new number of bytes in buffer.
+static size_t b64encode(uint8_t c, uint8_t *input, size_t size, std::ostringstream &sout) {
+ input[size++] = c;
+ if (size == 3) {
+ uint8_t code[4];
+ unsigned long value = 0;
+ value += input[0];
+ value <<= 8;
+ value += input[1];
+ value <<= 8;
+ value += input[2];
+ code[3] = b64base[value & 0x3f];
+ value >>= 6;
+ code[2] = b64base[value & 0x3f];
+ value >>= 6;
+ code[1] = b64base[value & 0x3f];
+ value >>= 6;
+ code[0] = b64base[value];
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ sout << std::string_view(reinterpret_cast(code), 4);
+ size = 0;
+ }
+ return size;
+}
+
+// Encodes the Base64 last 1 or 2 bytes and adds padding '='
+// Result, if any, is appended to buffer.
+// Returns 0.
+static size_t b64pad(const uint8_t *input, size_t size, std::ostringstream &sout) {
+ unsigned long value = 0;
+ uint8_t code[4] = {'=', '=', '=', '='};
+ switch (size) {
+ case 1:
+ value = input[0] << 4;
+ code[1] = b64base[value & 0x3f];
+ value >>= 6;
+ code[0] = b64base[value];
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ sout << std::string_view(reinterpret_cast(code), 4);
+ break;
+ case 2:
+ value = input[0];
+ value <<= 8;
+ value |= input[1];
+ value <<= 2;
+ code[2] = b64base[value & 0x3f];
+ value >>= 6;
+ code[1] = b64base[value & 0x3f];
+ value >>= 6;
+ code[0] = b64base[value];
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ sout << std::string_view(reinterpret_cast(code), 4);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+// Acumulates bytes in input buffer until 4 bytes are available.
+// Translate the 4 bytes from Base64 form and append to buffer.
+// Returns new number of bytes in buffer.
+static size_t b64decode(uint8_t c, uint8_t *input, size_t size, std::ostringstream &sout) {
+ // ignore invalid characters
+ if (b64unbase[c] > 64) {
+ return size;
+ }
+ input[size++] = c;
+ // decode atom
+ if (size == 4) {
+ uint8_t decoded[3];
+ int valid = 0;
+ int value = 0;
+ value = b64unbase[input[0]];
+ value <<= 6;
+ value |= b64unbase[input[1]];
+ value <<= 6;
+ value |= b64unbase[input[2]];
+ value <<= 6;
+ value |= b64unbase[input[3]];
+ decoded[2] = static_cast(value & 0xff);
+ value >>= 8;
+ decoded[1] = static_cast(value & 0xff);
+ value >>= 8;
+ decoded[0] = static_cast(value);
+ // take care of paddding
+ valid = (input[2] == '=') ? 1 : (input[3] == '=') ? 2 : 3;
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ sout << std::string_view(reinterpret_cast(decoded), valid);
+ return 0;
+ // need more data
+ } else {
+ return size;
+ }
+}
std::string encode_base64(const std::string &input) {
- std::istringstream sin(input);
std::ostringstream sout;
- base64::encoder E; // NOLINT(clang-analyzer-optin.cplusplus.UninitializedObject)
- E.encode(sin, sout);
+ uint8_t ctx[4]{};
+ size_t ctxlen = 0;
+ size_t ncols = 0;
+ for (const char b : input) {
+ ctxlen = b64encode(static_cast(b), ctx, ctxlen, sout);
+ if (ctxlen == 0) { // appended 4 characters
+ ncols += 4;
+ if (ncols >= 72) { // add CRLF every 72 columns
+ sout << "\r\n";
+ ncols = 0;
+ }
+ }
+ }
+ b64pad(ctx, ctxlen, sout);
return sout.str();
}
std::string decode_base64(const std::string &input) {
- std::istringstream sin(input);
std::ostringstream sout;
- base64::decoder E; // NOLINT(clang-analyzer-optin.cplusplus.UninitializedObject)
- E.decode(sin, sout);
+ uint8_t ctx[4]{};
+ size_t ctxlen = 0;
+ for (const char b : input) {
+ ctxlen = b64decode(static_cast(b), ctx, ctxlen, sout);
+ }
return sout.str();
}
diff --git a/tools/template/control.template b/tools/template/control.template
index 55bcbcb3e..5a96c3591 100644
--- a/tools/template/control.template
+++ b/tools/template/control.template
@@ -5,7 +5,7 @@ Homepage: https://docs.cartesi.io/machine/host/cmdline/
Architecture: ARG_ARCH
Maintainer: Machine Reference Unit
Provides: machine-emulator
-Depends: libboost-context1.81.0, libboost-filesystem1.81.0, libreadline8, openssl, libc-ares2, zlib1g, ca-certificates, libgomp1, lua5.4, libb64-0d, libcrypto++8, libprotobuf32, libgrpc++1.51
+Depends: libboost-context1.81.0, libboost-filesystem1.81.0, libreadline8, openssl, libc-ares2, zlib1g, ca-certificates, libgomp1, lua5.4, libcrypto++8, libprotobuf32, libgrpc++1.51
Section: devel
Priority: optional
Multi-Arch: foreign