0
$\begingroup$

I was playing around with stream ciphers an found this Wikipedia ChaCha20 page (the ChaCha variant). What I'm lost with is how to test this code. There are no testvectors anywhere on that page and I cannot find any. I wrote the following C code:

#define ROTL(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
#define QR(a, b, c, d) (            \
    a += b,  d ^= a,  d = ROTL(d,16),   \
    c += d,  b ^= c,  b = ROTL(b,12),   \
    a += b,  d ^= a,  d = ROTL(d, 8),   \
    c += d,  b ^= c,  b = ROTL(b, 7))
#define ROUNDS 20

void chacha_block(uint32_t out[16], uint32_t const in[16])
{
int i;
uint32_t x[16];

for (i = 0; i < 16; ++i)    
    x[i] = in[i];
// 10 loops × 2 rounds/loop = 20 rounds
for (i = 0; i < ROUNDS; i += 2) {
    // Odd round
    QR(x[0], x[4], x[ 8], x[12]); // column 0
    QR(x[1], x[5], x[ 9], x[13]); // column 1
    QR(x[2], x[6], x[10], x[14]); // column 2
    QR(x[3], x[7], x[11], x[15]); // column 3
    // Even round
    QR(x[0], x[5], x[10], x[15]); // diagonal 1 (main diagonal)
    QR(x[1], x[6], x[11], x[12]); // diagonal 2
    QR(x[2], x[7], x[ 8], x[13]); // diagonal 3
    QR(x[3], x[4], x[ 9], x[14]); // diagonal 4
}
for (i = 0; i < 16; ++i)
    out[i] = x[i] + in[i];
}
}

void main(){
    const char* constant = "expand 32-byte k";
    uint32_t inwhole[16];
    inwhole[0] = ((uint32_t*)constant)[0];
    inwhole[1] = ((uint32_t*)constant)[1];
    inwhole[2] = ((uint32_t*)constant)[2];
    inwhole[3] = ((uint32_t*)constant)[3];

    inwhole[4] = 0;//key[0];
    inwhole[5] = 0;//key[1];
    inwhole[6] = 0;//key[2];
    inwhole[7] = 0;//key[3];
    inwhole[8] = 0;//key[4];
    inwhole[9] = 0;//key[5];
    inwhole[10] = 0;//key[6];
    inwhole[11] = 0;//key[7];

    //Zero counter and nonce
    inwhole[12] = 0;
    inwhole[13] = 0;
    inwhole[14] = 0;
    inwhole[15] = 0;

    uint32_t out[16];
    chacha_block(out, inwhole);
    printHex((char*)out2,16*4);
    //This prints out:
 //76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee6586
}

I could not find any test vectors to validate this first keystream block against. Also I found it confusing that is the next keystream block meant to be generated by passing the previous output back to the chacha_block function? Also is this cipher meat to be used to xor the keystream blocks with the data (this was not explicitly mentioned in the article)?

$\endgroup$

1 Answer 1

2
$\begingroup$

ChaCha20 cipher had been specified by an "informational" RFC - RFC-8439 as a reference for use in Internet protocol specifications. The document contains some test vectors.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.