Take the 2-minute tour ×
Cryptography Stack Exchange is a question and answer site for software developers, mathematicians and others interested in cryptography. It's 100% free, no registration required.

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:

crypto_stream_xsalsa20
crypto_stream_salsa20
crypto_stream_salsa2012
crypto_stream_salsa208

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];
  crypto_scalarmult_curve25519(s,sk,pk);
  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.

Now:

  • 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:

crypto_box/curve25519xsalsa20poly1305/ref/before.c
crypto_stream/salsa2012/ref/xor.c
crypto_stream/salsa2012/ref/stream.c
crypto_stream/salsa20/ref/xor.c
crypto_stream/salsa20/ref/stream.c
crypto_stream/salsa208/ref/xor.c
crypto_stream/salsa208/ref/stream.c
crypto_stream/xsalsa20/ref/xor.c
crypto_stream/xsalsa20/ref/stream.c

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.

share|improve this question
    
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). –  nightcracker Oct 21 '13 at 11:00
    
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 –  nightcracker Oct 21 '13 at 11:02
    
Choosing all four 32-bit words of the constant as equal is probably a bad idea. –  CodesInChaos Oct 21 '13 at 11:02
    
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. –  Pascal Oct 21 '13 at 13:10
add comment

1 Answer 1

up vote 4 down vote accepted

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 paper justifies this as:

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 ?

No.

share|improve this answer
    
Thank you for the thorough answer and the additional links! And no, I won't change the constant. –  Pascal Oct 21 '13 at 14:51
    
@Pascal Don't forget to accept the answer if it satisfied your question. ;) –  e-sushi Oct 21 '13 at 17:52
1  
@e-sushi oh my bad. Thanks! –  Pascal Oct 22 '13 at 8:08
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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