Pure-C, zero-dependency TON address engine — fast, portable, endian-safe.
RAW & base64url (“friendly”) formats, CRC16-CCITT, bounceable/testnet flags, built-in SHA-256 with SHA-NI (x86) and ARMv8 Crypto Extensions.
- English • Русский
- Pure C (C99+) — zero dependencies, UB-free hot paths
- TON addresses: RAW (
<workchain>:<64-hex>) and Base64-URL - Flags: bounceable / non-bounceable, mainnet/testnet
- CRC16-CCITT (XModem) built in
- Built-in SHA-256:
- x86/x64 path with SHA-NI (enabled via build flags)
- ARM path using ARMv8 Crypto Extensions (
sha256h/sha256su0/sha256su1) - Portable fallback (no CPU extensions required)
- Endian-safe, cross-platform; tiny footprint; cache-friendly
- No TVM/BOC/CELL required — direct address computation, as fast as physically possible
This project was born from deep, hands-on reverse engineering of multiple TON wallet contracts. I parsed smart-contract sources byte-by-byte, studied funC and fift, traced assembler logs, and translated everything into pure C — without spinning up the entire TVM stack or serializing via BOC/CELL. The result is a first-of-its-kind library that is both ultra-lightweight and extremely optimized.
v1r1, v1r2, v1r3, v2r1, v2r2, v3r1, v3r2, v4r1, v4r2, v5r1, highload v1, highload v2, highload v3
# Portable (C99) — build Example/main.c against library sources in repo root
cc -O3 -std=c99 -Wall -Wextra -I. \
Example/main.c TONc.c sha256.c base64_url.c \
-o Example/example
# x86/x64 with SHA-NI (GCC/Clang)
cc -O3 -std=c99 -Wall -Wextra -I. -msse4.2 -msha \
Example/main.c TONc.c sha256.c base64_url.c \
-o Example/example
# ARMv8 with Crypto Extensions (GCC/Clang)
cc -O3 -std=c99 -Wall -Wextra -I. -march=armv8-a+crypto \
Example/main.c TONc.c sha256.c base64_url.c \
-o Example/exampleOn MSVC: enable
/O2and compile as C (not C++). For SHA-NI, use the appropriate intrinsics or/arch:AVX2(and enable SHA when available), and for ARM use ARM64 toolchain with crypto extensions.
// Hash public key into 32-byte address hash for a given TON wallet type.
// returns 1 on success, 0 on unknown type
int pubkey_to_hash(const uint8_t* public_key,
const char* type, // "v1r1"; "v1r2"; "v1r3"; "v2r1"; "v2r2"; "v3r1"; "v3r2"; "v4r1"; "v4r2"; "v5r1"; "hv1"; "hv2"; "hv3"
uint8_t* out);
// Address builder — writes either RAW or base64url to 'out'
void generate_ton_address(const uint8_t* public_key,
int is_raw, // 1 -> RAW "wc:hex", 0 -> base64url
int is_testnet, // 1 -> testnet, 0 -> mainnet
int is_bounceable, // 1 -> bounceable, 0 -> non-bounceable
const char* type, // "v1r1"; "v1r2"; "v1r3"; "v2r1"; "v2r2"; "v3r1"; "v3r2"; "v4r1"; "v4r2"; "v5r1"; "hv1"; "hv2"; "hv3"
int8_t workchain, // workchain_id
char* out);1) Base64-URL (“friendly”) address
uint8_t pubkey[32] = {/* ... your 32-byte pubkey ... */};
char addr[64]; // 48 chars + '\0' is enough
generate_ton_address(pubkey,
/*is_raw=*/0,
/*is_testnet=*/0,
/*is_bounceable=*/1,
/*type=*/"v5r1",
/*workchain=*/0,
/*out=*/addr);
// addr -> base64url (with '=' padding)2) RAW format <workchain>:<64-hex>
char raw[80]; // e.g. "-1:" + 64 hex + '\0'
generate_ton_address(pubkey, 1, 0, 0, "v5r1", 0, raw);
// raw -> "0:xxxxxxxx...64 hex..."- Zero allocations: you provide buffers; the library never allocates.
- Endian-safe and alignment-safe code paths.
- Deterministic results across platforms/compilers.
- Security: CRC16 used for address checksums only. SHA-256 implementation includes portable fallback + optimized ISA paths.
- Thanks to the Ledger team and Whales Corp. team for the initial idea and inspiration.
- Building TONc took substantial research and engineering effort: learning funC/fift, parsing contract layouts byte-by-byte, reading assembler logs, and porting the logic into clean C — without spinning up TVM or BOC/CELL serialization.
- To the best of my knowledge, this is the first library of this weight and optimization level for TON addresses in pure C.
- Чистый C (C99+) — без зависимостей, горячие пути без UB
- Адреса TON: RAW (
<workchain>:<64-hex>) и Base64-URL - Флаги: bounceable / non-bounceable, mainnet/testnet
- CRC16-CCITT (XModem) встроено
- SHA-256 внутри:
- на x86/x64 — путь с SHA-NI
- на ARM — реализация на ARMv8 Crypto Extensions
- портативная версия без инструкций
- Endian-safe, кроссплатформенность; компактность и высокая скорость
- Никакой TVM/BOC/CELL — прямой расчёт адресов, максимально быстро
Проект вырос из глубокого реверса кошельков TON. Я разбирал исходники контрактов побайтово, изучал funC и fift, читал логи ассемблера и переносил всё в чистый C — без поднятия TVM и без сериализации через BOC/CELL. В итоге — первая в мире настолько лёгкая и оптимизированная библиотека для адресов TON на чистом C.
v1r1, v1r2, v1r3, v2r1, v2r2, v3r1, v3r2, v4r1, v4r2, v5r1, highload v1, highload v2, highload v3
# Portable (C99) — build Example/main.c against library sources in repo root
cc -O3 -std=c99 -Wall -Wextra -I. \
Example/main.c TONc.c sha256.c base64_url.c \
-o Example/example
# x86/x64 with SHA-NI (GCC/Clang)
cc -O3 -std=c99 -Wall -Wextra -I. -msse4.2 -msha \
Example/main.c TONc.c sha256.c base64_url.c \
-o Example/example
# ARMv8 with Crypto Extensions (GCC/Clang)
cc -O3 -std=c99 -Wall -Wextra -I. -march=armv8-a+crypto \
Example/main.c TONc.c sha256.c base64_url.c \
-o Example/exampleMSVC включите
/O2и компилируйте как C (не C++). Для SHA-NI используйте соответствующие intrinsic-функции или/arch:AVX2(и при наличии включайте поддержку SHA), а для ARM используйте ARM64-инструментарий с криптографическими расширениями.
// Хэширует публичный ключ в 32-байтный хэш адреса для указанного типа адреса TON.
// Возвращает 1 если успешно, 0 если указан неизвестный тип
int pubkey_to_hash(const uint8_t* public_key,
const char* type, // "v1r1"; "v1r2"; "v1r3"; "v2r1"; "v2r2"; "v3r1"; "v3r2"; "v4r1"; "v4r2"; "v5r1"; "hv1"; "hv2"; "hv3"
uint8_t* out);
// Пишет RAW адрес или base64url в массив 'out'
void generate_ton_address(const uint8_t* public_key,
int is_raw, // 1 -> RAW "wc:hex", 0 -> base64url
int is_testnet, // 1 -> testnet, 0 -> mainnet
int is_bounceable, // 1 -> bounceable, 0 -> non-bounceable
const char* type, // "v1r1"; "v1r2"; "v1r3"; "v2r1"; "v2r2"; "v3r1"; "v3r2"; "v4r1"; "v4r2"; "v5r1"; "hv1"; "hv2"; "hv3"
int8_t workchain, // workchain_id
char* out);1) Base64-URL адрес
uint8_t pubkey[32] = {/* ... your 32-byte pubkey ... */};
char addr[64]; // 48 chars + '\0' is enough
generate_ton_address(pubkey,
/*is_raw=*/0,
/*is_testnet=*/0,
/*is_bounceable=*/1,
/*type=*/"v5r1",
/*workchain=*/0,
/*out=*/addr);
// addr -> base64url (with '=' padding)2) RAW-формат <workchain>:<64-hex>
char raw[80];
size_t raw_len = 0;
generate_ton_address(pubkey, 0, 1, "v5r1", 0, 1, raw, &raw_len);
// raw -> "0:xxxxxxxx...64 hex..."- Zero-alloc: буферы передаёт пользователь
- Endian-safe/alignment-safe
- Детерминированные результаты на всех платформах
- Безопасность: CRC16 — только для проверки адреса; SHA-256 содержит оптимизированные ISA-пути и портативную реализацию
- Отдельная благодарность командам Ledger и Whales Corp. за идею и вдохновение.
- Разработка заняла очень много времени и сил: изучение funC/fift, побайтовый разбор исходников контрактов, анализ ассемблерных логов, перенос всей логики на чистый C — без TVM/BOC/CELL.
- Насколько мне известно, это первая настолько лёгкая, быстрая и оптимизированная библиотека адресов TON на чистом C.
Ton: UQDV_vXQV_aDRY7zMDKkMLkGQ_MOfe4kCxKzzPzAhcQyC_CE