Dev

## Byteball-to-TCP Proxy

With the help of this special chatbot it is possible to develop the actual bot in any programming language. Byteball-to-TCP Proxy (bb2tcp) listens on the Byteball network like a regular chatbot, except that for each paired device it establishes a new TCP connection to a predefined server. Thus, it acts as a proxy between a custom TCP server and the paired Byteball client device.

This software makes it no longer necessary for the Byteball chatbots to be developed in Node.js. Thus, the developer is free to choose whichever programming language they prefer for the bot. What is more, *bb2tcp* can be configured to send notifications to a custom server upon any pairing attempts. The latter can be used to implement two-factor or passwordless authentication (for example, see Slice&Dice Dungeon ).

To implement passwordless authentication with the help of Byteball, the application should present the user with a customly generated QR code. The payload of that QR code should contain a pairing link such as *byteball:A/SCXz5tNuJDLuCO8PXpsfUoL7dCMBGnvSST7z0YPXjd@byteball.org/bb#**bki433fsb*** where the end part (in bold) is randomly generated by the server. When the user scans the given QR code with their Byteball device a pairing attempt with the code *bki433fsb* is made and the *bb2tcp* chatbot notifies the application by sending the device address and the provided pairing code to the application server. The application server then knows which Byteball device is attempting to authorize themselves so the respective user session's privileges could be elevated immediately without any input from the user.

The *bb2tcp* chatbot is developed and maintained by *@hyena* from the Byteball's official Slack. All questions and ideas for enhancements are welcome.

## Byteball address validation in C++

```
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
#include <type\_traits>

bool is\_byteball\_addr(const char \*addr) {
 static const unsigned char offsets[] = {
 1, 5, 6, 11, 20, 22, 28, 33,
 36, 41, 49, 58, 65, 74, 77, 79,
 82, 90, 94, 100, 102, 108, 112, 115,
 118, 126, 129, 131, 138, 147, 152, 154
 };
 const size\_t offsets\_sz = std::extent<decltype(offsets)>::value;
 bool bits[32\*5];
 unsigned char data[16];
 unsigned char checksum[4];

 { // Base32 validation and decoding.
 auto b32 = [](char c) -> unsigned char {
 return ( (c >= 65 && c <= 90) ? (unsigned char) ( c - 65) :
 (c >= 50 && c <= 55) ? (unsigned char) (26 + c - 50) : 255 );
 };

 auto isb32 = [](char c) -> bool {
 return ( (c >= 65 && c <= 90) || (c >= 50 && c <= 55) );
 };

 size\_t i = 0;
 char \*c = (char \*) &(\*addr);
 while (isb32(\*c) && i < 32) {
 unsigned char value = b32(\*c++);
 for (size\_t j=0; j<5; ++j) {
 bool bit = (value % 2);
 value /= 2;
 bits[5\*i + (4-j)] = bit;
 }
 ++i;
 }
 if (i != 32 || \*c) return false;
 }

 { // Separation of the checksum from the clean data.
 auto bits2bytes = [](bool \*b, unsigned char \*B, size\_t sz) -> void {
 for (size\_t i=0; i<sz; ++i) {
 unsigned char byte = 0;
 for (size\_t j=0; j<8; ++j) {
 bool bit = b[i\*8 + j];
 byte ^= (unsigned char) ( (-bit ^ byte) & (1 << (7-j)) );
 }
 B[i] = byte;
 }
 };

 bool data\_bits[128];
 bool checksum\_bits[32];
 size\_t start = 0;
 size\_t data\_bit\_i = 0;
 size\_t checksum\_bit\_i = 0;
 for (size\_t i=0; i<offsets\_sz; ++i) {
 for (size\_t j=start; j<offsets[i]; ++j) {
 data\_bits[data\_bit\_i++] = bits[j];
 }
 checksum\_bits[checksum\_bit\_i++] = bits[offsets[i]];
 start = offsets[i]+1;
 }
 memcpy(data\_bits+123, bits+155, 5); // Add last fragment.

 bits2bytes(data\_bits, data, 16);
 bits2bytes(checksum\_bits, checksum, 4);
 }

 { // Validate the checksum (requires the openssl/sha.h header).
 SHA256\_CTX context;
 unsigned char md[SHA256\_DIGEST\_LENGTH];

 SHA256\_Init(&context);
 SHA256\_Update(&context, (unsigned char\*) data, 16);
 SHA256\_Final(md, &context);

 if (md[ 5] == checksum[0]
 && md[13] == checksum[1]
 && md[21] == checksum[2]
 && md[29] == checksum[3]) return true;
 }

 return false;
}

int main( int argc, char \* argv [] ) {
 int i;

 for (i = 1; i < argc; ++i ) {
 bool valid = is\_byteball\_addr(argv[i]);
 printf( "%s is %s\n", argv[i], valid ? "VALID." : "INVALID!");
 }

 return 0;
}

```
byteball github repo

## References

1. ↑ https://github.com/byteball/byteball