/// <summary> /// Sets ck, tempK = HKDF(ck, inputKeyMaterial, 2). /// If HashLen is 64, then truncates tempK to 32 bytes. /// Calls InitializeKey(tempK). /// </summary> public void MixKey(ReadOnlySpan <byte> inputKeyMaterial) { int length = inputKeyMaterial.Length; Debug.Assert(length == 0 || length == Aead.KeySize || length == dh.DhLen); Span <byte> output = stackalloc byte[2 * hash.HashLen]; hkdf.ExtractAndExpand2(ck, inputKeyMaterial, output); output.Slice(0, hash.HashLen).CopyTo(ck); var tempK = output.Slice(hash.HashLen, Aead.KeySize); state.InitializeKey(tempK); }
/// <summary> /// Sets ck, tempK = HKDF(ck, inputKeyMaterial, 2). /// If HashLen is 64, then truncates tempK to 32 bytes. /// Calls InitializeKey(tempK). /// </summary> public unsafe void MixKey(byte *inputKeyMaterial, int inputKeyMaterialLength) { var length = inputKeyMaterialLength; Debug.Assert(length == 0 || length == Aead.KeySize || length == dh.DhLen); Span <byte> output = stackalloc byte[2 * hash.HashLen]; hkdf.ExtractAndExpand2(ck, hash.HashLen, inputKeyMaterial, inputKeyMaterialLength, output); var slice = output.Slice(0, hash.HashLen); for (var i = 0; i < hash.HashLen; i++) { ck[i] = slice[i]; } var tempK = output.Slice(hash.HashLen, Aead.KeySize); state.InitializeKey(tempK); }
/// <summary> /// Returns a pair of CipherState objects for encrypting transport messages. /// </summary> public (CipherState <CipherType> c1, CipherState <CipherType> c2) Split() { Span <byte> output = stackalloc byte[2 * hash.HashLen]; hkdf.ExtractAndExpand2(ck, null, output); var tempK1 = output.Slice(0, Aead.KeySize); var tempK2 = output.Slice(hash.HashLen, Aead.KeySize); var c1 = new CipherState <CipherType>(); var c2 = new CipherState <CipherType>(); c1.InitializeKey(tempK1); c2.InitializeKey(tempK2); return(c1, c2); }