在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
四个字节,但没有帮助(请参阅第二个代码块中的注释行)。
有什么想法吗?