a firstworks project
Rudiments
About Documentation Download Licensing News

Using the dh class

The dh class provides a simple Diffie-Hellman key exchange implementation.

Diffie-Hellman allows two parties to agree on a shared secret over an insecure channel. Both parties agree on a prime modulus and generator, then each generates their own key pair using generateKeys(). Each party shares their public key with the other using setPeerPublicKey(), then independently generates the same shared secret using generateSharedSecret().

The setPrimeModulus() and setGenerator() methods set the agreed-upon parameters. The generateKeys() method generates an ephemeral private/public key pair. The getPublicKey() and getPrivateKey() methods retrieve the generated keys. The setPeerPublicKey() method sets the other party's public key, and generateSharedSecret() computes the shared secret, which can be retrieved using getSharedSecret(). The clear() method resets the keys and shared secret while preserving the prime modulus and generator, and reset() clears everything.

The isSupported() method can be used to determine if Diffie-Hellman is available on the current platform.

The following example simulates a Diffie-Hellman key exchange between two parties (alice and bob) using a well-known 1024-bit prime modulus from RFC 2409.

#include <rudiments/dh.h>
#include <rudiments/stdio.h>

int main(int argc, const char **argv) {

	dh	alice;
	dh	bob;

	// check whether dh is supported
	if (!alice.isSupported()) {
		stdoutput.write("dh is not supported\n");
		return 1;
	}


	// both parties agree on a prime modulus and generator
	// (a well-known 128-byte/1024-bit modular
	// exponentiation group from RFC 2409)
	const byte_t	dhp[]={
		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
		0xC9,0x0F,0xDA,0xA2,0x21,0x68,0xC2,0x34,
		0xC4,0xC6,0x62,0x8B,0x80,0xDC,0x1C,0xD1,
		0x29,0x02,0x4E,0x08,0x8A,0x67,0xCC,0x74,
		0x02,0x0B,0xBE,0xA6,0x3B,0x13,0x9B,0x22,
		0x51,0x4A,0x08,0x79,0x8E,0x34,0x04,0xDD,
		0xEF,0x95,0x19,0xB3,0xCD,0x3A,0x43,0x1B,
		0x30,0x2B,0x0A,0x6D,0xF2,0x5F,0x14,0x37,
		0x4F,0xE1,0x35,0x6D,0x6D,0x51,0xC2,0x45,
		0xE4,0x85,0xB5,0x76,0x62,0x5E,0x7E,0xC6,
		0xF4,0x4C,0x42,0xE9,0xA6,0x37,0xED,0x6B,
		0x0B,0xFF,0x5C,0xB6,0xF4,0x06,0xB7,0xED,
		0xEE,0x38,0x6B,0xFB,0x5A,0x89,0x9F,0xA5,
		0xAE,0x9F,0x24,0x11,0x7C,0x4B,0x1F,0xE6,
		0x49,0x28,0x66,0x51,0xEC,0xE6,0x53,0x81,
		0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
	};

	const byte_t	dhg[]={0x02};

	alice.setPrimeModulus(dhp,sizeof(dhp));
	alice.setGenerator(dhg,sizeof(dhg));

	bob.setPrimeModulus(dhp,sizeof(dhp));
	bob.setGenerator(dhg,sizeof(dhg));


	// each party generates their own key pair
	alice.generateKeys();
	bob.generateKeys();


	// each party shares their public key with the other
	bob.setPeerPublicKey(alice.getPublicKey(),alice.getPublicKeySize());
	alice.setPeerPublicKey(bob.getPublicKey(),bob.getPublicKeySize());


	// each party independently generates the shared secret
	alice.generateSharedSecret();
	bob.generateSharedSecret();


	// verify that both shared secrets match
	stdoutput.printf("alice's shared secret: ");
	for (uint64_t i=0; i<alice.getSharedSecretSize(); i++) {
		stdoutput.printf("%02x",alice.getSharedSecret()[i]);
	}
	stdoutput.write('\n');

	stdoutput.printf("bob's shared secret:   ");
	for (uint64_t i=0; i<bob.getSharedSecretSize(); i++) {
		stdoutput.printf("%02x",bob.getSharedSecret()[i]);
	}
	stdoutput.write('\n');
}
Copyright 2017 - David Muse - Contact