Example #1
0
        public NodeId GetNodeId(byte[] signature, int recoveryId, byte[] messageType, byte[] data)
        {
            //return _signer.RecoverPublicKey(discoveryMessage.Signature, Keccak.Compute(Bytes.Concat(new[] {(byte)discoveryMessage.MessageType}, discoveryMessage.Payload)));

            var key = _signer.RecoverPublicKey(new Signature(signature, recoveryId), Keccak.Compute(Bytes.Concat(messageType, data)));

            return(key != null ? new NodeId(key) : null);
        }
Example #2
0
 public PublicKey GetNodeId(byte[] signature, int recoveryId, byte[] messageType, byte[] data)
 {
     return(_signer.RecoverPublicKey(new Signature(signature, recoveryId), Keccak.Compute(Bytes.Concat(messageType, data))));
 }
        public Packet Ack(EncryptionHandshake handshake, Packet auth)
        {
            handshake.AuthPacket = auth;

            AuthMessageBase authMessage;
            bool            isOld = false;

            try
            {
                _logger.Info($"Trying to decrypt an old version of {nameof(AuthMessage)}");
                byte[] plaintextOld = _eciesCipher.Decrypt(_privateKey, auth.Data);
                authMessage = _messageSerializationService.Deserialize <AuthMessage>(plaintextOld);
                isOld       = true;
            }
            catch (Exception)
            {
                _logger.Info($"Trying to decrypt version 4 of {nameof(AuthEip8Message)}");
                byte[] sizeData  = auth.Data.Slice(0, 2);
                byte[] plaintext = _eciesCipher.Decrypt(_privateKey, auth.Data.Slice(2), sizeData);
                authMessage = _messageSerializationService.Deserialize <AuthEip8Message>(plaintext);
            }

            var nodeId = new NodeId(authMessage.PublicKey);

            _logger.Debug($"Received AUTH v{authMessage.Version} from {nodeId}");

            handshake.RemoteNodeId        = nodeId;
            handshake.RecipientNonce      = _cryptoRandom.GenerateRandomBytes(32);
            handshake.EphemeralPrivateKey = new PrivateKey(_cryptoRandom.GenerateRandomBytes(32));

            handshake.InitiatorNonce = authMessage.Nonce;
            byte[] staticSharedSecret = BouncyCrypto.Agree(_privateKey, handshake.RemoteNodeId.PublicKey);
            byte[] forSigning         = staticSharedSecret.Xor(handshake.InitiatorNonce);

            handshake.RemoteEphemeralPublicKey = _signer.RecoverPublicKey(authMessage.Signature, new Keccak(forSigning));

            byte[] ackData;
            if (isOld) // what was the difference? shall I really include ephemeral public key in v4?
            {
                _logger.Debug($"Building an {nameof(AckMessage)}");
                AckMessage ackMessage = new AckMessage();
                ackMessage.EphemeralPublicKey = handshake.EphemeralPrivateKey.PublicKey;
                ackMessage.Nonce = handshake.RecipientNonce;
                ackData          = _messageSerializationService.Serialize(ackMessage);
            }
            else
            {
                _logger.Debug($"Building an {nameof(AckEip8Message)}");
                AckEip8Message ackMessage = new AckEip8Message();
                ackMessage.EphemeralPublicKey = handshake.EphemeralPrivateKey.PublicKey;
                ackMessage.Nonce = handshake.RecipientNonce;
                ackData          = _messageSerializationService.Serialize(ackMessage);
            }

            int size = ackData.Length + 32 + 16 + 65; // data + MAC + IV + pub

            byte[] sizeBytes  = size.ToBigEndianByteArray().Slice(2, 2);
            byte[] packetData = _eciesCipher.Encrypt(handshake.RemoteNodeId.PublicKey, ackData, sizeBytes);
            handshake.AckPacket = new Packet(Bytes.Concat(sizeBytes, packetData));
            SetSecrets(handshake, EncryptionHandshakeRole.Recipient);
            return(handshake.AckPacket);
        }