# Serpent intermediate rounds differs from example code, but result is still correct, is it a problem?

Through great pain and suffering, I've been able to successfully implement Serpent. For example, when using the key 00112233445566778899aabbccddeeff, and encrypting the plaintext 0123456789abcdeffedcba9876543210, the result is 929dd890dcc881c9a7d8b94b0aa0bad5.

However, when I compare my internal rounds to those of the example implementation, there are differences in all rounds except the final one, which is correct. Notice the difference too, my last round is the ciphertext, but it's not the case for the example.

Is that difference a problem, or not ? All other plaintext and keys output the correct ciphertext, so it's correct. Will that difference mean any issue for implementing different modes, is it an attack vector ?

For the key 00112233445566778899aabbccddeeff, and encrypting the plaintext 0123456789abcdeffedcba9876543210 I obtain:

R[00]=763c678fe817625f538ba6e05b920db9
R[01]=3d2fdec36f875b312c3b4dff7bdfd128
R[02]=bd9e4ae53f686b1da714cf4a9d2e6868
R[03]=8acc4503741256b9225d581711eacf4d
R[04]=d765bcb8c133fea981064ec5eb09f56f
R[05]=baa2fd5c5628e8445e79ee7ea5cf9cb5
R[06]=25023893d3789b727be0440a5cfa39e3
R[07]=2d93f0484f3dbc800c4537fd742b62f5
R[08]=6f36c03ab9a62671d418cfb487d45fe7
R[09]=b3d6210bf3bbd2d702a208ef25cfdbe0
R[10]=5c9af1c0d10ce8a3818b22f17f0e097b
R[11]=efb1e65f22e8e68826ce7db29492e5e2
R[12]=97443a983133cbe233b9fef910b96bce
R[13]=5f827660c8f7a489092ca20651ba18a4
R[14]=0a415d75cfe2d976980ac48c41fc5efd
R[16]=ef002fc254c43e7990da5474d7879461
R[17]=d7b61d1a39aee4c8a14cc4b1d8dc4226
R[18]=7b8cdd49398741c0d0ae6e095812b6a6
R[19]=34d5f60fd24717e0c4dcd1214e502833
R[20]=de5ba6aa229feebc9f34f62001ddc55f
R[21]=9fbd25551344a04b6a6744f9c2739b5a
R[22]=4f25a8e314d8ca550d99451ed02d1e67
R[23]=51880459ded93b04a54327624424c37d
R[24]=da4457c92effe0fe6956a25daa628f22
R[25]=82c6ef91a38269c14ca8b3b8c0f988f1
R[26]=cd2ecf8555c299fc37a7d9df59359b58
R[27]=cf8e350c9738ce9a45b63843eb175c00
R[28]=779285520a7e22fdbb4d7a83984944b2
R[29]=c66612592163cb3c0c83d2a4801ebe86
R[30]=c5be4758e4241f04383888de8aa432d6


And the example implementation is supposed to output this:

R[0]=4fcb58b3308dac762ce01be9b635dccd
R[1]=05f9fe5d51a3bdff9f0deac7aa7632ae
R[3]=846584a19b16ba521f063d59414653af
R[4]=fd18189f08c41a6dd7ddef61e3d8d317
R[5]=969ea7e193e27193fee9fb281e3baf21
R[6]=47a7396e37755090429dd245955c20f9
R[7]=0591ef4c825c569fc9fe46327b33a303
R[8]=7ac6cb9d51cb2dc0ab41377335fe8395
R[9]=c4dc01edf96c59f5558530597734a6ee
R[10]=6d1d9917a008f5b2cce85029eb731057
R[11]=98e18be8f6c96238dff22fc3793ac8b8
R[12]=806f08ae3877384767baf2f5f76ab152
R[13]=4d09e88bd47536d468e91ca058904324
R[14]=6502e4c55d5131686f0ddb1c3ddd3f49
R[15]=f9e837971189310c3a3f3189ed624dd3
R[16]=bd878d997602253112c7cfc88f764285
R[17]=b96d588ed3c97fc067488e18643ac192
R[18]=2bcfd08ce021ae749e39ab3c5c10a11a
R[19]=678c1b50af0b2e4caa9e1cc64471889b
R[20]=a84aaae3592fd7cdf7e24fe1c1e5d591
R[21]=932ca8fc87b98e3b52c11a192f2b785e
R[22]=1905ae8a6496790bc681d3528d9627bd
R[23]=6d2c474ac614c12611644a770b399529
R[24]=9a78f4d24f564e747c6819b9ce56e65a
R[25]=d34022c4f93138c1bce2d8aef53b200d
R[26]=8d279e2f64b18be3fa07f89fe7477e2a
R[27]=db149edfa067cbb145ab7d484204c862
R[28]=38ab78ea874c76c3836229687c5d44b6
R[29]=98402a842cc119f6761b51f4386cc718
R[31]=e42c56b2f61ae808f83bb016d7096127

• It is possible that those results are for an implementation not using the bit-slice mode, hence the difference in intermediate result. However I do not have the time to properly test this hypothesis. – user96649 May 10 at 8:39

To check if it is a bitslice issue, we can look at a round output, this is round 1 from the example:

0000 0101 1111 1001 1111 1110 0101 1101 0101 0001 1010 0011 1011 1101 1111 1111 1001 1111 0000 1101 1110 1010 1100 0111 1010 1010 0111 0110 0011 0010 1010 1110


And yours:

0011 1101 0010 1111 1101 1110 1100 0011 0110 1111 1000 0111 0101 1011 0011 0001 0010 1100 0011 1011 0100 1101 1111 1111 0111 1011 1101 1111 1101 0001 0010 1000


To check for bitslicing, start selecting every 4th bit in one of them (starting at 0), then compare it to the first 32-bit word of the other

As we can see, every 4th bit of the example does indeed match the first 32-bits of your output. I also spot checked the final 16 bits which also match. I suspect that if you keep going with that round, all bits match, as would the rest of the rounds. A rapid way to check if that is probably the case is to convert to binary then use an iterative counter to count the number of 1 bits per round.