From .NET 1.0 to .NET 9.0

Prof Bill Buchanan OBE FRSE
4 min readOct 26, 2024

Wow! How time flies! It just seems like yesterday when I installed my first .NET 1.1 program and was then wowed by the power of .NET 2.0. And, I thought that the world of software was going to completely change with .NET 3. And, so now, as I write this, I have compiled my first .NET 9.0 program [here]:

I started with .NET 1.1 and developed a Windows program for my Cisco network simulators, and was amazed when I could port all of my C# code over to create an ASP.NET C# application.

For many, .NET is a Microsoft Windows framework, but it’s actually open source and available on Mac OSX and Linux. In fact, I develop my Web site on a Mac, and using .NET. While I use Python, Rust and Golang for coding cryptography, I spend a great deal of time writing C# code.

Unfortunately, .NET has just not kept up with modern cryptography, and it can take years for it to adopt the latest standards. But, for me, .NET/C# is the most natural programming environment of all the programming languages; while it doesn’t give you the speed of C++ and Golang, it is fairly robust and will work well on most systems.

So, what’s new about .NET 9.0? Well, it’s got a new cross-platform integration for ML models [here]:

But, to me, .NET has kinda got stuck in a rut. While the big bang of .NET 3.0 tried to change the world of software towards WPF, it just never really took off, and never really led the world of software after it.

My .NET 9.0 app

In the following code, I build for .NET 9.0, but don’t actually use any of its features. The great thing with .NET, though, is that it is all backwards compatible, so something that runs in .NET 2.0 will run in .NET 9.0. And, so, last year, Bouncy Castle for C# added SPHINCS+ and a core part of this is the addition of Haraka256 and Haraka512 [here]:

So, now let’s code for this, and also integrate the test vectors from this paper [here]:

We can create a Dotnet console project for .NET 9.0 with:

dotnet new console --framework net9.0

First, we install the Bouncy Castle library:

dotnet add package BouncyCastle.Cryptography --version 2.4.0

Next, some code [here]:

namespace AES
{
using System.Security.Cryptography;
using Org.BouncyCastle.Crypto.Digests;
class Program
{
static void Main(string[] args)
{
string str="hello";
if (args.Length >0) str=args[0];
try {
Console.WriteLine ("Message:\t{0}\n",str);

var h1 = new Haraka256Digest();
var test=Convert.FromHexString("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f");
h1.BlockUpdate(test, 0, test.Length);

var hash1=new byte[h1.GetDigestSize()];
h1.DoFinal(hash1, 0);
Console.WriteLine ("Haraka256:\t\t{0}\n Input (hex): [{1}]\n",Convert.ToHexString(hash1),Convert.ToHexString(test));
var h2 = new Haraka256Digest();
str=str.PadRight(32, (char)0);

h2.BlockUpdate(System.Text.Encoding.UTF8.GetBytes(str), 0, str.Length);
var hash2=new byte[h2.GetDigestSize()];
h2.DoFinal(hash2, 0);
Console.WriteLine ("Haraka256:\t\t{0}\n Input: [{1}]\n\n",Convert.ToHexString(hash2),str);
var h3 = new Haraka512Digest();
var test2=Convert.FromHexString("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f");
h3.BlockUpdate(test2, 0, test2.Length);

var hash3=new byte[h3.GetDigestSize()];
h3.DoFinal(hash3, 0);
Console.WriteLine ("Haraka512:\t\t{0}\n Input (hex): [{1}]\n",Convert.ToHexString(hash3),Convert.ToHexString(test2));
var h4 = new Haraka512Digest();
str=str.PadRight(64, (char)0);

h4.BlockUpdate(System.Text.Encoding.UTF8.GetBytes(str), 0, str.Length);
var hash4=new byte[h4.GetDigestSize()];
h4.DoFinal(hash4, 0);
Console.WriteLine ("Haraka512:\t\t{0}\n Input: [{1}]\n",Convert.ToHexString(hash4),str);



} catch (Exception e) {
Console.WriteLine("Error: {0}",e.Message);
}
}
}

A sample run is:

A sample run is [here]:
Message: hello
Haraka256: 8027CCB87949774B78D0545FB72BF70C695C2A0923CBD47BBA1159EFBF2B2C1C
Input (hex): [000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F]

Haraka256: 99DA89DE939EC4DB4A20D58235AFA906F3C9649663A80A55DB6C88AD6BEAAC4C
Input: [hello ]
Haraka512: BE7F723B4E80A99813B292287F306F625A6D57331CAE5F34DD9277B0945BE2AA
Input (hex): [000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F]
Haraka512: 964597082F33CDADBBBE99C3913BB8B589FD5A7C9999618D62EAF8F2E43F77B0
Input: [hello ]

We can see the two test vectors work and where an input of 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F gives a hash of 0x8027CCB87949774B78D0545FB72BF70C695C2A0923CBD47BBA1159EFBF2B2C1C, and 0x000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F gives a hash of 0xBE7F723B4E80A99813B292287F306F625A6D57331CAE5F34DD9277B0945BE2AA and which ties-up with the test vector:

Conclusions

Hello, .NET 9.0.

--

--

Prof Bill Buchanan OBE FRSE
Prof Bill Buchanan OBE FRSE

Written by Prof Bill Buchanan OBE FRSE

Professor of Cryptography. Serial innovator. Believer in fairness, justice & freedom. Based in Edinburgh. Old World Breaker. New World Creator. Building trust.

No responses yet