Baratski has asked for the wisdom of the Perl Monks concerning the following question:

Hello. Is there a faster way to read and encrypt a file using the Twofish_PP module? I seem to be stuck reading 16 byte blocks. With the large (*MB) files that I want to work with, this can be a tiring waiting process. Am I way off here? Can anyone help?

Replies are listed 'Best First'.
Re: Twofish_PP.pm
by tachyon (Chancellor) on May 23, 2004 at 23:59 UTC

    Crypt::Twofrish_PP is pure perl which is fine for portability but inevitably slow. Unless you have a very good reason no to (ie there is no way in hell you can find a C compiler for your OS) use Crypt::Twofish2. You may want to use Crypt::CBC to do the cipher block chaining but Twofish2 supports CBC mode natively (unlike Twofish). The internal Twofish2 CBC is probably faster but it does not handle the padding for you as Crypt::CBC does.

    Note there is a Crypt::Twofish module but it is slower than the implementation in Crypt::Twofish2 which "implements the twofish cipher in a less braindamaged (read: slow and ugly) way than the existing Crypt::Twofish module."

    cheers

    tachyon

Re: Twofish_PP.pm
by graff (Chancellor) on May 24, 2004 at 00:05 UTC
    You can use the "read" function to pull in any reasonable number of bytes you like into a scalar, and loop over substrings of the scalar to build up the corresponding number of output cipher bytes and print that to output.

    I don't know enough about Twofish_PP (or other modules or conventions associated with this algorithm) to say what sort of formatting issues are assumed. Does the fact that it only deals with 16 bytes at a time mean that the output should be structured as lines of 16 characters terminated by newlines? Does this matter?

    In any case, you also need to be careful when you reach the end-of-file, because chances are good the file size won't be a multiple of 16, and you'll need to pad the string. For example (not tested):

    open( IN, "big.file" ) or die $!; while ( read( IN, my $cleartxt, 8192 ) > 0 ) { my $cryptxt = ""; while ( $cleartxt ) { $tocrypt = substr( $cleartxt, 0, 16 ); $cleartxt = substr( $cleartxt, 16 ); if ( length( $tocrypt ) != 16 ) { $tocrypt .= " " x ( 16 - length( $tocrypt )); } # do what you need with Twofish to encrypt, and # append result to $cryptxt } print $cryptxt; }

      I don't know enough about Twofish_PP (or other modules or conventions associated with this algorithm) to say what sort of formatting issues are assumed. Does the fact that it only deals with 16 bytes at a time mean that the output should be structured as lines of 16 characters terminated by newlines? Does this matter?

      There are a number of ciphers that fall into the category of block ciphers. They encrypt a chunk (block) of plain text at a time. To encrypt a plaintext string that is longer than this block size you chunkify the plain text into chunks of the correct length, encrypt each chunk and join the resultant ciphertext blocks together. This is called cipher block chaining and is implemented in Crypt::CBC. You do need to pad a plaintext string less than block size to encrypt it. There are a number of different ways to pad. Read the Crypt::CBC docs for a nice discussion.

      Crypt::DES, Crypt::DES_EDE3, Crypt::IDEA, Crypt::Blowfish, Crypt::Twofish and Crypt::Rijndael are all modules that implement block ciphers and need Crypt::CBC or the equivalent to encode arbitratily long plaintexts.

      cheers

      tachyon