Click here to Skip to main content
Click here to Skip to main content

DES and Triple DES Implementation in VB.NET

By , 28 Jan 2010
 

Introduction

I was doing a lot of small cryptographic operations on a slow CPU, and wasn't happy with the performance. Since I was only working with a few dozen bytes, I suspected that the problem was the .NET cryptographic service instantiation overhead, and that turned out to be the case.

Instead of learning the CyptoAPI and hoping that it would not have the same costs, I ported a C++ implementation by Christophe Devine (included in the zip) that would have no overhead costs.

Using the Code

I have included a demo that uses the DES class and the .NET crypto classes. It shows that the outputs are identical. There are also a couple benchmark buttons.

Using the class is very simple. First, create the class:

Dim myDes As New DES()

Then call the sub:

myDes.encrypt_des(key8, input, input.Length, output, outputLength)

The mode is CBC (Cipher Block Chaining).

For the demo, copy the output back to the input after encryption to decrypt. The input must be a multiple of 8 (no padding is added for you).

No exception handling is done by the DES class. If there were no errors, there will be no exception and it will put the number of bytes processed into the outputLength integer, which would be the same as input.Length.

There was no use of TransformFinalBlock for my purpose.

The DES class also works fine on the Compact Framework.

Demo Screenshots

Points of Interest

As you can see by the benchmarks, in a release configuration, the instantiation benchmark (a lot of small ops) is about 14 times faster than .NET (25 times faster on some systems), but the data benchmark (16 megs) is about 4 times slower, so this class is only useful for a lot of small ops.

VB.NET makes all the math stuff quite unsightly because of the whitespace enforcement and the removing of leading 0s from the hex constants. (Update: Found the option in Visual Studio to remove automatic formatting (Tools > Options > Text Editor > Basic > VB Specific.)

Two main things tripped me up:

  • Why wasn't &HFFFFFFFF a valid UInt32? Because hex constants are treated as Int32 by default, unless you add UI to the end: &HFFFFFFFFUI.
  • I needed to convert bytes to UInt32 before left shifting them into a UInt32 (GET_UINT32 sub). This CUInt bug cost me about 4 hours.

Since VB.NET doesn't have a concept of #define, I modified those translated subs to accept another variable as the inherited variable. And because of the different ways of working with arrays, I added an nSK enumerator to some subs.

This is GPL because Christophe's license is GPL.

Porting Example

People who are interested in porting C++ to VB.NET should also find this code useful. I can't write C++ very well but I can understand it.

Here are a couple porting examples:

/* DES round macro */

#define DES_ROUND(X,Y)                          \
{                                               \
    T = *SK++ ^ X;                              \
    Y ^= SB8[ (T      ) & 0x3F ] ^              \
         SB6[ (T >>  8) & 0x3F ] ^              \
         SB4[ (T >> 16) & 0x3F ] ^              \
         SB2[ (T >> 24) & 0x3F ];               \
                                                \
    T = *SK++ ^ ((X << 28) | (X >> 4));         \
    Y ^= SB7[ (T      ) & 0x3F ] ^              \
         SB5[ (T >>  8) & 0x3F ] ^              \
         SB3[ (T >> 16) & 0x3F ] ^              \
         SB1[ (T >> 24) & 0x3F ];               \
}
'DES round macro
'init nSK as -1
Private Sub DES_ROUND(ByRef X As UInt32, ByRef Y As UInt32, _
	ByRef T As UInt32, ByRef SK() As UInt32, ByRef nSK As Integer)
    nSK += 1
    T = SK(nSK) Xor X
    Y = Y Xor SB8((T      ) And &H3FUI) Xor _
              SB6((T >>  8) And &H3FUI) Xor _
              SB4((T >> 16) And &H3FUI) Xor _
              SB2((T >> 24) And &H3FUI)

    nSK += 1
    T = SK(nSK) Xor ((X << 28) Or (X >> 4))
    Y = Y Xor SB7((T      ) And &H3FUI) Xor _
              SB5((T >>  8) And &H3FUI) Xor _
              SB3((T >> 16) And &H3FUI) Xor _
              SB1((T >> 24) And &H3FUI)
End Sub
// DES 64-bit block encryption/decryption

void des_crypt( uint32 SK[32], uint8 input[8], uint8 output[8] )
{
    uint32 X, Y, T;

    GET_UINT32( X, input, 0 );
    GET_UINT32( Y, input, 4 );

    DES_IP( X, Y );

    DES_ROUND( Y, X );  DES_ROUND( X, Y );
    DES_ROUND( Y, X );  DES_ROUND( X, Y );
    DES_ROUND( Y, X );  DES_ROUND( X, Y );
    DES_ROUND( Y, X );  DES_ROUND( X, Y );
    DES_ROUND( Y, X );  DES_ROUND( X, Y );
    DES_ROUND( Y, X );  DES_ROUND( X, Y );
    DES_ROUND( Y, X );  DES_ROUND( X, Y );
    DES_ROUND( Y, X );  DES_ROUND( X, Y );

    DES_FP( Y, X );

    PUT_UINT32( Y, output, 0 );
    PUT_UINT32( X, output, 4 );
}
'DES 64-bit block encryption/decryption

Private Sub des_crypt(ByRef SK() As UInt32, _
	ByRef input() As Byte, ByRef output() As Byte)
    Dim X, Y, T As UInt32

    GET_UINT32(X, input, 0)
    GET_UINT32(Y, input, 4)

    DES_IP(X, Y, T)

    Dim nSK As Integer = -1
    DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
    DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
    DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
    DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
    DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
    DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
    DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)
    DES_ROUND(Y, X, T, SK, nSK) : DES_ROUND(X, Y, T, SK, nSK)

    DES_FP(Y, X, T)

    PUT_UINT32(Y, output, 0)
    PUT_UINT32(X, output, 4)
End Sub

History

  • 2010.01.27
    • Initial post
  • 2010.01.27
    • Prettied up code by adding whitespace and leading 0s
    • Added porting example to article

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

About the Author

Ted Ehrich
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Questionhelpmembera7medelmasry17 Jun '12 - 1:14 
GeneralIVmemberMember 14625785 Apr '10 - 9:55 
GeneralRe: IVmemberTed Ehrich6 Apr '10 - 4:45 
GeneralRe: IV [modified]memberibalthasar22 Apr '11 - 19:07 
GeneralVB quirksmembersupercat927 Jan '10 - 5:34 
GeneralRe: VB quirksmemberTed Ehrich28 Jan '10 - 13:17 
GeneralRe: VB quirksmembersupercat929 Jan '10 - 7:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 28 Jan 2010
Article Copyright 2010 by Ted Ehrich
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid