SALSAX file crypter documentation by EddyHawk
---
What
---
SALSAX is a file encrypter coded by EddyHawk (me).
It is part of PROTAGON File Crypter (PFC) series done by me.
SALSAX uses XSALSA cipher, MD4 & SHA-512 hash functions, and HMAC & PbKDF2
 constructions, all taken from WE Pascal sources.

---
What is XSALSA
---
SALSA20 is a stream cipher designed by Daniel J. Bernstein (DJB) [2005]. It is
a synchronous stream cipher having 20 rounds, claiming 256bit security, &
consistently faster than AES having 128bit key. It's a submission to
ECRYPT/eSTREAM and its variant with 12 rounds (SALSA20/12) has been included
in eSTREAM portfolio along with HC-128, SOSEMANUK, RABBIT, & GRAIN v1,
MICKEY V2, TRIVIUM.
Best performance of SALSA20 with 12 rounds is 2.80 cycles/byte on
Intel Core 2 Duo mcpu (by the designer himself).
SALSA20 is relatively easy to be implemented.
SALSA20 outputs 64 byte (512bit) at a time.

SALSA20 restriction: 2^70 bytes per pair of key/passphrase & nonce.

Best known attack to SALSA20:
 attack on 128bit key, 7 round requiring 2^109 complexity by Shi et al. [2012]
 attack on 256bit key, 8 round requiring 2^250 complexity by Shi et al. [2012]
 attack on 256bit key, 8 round requiring 2^472.2 complexity by Maitra et al.
  [2015]

Considering that SALSA20 also specified in 12 & 20 rounds, the 'security'
margin are high.

Best known analysis to SALSA20:
 128bit Salsa20/15: proven to be secure vs differential cryptanalysis in
  single- & related- key settings [Mouha, Preenel, 2013]

Unbroken status: as 2015, 10 years.

Best known encryption performance (by utilizing mmx/xmm regs):
 on PIII     : 8/12/20 round: ~ 6.4/8.9/14.3  cycles/byte
 on Core2 Duo: 8/12/20 round: ~ 1.9/2.6/ 4.0  cycles/byte
 on Core i7  :     /20 round: ~        / 3.23 cycles/byte

SALSA20 variants proposed including:
XSALSA (SALSA20 supporting longer nonce),
CHACHA (SALSA20 with faster diffusion & equal? speed) with changed column
 round function & different constant-distance rotation sets,
RUMBA20 (compression function using 4 SALSA20 instances as element for
 collision-resistant hash function).

---
My Thought to SALSA20
---
The so-called '4 of 32-bit SALSA20 constants', their origin & their
cryptographic significance never be fully explained by DJB except for their
diagonality or non-trivial shifts, are actually just these silly lowcase
ASCII strings:

'expand 32-byte k' for 256 bit key,
'expand 16-byte k' for 128 bit key,
'expand 10-byte k' for  80 bit key

These strings are actually reversed per 4 bytes during operation (so 'expa'
will be read 'apxe' since it be treated as 32bit little-endian word).

As a sidenote, here are the 'constants' for Rumba20 compression function:
'firstRumba20bloc'
'secondRumba20blo'
'thirdRumba20bloc'
'fourthRumba20blo'

Actually I expect something stronger than those for cipher constants. But:
-cipher designers are forced to use 'nothing on my sleeve' data instead of
 possibly stronger but more suspicious ones for their ciphers to prove that
 they don't insert some kind of 'trapdoor'/'backdoor' to secretly steal keys
 or decrypt plaintexts from produced ciphertexts.
-text constants like these are actually easier for implementation.
-the resulting randomness seems good regardless of these constants' lame
 appearance.

---
What is WE Pascal source
---
Wolfgang Ehrhardt (WE) creates a collection of crypt Pascal sources which is
freely available in Internet, supporting Borland Pascal 7, all flavors of
Borland Delphi, Free Pascal Compiler, & Virtual Pascal, in single source.

XSALSA stream cipher for SALSAX is adapted by me from that collection
[SALSA 18 Jul 2009], then compiled under Virtual Pascal v2.1b279, thus
activating WE's 32bit assembly code, giving improved performance than pure
32bit Pascal implementation.

MD4 & SHA-512 hash functions and HMAC & PbKDF2 constructions for CHAX are also
taken from that collection [CRC_Hash 12 Oct 2009], also compiled under
Virtual Pascal v2.1b279.

---
My Changes to WE Source
---
WE Pascal source for SALSA20 restricts round numbers to 8, 12, 20, thus I
modified the source for SALSAX (add another keysetup procedure) to allow
user-customizable round number. Thus users of SALSAX can choose:
-default round number, which is balance between speed & confidence
-lower round number for faster speed (less confidence)
-higher round number for higher confidence (slower speed)
-even lower round number for curiosity/testing/experiment
-even higher round number for curiosity/paranoidicity
But there's no modification to XSALSA stream cipher itself (respective to this
customizing)

