and right/left shifts work the same in all platforms
C++ has plenty of cruel and unusual cases of UB and IDB, but this luckily isn’t one
I’m actually unsure also by comparing against openSSH’s implementation:
Looking at these, they have POKE_U64
which pokes a unsigned 64-bit integer into memory (big-endian byte order, see https://github.com/openssh/openssh-portable/blob/master/sshbuf.h#L266). This is used to poke the IV to a byte buffer iv
. e.g.
0iv[0] = (seqnr >> 56) & 0xff;
1iv[1] = (seqnr >> 48) & 0xff;
2iv[2] = (seqnr >> 40) & 0xff;
3iv[3] = (seqnr >> 32) & 0xff;
4iv[4] = (seqnr >> 24) & 0xff;
5iv[5] = (seqnr >> 16) & 0xff;
6iv[6] = (seqnr >> 8) & 0xff;
7iv[7] = seqnr & 0xff;
Then, in chacha_ivsetup
(U8TO32_LITTLE
is defined here: https://github.com/openssh/openssh-portable/blob/master/chacha.c#L27)
0x->input[14] = U8TO32_LITTLE(iv + 0);
1x->input[15] = U8TO32_LITTLE(iv + 4);
So if I get this right, this is equivalent to:
0x->input[14] = (((seqnr >> 56) & 0xff) ) |
1 (((seqnr >> 48) & 0xff) << 8) |
2 (((seqnr >> 40) & 0xff) << 16) |
3 (((seqnr >> 32) & 0xff) << 24);
4
5x->input[15] = (((seqnr >> 24) & 0xff) ) |
6 (((seqnr >> 16) & 0xff) << 8) |
7 (((seqnr >> 8) & 0xff) << 16) |
8 (( seqnr & 0xff) << 24);
Which is weird in some sense, but not dependent on platform.