1

I need to cipher an array of unsigned char (16 byte long) with Serpent and Twofish. I use two libraries -write in c- from the official website. I try to use them, but the ciphertext that i will obtain isn’t correct. For checking I use this site. I don't understand where is the mistake.
My code is:

keyInstance keyTwofish;
cipherInstance cipherTwofish;
unsigned char *buffer_out_twofish;

char path_file_twofish[DIM];
...
//Twofish
if(cipherInit(&cipherTwofish,MODE_ECB,NULL)!=TRUE)
{
   perror("[ERROR] Function module02: makeKey.\n");
   return 0;
}
//key_dim*8=128 and key is an unsigned char key [16] that contain key
makeKey(&keyTwofish, DIR_ENCRYPT, key_dim*8, key);
…
//Buffer in is unsigned char buffer_in[16] contain plaintext
//byte_for_file=16 than byte_for_file*8=128
//Buffer out is unsigned char buffer_out_twofish[16]
blockEncrypt(&cipherTwofish, &keyTwofish, buffer_in, byte_for_file*8, buffer_out_twofish);

For Serpent is the same implementation.

When I print a sizeof of variable’s type the result is:

Size of Char: 1
Size of Integer: 4
Size of Long: 8

And when I do:

printf("\nPrint Char Array: ");
for (int j = 0; j < byte_for_file; ++j)
   printf("%x ", buffer_in[j]);
printf("\nPrint long Array: ");
test(buffer_in, byte_for_file);

where

void test (unsigned long * a, int b)
{
   for (int i = 0; i < b/sizeof(long); ++i)
      printf("%lx ", a[i]);
}

I get this:

Print Char Array: 87 ae bd 58 71 75 1d 36 43 ab 1d ef 69 f5 54 d7 
Print long Array: 361d757158bdae87 d754f569ef1dab43 
  • You are using the reference implementation and you test them *using a random website* ? Don't you think that is the wrong way around? What about comparing against the [Twofish](https://www.schneier.com/code/ecb_ival.txt) and [Serpent](http://www.cs.technion.ac.il/~biham/Reports/Serpent/Serpent-128-128.verified.test-vectors) test vectors? – Maarten Bodewes Apr 02 '15 at 16:48
  • @Laura Renoldi: Not sure which implementation you use, but here: http://cpansearch.perl.org/src/MLEHMANN/Crypt-Twofish2-1.02/twofish.c, for example - it says makeKey should receive key encoded as hex string. So if your key is say 255 255 255 you should pass "FFFFFF". – Giorgi Moniava Apr 02 '15 at 16:54
  • Note that if I input everything as hexadecimals on the site (as you should) I do get the correct value for the given test vectors, both for twofish as for serpent (128 bit keys). Note that the key for serpent starts with an 8 instead of a zero. – Maarten Bodewes Apr 02 '15 at 16:54
  • @MaartenBodewes I think that my cipher text is wrong not only for that site, also because for high number of plaintext all cipher text are like this: xxxx xxxx 0000 0000 xxxx xxxx 0000 0000, where xx is hex number. – Laura Renoldi Apr 02 '15 at 18:14
  • @Giorgi Yes, my key is encoded as hex string. – Laura Renoldi Apr 02 '15 at 18:15
  • Hmm, that's hard to answer without the code, but if it is C it may be a difference with regards to word size or endianess; I would not be surprised if it is. – Maarten Bodewes Apr 02 '15 at 18:18
  • it's also not easy to say- unless you show what you pass *in code* to those methods vs what you type on site – Giorgi Moniava Apr 02 '15 at 19:02
  • @MaartenBodewes the implementations that I use are the official ones, for serpent: [link](http://www.cl.cam.ac.uk/~rja14/serpent.html) and for twofish: [link](https://www.schneier.com/twofish-download.html) - I’m a new user and i can’t insert more than 1 link in my question-. I also think that this is a possible problem with word size and endianess. I've added two examples to my question to understand if this is effectively my problem. – Laura Renoldi Apr 02 '15 at 20:18
  • If I read the NIST API correctly, doesn't the key need to be specified in hexadecimals? It's pretty unclear what the function should accept, but it seems unsigned char isn't it. – Maarten Bodewes Apr 02 '15 at 20:58

1 Answers1

0

The Implementation you use expects a key as keyLen/4 ASCII characters representing the hex values for the key.

So you should change the line:

makeKey(&keyTwofish, DIR_ENCRYPT, key_dim*8, key);

into

makeKey(&keyTwofish, DIR_ENCRYPT, strlen(key)*4, key);

Because Hexvalues like eg. 0x30313233343536373839 are not interpreted as 0123456789 but as 0x0300030103020303030403050306030703080309 and the Key 0123456789 would be interpreted as 0x00010203040506070809.