But WE Pascal source, following DJB's C reference code, only implements
the so-called 'double-round' which ignore odd number of rounds.
So I must change WE source again to actually support odd number of rounds
(only 32bit part in the source is modified) for SALSAX.
First, I add check to 'salsa20wordtobyte' procedure for 'number of rounds'
and skip running 'double-round' for 0 & 1 value. Thus it will run correctly
for all even-number of rounds (even 0 round)
Then, I add oddness check after 'double-round'. if number of rounds is even,
run 'final addition' as usual (including 0 round), but if number of
rounds is odd, I add first half of 'double-round' (column) from WE's BASM
(the last odd round) to be run (including the registers pushes & pulls but
'edi'), before add the 'final addition'.

Previously I complained here about how Aumasson et al. incorrectly eliminate
transposition for odd round number for their cryptanalysis on Salsa20.
But now I realize that they are actually right :-)
Transposition is only a must for implementations which use only
the column-round function. The transposition turns rows into columns,
to ensure that the next operation of column-round function to that matrix
is equal to the operation of row-round function to the untransposed matrix.
Therefore, if what you implemented is just the column-round function
to process all rounds, transposition is actually the pre-processing part of
all rounds>1 instead of the post-processing part of odd round number
as I thought it would be. Thus, at the last round, no more transposition
should be applied (it should be applied before that round).

Examples:
Column-round function only, 3 rounds is requested:
round 1: column-round
round 2: transpose, column-round
round 3: transpose, column-round, final addition

Column- & row-round functions, 3 rounds is requested:
round 1: column-round
round 2: row-round
round 3: column-round, final addition

But dude, what if you were right? Remember that AES' last round omits
the MixColumns and thus reduce its complexity against some attacks.
Does omitting transposition before final addition here also make it less safe?
1.Transposition here is more equivalent to AES' ShiftRows, not AES' MixColumns
2.If DJB (author) want transposition to always be present before the final
addition, he will surely add it too after the last double-round. But he don't.
3.I'm not sure whether imposing this transposition, regardless the actual spec,
actually increase its safety, if any.
4.Omitting transposition should reduce SALSAX/CHAX/CHIX code size.
Thus I decide to remove the transposition from last odd round number.

Perhaps 21 rounds or more are already 'paranoid' enough and custom values
should be up-limited to say 40, but unless there's good reason to do that
(such as program hangs) I don't want to prevent users who wish to gain even
more confidence and willing to wait even longer ('paranoid' users). Very short
files (say less than 100kb) with extremely high round number (say 100) will
still be (en/de)crypted very fast and grants extreme confidence to the users.
Yet users should remember that relying on higher round number alone (and say
neglecting your passphrase strength) isn't sufficient because attacker(s)
always attack the weakest part.
Also remember that very high round number is beyond designer's recommendation
& imagination and may produce unexpected effect (say, short cycle)

---
SALSAX specific features
---
It accepts 256bit key only (as DJB recommends) & defaults to 16 rounds

192bit IV

Custom round number, from 0-65535

BASM32 core (WE's)

To improve speed, SALSAX avoids using salsa_encrypt_bytes
& instead using salsa_keystream_bytes. A special buffer is prepared to hold
keystream from salsa_keystream_bytes, and the buffer is 32bit-xor-ed with
plain/cipher -text (file) buffer using my 'xorbuf'.
But due to this, plain/cipher -text buffer becomes only half of other PFCs'
because the other half is used by the special buffer, while I want all PFCs
to have same sized buffer (so they can be fairly benchmarked).
Another problem is that Fast Verify also operates on half buffer (thus slower
than other PFcs).
I tackle the last problem by declare another buffer which occupy those
2 buffers (using Pascal 'absolute') when performing Fast Verify, so Fast Verify
get full buffer just like other PFCs.
Then I managed to rewrite 'xorbuf' for SALSAX so it can use single full buffer,
with few expenses such are additional 64byte mem, & more complex calculations
for xor-ing. Thus SALSAX can utilize full buffer for (de)crypt & Fast Verify,
plus (de)crypting the random-sized random-data addition is simplified.

---
Warning
---
Of course that users specifying non-default value (say 11 rounds) for
encryption for a plaintext must also specifying the same value under decryption
for the resulting ciphertext, if they want to get their ciphertext correctly
decrypted.

Remember that too low round numbers are too weak for 'security', the obvious
such values are 0 to 3. Values < 9 are only for meant for experiments.
Maximum value is only limited by program parameter size (longint) & cipher
internal parameter size (word), so max is 65535. That should be way way way
more than enough :-) If you specify minus value, it will default to 16,
while if you specify > 65535, it will default to 65535.

---
Notes for certain number of rounds
---
 <4: compressible keystream
  4: incompressible keystream
  5: DJB declares it broken (due to Fischer et al. attack)
  6: DJB declares it broken (due to Tsunoo et al. attack)
  7: best attack is 2^153, but DJB doesn't declare it broken
     'barely enough'
  8: DJB recommendation, somewhat risky (?) since best attack have reached this
     eventhough still very computationally infeasible (2^247.2)
     'slightly risky'
  9: 'minimal safe' for normal use
 12: DJB recommendation, eSTREAM chosen
 16: default in SALSAX, good middle value between 12 & 20
 20: DJB original recommendation, conservative
>20: paranoid
>24: ultra paranoid

End.