Click here to Skip to main content
Click here to Skip to main content
Go to top

DES and Triple DES Implementation in VB.NET

, 28 Jan 2010
Rate this:
Please Sign up or sign in to vote.
A simple DES/Triple DES implementation in VB.NET that doesn't have instantiation overhead.

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)

Share

About the Author

Ted Ehrich

United States United States
No Biography provided

Comments and Discussions

 
Questioninput data is not multiple of 8 Pinmembertetoeko24-Jul-13 7:44 
Questionhelp Pinmembera7medelmasry17-Jun-12 1:14 
GeneralIV PinmemberMember 14625785-Apr-10 9:55 
GeneralRe: IV PinmemberTed Ehrich6-Apr-10 4:45 
GeneralRe: IV [modified] Pinmemberibalthasar22-Apr-11 19:07 
GeneralVB quirks Pinmembersupercat927-Jan-10 5:34 
GeneralRe: VB quirks PinmemberTed Ehrich28-Jan-10 13:17 
GeneralRe: VB quirks Pinmembersupercat929-Jan-10 7:11 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140926.1 | Last Updated 28 Jan 2010
Article Copyright 2010 by Ted Ehrich
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid