Click here to Skip to main content
15,888,984 members
Articles / Programming Languages / Visual Basic

DES and Triple DES Implementation in VB.NET

Rate me:
Please Sign up or sign in to vote.
4.38/5 (5 votes)
28 Jan 2010GPL32 min read 53.5K   4K   16   9
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:

VB.NET
Dim myDes As New DES()

Then call the sub:

VB.NET
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

Image 1

Image 2

Image 3

Image 4

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:

C++
/* 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 ];               \
}
VB.NET
'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
C++
// 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 );
}
VB.NET
'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)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionPlease Help Me Pin
Member 135808864-Jun-18 21:28
Member 135808864-Jun-18 21:28 
Could it be that the messages and the entered keys are free, so for keys and messages it's up to the user to include anything in text form?

Questioninput data is not multiple of 8 Pin
tetoeko24-Jul-13 7:44
tetoeko24-Jul-13 7:44 
Questionhelp Pin
a7medelmasry17-Jun-12 1:14
a7medelmasry17-Jun-12 1:14 
GeneralIV Pin
Member 14625785-Apr-10 9:55
Member 14625785-Apr-10 9:55 
GeneralRe: IV Pin
Ted Ehrich6-Apr-10 4:45
Ted Ehrich6-Apr-10 4:45 
GeneralRe: IV [modified] Pin
ibalthasar22-Apr-11 19:07
ibalthasar22-Apr-11 19:07 
GeneralVB quirks Pin
supercat927-Jan-10 5:34
supercat927-Jan-10 5:34 
GeneralRe: VB quirks Pin
Ted Ehrich28-Jan-10 13:17
Ted Ehrich28-Jan-10 13:17 
GeneralRe: VB quirks Pin
supercat929-Jan-10 7:11
supercat929-Jan-10 7:11 

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

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