Correct TON mnemonic + Ed25519 keypair derivation for The Open Network in pure PHP.
TON cryptography for PHP: Ed25519 keypairs (sign / verify via libsodium) and TON-flavoured mnemonic seed derivation for The Open Network. The TON mnemonic format is PBKDF2-HMAC-SHA512 with salt "TON default seed" and 100 000 iterations — it is not BIP-39. The wordlist and derivation procedure mirror the TON reference implementation, so the same 24-word phrase produces the same Ed25519 keypair (and therefore the same wallet address) across all TON tooling.
"TON default seed", 100 000 iterations).ext-sodium.final readonly value objects, strict_types.BIP-39 mnemonic libraries derive the wrong key for TON. TON does not use the BIP-39 PBKDF2 salt ("mnemonic") or iteration scheme — it uses a distinct entropy → seed pipeline (hash_hmac pass feeding PBKDF2-HMAC-SHA512 with salt "TON default seed", 100 000 iterations). Feeding a TON phrase to a generic BIP-39 library yields a seed and address that do not match TON wallets. This package implements the TON procedure exactly, so derived addresses match official TON tooling byte-for-byte.
composer require amashukov/ton-crypto-php
use Amashukov\TonCrypto\Mnemonic;
$phrase = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art';
$keypair = Mnemonic::toKeyPair($phrase);
// Or just the raw 32-byte seed:
$seed = Mnemonic::toSeed($phrase);
toSeed() and toKeyPair() normalise the phrase (trims leading/trailing whitespace, collapses any inter-word run of whitespace — including tabs and newlines — to a single space). Both accept an optional $password argument that is fed through the HMAC step.
use Amashukov\TonCrypto\KeyPair;
$kp = KeyPair::generate(); // 32-byte seed from random_bytes()
$kp = KeyPair::fromSeed($seedBytes); // explicit 32-byte seed
$signature = $kp->sign('payload'); // 64 raw bytes (Ed25519 detached)
$ok = $kp->verify('payload', $signature);
verify() returns false for any signature whose length is not exactly 64 bytes, in addition to the cryptographic check.
KeyPair layoutKeyPair::SEED_BYTES = 32 (libsodium SODIUM_CRYPTO_SIGN_SEEDBYTES)KeyPair::PUBLIC_KEY_BYTES = 32KeyPair::SECRET_KEY_BYTES = 64 (libsodium layout: seed ‖ publicKey)KeyPair::SIGNATURE_BYTES = 64TON default seedhash_hmac('sha512', $password, $normalizedPhrase, true) produces the entropy fed into PBKDF2These constants are exposed on Mnemonic::DEFAULT_SALT, Mnemonic::PBKDF2_ITERATIONS, Mnemonic::PBKDF2_OUTPUT_BYTES.
ext-sodiumext-hash (bundled with PHP core; used for HMAC-SHA512 + PBKDF2)No composer dependencies.
| Package | Tier | Purpose |
|---|---|---|
| amashukov/ton-cell-php | leaf | TLB Cell / BoC serialization |
| amashukov/ton-wallet-php | composite | TON wallet contracts + address derivation |
| amashukov/toncenter-client-php | RPC | toncenter v2/v3 API client |
| amashukov/ton-php | meta | TON umbrella package |
| amashukov/keccak-php | leaf | keccak-256 hashing |
@PER-CS ruleset.MIT.
How can I help you explore Laravel packages today?