Как проверить TON proof на php?

Рейтинг: 0Ответов: 1Опубликовано: 21.08.2023

Я хочу проверить TON proof используя php. Следуя документации, я увидел схему проверки:

message = utf8_encode("ton-proof-item-v2/") ++ 
          Address ++
          AppDomain ++
          Timestamp ++  
          Payload 
signature = Ed25519Sign(privkey, sha256(0xffff ++ utf8_encode("ton-connect") ++ sha256(message)))

где:

  • Address is the wallet address encoded as a sequence:
    • workchain: 32-bit signed integer big endian;
    • hash: 256-bit unsigned integer big endian;
  • AppDomain is Length ++ EncodedDomainName
    • Length is 32-bit value of utf-8 encoded app domain name length in bytes
    • EncodedDomainName id Length-byte utf-8 encoded app domain name
  • Timestamp 64-bit unix epoch time of the signing operation
  • Payload is a variable-length binary string.

Я делаю это так:

$pubKey = "05264d80c7ad5a953cf56cdecf68ec******";
        $address = "0:312ed56825e7455a7948c34677e418e6c371d263c0fd7*****";
        $payload = "d0143e296879ed8f0000000064e328d8d751ea7c3c44827c8b6fcd5c83efcbfa";
        $domainLengthBytes = 21;
        $domainValue = "ton-connect.github.io";
        $timestamp = 1692608455;
        $message = utf8_encode("ton-proof-item-v2/").$address.$domainLengthBytes.$domainValue.$timestamp.$payload;
        $signature = sodium_crypto_sign_detached($message,$pubKey);
        print_r($message);

Но я получаю неправильную подпись. Как мне сделать проверку, использую схему выше?

Ответы

▲ 1Принят

Долго мучился, но этот вариант отработал. Конвертировал чат GPT из других примеров.

function check_proof($ton_proof, $account) {
    $workchain = $account["workchain"];
    $address = hex2bin($account["address"]);
    $public_key = hex2bin($account["public_key"]);
    $timestamp = $ton_proof["timestamp"];
    $domain_length = $ton_proof["domain"]["lengthBytes"];
    $domain_value = $ton_proof["domain"]["value"];
    $signature = base64_decode($ton_proof["signature"]);
    $payload = $ton_proof["payload"];

    // Создание сообщения
    $message = "ton-proof-item-v2/";
    $message .= pack("V", $workchain);  // 4 байта, little-endian
    $message .= $address;
    $message .= pack("V", $domain_length); // 4 байта, little-endian
    $message .= $domain_value;
    $message .= pack("P", $timestamp); // 8 байт, little-endian
    $message .= $payload;

    // Создание сообщения для подписи
    $hashed_message = hash("sha256", $message, true);
    $signature_message = "\xFF\xFF" . "ton-connect" . $hashed_message;
    $hashed_signature_message = hash("sha256", $signature_message, true);

    // Проверка подписи
    $valid = sodium_crypto_sign_verify_detached($signature, $hashed_signature_message, $public_key);

    return $valid;
}



 // Пример использования
$ton_proof = [
    "timestamp" => 1695495616,
    "domain" => [
        "lengthBytes" => 12,
        "value" => "example.com" 
    ],
    "signature" => "sampleSignature==", 
    "payload" => "samplePayload" 
];

$account = [
    "workchain" => 0,
    "address" => "sampleAddress", //0: удалить из адреса
    "public_key" => "samplePublicKey" // получить по API https://tonapi.io/v2/tonconnect/stateinit используя walletStateInit
];

$isValid = check_proof($ton_proof, $account); 

if ($isValid) {
    echo "Подпись действительна.";
} else {
    echo "Подпись недействительна.";
}