VBCorLib for VB6

Sunday, August 27, 2006

First Hash Algorithm

Well after finishing all of the symmetrical cipher algorithms I decided to begin the journey into the hash algorithms. My first stop was the SHA-1 (Secure Hash Algorithm). The first class representation was the SHACryptoServiceProvider class which is just a wrapper around the CryptoAPI calls that support the hashing within Windows.

I began my journey by learning how the CryptoAPI worked when hashing data. After a bit of digging in the MSDN I found what I was looking for and a short time later I was succeeding with generating SHA-1 hashes. Once I was comfortable with that, it was a fairly easy class to implement. I used .NET to generate a series of plain text and hashed values that I would test the class with. It went pretty smoothly. Then I noticed there was the SHAManaged class.

I realized that I was going to need to actually implement the SHA-1 algorithm, so I went searching for the rfc and sure enough there it was; RFC 3174. After reading through the workings a couple of times I noticed it came with an implementation in C. I studied the code for a bit and decided it shouldn't be an overwhelming implementation.

I coded up the implementation in VB, checking the example and re-reading the RFC. I ran it against one test, a 1-byte array with the value zero. Overflow! Uhhhh... well after going around I realized that the example used unsigned integers. Now I'm not the smartest guy, but I'm pretty sure VB6 doesn't have those. I needed to do unsigned addition. It's very complicated when you try to fake it in VB6, so I resorted to some ASM from Matt Curland and expanded the Helper class to do the unsigned addition. Once I got all that working and the Endian swapping correct, it worked like a charm.

The SHA-1 algorithm is pretty straigh forward, though I'm pretty sure the remaining algorithms will be reminding how easy I had it this time.

-Kelly

Tuesday, August 15, 2006

Rijndael Speed Update

After digging deep into optimizing the Rijndael implementation, I succeeded in equaling the speed of .NET in some configurations and running a close 2nd in the others.

The original test configuration was using a 3meg file and the ECB cipher mode, which is basically a raw encryption on the individual blocks. Original scores were .NET @ 147ms and VBCorLib @ 302ms. After the massive optimizations, I brought VBCorLib to 172ms. That is a tremendous increase in performance.

I further tried an optimized 256bit block size version. The results were .NET @ 183ms and VBCorLib @ 183ms. A dead heat. Even using the heaviest cipher mode of CFB, VBCorLib is only 50ms behind on a 3meg file at 435ms to 385ms for .NET.

So with enough tweaking, I got more than what I was originally asking for. VB6 seems to still have some kick left.

-Kelly

Monday, August 14, 2006

Rijndael

Well, I've finished implementing all of the Rijndael classes. It was quite a learning process. Ok, I'm not completely done. All of the classes are implemented, but I did a couple a tests and figured out how to optimize it by 30%.

I got the code all the way down to a single shared cipher routine among all block sizes and table look ups. It's a very small and elegant routine, but requires more array accesses than a flattened special version for each blocksize and cipher direction. Unfortunately this massive decrease in code size increased the time tests by 50%.

I'm going to flatten out all of the combinations to remove roughly 1/3 of all array access calls. My tests show an encryption using 128bit blocks and keys with a cipher mode of ECB takes twice as long as the .NET version. Now I know twice the time isn't the greatest, but in VB terms I believe it's excellent compared to .NET. It all comes down to the lack of direct memory manipulation in VB.

On my machine (2.0 ghz Dothan) a 3 meg array took .NET 147ms and VBCorLib took 302ms. This was using the 128bit block and key size in ECB mode.

So the end is wrapping up for the symmetric ciphers and I should be heading towards the hashes next. That will be an all new adventure!

-Kelly

Tuesday, August 01, 2006

Cryptography

Cryptography is a very interesting study at the least. I've managed to learn the CryptoAPI functions to implement the DES, TripleDES, and RC2 cryptographic methods. Now I've been messing around with the Rijndael algorithm. It's based on the AES cipher, but allows for larger blocks to be handled. I haven't started to learn about the hash functions. I'm sure they will be another adventure.

Otherwise, things are coming along fine. The tests for these routines are quite long as I read in a file with all the required information to perform encryption/decryption. I do many combinations for the parameters making for large amounts of test data. But, I think it's important that these routines are solid on the first try.

Also, I'm seriously considering breaking binary compatibility. There are some updates that are needling me. I'm thinking that since the source code is downloaded the most then everyone is probably compiling it themselves, meaning there is no binary compatibility anyways. So I'm really thinking about cleaning things up and updating some interfaces. Well see how it goes.

-Kelly