Hybrid Encryption Framework

Cypherlock uses a multitude of different key constructs for encrypted messages. It combines assymmetric keys with varying key lifetimes with symmetric keys generated from user input.

To securely and easily implement multi-key cryptography, including header packaging and integrity, and automated enforcement of key management policies, we have developed a library that allows easy definition of key dependencies and handles everything from key generation to message encoding.

 0
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
	// Complete example of implementing a 3DH key-exchange with authenticated message encryption
	// including all key management tasks and exclusive use of protected memory...
	msg := []byte("This is a secret message that is encrypted")

	// Select memory protection scheme.
	engine := new(memprotect.Protected)
	engine.Init(new(memprotect.Protected).Cell(32)) // Replace with actuall symmetric key for persistent key storage.
	defer engine.Finish()

	// Let's create a few keys with different key management policies.
	// Static keys:
	key1 := protectedcrypto.NewCurve25519(engine) // Senders long term key.
	key1.Generate()

	key2 := protectedcrypto.NewCurve25519(engine) // Recipient's long term key.
	key2.Generate()

	// Ephemeral keys:
	key3 := protectedcrypto.NewCurve25519Ephemeral(engine) // Sender's short term key.
	key4 := protectedcrypto.NewCurve25519Ephemeral(engine) // Recipient's long term key.

	// ===== SENDER =====
	// Define a 3DH key agreement using cross-over between long-term and short-term keys.
	tsc := &SecretCalculator{
		Combiner:           protectedcrypto.NewSecretCombiner(engine),
		MessageType:        400,
		Nonce:              nil,				// Nonce is generated if not given.
		DeterministicNonce: nil,				// Allows for including a non-random value into key generation.
		Keys: []KeyContainer{
			KeyContainer{
				SecretGenerator: key1,
				MyPublicKey:     key1.PublicKey(),
				PeerPublicKey:   key2.PublicKey(),
			},
			KeyContainer{
				SecretGenerator: key3,
				MyPublicKey:     nil,			// Public key is inserted if not given.
				PeerPublicKey:   key2.PublicKey(),
			},
			KeyContainer{
				SecretGenerator: key4,
				MyPublicKey:     nil,
				PeerPublicKey:   key1.PublicKey(),
			},
		},
	}
	encrypted, _ := tsc.Encrypt(msg, make([]byte, 0, tsc.EncryptedSize(msg))) // Encrypt message into pre-allocated buffer.

	// ===== RECIPIENT =====
	// The sender's public keys are encoded into the message and covered by integrity protection and linked into the authenticated encryption.
	tsc2 := &SecretCalculator{
		Combiner:           protectedcrypto.NewSecretCombiner(engine),
		MessageType:        400,
		DeterministicNonce: nil,
		Keys: []KeyContainer{
			KeyContainer{
				SecretGenerator: key2,
			},
			KeyContainer{
				SecretGenerator: key2,
			},
			KeyContainer{
				SecretGenerator: key1,
			},
		},
	}
	out, _ := tsc2.Decrypt(encrypted, make([]byte, 0, tsc2.DecryptedSize(encrypted))) // Decrypt message into pre-allocated buffer.

Get the source here: encrypt