Class: Ciri::P2P::RLPX::EncryptionHandshake
- Inherits:
-
Object
- Object
- Ciri::P2P::RLPX::EncryptionHandshake
- Defined in:
- lib/ciri/p2p/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.
48 49 50 51 |
# File 'lib/ciri/p2p/rlpx/encryption_handshake.rb', line 48 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.
46 47 48 |
# File 'lib/ciri/p2p/rlpx/encryption_handshake.rb', line 46 def initiator_nonce @initiator_nonce end |
#private_key ⇒ Object (readonly)
Returns the value of attribute private_key.
46 47 48 |
# File 'lib/ciri/p2p/rlpx/encryption_handshake.rb', line 46 def private_key @private_key end |
#receiver_nonce ⇒ Object (readonly)
Returns the value of attribute receiver_nonce.
46 47 48 |
# File 'lib/ciri/p2p/rlpx/encryption_handshake.rb', line 46 def receiver_nonce @receiver_nonce end |
#remote_id ⇒ Object (readonly)
Returns the value of attribute remote_id.
46 47 48 |
# File 'lib/ciri/p2p/rlpx/encryption_handshake.rb', line 46 def remote_id @remote_id end |
#remote_key ⇒ Object (readonly)
Returns the value of attribute remote_key.
46 47 48 |
# File 'lib/ciri/p2p/rlpx/encryption_handshake.rb', line 46 def remote_key @remote_key end |
#remote_random_key ⇒ Object (readonly)
Returns the value of attribute remote_random_key.
46 47 48 |
# File 'lib/ciri/p2p/rlpx/encryption_handshake.rb', line 46 def remote_random_key @remote_random_key end |
Instance Method Details
#auth_ack_msg ⇒ Object
85 86 87 88 89 90 91 |
# File 'lib/ciri/p2p/rlpx/encryption_handshake.rb', line 85 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
61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/ciri/p2p/rlpx/encryption_handshake.rb', line 61 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
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/ciri/p2p/rlpx/encryption_handshake.rb', line 99 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
93 94 95 96 97 |
# File 'lib/ciri/p2p/rlpx/encryption_handshake.rb', line 93 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
76 77 78 79 80 81 82 83 |
# File 'lib/ciri/p2p/rlpx/encryption_handshake.rb', line 76 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
57 58 59 |
# File 'lib/ciri/p2p/rlpx/encryption_handshake.rb', line 57 def random_key @random_key ||= Ciri::Key.random end |