I'm currently examining the NaCl library written by Daniel J. Bernstein and I noticed that the library hard codes the sigma:

static const unsigned char sigma[16] = "expand 32-byte k";

In all the salsa stream implementations:


and the crypto_box library wrapper:

static const unsigned char sigma[16] = "expand 32-byte k";
static const unsigned char n[16] = {0};

int crypto_box_beforenm(
  unsigned char *k,
  const unsigned char *pk,
  const unsigned char *sk
  unsigned char s[32];
  return crypto_core_hsalsa20(k,n,s,sigma);

As far as I understand from the paper the constant is used to expand the Stream Cipher.


  • Why is this variable hardcoded in the library?
  • Would it make sense to change this magic string to a different value?
  • Edit: What are the security considerations of using the sigma as provided in the library?

Implementations can be found in the files:


Edit: I found the reference to this constant in the paper referenced above as "Salsa20" constant:

(x0; x5; x10; x15) = (0x61707865; 0x3320646e; 0x79622d32; 0x6b206574); in other words, (x0; x5; x10; x15) is the Salsa20 constant.

which is "expand 32-byte k" considering endianness.

  • $\begingroup$ Your third question is way too broad. The first is very simply answered: because (X)Salsa uses this constant. The second is less simple though. In general the answer would be "yes", but there probably are weak values that you shouldn't use (like all zeroes). $\endgroup$
    – orlp
    Oct 21, 2013 at 11:00
  • $\begingroup$ If you are interested in (X)Salsa, and it's successor ChaCha, I'd suggest reading these papers: cr.yp.to/snuffle/salsafamily-20071225.pdf cr.yp.to/snuffle/spec.pdf cr.yp.to/snuffle/design.pdf cr.yp.to/snuffle/xsalsa-20110204.pdf cr.yp.to/chacha/chacha-20080128.pdf $\endgroup$
    – orlp
    Oct 21, 2013 at 11:02
  • $\begingroup$ Choosing all four 32-bit words of the constant as equal is probably a bad idea. $\endgroup$ Oct 21, 2013 at 11:02
  • $\begingroup$ I now found a reference to this constant in the paper. I must confess that I find the usage of this constant a bit frightening. $\endgroup$
    – Pascal
    Oct 21, 2013 at 13:10

1 Answer 1


Salsa20 has strong rotational symmetry. The main point of these constant is that they're not invariant under rotations, introducing an asymmetry. The precise value isn't very important, as long as it's sufficiently asymmetric.

Bernstein - Salsa20 security says:

Notes on the diagonal constants

Each Salsa20 column round affects each column in the same way starting from the diagonal. Each Salsa20 row round affects each row in the same way starting from the diagonal. Consequently, shifting the entire Salsa20 hash-function input array along the diagonal has exactly the same effect on the output.

The Salsa20 expansion function eliminates this shift structure by limiting the attacker’s control over the hash-function input. In particular, the input diagonal is always 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574, which is different from all its nontrivial shifts. In other words, two distinct arrays with this diagonal are always in distinct orbits under the shift group.

Similarly, the Salsa20 hash-function operations are almost compatible with rotation of each input word by, say, 10 bits. Rotation changes the effect of carries that cross the rotation boundary, but it is consistent with all other carries, and with the Salsa20 operations other than addition.

The Salsa20 expansion function also eliminates this rotation structure. The input diagonal is different from all its nontrivial shifts and all its nontrivial rotations and all nontrivial shifts of its nontrivial rotations. In other words, two distinct arrays with this diagonal are always in distinct orbits under the shift/rotate group.

Another relevant document is the somewhat ranty Response to "On the Salsa20 core function".

SipHash shares some design principles with Salsa20 and has a similar constant. The SipHash paper explains the choice of values:

Choice of constants.

The initial state constant corresponds to the ASCII string “somepseudorandomlygeneratedbytes”, big-endian encoded. There is nothing special about this value; the only requirement was some asymmetry so that the initial $v_0$ and $v_1$ differ from $v_2$ and $v_3$.

This constant may be set to a “personalization string” but we have not evaluated whether it can safely be chosen as a “tweak”. Note that two nonzero words of initialization constants would have been as safe as four.

Would it make sense to change this magic string to a different value?

Keep it unchanged. There might be some rare scenarios where it's useful to customize the constant, but in general you should not.

In response to a question on the CurveCP mailing list, Bernstein wrote:

Is there a recommendation to customise sigma per application ?


  • $\begingroup$ Thank you for the thorough answer and the additional links! And no, I won't change the constant. $\endgroup$
    – Pascal
    Oct 21, 2013 at 14:51
  • $\begingroup$ What rare scenarios would make it useful to customize the constant, other than to produce a "different" cipher that has no equivalent keys in common with the original Salsa20? $\endgroup$
    – forest
    Mar 26, 2018 at 0:31
  • $\begingroup$ Another useful aspect of the constant is that it keeps that part of the block from being attacker-controlled. If it were a customizable input an attacker could control half the input (4 words for that, 2 words for the counter, 2 words for the nonce). It also prevents the all-zero block, which would result in a keystream of all zeros. Neither property is particular to this constant, but they're also why there is a constant in the first place. $\endgroup$ Sep 23, 2021 at 1:18

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.