public static EcdhRatchetStep InitializeServer(IKeyDerivation kdf, IDigest digest, IKeyAgreement previousKeyPair, byte[] rootKey, ArraySegment <byte> remotePublicKey, IKeyAgreement keyPair, byte[] receiveHeaderKey, byte[] sendHeaderKey) { if (receiveHeaderKey.Length != 32 || sendHeaderKey.Length != 32) { throw new InvalidOperationException("Keys need to be 32 bytes."); } Log.Verbose($"--Initialize ECDH Ratchet"); Log.Verbose($"Root Key: {Log.ShowBytes(rootKey)}"); Log.Verbose($"Prev ECDH Private: ({Log.ShowBytes(previousKeyPair.GetPublicKey())})"); Log.Verbose($"ECDH Public: {Log.ShowBytes(remotePublicKey)}"); Log.Verbose($"Curr ECDH Private: ({Log.ShowBytes(keyPair.GetPublicKey())})"); var e = new EcdhRatchetStep { EcdhKey = keyPair, ReceiveHeaderKey = receiveHeaderKey, SendHeaderKey = sendHeaderKey }; // receive chain Log.Verbose(" --Receiving Chain"); var rcderived = previousKeyPair.DeriveKey(remotePublicKey); rcderived = digest.ComputeDigest(rcderived); Log.Verbose($" C Input Key: {Log.ShowBytes(rootKey)}"); Log.Verbose($" C Key Info: {Log.ShowBytes(rcderived)}"); var rckeys = kdf.GenerateKeys(rcderived, rootKey, 3, 32); Log.Verbose($" C Key Out 0: {Log.ShowBytes(rckeys[0])}"); Log.Verbose($" C Key Out 1: {Log.ShowBytes(rckeys[1])}"); Log.Verbose($" C Key Out 2: {Log.ShowBytes(rckeys[2])}"); rootKey = rckeys[0]; e.ReceivingChain.Initialize(rckeys[1]); e.NextReceiveHeaderKey = rckeys[2]; // send chain Log.Verbose(" --Sending Chain"); var scderived = keyPair.DeriveKey(remotePublicKey); scderived = digest.ComputeDigest(scderived); Log.Verbose($" C Input Key: {Log.ShowBytes(rootKey)}"); Log.Verbose($" C Key Info: {Log.ShowBytes(scderived)}"); var sckeys = kdf.GenerateKeys(scderived, rootKey, 3, 32); Log.Verbose($" C Key Out 0: {Log.ShowBytes(sckeys[0])}"); Log.Verbose($" C Key Out 1: {Log.ShowBytes(sckeys[1])}"); Log.Verbose($" C Key Out 2: {Log.ShowBytes(sckeys[2])}"); rootKey = sckeys[0]; e.SendingChain.Initialize(sckeys[1]); e.NextSendHeaderKey = sckeys[2]; // next root key Log.Verbose($"Next Root Key: ({Log.ShowBytes(rootKey)})"); e.NextRootKey = rootKey; return(e); }
public static bool VerifySignedMessage(this IVerifier sig, IDigest digest, ArraySegment <byte> message) { if (message.Count <= sig.SignatureSize) { throw new InvalidOperationException("The message size is smaller than or equal to the size of a signature"); } var hash = digest.ComputeDigest( new ArraySegment <byte>(message.Array, message.Offset, message.Count - sig.SignatureSize)); return(sig.Verify( new ArraySegment <byte>(hash), new ArraySegment <byte>(message.Array, message.Offset + message.Count - sig.SignatureSize, sig.SignatureSize))); }
public static EcdhRatchetStep[] InitializeClient(IKeyDerivation kdf, IDigest digest, byte[] rootKey, ArraySegment <byte> remotePublicKey0, ArraySegment <byte> remotePublicKey1, IKeyAgreement keyPair, byte[] receiveHeaderKey, byte[] sendHeaderKey, IKeyAgreement nextKeyPair) { if (receiveHeaderKey.Length != 32 || sendHeaderKey.Length != 32) { throw new InvalidOperationException("Keys need to be 32 bytes."); } Log.Verbose($"--Initialize ECDH Ratchet CLIENT"); Log.Verbose($"Root Key: {Log.ShowBytes(rootKey)}"); Log.Verbose($"ECDH Public 0: {Log.ShowBytes(remotePublicKey0)}"); Log.Verbose($"ECDH Public 1: {Log.ShowBytes(remotePublicKey1)}"); Log.Verbose($"ECDH Private: ({Log.ShowBytes(keyPair.GetPublicKey())})"); var e0 = new EcdhRatchetStep { EcdhKey = keyPair, SendHeaderKey = sendHeaderKey }; // receive chain doesn't exist Log.Verbose(" --Receiving Chain"); // send chain Log.Verbose(" --Sending Chain"); var scderived = keyPair.DeriveKey(remotePublicKey0); scderived = digest.ComputeDigest(scderived); Log.Verbose($" C Input Key: {Log.ShowBytes(rootKey)}"); Log.Verbose($" C Key Info: {Log.ShowBytes(scderived)}"); var sckeys = kdf.GenerateKeys(scderived, rootKey, 3, 32); Log.Verbose($" C Key Out 0: {Log.ShowBytes(sckeys[0])}"); Log.Verbose($" C Key Out 1: {Log.ShowBytes(sckeys[1])}"); Log.Verbose($" C Key Out 2: {Log.ShowBytes(sckeys[2])}"); rootKey = sckeys[0]; e0.SendingChain.Initialize(sckeys[1]); var nextSendHeaderKey = sckeys[2]; var e1 = InitializeServer(kdf, digest, keyPair, rootKey, remotePublicKey1, nextKeyPair, receiveHeaderKey, nextSendHeaderKey); return(new[] { e0, e1 }); }
public static byte[] ComputeDigest(this IDigest digest, byte[] data, int offset, int length) => digest.ComputeDigest(new ArraySegment <byte>(data, offset, length));
public static byte[] ComputeDigest(this IDigest digest, byte[] data) => digest.ComputeDigest(new ArraySegment <byte>(data));