Implementation of ChaCha20

Hello, I have a problem that I can’t understand.
I wrote this code:

#include <stdint.h>
#include <string.h>

 /*** EDIT THIS!! ***/
#define NONCE "\x00\x00\x00\x00\x00\x00\x00\x4a\x00\x00\x00\x00"

#define RtoL(x, n) \
        ((x << n) | (x >> (32 - n)))

#define QR(a, b, c, d) \
    estado[a] += estado[b]; estado[d] ^= estado[a]; estado[d] = RtoL(estado[d], 16); \
    estado[c] += estado[d]; estado[b] ^= estado[c]; estado[b] = RtoL(estado[b], 12); \
    estado[a] += estado[b]; estado[d] ^= estado[a]; estado[d] = RtoL(estado[d], 8); \
    estado[c] += estado[d]; estado[b] ^= estado[c]; estado[b] = RtoL(estado[b], 7);

// "expand 32-byte k"
static const uint32_t chachaConst[4] = {0x61707865,
                                        0x3320646e,
                                        0x79622d32,
                                        0x6b206574};
static uint32_t chachaKey[8],
                chachaCount = 0,
                chachaNonce[3];
static uint8_t quedanPorLeer = 0,
               chachaRandomOutput[64];

static void chacha()
{
    uint32_t estado[16];
    uint32_t i;
    memcpy(estado, chachaConst, 16);
    memcpy(&estado[4], chachaKey, 64);
    chachaCount++;
    estado[12] = chachaCount;
    memcpy(&estado[13], chachaNonce, 12);
    memcpy(chachaRandomOutput, estado, 64);

    for(i = 0; i < 10; i++)
    {
        QR(0, 4,  8, 12)
        QR(1, 5,  9, 13)
        QR(2, 6, 10, 14)
        QR(3, 7, 11, 15)
        QR(0, 5, 10, 15)
        QR(1, 6, 11, 12)
        QR(2, 7,  8, 13)
        QR(3, 4,  9, 14)
    }

    uint32_t *q = (uint32_t*)chachaRandomOutput;
    for(i = 0; i < 64; i++)
        q[i] += estado[i];
}

void chachaSeed(const uint8_t s[32])
{
    memcpy(chachaKey, s, 32);
    memcpy(chachaNonce, NONCE, 12);
    chachaCount = 0;
    quedanPorLeer = 0;
}

uint8_t chachaGet()
{
    if(!quedanPorLeer)
    {
        chacha();
        quedanPorLeer = 64;
    }
    return chachaRandomOutput[64 - (quedanPorLeer--)];
}

It’s an implementation of the ChaCha20, and it is thought to work like a CSPRNG. Compiled on a Debian with this main:

int main()
{
    chachaSeed("abcdefghijklmnopqrstuvwxyz123456");
    for(;;) printf("%02x ", chachaGet());
}

Works great, and its output doesn’t differ from the testing vectors of its RFC RFC 7539 - ChaCha20 and Poly1305 for IETF Protocols .
But with this code on the arduino:

void setup()
{
    Serial.begin(9600);
    chachaSeed("abcdefghijklmnopqrstuvwxyz123456");
}

void loop()
{
    for(;;) Serial.println(chachaGet());
}

It doesn’t work. At compilation time it doesn’t throw any error, but running connected to the serial of the Arduino IDE with an USB, doesn’t print anything.

I’ve made various tests, like

void setup()
{
    Serial.begin(9600);
    pinMode(13, OUTPUT);
    pinMode(12, OUTPUT);
    pinMode(11, OUTPUT);
    chachaSeed("abcdefghijklmnopqrstuvwxyz123456");
}

void loop()
{
    char c = chachaGet():
    digitalWrite(13, HIGH);
    for(;;)
    {
        digitalWrite(12, HIGH);
        Serial.println(c);
    }
    digitalWrite(11, HIGH);
}

The leds at ping 13 and 12 lights up, but the 11 pin doesn’t. I can’t understand.
Can anyone help me?? Thanks.

You need to post a complete Arduino program.

...R

/* main.ino */
#include <chacha.h>

void setup()
{
    Serial.begin(9600);
    chachaSeed("abcdefghijklmnopqrstuvwxyz123456");
}

void loop()
{
    char c = chachaGet();
    Serial.println(c);
}
/* chacha.h */

#include <stdint.h>
#include <string.h>

 /*** EDIT THIS!! ***/
#define NONCE "\x00\x00\x00\x00\x00\x00\x00\x4a\x00\x00\x00\x00"

#define RtoL(x, n) \
        ((x << n) | (x >> (32 - n)))

#define QR(a, b, c, d) \
    estado[a] += estado[b]; estado[d] ^= estado[a]; estado[d] = RtoL(estado[d], 16); \
    estado[c] += estado[d]; estado[b] ^= estado[c]; estado[b] = RtoL(estado[b], 12); \
    estado[a] += estado[b]; estado[d] ^= estado[a]; estado[d] = RtoL(estado[d], 8); \
    estado[c] += estado[d]; estado[b] ^= estado[c]; estado[b] = RtoL(estado[b], 7);

// "expand 32-byte k"
static const uint32_t chachaConst[4] = {0x61707865,
                                        0x3320646e,
                                        0x79622d32,
                                        0x6b206574};
static uint32_t chachaKey[8],
                chachaCount = 0,
                chachaNonce[3];
static uint8_t quedanPorLeer = 0,
               chachaRandomOutput[64];

static void chacha()
{
    uint32_t estado[16];
    uint32_t i;
    memcpy(estado, chachaConst, 16);
    memcpy(&estado[4], chachaKey, 64);
    chachaCount++;
    estado[12] = chachaCount;
    memcpy(&estado[13], chachaNonce, 12);
    memcpy(chachaRandomOutput, estado, 64);

    for(i = 0; i < 10; i++)
    {
        QR(0, 4,  8, 12)
        QR(1, 5,  9, 13)
        QR(2, 6, 10, 14)
        QR(3, 7, 11, 15)
        QR(0, 5, 10, 15)
        QR(1, 6, 11, 12)
        QR(2, 7,  8, 13)
        QR(3, 4,  9, 14)
    }

    uint32_t *q = (uint32_t*)chachaRandomOutput;
    for(i = 0; i < 64; i++)
        q[i] += estado[i];
}

void chachaSeed(const uint8_t s[32])
{
    memcpy(chachaKey, s, 32);
    memcpy(chachaNonce, NONCE, 12);
    chachaCount = 0;
    quedanPorLeer = 0;
}

uint8_t chachaGet()
{
    if(!quedanPorLeer)
    {
        chacha();
        quedanPorLeer = 64;
    }
    return chachaRandomOutput[64 - (quedanPorLeer--)];
}

Here it is. Thanks for the reply.

How about an explanation of what the different functions are supposed to do?

Does "chacha" mean something or is it just convenient gibberish? Meaningful names make a program much easier to understand.

...R

ChaCha20 is a stream cipher designed by Daniel J. Bernstein. One can use a stream cipher like a CSPRNG (Criptographically Secure Pseudo-Random Number Generator), and the file chacha.h is an implementation of the ChaCha20 like a CSPRNG. The chachaSeed() sets the seed, and the chachaGet() returns the next pseudo-random number generated by the algorithm for that seed. It's like srandom() and random() of the ANSI C but more secure. The file chacha.h is written by me and works great compiled on a linux system. The problem is in the arduino, where doesn't throw any error at compile time, but when executing Serial.print() before chachaGet() the arduino gets stuck. I can't understand this.

Sorry. I am out of my depth.

...R