Class: Ciri::DevP2P::RLPX::EncryptionHandshake
- Inherits:
-
Object
- Object
- Ciri::DevP2P::RLPX::EncryptionHandshake
- Defined in:
- lib/ciri/devp2p/rlpx/encryption_handshake.rb
Overview
handle key exchange handshake
Instance Attribute Summary collapse
-
#initiator_nonce ⇒ Object
readonly
Returns the value of attribute initiator_nonce.
-
#private_key ⇒ Object
readonly
Returns the value of attribute private_key.
-
#receiver_nonce ⇒ Object
readonly
Returns the value of attribute receiver_nonce.
-
#remote_id ⇒ Object
readonly
Returns the value of attribute remote_id.
-
#remote_key ⇒ Object
readonly
Returns the value of attribute remote_key.
-
#remote_random_key ⇒ Object
readonly
Returns the value of attribute remote_random_key.
Instance Method Summary collapse
- #auth_ack_msg ⇒ Object
- #auth_msg ⇒ Object
- #extract_secrets(auth_packet, auth_ack_packet, initiator:) ⇒ Object
- #handle_auth_ack_msg(msg) ⇒ Object
- #handle_auth_msg(msg) ⇒ Object
-
#initialize(private_key:, remote_id:) ⇒ EncryptionHandshake
constructor
A new instance of EncryptionHandshake.
- #random_key ⇒ Object
Constructor Details
#initialize(private_key:, remote_id:) ⇒ EncryptionHandshake
Returns a new instance of EncryptionHandshake.
43 44 45 46 |
# File 'lib/ciri/devp2p/rlpx/encryption_handshake.rb', line 43 def initialize(private_key:, remote_id:) @private_key = private_key @remote_id = remote_id end |
Instance Attribute Details
#initiator_nonce ⇒ Object (readonly)
Returns the value of attribute initiator_nonce.
41 42 43 |
# File 'lib/ciri/devp2p/rlpx/encryption_handshake.rb', line 41 def initiator_nonce @initiator_nonce end |
#private_key ⇒ Object (readonly)
Returns the value of attribute private_key.
41 42 43 |
# File 'lib/ciri/devp2p/rlpx/encryption_handshake.rb', line 41 def private_key @private_key end |
#receiver_nonce ⇒ Object (readonly)
Returns the value of attribute receiver_nonce.
41 42 43 |
# File 'lib/ciri/devp2p/rlpx/encryption_handshake.rb', line 41 def receiver_nonce @receiver_nonce end |
#remote_id ⇒ Object (readonly)
Returns the value of attribute remote_id.
41 42 43 |
# File 'lib/ciri/devp2p/rlpx/encryption_handshake.rb', line 41 def remote_id @remote_id end |
#remote_key ⇒ Object (readonly)
Returns the value of attribute remote_key.
41 42 43 |
# File 'lib/ciri/devp2p/rlpx/encryption_handshake.rb', line 41 def remote_key @remote_key end |
#remote_random_key ⇒ Object (readonly)
Returns the value of attribute remote_random_key.
41 42 43 |
# File 'lib/ciri/devp2p/rlpx/encryption_handshake.rb', line 41 def remote_random_key @remote_random_key end |
Instance Method Details
#auth_ack_msg ⇒ Object
80 81 82 83 84 85 86 |
# File 'lib/ciri/devp2p/rlpx/encryption_handshake.rb', line 80 def auth_ack_msg # make nonce bytes nonce = random_nonce(SHA_LENGTH) @receiver_nonce = nonce random_pubkey = random_key.raw_public_key[1..-1] AuthRespV4.new(random_pubkey: random_pubkey, nonce: nonce, version: 4) end |
#auth_msg ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/ciri/devp2p/rlpx/encryption_handshake.rb', line 56 def auth_msg # make nonce bytes nonce = random_nonce(SHA_LENGTH) @initiator_nonce = nonce # remote first byte tag token = dh_compute_key(private_key, remote_key) raise StandardError.new("token size #{token.size} not correct") if token.size != nonce.size # xor signed = xor(token, nonce) signature = random_key.ecdsa_signature(signed).signature initiator_pubkey = private_key.raw_public_key[1..-1] AuthMsgV4.new(signature: signature, initiator_pubkey: initiator_pubkey, nonce: nonce, version: 4) end |
#extract_secrets(auth_packet, auth_ack_packet, initiator:) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/ciri/devp2p/rlpx/encryption_handshake.rb', line 94 def extract_secrets(auth_packet, auth_ack_packet, initiator:) secret = dh_compute_key(random_key, remote_random_key) shared_secret = Ciri::Utils.keccak(secret, Ciri::Utils.keccak(receiver_nonce, initiator_nonce)) aes_secret = Ciri::Utils.keccak(secret, shared_secret) mac = Ciri::Utils.keccak(secret, aes_secret) secrets = Secrets.new(remote_id: remote_id, aes: aes_secret, mac: mac) # initial secrets macs mac1 = Digest::SHA3.new(256) mac1.update xor(mac, receiver_nonce) mac1.update auth_packet mac2 = Digest::SHA3.new(256) mac2.update xor(mac, initiator_nonce) mac2.update auth_ack_packet if initiator secrets.egress_mac = mac1 secrets.ingress_mac = mac2 else secrets.egress_mac = mac2 secrets.ingress_mac = mac1 end secrets end |
#handle_auth_ack_msg(msg) ⇒ Object
88 89 90 91 92 |
# File 'lib/ciri/devp2p/rlpx/encryption_handshake.rb', line 88 def handle_auth_ack_msg(msg) # make nonce bytes @receiver_nonce = msg.nonce @remote_random_key = Ciri::Key.new(raw_public_key: "\x04" + msg.random_pubkey) end |
#handle_auth_msg(msg) ⇒ Object
71 72 73 74 75 76 77 78 |
# File 'lib/ciri/devp2p/rlpx/encryption_handshake.rb', line 71 def handle_auth_msg(msg) @remote_key = Ciri::Key.new(raw_public_key: "\x04" + msg.initiator_pubkey) @initiator_nonce = msg.nonce token = dh_compute_key(private_key, @remote_key) signed = xor(token, msg.nonce) @remote_random_key = Ciri::Key.ecdsa_recover(signed, msg.signature) end |
#random_key ⇒ Object
52 53 54 |
# File 'lib/ciri/devp2p/rlpx/encryption_handshake.rb', line 52 def random_key @random_key ||= Ciri::Key.random end |