Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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)));
        }
Exemplo n.º 3
0
        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 });
        }
Exemplo n.º 4
0
 public static byte[] ComputeDigest(this IDigest digest, byte[] data, int offset, int length) =>
 digest.ComputeDigest(new ArraySegment <byte>(data, offset, length));
Exemplo n.º 5
0
 public static byte[] ComputeDigest(this IDigest digest, byte[] data) =>
 digest.ComputeDigest(new ArraySegment <byte>(data));