使用现有的ChaCha20实现生成HChaCha20内部状态

时间:2019-05-16 02:47:18

标签: openssl

RFC7539 § 2.3.2. Test Vector for the ChaCha20 Block Function中,它显示“ ChaCha20操作结束时的ChaCha状态”。这样就可以用PHP 7.2.8和OpenSSL做到这一点:

<?php

$key = implode(range(chr(0x00), chr(0x1f)), '');
$nonce = "\x00\x00\x00\x09\x00\x00\x00\x4a\x00\x00\x00\x00";
$counter = 1;

$ciphertext = openssl_encrypt(
    str_repeat("\0", 64),
    'chacha20',
    $key,
    OPENSSL_RAW_DATA,
    pack('V', $counter) . $nonce
);

$ciphertext = bin2hex(preg_replace('#(.)(.)(.)(.)#', '$4$3$2$1', $ciphertext));
$ciphertext = chunk_split($ciphertext, 8, ' ');
$ciphertext = chunk_split($ciphertext, 32 + 4);

echo $ciphertext;

我正在为XChaCha § 2.2.1. Test Vector for the HChaCha20 Block Function的草稿做相同的事情,并且遇到了一些困难。我的代码:

<?php

$key = implode(range(chr(0x00), chr(0x1f)), '');
$nonce = "\x00\x00\x00\x09\x00\x00\x00\x4a\x00\x00\x00\x00\x31\x41\x59\x27";

// $nonce = strrev(substr($nonce, 0, 4)) . substr($nonce, 4);

$ciphertext = openssl_encrypt(
    str_repeat("\0", 64),
    'chacha20',
    $key,
    OPENSSL_RAW_DATA,
    $nonce
);

$ciphertext = bin2hex(preg_replace('#(.)(.)(.)(.)#', '$4$3$2$1', $ciphertext));
$ciphertext = chunk_split($ciphertext, 8, ' ');
$ciphertext = chunk_split($ciphertext, 32 + 4);

echo $ciphertext;

根据这张图表,看一下草稿似乎应该起作用:

              cccccccc  cccccccc  cccccccc  cccccccc
              kkkkkkkk  kkkkkkkk  kkkkkkkk  kkkkkkkk
              kkkkkkkk  kkkkkkkk  kkkkkkkk  kkkkkkkk
              bbbbbbbb  nnnnnnnn  nnnnnnnn  nnnnnnnn

       ChaCha20 State: c=constant k=key b=blockcount n=nonce

              cccccccc  cccccccc  cccccccc  cccccccc
              kkkkkkkk  kkkkkkkk  kkkkkkkk  kkkkkkkk
              kkkkkkkk  kkkkkkkk  kkkkkkkk  kkkkkkkk
              nnnnnnnn  nnnnnnnn  nnnnnnnn  nnnnnnnn

             HChaCha20 State: c=constant k=key n=nonce

即。块计数器只是被随机数的额外位所代替。

我注意到我在第一个示例中使用的方法执行pack('V', $counter),它给出的是01000000而不是00000001,所以有点像是我需要先对它们进行strrev四个字节,但没有帮助(请参阅第二个代码块中的注释行)。

有什么想法吗?

0 个答案:

没有答案