Goldilocks and Cybersecurity

Sitting comfortably? Well, once upon a time, there were three bears, and they made some porridge. But the porridge was too hot, so they…

Goldilocks and Cybersecurity

Sitting comfortably? Well, once upon a time, there were three bears, and they made some porridge. But the porridge was too hot, so they went for a walk in the woods. Blah, blah, blah, and the rest is history.

And so what has Goldilocks and the Three Bears got to do with Cybersecurity? Well, at the core of many of our secure tunnel connections — such as the one you are using now to connect to this article — is a magical little method known as ECDH (Elliptic Curve Diffie Hellman). With this, Bob and Alice create their secret values for the session (a and b), and they pick a point on the curve at G. Bob passes bG and Alice passes aG, and they both end up with the same value of abG (and which is a point on the elliptic curve), and then can derive the secret key they will use for their session.

One of the most popular curves for this is Curve 25519, and which is used with Tor, and many other applications. Overall, we use a prime number to define the security level of the curve, and for Curve 25519, it is 2²⁵⁵-19 (“Did you see what we did there?”). But, there’s a problem in that although we are using a 256-bit prime number, the security level is only equivalent to a 128-bit key. While this may be okay now for cracking, the power of the Cloud and GPUs could start to approach this, and our key could be cracked within the next few years.

The Goldilocks prime and Ed448/X448

And, so we meet Goldilocks. With this, we have Curve 448 and the Goldilocks prime number (2⁴⁴⁸-2²²⁴-1). The curve itself fits in with y²+x²=1−39081x²y², and where we use our Goldilocks prime number [here]:

The Goldilocks prime is defined as the golden ratio ϕ=2²²⁴. The form of ϕ²-ϕ-1, and which is the form of the golden ratio and because 224 = 32 x 7 = 28 x 8 = 56 x 4. This makes it easier to process with 32 bits and 54 bits at a time. Overall this choice of prime makes the calculations related to the prime number extremely fast.

The paper also outlines the Riddinghood prime number, and which is ²⁴⁸⁰-²²⁴⁰-1. This is a useful prime number for performance for a 64-bit processing engine, while the Goldilocks prime is useful for both 32-bit and 64-bit processing. We can then implement a key exchange method of X448 and a signature method of Ed448.

Ed448

The Ed448 method is used with the signing for the Edwards-Curve Digital Signature Algorithm (EdDSA), and is defined in RFC 8032. It uses a public key size of 57 bytes, a private key size of 57 bytes, and a signature size of 114 bytes. This gives us 224 bit security. The code is [here]:

namespace EdDSA
{
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Parameters;

class Program
{

static void Main(string[] args)
{

var msg="Hello";

if (args.Length >0) msg=args[0];


try {


Org.BouncyCastle.Crypto.Parameters.Ed448KeyGenerationParameters keygenParams = new Org.BouncyCastle.Crypto.Parameters.Ed448KeyGenerationParameters (new SecureRandom());
Org.BouncyCastle.Crypto.Generators.Ed448KeyPairGenerator generator = new Org.BouncyCastle.Crypto.Generators.Ed448KeyPairGenerator();
generator.Init(keygenParams);
var keyPair = generator.GenerateKeyPair();
// Create signature
var signer = SignerUtilities.GetSigner("Ed448");
var privateKey = (Ed448PrivateKeyParameters) keyPair.Private;
var publicKey = (Ed448PublicKeyParameters) keyPair.Public;

signer.Init(true, privateKey);
signer.BlockUpdate(System.Text.Encoding.ASCII.GetBytes(msg), 0, msg.Length);

// Verify signature
var signer2 = SignerUtilities.GetSigner("Ed448");
signer2.Init(false, publicKey);
signer2.BlockUpdate(System.Text.Encoding.ASCII.GetBytes(msg), 0, msg.Length);
var rtn=signer2.VerifySignature(signer.GenerateSignature());

Console.WriteLine("Ed448");
Console.WriteLine("== Message: {0} ",msg);
Console.WriteLine("\n== Signature === ");
Console.WriteLine("== Signature: {0} [{1}] ",Convert.ToHexString(signer.GenerateSignature()),Convert.ToBase64String(signer.GenerateSignature()));
Console.WriteLine("== Verified: {0} ",rtn);
Console.WriteLine("\n== Private key === ");
Console.WriteLine("== Private key ==={0} ",Convert.ToHexString(privateKey.GetEncoded()));
Console.WriteLine("\n== Public key === ");
Console.WriteLine("== Public key ==={0} ",Convert.ToHexString(publicKey.GetEncoded()));

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

}

A sample run is [here]:

<pre>
Ed448
== Message: Hello 123
== Signature ===
== Signature: B4F6A23570EDD90D9A74287052CCC5CBF588DDE005A09D01AD1C2CC0F909E6E83E3BBA7FD0189A1DCEE4A95E2EADE8884BAF40531A84385F80D8C5E88E7DAACAFE8FC4698801007A5A138A08B8233F225230AB65EDDB80CA925FD75E1A0883EB5E5A8F27C2575ED115230F15020E209E1300 [tPaiNXDt2Q2adChwUszFy/WI3eAFoJ0BrRwswPkJ5ug+O7p/0BiaHc7kqV4ureiIS69AUxqEOF+A2MXojn2qyv6PxGmIAQB6WhOKCLgjPyJSMKtl7duAypJf114aCIPrXlqPJ8JXXtEVIw8VAg4gnhMA]
== Verified: True
== Private key ===
== Private key ===45430D7A4AB58A8669BA89EC1C60DBFDA04C8B93BB3FED65FA2175D873DA84B57237F9803F97A58E3C3A8FBC1E2C75A22F4AEDE274DCDD086D
== Public key ===
== Public key ===979A473F188825A9E435151DA6604B2BC560F2926154155F6363BB2FBB474FB8CF68D928BBE93F17CDCE694368C6FD6F82552AC408F1C68680

We can see we have 114 hex characters for the keys, and which is 57 bytes.

Conclusions

Want to remember some primes? Try 99, 997, 2¹⁹-1, 2²²⁵-19 and now 2⁴⁴⁸-2²²⁴-1. For the Goldilocks one, just remember “448” and then half the next one, and then subtract 1.

And, if you want some more examples of crypto using C#, try here:

https://asecuritysite.com/csharp/