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

---
What is Serpent
---
Serpent is a block cipher designed by Ross J. Anderson, Eli Biham, &
 Lars R. Knudsen [1998].
It is a 128bit block SPN cipher having up to 256 bit key & 32 rounds.
It's a submission to AES process and managed to become 1 of five AES finalists,
 along with Mars, RC6, Rijndael, & Twofish.

Best known attacks on Serpent:
 differential-linear attack on 10/12 round w/ 128/256 bit key
  [Dunkelman et al., 2008]

IP status: patented?
Unbroken status: as 2015, 17 years.

Best known encryption performance is:
 ~35 cycles/byte on PIII

Requirements: no static table (S-boxes implemented as series of logic ops)
Limitations:

---
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.

Serpent block cipher for SERPEN is adapted by me from that collection
[Serpent 18 Jul 2009], then compiled under Virtual Pascal v2.1b279.

MD4 & SHA512 hash functions and PbKDF2 & HMAC for SERPEN is also taken from
that collection [CRC_Hash 25 Aug 2014], also compiled under Virtual Pascal
v2.1b279.

---
My Changes to WE Source
---
I know that Serpent is much slower than AES in software,
but strangely WE's source of Serpent generates even much slower Serpent. 

So I decided to take a look at the source, hoping to find ways
to optimize it. After browsing it, and some trials and errors, I managed to
convert RND0-RND7 & Transform from its BASM16 section into (not yet purely)
BASM32 to replace its 32bit section. BASM16 section is actually has
different form than 32bit section (Osvik's) and it requires only 5 vs 18(!)
local 32bit words needed by 32bit section.
But it pass the all mode selftests anyway, so no problem.
Serpen's crypt performance are significantly improved by these changes.
Key setup is also faster because it uses RND0-RND7 too.

Then I seek for further optimization and combine Transform to each RND
as RND#T (to reduce multiple loads of same data) to replace separate calls
to RND# & Transform in the crypt routine, which again significantly improve
crypt performance.
Key setup still uses RND# w/o Transform, so they stay.
Then I also convert InvTrans & InvTRND0-7 & combine them too. But this has
no effect on Serpen. Serpen uses CFB mode which doesn't need Inverse.

Further performance are obtained by integrating RNDT#, InvTrans & InvTRND# as
sub-procedure in (de)crypt procedure. Therefore no more procedure vars, local
vars, & moving their content around from procedure vars to be local vars to be
mcpu registers & back again, which once again improves (de)crypt performance.
Total improvement is ~ 4-5 x faster the than original.

Finally, data moving-around in RND0-7 is completely removed, which increases
WE's Serpent speed during key expansion (round keys generation).
Now RND0-7 are for key setup, RND#T & RND7c are for crypt, and InvTrans,
InvRND7, & InvTRND1-6 are for decrypt.

Anyway, the increased (de)crypt speed should now makes Serpen more viable
to use than before.

---
SERPEN specific features
---
16kb file buffer
 Actually its crypt speed isn't affected regardless you use 1 or 16 kb
 file buffer, which unlike other PFCs (say, Fisces). 
 But I stick to 16kb file buffer so then at least Serpen's Fast Verify will be
 as fast as other PFCs.

256bit key
 the largest size supported by the cipher & recommended by the designers.
 KSA performance is the same regardless key size.
 (de)crypt performance is the same regardless key size.
 crypt performance = decrypt performance.

Optimized BASM32 core for much improved (de)crypt speed & for faster init

Custom round number, but only these values are allowed:
  8: unsafe (only meant for testing purposes)
 16: minimal safe (some safety margin)
 24: default (better speed than 32 & still good safety margin)
 32: original

---
Regarding custom round number
---
There were objections to this:
 1st, Serpent, unlike say Twofish, doesn't seem to designed for extended
  rounds.
 2nd, how to generate round keys for extended rounds?
 3rd, looking at Serpent proposal, 32 rounds are more of strength neccesity
  and not simply 'doubling 16 rounds'. So reduced rounds perhaps isn't
  such a good idea.
 4th, reduced rounds removes the reason for selecting Serpent in the 1st place
  (higher confidence of its safety because of its high number of rounds).
But I implement it anyway because:
 1st, extended rounds aren't supported here
 2nd, because of 1st, extended round keys aren't needed
 3rd, however, best known attack so far is on 12 rounds, so 16 rounds has
  sufficient albeit small safety margin
 4th, thus the default is 24 instead of 16

---
Caution
---
Of course that users specifying non-default value (say 16 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.

---
FAQ
---
Why use Serpent? It's sloow
 On the other hand, Serpent is considered as the strongest of all AES
 finalists. Thus it's an excellent alternative for the most conservative users.
 Regarding its number of rounds, Serpent authors claim contradictive things:
 -pre-Serpent needs 64 rounds w/ less complex linear transform.
  so Serpent uses more complex linear transform to reduce it to 32 rounds
 -on the other hand, they claim that Serpent has ample security margin
  (existing differential/linear attacks aren't useful against Serpent
  reduced to 16 rounds)
 They also claim that Serpent w/ only 16 rounds is as secure as 3TDES,
  but remember that 3TDES w/ its 168bit key has only 112bit effective strength.
Why not use EAX?
 EAX is more efficient for very fast block cipher like AES.
 Serpent is slow-performing block cipher already. It will even run 2x slower
  with EAX, making it unacceptable to be used as file encrypter.
Why not Whirlpool for PBKDF2?
 People uses Serpent if they doesn't want AES.
 Whirlpool is based on W block cipher which is very similar to AES, co-designed
  by co-designer of AES.
 Thus this is a fully non-AES solution for them.
Why only 8,16,24,32 rounds are supported?
 Because 8 rounds of Serpent is actually 1 big, complete round.

---
Wishlist
---
-Speeding up Serpen even further
 Especially since some modern crypters reporting much higher speed w/ Serpent
 (I guess they use multithread)

End.