From 50aeefcb5198d99777e19f9a0100fe74af630dfb Mon Sep 17 00:00:00 2001 From: Mathias Hall-Andersen Date: Fri, 23 Jun 2017 13:41:59 +0200 Subject: Beginning work noise handshake --- src/noise_helpers.go | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/noise_helpers.go (limited to 'src/noise_helpers.go') diff --git a/src/noise_helpers.go b/src/noise_helpers.go new file mode 100644 index 0000000..df25011 --- /dev/null +++ b/src/noise_helpers.go @@ -0,0 +1,86 @@ +package main + +import ( + "crypto/hmac" + "crypto/rand" + "golang.org/x/crypto/blake2s" + "golang.org/x/crypto/curve25519" + "hash" +) + +/* KDF related functions. + * HMAC-based Key Derivation Function (HKDF) + * https://tools.ietf.org/html/rfc5869 + */ + +func HMAC(sum *[blake2s.Size]byte, key []byte, input []byte) { + mac := hmac.New(func() hash.Hash { + h, _ := blake2s.New256(nil) + return h + }, key) + mac.Write(input) + mac.Sum(sum[:0]) +} + +func KDF1(key []byte, input []byte) (t0 [blake2s.Size]byte) { + HMAC(&t0, key, input) + HMAC(&t0, t0[:], []byte{0x1}) + return +} + +func KDF2(key []byte, input []byte) (t0 [blake2s.Size]byte, t1 [blake2s.Size]byte) { + var prk [blake2s.Size]byte + HMAC(&prk, key, input) + HMAC(&t0, prk[:], []byte{0x1}) + HMAC(&t1, prk[:], append(t0[:], 0x2)) + return +} + +func KDF3(key []byte, input []byte) (t0 [blake2s.Size]byte, t1 [blake2s.Size]byte, t2 [blake2s.Size]byte) { + var prk [blake2s.Size]byte + HMAC(&prk, key, input) + HMAC(&t0, prk[:], []byte{0x1}) + HMAC(&t1, prk[:], append(t0[:], 0x2)) + HMAC(&t2, prk[:], append(t1[:], 0x3)) + return +} + +/* + * + */ + +func addToChainKey(c [blake2s.Size]byte, data []byte) [blake2s.Size]byte { + return KDF1(c[:], data) +} + +func addToHash(h [blake2s.Size]byte, data []byte) [blake2s.Size]byte { + return blake2s.Sum256(append(h[:], data...)) +} + +/* Curve25519 wrappers + * + * TODO: Rethink this + */ + +func newPrivateKey() (sk NoisePrivateKey, err error) { + // clamping: https://cr.yp.to/ecdh.html + _, err = rand.Read(sk[:]) + sk[0] &= 248 + sk[31] &= 127 + sk[31] |= 64 + return +} + +func (sk *NoisePrivateKey) publicKey() (pk NoisePublicKey) { + apk := (*[NoisePublicKeySize]byte)(&pk) + ask := (*[NoisePrivateKeySize]byte)(sk) + curve25519.ScalarBaseMult(apk, ask) + return +} + +func (sk *NoisePrivateKey) sharedSecret(pk NoisePublicKey) (ss [NoisePublicKeySize]byte) { + apk := (*[NoisePublicKeySize]byte)(&pk) + ask := (*[NoisePrivateKeySize]byte)(sk) + curve25519.ScalarMult(&ss, apk, ask) + return ss +} -- cgit v1.2.3