diff --git a/doc/crypt.tex b/doc/crypt.tex
index dcda02b4..e3746b03 100644
--- a/doc/crypt.tex
+++ b/doc/crypt.tex
@@ -600,7 +600,7 @@ As of this release the current cipher\_descriptors elements are the following:
\index{Cipher descriptor table}
\index{blowfish\_desc} \index{xtea\_desc} \index{rc2\_desc} \index{rc5\_desc} \index{rc6\_desc} \index{saferp\_desc} \index{aes\_desc} \index{twofish\_desc}
\index{des\_desc} \index{des3\_desc} \index{noekeon\_desc} \index{skipjack\_desc} \index{anubis\_desc} \index{khazad\_desc} \index{kseed\_desc} \index{kasumi\_desc} \index{camellia\_desc} \index{aes\_enc\_desc}
-\index{idea\_desc}
+\index{idea\_desc} \index{serpent\_desc}
\begin{figure}[hpbt]
\begin{small}
\begin{center}
@@ -626,6 +626,7 @@ As of this release the current cipher\_descriptors elements are the following:
\hline KASUMI & kasumi\_desc & 8 & 16 & 8 \\
\hline Camellia & camellia\_desc & 16 & 16, 24, 32 & 18, 24 \\
\hline IDEA & idea\_desc & 8 & 16 & 8 \\
+ \hline Serpent & serpent\_desc & 16 & 16, 24, 32 & 32 \\
\hline
\end{tabular}
\end{center}
diff --git a/libtomcrypt_VS2008.vcproj b/libtomcrypt_VS2008.vcproj
index d9fd2c2a..0765d2c9 100644
--- a/libtomcrypt_VS2008.vcproj
+++ b/libtomcrypt_VS2008.vcproj
@@ -387,6 +387,10 @@
RelativePath="src\ciphers\rc6.c"
>
+
+
diff --git a/makefile.mingw b/makefile.mingw
index 4a25590e..6474ef9a 100644
--- a/makefile.mingw
+++ b/makefile.mingw
@@ -39,13 +39,14 @@ OBJECTS=src/ciphers/aes/aes.o src/ciphers/aes/aes_enc.o src/ciphers/anubis.o src
src/ciphers/camellia.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/idea.o src/ciphers/kasumi.o \
src/ciphers/khazad.o src/ciphers/kseed.o src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o \
src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/saferp.o \
-src/ciphers/skipjack.o src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_add_aad.o \
-src/encauth/ccm/ccm_add_nonce.o src/encauth/ccm/ccm_done.o src/encauth/ccm/ccm_init.o \
-src/encauth/ccm/ccm_memory.o src/encauth/ccm/ccm_process.o src/encauth/ccm/ccm_reset.o \
-src/encauth/ccm/ccm_test.o src/encauth/chachapoly/chacha20poly1305_add_aad.o \
-src/encauth/chachapoly/chacha20poly1305_decrypt.o src/encauth/chachapoly/chacha20poly1305_done.o \
-src/encauth/chachapoly/chacha20poly1305_encrypt.o src/encauth/chachapoly/chacha20poly1305_init.o \
-src/encauth/chachapoly/chacha20poly1305_memory.o src/encauth/chachapoly/chacha20poly1305_setiv.o \
+src/ciphers/serpent.o src/ciphers/skipjack.o src/ciphers/twofish/twofish.o src/ciphers/xtea.o \
+src/encauth/ccm/ccm_add_aad.o src/encauth/ccm/ccm_add_nonce.o src/encauth/ccm/ccm_done.o \
+src/encauth/ccm/ccm_init.o src/encauth/ccm/ccm_memory.o src/encauth/ccm/ccm_process.o \
+src/encauth/ccm/ccm_reset.o src/encauth/ccm/ccm_test.o \
+src/encauth/chachapoly/chacha20poly1305_add_aad.o src/encauth/chachapoly/chacha20poly1305_decrypt.o \
+src/encauth/chachapoly/chacha20poly1305_done.o src/encauth/chachapoly/chacha20poly1305_encrypt.o \
+src/encauth/chachapoly/chacha20poly1305_init.o src/encauth/chachapoly/chacha20poly1305_memory.o \
+src/encauth/chachapoly/chacha20poly1305_setiv.o \
src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o \
src/encauth/chachapoly/chacha20poly1305_test.o src/encauth/eax/eax_addheader.o \
src/encauth/eax/eax_decrypt.o src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \
diff --git a/makefile.msvc b/makefile.msvc
index a80a7e16..dbe82fd8 100644
--- a/makefile.msvc
+++ b/makefile.msvc
@@ -32,13 +32,14 @@ OBJECTS=src/ciphers/aes/aes.obj src/ciphers/aes/aes_enc.obj src/ciphers/anubis.o
src/ciphers/camellia.obj src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/idea.obj src/ciphers/kasumi.obj \
src/ciphers/khazad.obj src/ciphers/kseed.obj src/ciphers/multi2.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj \
src/ciphers/rc5.obj src/ciphers/rc6.obj src/ciphers/safer/safer.obj src/ciphers/safer/saferp.obj \
-src/ciphers/skipjack.obj src/ciphers/twofish/twofish.obj src/ciphers/xtea.obj src/encauth/ccm/ccm_add_aad.obj \
-src/encauth/ccm/ccm_add_nonce.obj src/encauth/ccm/ccm_done.obj src/encauth/ccm/ccm_init.obj \
-src/encauth/ccm/ccm_memory.obj src/encauth/ccm/ccm_process.obj src/encauth/ccm/ccm_reset.obj \
-src/encauth/ccm/ccm_test.obj src/encauth/chachapoly/chacha20poly1305_add_aad.obj \
-src/encauth/chachapoly/chacha20poly1305_decrypt.obj src/encauth/chachapoly/chacha20poly1305_done.obj \
-src/encauth/chachapoly/chacha20poly1305_encrypt.obj src/encauth/chachapoly/chacha20poly1305_init.obj \
-src/encauth/chachapoly/chacha20poly1305_memory.obj src/encauth/chachapoly/chacha20poly1305_setiv.obj \
+src/ciphers/serpent.obj src/ciphers/skipjack.obj src/ciphers/twofish/twofish.obj src/ciphers/xtea.obj \
+src/encauth/ccm/ccm_add_aad.obj src/encauth/ccm/ccm_add_nonce.obj src/encauth/ccm/ccm_done.obj \
+src/encauth/ccm/ccm_init.obj src/encauth/ccm/ccm_memory.obj src/encauth/ccm/ccm_process.obj \
+src/encauth/ccm/ccm_reset.obj src/encauth/ccm/ccm_test.obj \
+src/encauth/chachapoly/chacha20poly1305_add_aad.obj src/encauth/chachapoly/chacha20poly1305_decrypt.obj \
+src/encauth/chachapoly/chacha20poly1305_done.obj src/encauth/chachapoly/chacha20poly1305_encrypt.obj \
+src/encauth/chachapoly/chacha20poly1305_init.obj src/encauth/chachapoly/chacha20poly1305_memory.obj \
+src/encauth/chachapoly/chacha20poly1305_setiv.obj \
src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.obj \
src/encauth/chachapoly/chacha20poly1305_test.obj src/encauth/eax/eax_addheader.obj \
src/encauth/eax/eax_decrypt.obj src/encauth/eax/eax_decrypt_verify_memory.obj src/encauth/eax/eax_done.obj \
diff --git a/makefile.unix b/makefile.unix
index feda69ed..4594f287 100644
--- a/makefile.unix
+++ b/makefile.unix
@@ -49,13 +49,14 @@ OBJECTS=src/ciphers/aes/aes.o src/ciphers/aes/aes_enc.o src/ciphers/anubis.o src
src/ciphers/camellia.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/idea.o src/ciphers/kasumi.o \
src/ciphers/khazad.o src/ciphers/kseed.o src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o \
src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/saferp.o \
-src/ciphers/skipjack.o src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_add_aad.o \
-src/encauth/ccm/ccm_add_nonce.o src/encauth/ccm/ccm_done.o src/encauth/ccm/ccm_init.o \
-src/encauth/ccm/ccm_memory.o src/encauth/ccm/ccm_process.o src/encauth/ccm/ccm_reset.o \
-src/encauth/ccm/ccm_test.o src/encauth/chachapoly/chacha20poly1305_add_aad.o \
-src/encauth/chachapoly/chacha20poly1305_decrypt.o src/encauth/chachapoly/chacha20poly1305_done.o \
-src/encauth/chachapoly/chacha20poly1305_encrypt.o src/encauth/chachapoly/chacha20poly1305_init.o \
-src/encauth/chachapoly/chacha20poly1305_memory.o src/encauth/chachapoly/chacha20poly1305_setiv.o \
+src/ciphers/serpent.o src/ciphers/skipjack.o src/ciphers/twofish/twofish.o src/ciphers/xtea.o \
+src/encauth/ccm/ccm_add_aad.o src/encauth/ccm/ccm_add_nonce.o src/encauth/ccm/ccm_done.o \
+src/encauth/ccm/ccm_init.o src/encauth/ccm/ccm_memory.o src/encauth/ccm/ccm_process.o \
+src/encauth/ccm/ccm_reset.o src/encauth/ccm/ccm_test.o \
+src/encauth/chachapoly/chacha20poly1305_add_aad.o src/encauth/chachapoly/chacha20poly1305_decrypt.o \
+src/encauth/chachapoly/chacha20poly1305_done.o src/encauth/chachapoly/chacha20poly1305_encrypt.o \
+src/encauth/chachapoly/chacha20poly1305_init.o src/encauth/chachapoly/chacha20poly1305_memory.o \
+src/encauth/chachapoly/chacha20poly1305_setiv.o \
src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o \
src/encauth/chachapoly/chacha20poly1305_test.o src/encauth/eax/eax_addheader.o \
src/encauth/eax/eax_decrypt.o src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \
diff --git a/makefile_include.mk b/makefile_include.mk
index 5210cdd7..f735a6a3 100644
--- a/makefile_include.mk
+++ b/makefile_include.mk
@@ -188,13 +188,14 @@ OBJECTS=src/ciphers/aes/aes.o src/ciphers/aes/aes_enc.o src/ciphers/anubis.o src
src/ciphers/camellia.o src/ciphers/cast5.o src/ciphers/des.o src/ciphers/idea.o src/ciphers/kasumi.o \
src/ciphers/khazad.o src/ciphers/kseed.o src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o \
src/ciphers/rc5.o src/ciphers/rc6.o src/ciphers/safer/safer.o src/ciphers/safer/saferp.o \
-src/ciphers/skipjack.o src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_add_aad.o \
-src/encauth/ccm/ccm_add_nonce.o src/encauth/ccm/ccm_done.o src/encauth/ccm/ccm_init.o \
-src/encauth/ccm/ccm_memory.o src/encauth/ccm/ccm_process.o src/encauth/ccm/ccm_reset.o \
-src/encauth/ccm/ccm_test.o src/encauth/chachapoly/chacha20poly1305_add_aad.o \
-src/encauth/chachapoly/chacha20poly1305_decrypt.o src/encauth/chachapoly/chacha20poly1305_done.o \
-src/encauth/chachapoly/chacha20poly1305_encrypt.o src/encauth/chachapoly/chacha20poly1305_init.o \
-src/encauth/chachapoly/chacha20poly1305_memory.o src/encauth/chachapoly/chacha20poly1305_setiv.o \
+src/ciphers/serpent.o src/ciphers/skipjack.o src/ciphers/twofish/twofish.o src/ciphers/xtea.o \
+src/encauth/ccm/ccm_add_aad.o src/encauth/ccm/ccm_add_nonce.o src/encauth/ccm/ccm_done.o \
+src/encauth/ccm/ccm_init.o src/encauth/ccm/ccm_memory.o src/encauth/ccm/ccm_process.o \
+src/encauth/ccm/ccm_reset.o src/encauth/ccm/ccm_test.o \
+src/encauth/chachapoly/chacha20poly1305_add_aad.o src/encauth/chachapoly/chacha20poly1305_decrypt.o \
+src/encauth/chachapoly/chacha20poly1305_done.o src/encauth/chachapoly/chacha20poly1305_encrypt.o \
+src/encauth/chachapoly/chacha20poly1305_init.o src/encauth/chachapoly/chacha20poly1305_memory.o \
+src/encauth/chachapoly/chacha20poly1305_setiv.o \
src/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o \
src/encauth/chachapoly/chacha20poly1305_test.o src/encauth/eax/eax_addheader.o \
src/encauth/eax/eax_decrypt.o src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \
diff --git a/notes/ccm_tv.txt b/notes/ccm_tv.txt
index 40cb2f19..001a779b 100644
--- a/notes/ccm_tv.txt
+++ b/notes/ccm_tv.txt
@@ -282,3 +282,38 @@ CCM-camellia (16 byte key)
31: 20C3DFE512F4EC1F17973BBB164E9F1B77CC3EB37B486119614764F4C7D0E2, 57CEB0625D34AD40935B03C54A1B8779
32: 913F8D366D4C2AC10ACB3196CCBDB5F436CFA92377045EB3A1C066F6ED7DE0E9, F48C8BB647E719049DB38C39EF779CE2
+CCM-serpent (16 byte key)
+ 0: , 726ABF3B4ACBBC8B070A9FC609236977
+ 1: 6A, 7E6C89FFAC41D271DEC5BAD3AD8EA354
+ 2: 2C81, 00E3ACFA709B79FBDA9E71CD3C9168FB
+ 3: FE9C81, 43353C952AAFD83A2C1D5589C8E24E45
+ 4: A2F11A0E, DEE85E7C3658DC8DF46D5AE1ED89AB59
+ 5: CBE82F9630, B2D90C1FC51FB51A145174AD9684FA71
+ 6: 188CEA135A54, 3694247A366DDD83E1FE316FF15DA749
+ 7: 2A41651928C6A8, E9B876246C7DC7E43C8209EA8549B79D
+ 8: B98493573BAE3B79, F855DA22A957D0AFA34C5EBB0E142808
+ 9: 123FE16121F02E5BD6, FAE0086D7A55E70C29DC1290D841D5DC
+ 10: 5F94D4D6751C9795A50F, 668ADCD75C09D13CC899CF754F1FE15E
+ 11: 9536425ACA7760D046DCCE, 3E965163CFD52A417524A2CEC1EEC35C
+ 12: 7AB41CD2E0F078158FF0FADA, 40A3F1FC69F504D360D2B436F9106518
+ 13: BC6CEE61B19E6E31951C93836D, FC0A38F88337EE3A36CC7967326AD369
+ 14: 15257C23B2D63E00240F6D6A4D73, 30B0A6DC89C7B510508BD7967CEBB459
+ 15: 0462B854CEB1C296E2CB8E490CA8F1, 335B6AF1F0FB1CA58D8C597A4D026393
+ 16: F0D7486377DB32DE318E5828CC80078C, 7DD1C34BDB97EFAD73DFA536D974EC90
+ 17: 4060AAB19ADE345E17855306079C75C6CE, FCCF85A879E68FFCFD8E6DC87FE6C1A6
+ 18: 0675484821044CC980FFADE6CA7E8AB4B30B, CD126CFAC9051B879FA9D97BAD93AF0F
+ 19: 71410ABE5055DA1364FF49B7C5414CEF2F78CC, 829D43AAB76120A8DC1413471A933022
+ 20: 89BF4BA19F90227C76227AB3AFBD081D946B89AD, 922FCC378C436872AB6EC7A8D38A4F85
+ 21: F8C43EDA603B3B2E932D124708B5016EEBFB24CDAD, DFE32FC372DDC93147824B8A6C22C7C3
+ 22: 0935912F14181741FB895A1FA5E4DDB457EFA69818F5, 644F7A9195AC51D3DBA2C31D1A0D5EFC
+ 23: 5ED4EC4AA4A73FCA3FA526DEB0F6203631DA2D9BB1A0D4, 4E1FD5B50AEFF1DC3621B7FADA27904A
+ 24: A7A8D1396FE4C92276D74E20EAC7A3878ECA9BA36EFC0890, 612479C852B0F156292D416E66EBDE02
+ 25: 98215D0F2308E7141D03DCFDBD4B1D7BB2535F1EA8DB1CDD22, 083456921EBFCD54468FDED21F6FC3C9
+ 26: 325D0D2B6309F5032A3419A3866D3DA98DD0431570DD7CEA788E, 44AA618565711D440BCF155B1E5EB5DB
+ 27: 44F7DB4FF3E3B56E0550F05C186DEC9B5FBB4ACAF9FC285646B8F3, 152B310160CD3867B9E4ED19764A6A77
+ 28: 3350DA12E24D7A2F6B6267351BF888A77163B64E0A793080C57914E9, C17FDF94E9D6EE6DA8D677B33363E2C9
+ 29: 3A39B76E3B7453AB8C93586A56AB8A24829D850D1C02E8CB469DA1B9EE, 3B754A51F325FAF7D2027C56932B6D1B
+ 30: 66460EBE06BB081686606ED76C9C4267E8C6723BBB96F9DCA45632BB3BAA, 868F460107DF75880FCAF007719BC3D6
+ 31: 6EE6731CF4308C4B76DFEBDE9342DCDBA540BCD408697A666E10CF3B070D36, 0E4A1EFBC616F54B45C1613680E6C894
+ 32: 233CDC7E52BBA8450E76270723AA771877BD10954DA306911AE4E141A95C5489, C557E221C25644FD57E8D2E716EABFB4
+
diff --git a/notes/cipher_tv.txt b/notes/cipher_tv.txt
index b7217bcb..bdebbe48 100644
--- a/notes/cipher_tv.txt
+++ b/notes/cipher_tv.txt
@@ -2339,3 +2339,161 @@ Key Size: 16 bytes
49: 132613157CA97A35
+Cipher: serpent
+Key Size: 16 bytes
+ 0: 4C7D8A328072A22C823E4A1F3ACDA16D
+ 1: F3436B52DFE96FDF63C1022C12605E01
+ 2: D09DDC0E2D4EAA12614A60E69E7FDEDE
+ 3: 2D59407400422FB0261995D4E605F7DE
+ 4: 742E889747CCFFE18751B8DCDB1D8392
+ 5: 08C18E529FF09A6A62A06DC0A95CB18C
+ 6: DDB44E9668F5C1D1022E7F3362A7FD72
+ 7: 8CB1EB9DBA6AA24FA9EFE299719ADE70
+ 8: 5ABBCDB55E2F63542F4A3A7F78E03D8F
+ 9: C3148BF3FC1ED6E58827DA0243DB026A
+10: 2C63349B3E87437E88C1E8C24A42CBFF
+11: 0D81637AD817D7BB6057E05B33BDE89C
+12: 63A6338C4413DE93232D1137D3B4B5F3
+13: 4979CADD7DC0A8A7864547400784CCAA
+14: A0F7717D9F30AF023B68715FD0F586E5
+15: 6A82314506773190EFDB99BC82796EC3
+16: 6E24C30869393EC6D591901984CD3375
+17: C1DD310FE278FAAD2F8DF4F98088C5D6
+18: C806DD34A64A9C919A832E53DC7AC9DD
+19: 6E0C31BA89B92F9A117D234E9AEFDC87
+20: 76BB6900B0356047989803FD6DFD921A
+21: 69656813894044B243565C8646729D83
+22: C5B5CCA56367361718AC83438B777F50
+23: 50164105407E66060A20B06C712F39AF
+24: EB185AE6E8F691918AC6CAACB0BBEDDC
+25: E06EABCC4907CBEE474925BE276352D9
+26: A1017D3D0DF0F34BE288ABE6121FF5D7
+27: E5D7AFB5E0A177332DE1849709BFA137
+28: CE707C175ABBA720E7569722C394B771
+29: D0AFDD3954703AA68FC48C906148FB07
+30: 1144EB2FB275FD030BFCA0E2757F412A
+31: E7BFC2E528A99A6AC48F133DC1D8A2A8
+32: A27E54A237A91E3D8F845F3D8A4B0771
+33: E95277B8353F4D194B3DF8C1E31CAFCD
+34: 7A643CF73F018D8BAE449C60C5AA34D2
+35: 350E523CC35DB3F0CCF712B423D944FC
+36: F4E1CBD38F379AEB37BCEC7489282926
+37: ADF64B0CE1CF4461C4CA2AF5DEFD2A51
+38: AE6219617D186AC6C324832383A0EE53
+39: 533094603845C674AB4F915E660DEBB5
+40: 97C2B4B94F3057613692B452606E2BDD
+41: 37E6FEF71C55A58DCE8B641EB1AADAFF
+42: F0236BE046EF46B78256AA3C6EA2731D
+43: FC354DC818B2406E17AB5A194B5A8AF6
+44: CFAAD2165A59BEA3283FDB057948AFFC
+45: 0AB2F01A911996BF98035292AE2C6F24
+46: 5E45901119391E81EE392B2E78897038
+47: 3619AF47AB128405544DDF377ADDB80A
+48: 635CA8B8968DF2EA5D377C61156044FA
+49: B02D925EE0A47E45C32FC261813CC257
+
+Key Size: 24 bytes
+ 0: 753D5B42D86672FB29070C4FE4EAAF4C
+ 1: 04D794B6EBB934D244813C0D8664124B
+ 2: 7DF123A5CCCFF43D8A7EFC8200E40DAC
+ 3: CDE0B4E9C2F9A0596B72D0C294763CCA
+ 4: 95B341AF73152EB44850E65BA41F835E
+ 5: CECD25A9CA5A6F7FFD0DCFE125857C83
+ 6: DEE7E320983F0841CF2D4F9361D1F86C
+ 7: FD6689BCDB3979289701134E36461513
+ 8: DF1EB30E9EC17F28AB2390DF5149C95F
+ 9: C1167910D14F2335BB3D51E84BF9C00D
+10: FA7CB639BBDAB4A95C6170E97B778429
+11: 34D95FCA8C309190960FA2A585CFCD14
+12: 229BADE5090D5A8E0FBE14D691FABE26
+13: D634EB7B7C8250E31B5E5282F1A5BCDA
+14: 1C74AC94B2996B56C468ECC3279CC90B
+15: A8E203CDE49DD7B75947CDD4BF602CC3
+16: 5FEDE885F086CC4DB9CD4B88A671C635
+17: BF0468962FD3CF7FB3C56A0D4E495279
+18: FA545A5E62D495A78ABB5DB22CB32979
+19: C46651AD99291B20CF9AEC33BAB150B6
+20: 00B912000F583BCC777EF4BDDCC41CA5
+21: 8010FA2E1D05677221904EAC7B717449
+22: 0432C8A62427586C03E9B6D6B58730BC
+23: 4CC70D235863006EEB38A8FF77D2D26E
+24: AC0C2878D7B24E07FF8F082937A0ECB3
+25: B3220213E730B965704BB421F20FB271
+26: 4099A7F5654A20E69437069DBD5C4033
+27: 86C0FF7196543B12D37694B1B6D5C15D
+28: F8E7D2F8DF2BFFD038D53CE1DCCE56C0
+29: 0FDF7635291A88BAB065BF3C1465DB83
+30: DCC2915BAE71AE13625AAD09CF20E939
+31: 233D73653107EE12441E2D3B1F4D15B0
+32: 93010FBC36A59338C12B8E4CEE962758
+33: A28C25E43B8A5DF411A628F1E706F95D
+34: 0888FAF1CA0FA63932AADC35D7800CF5
+35: 8800A7DAD2A72CA213886F6B40A2A171
+36: 780EAD41E4B9138C505DFD17259F60A7
+37: D29AEE369B6369873A280BF82E558B39
+38: F08B02049678A56B834CEE410D0F89FA
+39: 06766638EA1C9F87AC50ECB833F2DDD8
+40: AB4AAE5039497996403EE050EBEED49F
+41: A3C421A8904815E29FF8EA7F8F73BDFE
+42: C8F6A6EFFCAB57288B449DC21B305B9F
+43: AD74935E4516B4898136C8081BC0F501
+44: 38652264470798FD14C447309B636999
+45: 81570450125A44D18FA95D66D849C4B9
+46: A54560FFEC85BCA455F1B9110B85AA6E
+47: 1EE7838B7167B1023A1D216C64A4D016
+48: 8D4027CBF78A3C40DD988571625C7AF4
+49: F018A1F3A5ECA0F552FE2A91B084294D
+
+Key Size: 32 bytes
+ 0: DE269FF833E432B85B2E88D2701CE75C
+ 1: 9F8A7BD8355A5DA8F962F60B937642E3
+ 2: 364FADEF177F89C7F76D5242AC4C9AED
+ 3: C8467544AA4024525CE7CDE4536424D5
+ 4: B624A3E479FF2CB40DEB2DD492C0FA7B
+ 5: 169C3DD5F2E8DAE95AD2C311BE3D22D3
+ 6: D607FBC8986E0613A5D3E6705B824276
+ 7: 555BFE5CD108FD6C7CD60D41E1EBF427
+ 8: 3992E8417207969B17E77D7F2782352F
+ 9: 30BB268730B585215A809064CB6BB02F
+10: 4B04596B53036803CEAC49941FED8C9F
+11: FA40AC41AF79BC7FFABE61F4AC970FDF
+12: 7AE0FF90DE1D3CE31B72CB6808C99324
+13: BC3C6ED7EDDF820A266C584E83DB9A8D
+14: 578D9AA20A86C239CA3A37B359170B97
+15: AA20FF60C011A93A40A603F34389DC54
+16: 55F27D4338056970D3386570F2C4B687
+17: 00AAB0B8AA64D8FCF962BFAE3ED6ADA3
+18: 81B305AF82100BE96B58B61263C455AF
+19: 305F4DA751C7E1278C3640A62B685C8B
+20: 9BA6BDF257560FBE2E7EEA68F9F56A6D
+21: 63C3EEA7C1F7F792455F94DE12453A22
+22: D006597A75C55AFD697D2C3B682ED7CC
+23: 5D73056F39CD3202A415F7A79CC06D68
+24: FD5275B3312208D3FE7800E924118F80
+25: AEB0FBEF9B702C040CF7CC69852213C7
+26: 30743D504858C8AF88EAF67EC36210E6
+27: 24BEE43160AAC086893904F4E0E4DD4C
+28: 2DE746D379907BC0283A9E740BD2FF8C
+29: 6C9AED135243A1D74AD499EA4F715C59
+30: C3F270819104BC72A37075EB17597B08
+31: E2D8E0AB533C5E6F01BA20B521F93B5C
+32: 1D28B307F349CEAD34482C8AC0CFF029
+33: 4BC2D07A4E4186F4925D6653FA968270
+34: C650ACAC93555956FC26CA6437C5C961
+35: 70D56EF90E4703B7A84096D6325013A2
+36: 69714F2AABE76A078AB39917D0B7DD82
+37: C2AE9D7016AF9FCCA3CCFF54A1140B4B
+38: 4A7F1F21A402EA5ABF62EBA30D227086
+39: 7C40B445D30258EF5F1BCBCD9FD556B7
+40: 434DFEE99021592E6A8D9C3C6FCB50E2
+41: FF4DF73D4A4C63432F874438B196DE64
+42: 05A0B7E9412A7D12931DBDEA87B0A9DA
+43: 9EEB9F8B646BF296E08335E839DAC581
+44: 0EDB3008C41E0F88124D6CBFF73C816D
+45: 4157908C9C90B568DAA611B759C26D39
+46: B7C1CC378876668DC8F08EBE4F86589C
+47: 8836CB48E3E257AE4DD3995034C1D6DA
+48: A8E6EB5A6C65673D6E72A6159FBD3CCB
+49: 80DEC7F355AEA1BCCD1F8209C3FE9E16
+
+
diff --git a/notes/eax_tv.txt b/notes/eax_tv.txt
index b3d9e620..f1a583cc 100644
--- a/notes/eax_tv.txt
+++ b/notes/eax_tv.txt
@@ -586,3 +586,38 @@ EAX-idea (16 byte key)
15: 7F2F87C5A4DD93A73A1F83FE0D3066, 3B9CFCB7B4C90CAB
16: 22A2BC3531E9FBCAAEB678B419227CE4, A38C34F31BAFA2EA
+EAX-serpent (16 byte key)
+ 0: , 97A6952931A6CDA57BCC4716D30F82A1
+ 1: 96, 7C2A3B5E78FD8E51D8EFA5B18704EABF
+ 2: DA43, FC534F23581A3A767EA2EDF709B5AF64
+ 3: 6712DB, 7DBB01EBC12F5DDEF4EA73AFB9333F87
+ 4: 26AA0D44, 0811A8CBB5C44104BD9EFF485A847DB5
+ 5: 3536F9E911, 1A28F0F4140C1EA11433897919C6865C
+ 6: 6FE844A82588, 2AEB14AAEC834F069E4FF8EB58C84D53
+ 7: 9845B4C2DE5C80, ADE2938A7195AA6F3D5311436DDA7AF9
+ 8: BFCFFDBADE812BB1, 86379A0BD9D056C7B8DD13A7A344E0D2
+ 9: AE58D2CEF3546BE633, 7D9AF596AAEB3E64B4DD6548C1EF7C5A
+ 10: BE55A4240519306EC22E, 9D8932C3DAD8F64366F7280D1FF15B57
+ 11: 7D22DF89DE40EDBB5A2CD0, 8D1A5E14933F430D171473E79AFAC748
+ 12: 723E2E279953930DDBF6FB7E, 64F83827882916B8CAEDE297B7CE5E5B
+ 13: 978AEFC3F017FBAEAA71F66E95, 14B825061B7268BD58D0386212CCB2B6
+ 14: E81D5B4A5D124329B35E3542E637, F689AF556D208DBB524025A2AEBA3B54
+ 15: 1DF96C551C75E13FCF077D25314779, 733E93DDC99CE73220336C75E0B0FF13
+ 16: 631EC21D6892E8CD3BA4894AF357602E, 294DCD6EBC59FE575AFD89356E792C92
+ 17: B5EBF5378580BE3BBC1507B2667189BE61, 84AF67D9154C9938660BF8B797878A05
+ 18: B4FD794C8616540EC9BA129AF21A9F0BA768, D6C65005C772005488CAE0EBB75D6A43
+ 19: E607A3F3612D084E187F4E5A1506CB85E5F456, B9AB2A96B877A5DB507F676A3E5820BC
+ 20: 545E4AC37DFC52F7BD113DC2150BA08E3C865039, B1F3E0969DC54CB2A1BAACA190365FCF
+ 21: 65A85C4ED7495E93FCF8EB77C71E6DB3AEB97849B1, 279646B82D6B10944A7FAFFBF62B726D
+ 22: 13650C731A41A257274DA26139C6E1C0D4E0A9302A7F, 4F29AACBACB496E5C30715E4FD6700F4
+ 23: ED9DBDF146A4C2F0FBB0ED17EE8D5155EA2D208A8E8CFA, 20F1E5754C15CA7EBAACBD8673C8BC09
+ 24: 5BA09045237D8DD1D71C8E88611A61D24F16F5813D42ADCF, C5DFF900DC89989E30EC3466B1E807C9
+ 25: 86BB29486407CA1E3D060D67136394FB7A1161F85028FDC632, F2376DA28876CC987434CE7311992FB4
+ 26: 3BD15D58DBC6B050B4ACCC6278F912ECA2E4E3BD86B20041B62E, 6A4786A05D146DFAF8868C511CD63C6C
+ 27: 6A4A427F65A0B6C95E6192FF8F53A4F2810D83015298AD6EBE9A8F, 97DA45CC64772B2041649AFB529C0469
+ 28: 0167FC2B17965AB0D38592796D5CD41D3AC6C7D36EC97A92D4CD38E6, 297C86CCBDE5E7692AB5E4CBA9C7068D
+ 29: 8FFA2B377A264C13DF09C80755543D0BEE76048DD10C405BFCF4318AD6, F64D9A18F677C48A2FE312D7D798C3AD
+ 30: 2BEF6C54A7D57D5DEA5A7A39CD2B201D18F1CA1941F8F9AE9A78F28CE533, 7F64BF8DD0962AC93642564249698777
+ 31: EFD3F06A589F09A08D00A70F2235D64E54ED7E213F4D39191586087AC20833, 9035327451DBC7F9E9A49FF83B704C97
+ 32: 1DFDE8719F4FC7C235A1BB9862E1E6E132EC0C77EFEC71FD7E48C6B000C14291, 0CD8517E1B79FCA166F9D7CA1FB6336F
+
diff --git a/notes/gcm_tv.txt b/notes/gcm_tv.txt
index 0e3962cf..93900af7 100644
--- a/notes/gcm_tv.txt
+++ b/notes/gcm_tv.txt
@@ -274,3 +274,37 @@ GCM-camellia (16 byte key)
31: 6F575BCEF0FC079F8FA300040AA50AD6CF6F4C92A27E24A210AD32FB1FB0E7, 057E5239A6277E1D96BC277D4EEF5FFA
32: 5090FF37EF4F163F5B54AEA54DAF1CDAC1125C46A8617CE3D251576BF52143E2, 182FD3ED463E1A6A615F4E25B34CA748
+GCM-serpent (16 byte key)
+ 1: 59, 99CC473736142E231C8E2F7983696FC2
+ 2: A073, 97EA5DB74235D7C9CF7ACDAAE9A0A7D3
+ 3: 7384C2, 0284EC6DBF6EEE7AC038894F0B83E740
+ 4: 6BC5F0D5, B1A9E78ABFDA9DAFD93E3E6F10785402
+ 5: BCFD59F173, 818144A066F55AAEB713F6936CE79501
+ 6: 87DEE1FA7D21, 6694DA4EE26599A6836C7736C5A0A9AA
+ 7: FA2DD1DEAD1ED2, 9B7F45A3E8C5584CA68C5E8C24073036
+ 8: B6AEEC38E4BAE411, CCCB1EBCE819F011241CD295818B4CAE
+ 9: FE2FD69E73754AB2AB, E08D2FF91E5B08DCCAD050A0F399518C
+ 10: 409169EB71E9986BA336, E797131B00564D9A4F420FDCA4EDE649
+ 11: FECDF3D772D5595FD84330, 232FF07D2945D119058EBE9D0A09C852
+ 12: A849518D738FF180519CAC0B, 4E7EE3BBA0442C19A854383255D2A6B0
+ 13: C9F9F35975DA8CD50ED16302DA, 7D9F2B224D975EDECC381B78F845EE88
+ 14: E5AB8D47CAB6B2AF0110C9C9A3EF, 218A677E10FCD9862B5E6C885D7D01C1
+ 15: 82FD0D94DFF3FCFE5C1133F8DBA522, 1930CBD7C04F6B075875C8641FA9E39A
+ 16: 7EDF3267E7E798C0622F31FC7235B86F, AA472388E03067DBFFED9F8DAC6DD296
+ 17: 0A51F0E3D46C47EB677CD33CFE7638D762, A961F757ACCFF8677A9D33D1AB16C7A0
+ 18: 2C5F591358F2BC1CE2FB984CA5BD35680EFF, 6D722B6E47DE42FD33D99C2847951724
+ 19: 4282489BEA7383C82544969E1BED4201687178, 2B70E41844175DA01170DEF7AE4C677E
+ 20: 1A1410118E91AF9D670DA0F3A6245410BF4A58C1, 20214C685137D8E642E5040E020103E8
+ 21: CA792BD1ABC2F0D671D5A24CF7ED286E45A858C15E, 969B7BB2762B440DA35E97AE4A7D8AF6
+ 22: 46035A0BE300E7C6ECF6CFFB9BB0E30C3DA5F33837FA, 0371E1F6A3C71EC92D9A1109539CE20B
+ 23: D0D19F32DD401A2F26CF7CCC3EEA551F9EF6EBC62B4503, 07AC0EDF5BA03782F655C1864FE03A1C
+ 24: 0BA2D9B107991D08020537FAAA73E85733FB2E94E5370A91, 3D192C4A6CEFB1E9C01224A83CE56C22
+ 25: FD83350D639213E2CD87B17C46A3A68FD4744A0E9132A54408, 76DE3B21C33287DA5F6A6496D8EF0544
+ 26: 2AC44A6ACCADB4B3FAA87DA0CA2F0E64435350D5629345862FDD, 9DA24FB432515AF720127024DF7522CB
+ 27: 3E72B3820ED4B358D78275A33BCC06B378BD1075974B66A7BF7CB8, 9D05B7C4C3A394E40D56F8E48D62D1F8
+ 28: 82B4AAAEBEEFBD4960B23E8020733926C4716BDFA6B6DD1A97CA3623, 9D9056217F955B28AC37932A213012E3
+ 29: 85B43B381EBF7D4A61BF261DC2E0018FED9A3BFFA5097150624E00BDEA, 128B0ACC4E5342174BB092BEB87B9A30
+ 30: 8C06161B3CA867B3EB61A9C71C85EB8586772BD45682FD57B15E03C0423B, A17FE2999ACA23CEF1196E3424A0ED0C
+ 31: 4331553A74B44F279B6B007E9714322105AE73ADB83A7FBC5A622DDFAFAED6, EB4781C244484C51A155F2A0F78D38FE
+ 32: 855378D251F29B822948E3788176E96247B7CA292D4DEF383FFD936BE3F7F42B, 6A08DF742301EED938AECC730D187AD2
+
diff --git a/notes/ocb3_tv.txt b/notes/ocb3_tv.txt
index 8a867e2c..c65a462c 100644
--- a/notes/ocb3_tv.txt
+++ b/notes/ocb3_tv.txt
@@ -282,3 +282,38 @@ OCB3-camellia (16 byte key)
31: 41C092516DC494E4E165EABAF939858EDAE3D3DAE488D14EFDB0E850675565, F45307A495AFE24E29E2AB744311F07C
32: EFFEAF5A73C2A825AFEE12A2BE80406937C75D4264FD937A310FA57C7D5D01CB, 3B430C0DA47DAA069FCC5C92C5427396
+OCB3-serpent (16 byte key)
+ 0: , 41644B8EC26D2E17704E9672E35B7680
+ 1: CB, C2A63BA8383D6B7715F9F9537832AB3A
+ 2: CF55, 05C93C786C5690D7263D1E8A2000FD60
+ 3: C2DC71, C5DD3ADFC37AE996864C668A4FA79661
+ 4: 70B3C079, 196DC9A8BE594ACE825F71BE8ABDC5A4
+ 5: C546167392, 8BFF55BAAEFDA76EC8DE7E5B301C1B78
+ 6: 8F6B6E1C7DA4, F9C28EB7BC64C26F3C862AE5315C9C70
+ 7: BEF54F32A4E502, D931EC6EA9165E4A23DE6531D728F79D
+ 8: 862DA6C6C4C6864A, 8D087F4E192AA08AC14CC0E8FE735A33
+ 9: 5336AB6945FAA347B8, 9CAD11FBE86011F872C68D85B7003DB3
+ 10: F4950C42B79374E4C0D2, 775ADDAD869DD3B912444D33B8B98AE6
+ 11: E445E8B46DA8623E3F6960, AD253749B2453F1D86D5D4CE91C3A11E
+ 12: A9B21268031B0DBC8D091FB4, 11CF154818B007F9E2335DC2CE3692AB
+ 13: 5DDD737D9CAAECA39E9A282CE2, DA8E7275360A6099A5FCD3EE4D65C30F
+ 14: 66631DA582F7A1E8C35ABBB869A5, 71927DD54E189F5C43B68B675F00CCE0
+ 15: 3475EBEF7803C8D3CDB8774FF7AED2, EE2D9370434B6CDC2DAD922265AD0E53
+ 16: 732536E50C887334D05DB25F2ECC6ED3, 9233CF71135D979C27E79FD6AB7DAF25
+ 17: AE5BCDA23B70894E1192ADDA30A10FE30A, D05D97B23D3F813622DE7A7EFC67BF8B
+ 18: 65F2023E4DF6006180709A239A5A9387D649, EDA9F67ABB96AC268E23BFA1F07192F9
+ 19: 837A31A15D3562C99C1A108CE27F81CDEB1245, 91DBA8ADA9BAC949B22B86C08E04C27E
+ 20: EED3C97EE7CBA13815E6EF5E22C75A7D486BF274, 714DE1E7163934419D650D99F1FECB77
+ 21: 59E589AF5ACD014D4AB450490287E7BF766CBDD131, 914DA019D53052AF65BC066112FE7CCD
+ 22: 9F8AB009C4A3E849C8055ECBD7AEDD6A1F70426385C1, 6654B56A1D589EA5486BFE902C355FA2
+ 23: 532438DBE6E47A8729EE02E8C47111E4D7B90A7B098499, 34F3A82F9D7E6BADB6F8CE7193D81663
+ 24: 2FD29C61D3A70C9EDA7EB42CA3DBDB1ED24E20DBD5710F4E, 4CB52CF090FFF15974236428DC0D321F
+ 25: E3E404730231203895EFFDD83495AEFE265D4B4F122EF32894, 3739208F2E9D9AD3FCA138E8BC399A65
+ 26: 2FB6945DFC9144D25C505F991C154243B5BBEE43BEDC3C9F3978, 2C291D274D751C93DA3168A45DF7FF2C
+ 27: 11F244A9265C3D0FF8DE581F28002434C395458143F94C02BD7A55, 8B73783A1BEE7CC879C8944BA15E033E
+ 28: 7AA49DCBC09E877CC91714FE6CE2CADECAF9DF771197DF0EAA2B5B20, 7DFFABCC40089E828F3C1A4DBBE28A68
+ 29: C05269D72B17120FBE86397D655279F7C198467567F0B1FA24BBB077DF, E5487A7BCAFDBC08342369DA09FABF12
+ 30: 7F97808D172665B399495FCAA6A673010E98EB6ADB25C1A41CF0F957B958, 33E6CA26292F6E9F55EBC6BFB3694E89
+ 31: F7435456F02EE5ACE92F7E1F29D239A09AEB487BDA78B08A40837547CBFDC7, 86E15E8711A93AE7F89808D21BD69AD6
+ 32: 9D49A127710AE66D612C8E7089CB254523109DFBB0ED2A3E44412C3BD81326FA, 624FA0DF639EB14A5A337273886E6CE5
+
diff --git a/notes/ocb_tv.txt b/notes/ocb_tv.txt
index ec8b2073..c2625d6c 100644
--- a/notes/ocb_tv.txt
+++ b/notes/ocb_tv.txt
@@ -586,3 +586,38 @@ OCB-idea (16 byte key)
15: 21C3BCB256DBFC0B472F30A6D469CA, 3ADD0D84695C5B14
16: BE073E735F86AFA6D3A4F56C914D5EB8, 07921F5BA6E9F250
+OCB-serpent (16 byte key)
+ 0: , D9490CE405238D17C036B3E5DF4DFC7F
+ 1: DB, 44C1E20A0467B693019DFBA21EAF9035
+ 2: A343, 2E20DAB7135E395AA3FF227959A70610
+ 3: CB7E24, EE8FAA34CA9C43CFB24061B79DE82C70
+ 4: F9BCE9E7, B6A48414BED23D37F99FED990A3A0B14
+ 5: 2D3FB0FEA0, 06700497ABDC995F781771CCEAC341B7
+ 6: 0C1BAB99858B, E4EB74D56565A50D16CF91D9872B702E
+ 7: 72CEBD89561A1D, 8FCC39F07C721EC8C92AEEA3C4BE845F
+ 8: A6CC972273DAF3E8, 099BDEA86D5CB994285A7AB9BC59EAC7
+ 9: 0ED1E78C9A39377377, C969C9583F3CCE5799630C5450BE9134
+ 10: F68611B69D657B6D6DC4, 893C25068299C5F6305411E3A9199616
+ 11: 7402BE21EEE415AA5438F8, 01916E4C573FF695CFEC41C7F29EA1CC
+ 12: 125918FFB1902AC3F4F81265, F3EA4E417E4DA6B8BDCCC8BD4E87FE27
+ 13: 01C2E839EB6C4CFFFF4856C97C, B57A6FB6918F8E11113E449D75CF638F
+ 14: 708B33704EB6E379FEC223371C74, 44EC0A795B2E604D29B8E917A73EAC29
+ 15: A45EEE44431E19F61B5E4D257B7BDD, E42E3A6D212B42595E39E5A6E14B0C43
+ 16: F23AD7425EB8D3CE0FAFDCBEF52A1962, 5C6BD772DD1DE0070391A9BF63D0913D
+ 17: 9B40D36F988B6F105380C7C949EDB1F379, 78FC67EEC03CE078A72977801B75DA52
+ 18: 9A894DFCA373610C48ED16149CE0D84E2939, D2E05400320F61FDAF1729F5505B513F
+ 19: 47CE7BBF27734E7C480CD4F9DD69F4B3E11223, 07C22A4DCCB71372A12ABB0ED2C5EAD3
+ 20: 61F7F55DD6DC89472728E54C53CCC7034922EC7C, 490D005087FF9ACB5211FE2E40D3B5B7
+ 21: DE27EBD9891828F422321C96BA900026F4033A1B98, E8C33743F34494061455F0F5A104F218
+ 22: D73F22E0BBE04F9B7537DB5A8B35D9B978AC45B1DCA0, 3271FA71E989D845EEB7E76755A68CB0
+ 23: F61DC254C28E7CEA0B526D9E4BF0E6C554A09251BC0BAA, FA74560634DDAD5F56B8842B2E49EFE8
+ 24: 6155A4D65C03F0AB2665FC65408FDD29276C4D3B6E957CCE, E41DCA2C8D3601AD9C344BE53334F8A7
+ 25: 9C4487CC097FF24A45502A9A3C0F7A2134235EDB2108ED470A, C28CB7100F45C6D87B0CE1682871761D
+ 26: 0CB17A181F579A62B28A1171B1C3AF8A275C8D99D6AF95A3514A, 33BB5B063092B223A40C310B98B8FDE9
+ 27: A5D0455E5E4C3DE2009A774F055F5DDAFFDC89A25872E99DCB1E75, 19488A3644BBF9BB621E80ED45EB826D
+ 28: F4A054D11AD6B2A3A7F7A4EF40A09243373F4C151320464A0A9A9E06, 272D1709AA49838DEDA8F78D9878CD4F
+ 29: 83EFF58C64BFCD1CB5DD0F6D040B8ACFE6C8992E14605FCCCFF142D0AC, 5BE7739321D83A5E4CC9AB5FA6D56966
+ 30: E12A3514CBF30326E5078B8117678823E6AFA8F3A78FEAF06C5B1508CEA0, 301B3BE76675FD30209EEA086BB40CD8
+ 31: 77E2B65956B52BD90E90081F389BBFC8D4550FBCC74B6469C5CE98FC093A0F, C43272FD03A35AE4D9AF467CD7811F1D
+ 32: 77E116BE37F8153D717F3F19DEFD045C2E8CAC499295B9EE6A95A3509D4CBC47, A0406E2C09C510AB5A9E5A5B20B0C306
+
diff --git a/notes/omac_tv.txt b/notes/omac_tv.txt
index 187d702f..2abd0ed2 100644
--- a/notes/omac_tv.txt
+++ b/notes/omac_tv.txt
@@ -586,3 +586,38 @@ OMAC-idea (16 byte key)
15: 2650AF8B3983AE0D
16: 50F09209EB28179E
+OMAC-serpent (16 byte key)
+ 0: 32B85B2D0F6A080E75F1FFE3A9FB5FFB
+ 1: F64B8FE18564E74DCBD49F773D7979CA
+ 2: E3C48FFF5808AA7945481908FC717548
+ 3: E0C62FF36F4B4EA65E1AF2D09039CFE3
+ 4: AB03CE05922E2B6AF001B267DBE31BB1
+ 5: E4064DD1F7B97BB930F38C601375A6ED
+ 6: DC0E7B1BA3CDBD7E12EE7925937551CC
+ 7: 57339E1EF4A9E91D10C3FBE6FE93CC93
+ 8: 85DF3A320B77510535723BDB885C6471
+ 9: 15E3F593D2200F27DEF08CEFE763CBC6
+ 10: FEA659B89FD367CB508411FFED43F1B8
+ 11: 4B7C3776A1520E31A5BC80EBE3470276
+ 12: 425FC3093FEEB420672EA70A71D7C7BC
+ 13: EDE32E118616A02F3E43E1607D5E715E
+ 14: 00ABB127256308E517C12D41D72C6F53
+ 15: 2AC61ED0CE3393129EA22A6715536334
+ 16: 01175B1577CE91E81C27B51372617995
+ 17: ECE4166171B912D090AB134875C7249C
+ 18: 481E14C574AA8AB6DFBDFA81B3B6F298
+ 19: 2CC33E74FC8FF36A268D25E28610B46E
+ 20: 270735B926CE2F9AD7DEC785D4B4F8E3
+ 21: 5A47B86DBF557698B37025A70417FCFF
+ 22: 19130FFE070FD9C2546C98B76D447104
+ 23: C6BC0BED4C8CF5E182F69DAA13AFA47C
+ 24: BC33925A9EFE64C20B24278663C7FBB0
+ 25: 1552EB3F1396031C7306B2D34EEEC01A
+ 26: 8C0BFE93E9FCF490CA4B4254CFD2C24D
+ 27: 3F570BD03EA24C72CF6CC740B4EA2652
+ 28: C34DAA57DED46E788573472F4DAA1743
+ 29: EA26F5DAC00DEC6BC7F5DA35902DB020
+ 30: 71573E129764A4C1B8F8A2D1BF2013CF
+ 31: C7E18CC108DF3FF1E3A024A1B0B928E0
+ 32: 6E458187EC664A776005EA140154ACBF
+
diff --git a/notes/pmac_tv.txt b/notes/pmac_tv.txt
index e088cc8f..5db6c709 100644
--- a/notes/pmac_tv.txt
+++ b/notes/pmac_tv.txt
@@ -586,3 +586,38 @@ PMAC-idea (16 byte key)
15: DD3E679D6387A082
16: 872DDF68887A9606
+PMAC-serpent (16 byte key)
+ 0: F339DEF404209BCB165EB7BCFD992CBE
+ 1: 4AC8EFF62CBCF0DF5EED09C481DAEC02
+ 2: 8D89B71DE01632A07641FA5A92DB8F3F
+ 3: CD3BA1D7DD7ABE17BFBD48E1B391EB77
+ 4: 579BF88799B0B67F2E1B12D34B20DF9C
+ 5: 56C6AACC2B142F18A680B6AAA5AA82A4
+ 6: 082EFD0AA9B9BA02132F2B74B748E243
+ 7: 6B800A69716D6FFF5C9836176F724AA3
+ 8: FF406270AED77526DC8E84FEFC7A57C2
+ 9: C2E5741342F888E4CE0D661986388FEE
+ 10: 47AB010F388A9E10017155D88F35F20B
+ 11: A5623D8A148DF62024F2C621DE0C4E2A
+ 12: C6B47AAAF01A7E4683C461D119288354
+ 13: FB7274149DB6E4E2CC757E8A95EBE335
+ 14: FE74C4559520165DABCB75942C333950
+ 15: EFD0DEBF6304F04C6CFAD4B6A4DF6C58
+ 16: 89BDE6A86A4A14ED553732CF979F9599
+ 17: AEB77664F24297E6471218B2F68A5BFD
+ 18: 1AD0F4ED52FDEF747BF3E3C8DF7334DE
+ 19: 16273AD4918181B8E183F661D1EE7991
+ 20: 061DBAABEA31DFBD68A57151633FEDF5
+ 21: 2206B89F47FA497C506B25736B672F70
+ 22: 86F3809E186C70B2FD7B0BC88A0A81F6
+ 23: 193CD2D4777DAE6FD7EF176EA9065C81
+ 24: 9274BBB50D1CB86C39CA0AC0A5224A9E
+ 25: F7BD94AB66D03AA22CB41F72874316DE
+ 26: 1E48C30E5502E98B7F7038BEE7BC658A
+ 27: AB7E6F468283DA5219CC76D83915CA63
+ 28: 54CBD6BB08511366E56EA95414766D97
+ 29: 73E91132A2B53930D4415A5B4F7BD523
+ 30: 67E45427A9CCFAB9A11BD6AF2C4E9A80
+ 31: 11F399978DB69A7957F2DF1A44206841
+ 32: D6C0DE7EEB98DA9EB0F800D2734B100A
+
diff --git a/src/ciphers/serpent.c b/src/ciphers/serpent.c
new file mode 100644
index 00000000..cdd34fa5
--- /dev/null
+++ b/src/ciphers/serpent.c
@@ -0,0 +1,727 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ */
+
+/* Based on serpent.cpp - originally written and placed in the public domain by Wei Dai
+ https://github.com/weidai11/cryptopp/blob/master/serpent.cpp
+
+ On 2017-10-16 wikipedia says:
+ "The Serpent cipher algorithm is in the public domain and has not been patented."
+ https://en.wikipedia.org/wiki/Serpent_(cipher)
+ */
+
+#include "tomcrypt.h"
+
+#ifdef LTC_SERPENT
+
+const struct ltc_cipher_descriptor serpent_desc = {
+ "serpent",
+ 25, /* cipher_ID */
+ 16, 32, 16, 32, /* min_key_len, max_key_len, block_len, default_rounds */
+ &serpent_setup,
+ &serpent_ecb_encrypt,
+ &serpent_ecb_decrypt,
+ &serpent_test,
+ &serpent_done,
+ &serpent_keysize,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+/* linear transformation */
+#define _LT(i,a,b,c,d,e) { \
+ a = ROLc(a, 13); \
+ c = ROLc(c, 3); \
+ d = ROLc(d ^ c ^ (a << 3), 7); \
+ b = ROLc(b ^ a ^ c, 1); \
+ a = ROLc(a ^ b ^ d, 5); \
+ c = ROLc(c ^ d ^ (b << 7), 22); \
+ }
+
+/* inverse linear transformation */
+#define _ILT(i,a,b,c,d,e) { \
+ c = RORc(c, 22); \
+ a = RORc(a, 5); \
+ c ^= d ^ (b << 7); \
+ a ^= b ^ d; \
+ b = RORc(b, 1); \
+ d = RORc(d, 7) ^ c ^ (a << 3); \
+ b ^= a ^ c; \
+ c = RORc(c, 3); \
+ a = RORc(a, 13); \
+ }
+
+/* order of output from S-box functions */
+#define _beforeS0(f) f(0,a,b,c,d,e)
+#define _afterS0(f) f(1,b,e,c,a,d)
+#define _afterS1(f) f(2,c,b,a,e,d)
+#define _afterS2(f) f(3,a,e,b,d,c)
+#define _afterS3(f) f(4,e,b,d,c,a)
+#define _afterS4(f) f(5,b,a,e,c,d)
+#define _afterS5(f) f(6,a,c,b,e,d)
+#define _afterS6(f) f(7,a,c,d,b,e)
+#define _afterS7(f) f(8,d,e,b,a,c)
+
+/* order of output from inverse S-box functions */
+#define _beforeI7(f) f(8,a,b,c,d,e)
+#define _afterI7(f) f(7,d,a,b,e,c)
+#define _afterI6(f) f(6,a,b,c,e,d)
+#define _afterI5(f) f(5,b,d,e,c,a)
+#define _afterI4(f) f(4,b,c,e,a,d)
+#define _afterI3(f) f(3,a,b,e,c,d)
+#define _afterI2(f) f(2,b,d,e,c,a)
+#define _afterI1(f) f(1,a,b,c,e,d)
+#define _afterI0(f) f(0,a,d,b,e,c)
+
+/* The instruction sequences for the S-box functions
+ * come from Dag Arne Osvik's paper "Speeding up Serpent".
+ */
+
+#define _S0(i, r0, r1, r2, r3, r4) { \
+ r3 ^= r0; \
+ r4 = r1; \
+ r1 &= r3; \
+ r4 ^= r2; \
+ r1 ^= r0; \
+ r0 |= r3; \
+ r0 ^= r4; \
+ r4 ^= r3; \
+ r3 ^= r2; \
+ r2 |= r1; \
+ r2 ^= r4; \
+ r4 = ~r4; \
+ r4 |= r1; \
+ r1 ^= r3; \
+ r1 ^= r4; \
+ r3 |= r0; \
+ r1 ^= r3; \
+ r4 ^= r3; \
+}
+
+#define _I0(i, r0, r1, r2, r3, r4) { \
+ r2 = ~r2; \
+ r4 = r1; \
+ r1 |= r0; \
+ r4 = ~r4; \
+ r1 ^= r2; \
+ r2 |= r4; \
+ r1 ^= r3; \
+ r0 ^= r4; \
+ r2 ^= r0; \
+ r0 &= r3; \
+ r4 ^= r0; \
+ r0 |= r1; \
+ r0 ^= r2; \
+ r3 ^= r4; \
+ r2 ^= r1; \
+ r3 ^= r0; \
+ r3 ^= r1; \
+ r2 &= r3; \
+ r4 ^= r2; \
+}
+
+#define _S1(i, r0, r1, r2, r3, r4) { \
+ r0 = ~r0; \
+ r2 = ~r2; \
+ r4 = r0; \
+ r0 &= r1; \
+ r2 ^= r0; \
+ r0 |= r3; \
+ r3 ^= r2; \
+ r1 ^= r0; \
+ r0 ^= r4; \
+ r4 |= r1; \
+ r1 ^= r3; \
+ r2 |= r0; \
+ r2 &= r4; \
+ r0 ^= r1; \
+ r1 &= r2; \
+ r1 ^= r0; \
+ r0 &= r2; \
+ r0 ^= r4; \
+}
+
+#define _I1(i, r0, r1, r2, r3, r4) { \
+ r4 = r1; \
+ r1 ^= r3; \
+ r3 &= r1; \
+ r4 ^= r2; \
+ r3 ^= r0; \
+ r0 |= r1; \
+ r2 ^= r3; \
+ r0 ^= r4; \
+ r0 |= r2; \
+ r1 ^= r3; \
+ r0 ^= r1; \
+ r1 |= r3; \
+ r1 ^= r0; \
+ r4 = ~r4; \
+ r4 ^= r1; \
+ r1 |= r0; \
+ r1 ^= r0; \
+ r1 |= r4; \
+ r3 ^= r1; \
+}
+
+#define _S2(i, r0, r1, r2, r3, r4) { \
+ r4 = r0; \
+ r0 &= r2; \
+ r0 ^= r3; \
+ r2 ^= r1; \
+ r2 ^= r0; \
+ r3 |= r4; \
+ r3 ^= r1; \
+ r4 ^= r2; \
+ r1 = r3; \
+ r3 |= r4; \
+ r3 ^= r0; \
+ r0 &= r1; \
+ r4 ^= r0; \
+ r1 ^= r3; \
+ r1 ^= r4; \
+ r4 = ~r4; \
+}
+
+#define _I2(i, r0, r1, r2, r3, r4) { \
+ r2 ^= r3; \
+ r3 ^= r0; \
+ r4 = r3; \
+ r3 &= r2; \
+ r3 ^= r1; \
+ r1 |= r2; \
+ r1 ^= r4; \
+ r4 &= r3; \
+ r2 ^= r3; \
+ r4 &= r0; \
+ r4 ^= r2; \
+ r2 &= r1; \
+ r2 |= r0; \
+ r3 = ~r3; \
+ r2 ^= r3; \
+ r0 ^= r3; \
+ r0 &= r1; \
+ r3 ^= r4; \
+ r3 ^= r0; \
+}
+
+#define _S3(i, r0, r1, r2, r3, r4) { \
+ r4 = r0; \
+ r0 |= r3; \
+ r3 ^= r1; \
+ r1 &= r4; \
+ r4 ^= r2; \
+ r2 ^= r3; \
+ r3 &= r0; \
+ r4 |= r1; \
+ r3 ^= r4; \
+ r0 ^= r1; \
+ r4 &= r0; \
+ r1 ^= r3; \
+ r4 ^= r2; \
+ r1 |= r0; \
+ r1 ^= r2; \
+ r0 ^= r3; \
+ r2 = r1; \
+ r1 |= r3; \
+ r1 ^= r0; \
+}
+
+#define _I3(i, r0, r1, r2, r3, r4) { \
+ r4 = r2; \
+ r2 ^= r1; \
+ r1 &= r2; \
+ r1 ^= r0; \
+ r0 &= r4; \
+ r4 ^= r3; \
+ r3 |= r1; \
+ r3 ^= r2; \
+ r0 ^= r4; \
+ r2 ^= r0; \
+ r0 |= r3; \
+ r0 ^= r1; \
+ r4 ^= r2; \
+ r2 &= r3; \
+ r1 |= r3; \
+ r1 ^= r2; \
+ r4 ^= r0; \
+ r2 ^= r4; \
+}
+
+#define _S4(i, r0, r1, r2, r3, r4) { \
+ r1 ^= r3; \
+ r3 = ~r3; \
+ r2 ^= r3; \
+ r3 ^= r0; \
+ r4 = r1; \
+ r1 &= r3; \
+ r1 ^= r2; \
+ r4 ^= r3; \
+ r0 ^= r4; \
+ r2 &= r4; \
+ r2 ^= r0; \
+ r0 &= r1; \
+ r3 ^= r0; \
+ r4 |= r1; \
+ r4 ^= r0; \
+ r0 |= r3; \
+ r0 ^= r2; \
+ r2 &= r3; \
+ r0 = ~r0; \
+ r4 ^= r2; \
+}
+
+#define _I4(i, r0, r1, r2, r3, r4) { \
+ r4 = r2; \
+ r2 &= r3; \
+ r2 ^= r1; \
+ r1 |= r3; \
+ r1 &= r0; \
+ r4 ^= r2; \
+ r4 ^= r1; \
+ r1 &= r2; \
+ r0 = ~r0; \
+ r3 ^= r4; \
+ r1 ^= r3; \
+ r3 &= r0; \
+ r3 ^= r2; \
+ r0 ^= r1; \
+ r2 &= r0; \
+ r3 ^= r0; \
+ r2 ^= r4; \
+ r2 |= r3; \
+ r3 ^= r0; \
+ r2 ^= r1; \
+}
+
+#define _S5(i, r0, r1, r2, r3, r4) { \
+ r0 ^= r1; \
+ r1 ^= r3; \
+ r3 = ~r3; \
+ r4 = r1; \
+ r1 &= r0; \
+ r2 ^= r3; \
+ r1 ^= r2; \
+ r2 |= r4; \
+ r4 ^= r3; \
+ r3 &= r1; \
+ r3 ^= r0; \
+ r4 ^= r1; \
+ r4 ^= r2; \
+ r2 ^= r0; \
+ r0 &= r3; \
+ r2 = ~r2; \
+ r0 ^= r4; \
+ r4 |= r3; \
+ r2 ^= r4; \
+}
+
+#define _I5(i, r0, r1, r2, r3, r4) { \
+ r1 = ~r1; \
+ r4 = r3; \
+ r2 ^= r1; \
+ r3 |= r0; \
+ r3 ^= r2; \
+ r2 |= r1; \
+ r2 &= r0; \
+ r4 ^= r3; \
+ r2 ^= r4; \
+ r4 |= r0; \
+ r4 ^= r1; \
+ r1 &= r2; \
+ r1 ^= r3; \
+ r4 ^= r2; \
+ r3 &= r4; \
+ r4 ^= r1; \
+ r3 ^= r0; \
+ r3 ^= r4; \
+ r4 = ~r4; \
+}
+
+#define _S6(i, r0, r1, r2, r3, r4) { \
+ r2 = ~r2; \
+ r4 = r3; \
+ r3 &= r0; \
+ r0 ^= r4; \
+ r3 ^= r2; \
+ r2 |= r4; \
+ r1 ^= r3; \
+ r2 ^= r0; \
+ r0 |= r1; \
+ r2 ^= r1; \
+ r4 ^= r0; \
+ r0 |= r3; \
+ r0 ^= r2; \
+ r4 ^= r3; \
+ r4 ^= r0; \
+ r3 = ~r3; \
+ r2 &= r4; \
+ r2 ^= r3; \
+}
+
+#define _I6(i, r0, r1, r2, r3, r4) { \
+ r0 ^= r2; \
+ r4 = r2; \
+ r2 &= r0; \
+ r4 ^= r3; \
+ r2 = ~r2; \
+ r3 ^= r1; \
+ r2 ^= r3; \
+ r4 |= r0; \
+ r0 ^= r2; \
+ r3 ^= r4; \
+ r4 ^= r1; \
+ r1 &= r3; \
+ r1 ^= r0; \
+ r0 ^= r3; \
+ r0 |= r2; \
+ r3 ^= r1; \
+ r4 ^= r0; \
+}
+
+#define _S7(i, r0, r1, r2, r3, r4) { \
+ r4 = r2; \
+ r2 &= r1; \
+ r2 ^= r3; \
+ r3 &= r1; \
+ r4 ^= r2; \
+ r2 ^= r1; \
+ r1 ^= r0; \
+ r0 |= r4; \
+ r0 ^= r2; \
+ r3 ^= r1; \
+ r2 ^= r3; \
+ r3 &= r0; \
+ r3 ^= r4; \
+ r4 ^= r2; \
+ r2 &= r0; \
+ r4 = ~r4; \
+ r2 ^= r4; \
+ r4 &= r0; \
+ r1 ^= r3; \
+ r4 ^= r1; \
+}
+
+#define _I7(i, r0, r1, r2, r3, r4) { \
+ r4 = r2; \
+ r2 ^= r0; \
+ r0 &= r3; \
+ r2 = ~r2; \
+ r4 |= r3; \
+ r3 ^= r1; \
+ r1 |= r0; \
+ r0 ^= r2; \
+ r2 &= r4; \
+ r1 ^= r2; \
+ r2 ^= r0; \
+ r0 |= r2; \
+ r3 &= r4; \
+ r0 ^= r3; \
+ r4 ^= r1; \
+ r3 ^= r4; \
+ r4 |= r0; \
+ r3 ^= r2; \
+ r4 ^= r2; \
+}
+
+/* key xor */
+#define _KX(r, a, b, c, d, e) { \
+ a ^= k[4 * r + 0]; \
+ b ^= k[4 * r + 1]; \
+ c ^= k[4 * r + 2]; \
+ d ^= k[4 * r + 3]; \
+}
+
+#define _LK(r, a, b, c, d, e) { \
+ a = k[(8-r)*4 + 0]; \
+ b = k[(8-r)*4 + 1]; \
+ c = k[(8-r)*4 + 2]; \
+ d = k[(8-r)*4 + 3]; \
+}
+
+#define _SK(r, a, b, c, d, e) { \
+ k[(8-r)*4 + 4] = a; \
+ k[(8-r)*4 + 5] = b; \
+ k[(8-r)*4 + 6] = c; \
+ k[(8-r)*4 + 7] = d; \
+}
+
+static int _setup_key(const unsigned char *key, int keylen, int rounds, ulong32 *k)
+{
+ int i;
+ ulong32 t;
+ ulong32 k0[8] = { 0 }; /* zero-initialize */
+ ulong32 a, b, c, d, e;
+
+ for (i = 0; i < 8 && i < keylen/4; ++i) {
+ LOAD32L(k0[i], key + i * 4);
+ }
+ if (keylen < 32) {
+ k0[keylen/4] |= (ulong32)1 << ((keylen%4)*8);
+ }
+
+ t = k0[7];
+ for (i = 0; i < 8; ++i) {
+ k[i] = k0[i] = t = ROLc(k0[i] ^ k0[(i+3)%8] ^ k0[(i+5)%8] ^ t ^ 0x9e3779b9 ^ i, 11);
+ }
+ for (i = 8; i < 4*(rounds+1); ++i) {
+ k[i] = t = ROLc(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i, 11);
+ }
+ k -= 20;
+
+ for (i = 0; i < rounds/8; i++) {
+ _afterS2(_LK); _afterS2(_S3); _afterS3(_SK);
+ _afterS1(_LK); _afterS1(_S2); _afterS2(_SK);
+ _afterS0(_LK); _afterS0(_S1); _afterS1(_SK);
+ _beforeS0(_LK); _beforeS0(_S0); _afterS0(_SK);
+ k += 8*4;
+ _afterS6(_LK); _afterS6(_S7); _afterS7(_SK);
+ _afterS5(_LK); _afterS5(_S6); _afterS6(_SK);
+ _afterS4(_LK); _afterS4(_S5); _afterS5(_SK);
+ _afterS3(_LK); _afterS3(_S4); _afterS4(_SK);
+ }
+ _afterS2(_LK); _afterS2(_S3); _afterS3(_SK);
+
+ return CRYPT_OK;
+}
+
+static int _enc_block(const unsigned char *in, unsigned char *out, ulong32 *k)
+{
+ ulong32 a, b, c, d, e;
+ unsigned int i = 1;
+
+ LOAD32L(a, in + 0);
+ LOAD32L(b, in + 4);
+ LOAD32L(c, in + 8);
+ LOAD32L(d, in + 12);
+
+ do {
+ _beforeS0(_KX); _beforeS0(_S0); _afterS0(_LT);
+ _afterS0(_KX); _afterS0(_S1); _afterS1(_LT);
+ _afterS1(_KX); _afterS1(_S2); _afterS2(_LT);
+ _afterS2(_KX); _afterS2(_S3); _afterS3(_LT);
+ _afterS3(_KX); _afterS3(_S4); _afterS4(_LT);
+ _afterS4(_KX); _afterS4(_S5); _afterS5(_LT);
+ _afterS5(_KX); _afterS5(_S6); _afterS6(_LT);
+ _afterS6(_KX); _afterS6(_S7);
+
+ if (i == 4) break;
+
+ ++i;
+ c = b;
+ b = e;
+ e = d;
+ d = a;
+ a = e;
+ k += 32;
+ _beforeS0(_LT);
+ } while (1);
+
+ _afterS7(_KX);
+
+ STORE32L(d, out + 0);
+ STORE32L(e, out + 4);
+ STORE32L(b, out + 8);
+ STORE32L(a, out + 12);
+
+ return CRYPT_OK;
+}
+
+static int _dec_block(const unsigned char *in, unsigned char *out, ulong32 *k)
+{
+ ulong32 a, b, c, d, e;
+ unsigned int i;
+
+ LOAD32L(a, in + 0);
+ LOAD32L(b, in + 4);
+ LOAD32L(c, in + 8);
+ LOAD32L(d, in + 12);
+ e = 0; LTC_UNUSED_PARAM(e); /* avoid scan-build warning */
+ i = 4;
+ k += 96;
+
+ _beforeI7(_KX);
+ goto start;
+
+ do {
+ c = b;
+ b = d;
+ d = e;
+ k -= 32;
+ _beforeI7(_ILT);
+start:
+ _beforeI7(_I7); _afterI7(_KX);
+ _afterI7(_ILT); _afterI7(_I6); _afterI6(_KX);
+ _afterI6(_ILT); _afterI6(_I5); _afterI5(_KX);
+ _afterI5(_ILT); _afterI5(_I4); _afterI4(_KX);
+ _afterI4(_ILT); _afterI4(_I3); _afterI3(_KX);
+ _afterI3(_ILT); _afterI3(_I2); _afterI2(_KX);
+ _afterI2(_ILT); _afterI2(_I1); _afterI1(_KX);
+ _afterI1(_ILT); _afterI1(_I0); _afterI0(_KX);
+ } while (--i != 0);
+
+ STORE32L(a, out + 0);
+ STORE32L(d, out + 4);
+ STORE32L(b, out + 8);
+ STORE32L(e, out + 12);
+
+ return CRYPT_OK;
+}
+
+int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
+{
+ int err;
+
+ LTC_ARGCHK(key != NULL);
+ LTC_ARGCHK(skey != NULL);
+
+ if (num_rounds != 0 && num_rounds != 32) return CRYPT_INVALID_ROUNDS;
+ if (keylen != 16 && keylen != 24 && keylen != 32) return CRYPT_INVALID_KEYSIZE;
+
+ err = _setup_key(key, keylen, 32, skey->serpent.k);
+#ifdef LTC_CLEAN_STACK
+ burn_stack(sizeof(ulong32) * 14 + sizeof(int));
+#endif
+ return err;
+}
+
+int serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+{
+ int err = _enc_block(pt, ct, skey->serpent.k);
+#ifdef LTC_CLEAN_STACK
+ burn_stack(sizeof(ulong32) * 5 + sizeof(int));
+#endif
+ return err;
+}
+
+int serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+{
+ int err = _dec_block(ct, pt, skey->serpent.k);
+#ifdef LTC_CLEAN_STACK
+ burn_stack(sizeof(ulong32) * 5 + sizeof(int));
+#endif
+ return err;
+}
+
+void serpent_done(symmetric_key *skey)
+{
+ LTC_UNUSED_PARAM(skey);
+}
+
+int serpent_keysize(int *keysize)
+{
+ LTC_ARGCHK(keysize != NULL);
+
+ if (*keysize >= 32) { *keysize = 32; }
+ else if (*keysize >= 24) { *keysize = 24; }
+ else if (*keysize >= 16) { *keysize = 16; }
+ else return CRYPT_INVALID_KEYSIZE;
+ return CRYPT_OK;
+}
+
+int serpent_test(void)
+{
+#ifndef LTC_TEST
+ return CRYPT_NOP;
+#else
+ static const struct {
+ unsigned char key[32];
+ int keylen;
+ unsigned char pt[16], ct[16];
+ } tests[] = {
+ {
+ /* key */ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* keylen */ 32,
+ /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* ct */ {0xA2,0x23,0xAA,0x12,0x88,0x46,0x3C,0x0E,0x2B,0xE3,0x8E,0xBD,0x82,0x56,0x16,0xC0}
+ },
+ {
+ /* key */ {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* keylen */ 32,
+ /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* ct */ {0xEA,0xE1,0xD4,0x05,0x57,0x01,0x74,0xDF,0x7D,0xF2,0xF9,0x96,0x6D,0x50,0x91,0x59}
+ },
+ {
+ /* key */ {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* keylen */ 32,
+ /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* ct */ {0x65,0xF3,0x76,0x84,0x47,0x1E,0x92,0x1D,0xC8,0xA3,0x0F,0x45,0xB4,0x3C,0x44,0x99}
+ },
+ {
+ /* key */ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* keylen */ 24,
+ /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* ct */ {0x9E,0x27,0x4E,0xAD,0x9B,0x73,0x7B,0xB2,0x1E,0xFC,0xFC,0xA5,0x48,0x60,0x26,0x89}
+ },
+ {
+ /* key */ {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* keylen */ 24,
+ /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* ct */ {0x92,0xFC,0x8E,0x51,0x03,0x99,0xE4,0x6A,0x04,0x1B,0xF3,0x65,0xE7,0xB3,0xAE,0x82}
+ },
+ {
+ /* key */ {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* keylen */ 24,
+ /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* ct */ {0x5E,0x0D,0xA3,0x86,0xC4,0x6A,0xD4,0x93,0xDE,0xA2,0x03,0xFD,0xC6,0xF5,0x7D,0x70}
+ },
+ {
+ /* key */ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* keylen */ 16,
+ /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* ct */ {0x26,0x4E,0x54,0x81,0xEF,0xF4,0x2A,0x46,0x06,0xAB,0xDA,0x06,0xC0,0xBF,0xDA,0x3D}
+ },
+ {
+ /* key */ {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* keylen */ 16,
+ /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* ct */ {0x4A,0x23,0x1B,0x3B,0xC7,0x27,0x99,0x34,0x07,0xAC,0x6E,0xC8,0x35,0x0E,0x85,0x24}
+ },
+ {
+ /* key */ {0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* keylen */ 16,
+ /* pt */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* ct */ {0xE0,0x32,0x69,0xF9,0xE9,0xFD,0x85,0x3C,0x7D,0x81,0x56,0xDF,0x14,0xB9,0x8D,0x56}
+ }
+ };
+
+ unsigned char buf[2][16];
+ symmetric_key key;
+ int err, x;
+
+ for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
+ if ((err = serpent_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) {
+ return err;
+ }
+ if ((err = serpent_ecb_encrypt(tests[x].pt, buf[0], &key)) != CRYPT_OK) {
+ return err;
+ }
+ if (compare_testvector(buf[0], 16, tests[x].ct, 16, "SERPENT Encrypt", x)) {
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ if ((err = serpent_ecb_decrypt(tests[x].ct, buf[1], &key)) != CRYPT_OK) {
+ return err;
+ }
+ if (compare_testvector(buf[1], 16, tests[x].pt, 16, "SERPENT Decrypt", x)) {
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+ }
+
+ return CRYPT_OK;
+#endif
+}
+
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h
index 31aaeb85..f4cac7f0 100644
--- a/src/headers/tomcrypt_cipher.h
+++ b/src/headers/tomcrypt_cipher.h
@@ -165,6 +165,12 @@ struct idea_key {
};
#endif
+#ifdef LTC_SERPENT
+struct serpent_key {
+ ulong32 k[33*4];
+};
+#endif
+
typedef union Symmetric_key {
#ifdef LTC_DES
struct des_key des;
@@ -226,6 +232,9 @@ typedef union Symmetric_key {
#endif
#ifdef LTC_IDEA
struct idea_key idea;
+#endif
+#ifdef LTC_SERPENT
+ struct serpent_key serpent;
#endif
void *data;
} symmetric_key;
@@ -840,6 +849,16 @@ int idea_keysize(int *keysize);
extern const struct ltc_cipher_descriptor idea_desc;
#endif
+#ifdef LTC_SERPENT
+int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
+int serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey);
+int serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey);
+int serpent_test(void);
+void serpent_done(symmetric_key *skey);
+int serpent_keysize(int *keysize);
+extern const struct ltc_cipher_descriptor serpent_desc;
+#endif
+
#ifdef LTC_ECB_MODE
int ecb_start(int cipher, const unsigned char *key,
int keylen, int num_rounds, symmetric_ECB *ecb);
diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h
index a381e4be..0fd06b00 100644
--- a/src/headers/tomcrypt_custom.h
+++ b/src/headers/tomcrypt_custom.h
@@ -203,6 +203,7 @@
#define LTC_MULTI2
#define LTC_CAMELLIA
#define LTC_IDEA
+#define LTC_SERPENT
/* stream ciphers */
#define LTC_CHACHA
diff --git a/src/misc/crypt/crypt.c b/src/misc/crypt/crypt.c
index 6526a9c0..7084e6a5 100644
--- a/src/misc/crypt/crypt.c
+++ b/src/misc/crypt/crypt.c
@@ -124,6 +124,9 @@ const char *crypt_build_settings =
#endif
#if defined(LTC_IDEA)
" IDEA\n"
+#endif
+#if defined(LTC_SERPENT)
+ " Serpent\n"
#endif
"Stream ciphers built-in:\n"
#if defined(LTC_CHACHA)
diff --git a/src/misc/crypt/crypt_register_all_ciphers.c b/src/misc/crypt/crypt_register_all_ciphers.c
index 55b46602..6c539997 100644
--- a/src/misc/crypt/crypt_register_all_ciphers.c
+++ b/src/misc/crypt/crypt_register_all_ciphers.c
@@ -96,6 +96,9 @@ int register_all_ciphers(void)
#endif
#ifdef LTC_IDEA
REGISTER_CIPHER(&idea_desc);
+#endif
+#ifdef LTC_SERPENT
+ REGISTER_CIPHER(&serpent_desc);
#endif
return err;
}
diff --git a/src/misc/crypt/crypt_sizes.c b/src/misc/crypt/crypt_sizes.c
index 4662817c..9d73185f 100644
--- a/src/misc/crypt/crypt_sizes.c
+++ b/src/misc/crypt/crypt_sizes.c
@@ -125,6 +125,9 @@ static const crypt_size _crypt_sizes[] = {
#ifdef LTC_RC6
_SZ_STRINGIFY_S(rc6_key),
#endif
+#ifdef LTC_SERPENT
+ _SZ_STRINGIFY_S(serpent_key),
+#endif
#ifdef LTC_SKIPJACK
_SZ_STRINGIFY_S(skipjack_key),
#endif
diff --git a/tests/test.c b/tests/test.c
index 0ce81d22..8d938abd 100644
--- a/tests/test.c
+++ b/tests/test.c
@@ -180,6 +180,9 @@ static void _unregister_all(void)
#ifdef LTC_IDEA
unregister_cipher(&idea_desc);
#endif
+#ifdef LTC_SERPENT
+ unregister_cipher(&serpent_desc);
+#endif
#ifdef LTC_TIGER
unregister_hash(&tiger_desc);