Class: CryptoToolchain::DiffieHellman::Peer
- Defined in:
- lib/crypto_toolchain/diffie_hellman/peer.rb
Direct Known Subclasses
Instance Attribute Summary collapse
-
#addresses ⇒ Object
readonly
Returns the value of attribute addresses.
-
#channel ⇒ Object
readonly
Returns the value of attribute channel.
-
#debug ⇒ Object
(also: #debug?)
readonly
Returns the value of attribute debug.
-
#g ⇒ Object
readonly
Returns the value of attribute g.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#p ⇒ Object
readonly
Returns the value of attribute p.
-
#received_messages ⇒ Object
readonly
Returns the value of attribute received_messages.
Instance Method Summary collapse
- #add_address(peer) ⇒ Object
- #datum_response(msg) ⇒ Object
- #die_response(msg) ⇒ Object
- #encrypted_message_for(peer, message:, initial: false) ⇒ Object
- #info_for(peer) ⇒ Object
-
#initialize(debug: false, name: SecureRandom.uuid, p: NIST_P, g: NIST_G) ⇒ Peer
constructor
A new instance of Peer.
- #invalid_pubkey? ⇒ Boolean
- #key_exchange_response(msg) ⇒ Object
- #my_address_message(initial: false) ⇒ Object
- #peer_address_response(msg) ⇒ Object
- #privkey ⇒ Object
- #process! ⇒ Object (also: #process)
- #pubkey ⇒ Object
- #send_msg(peer, message) ⇒ Object
- #valid_pubkey? ⇒ Boolean
- #when_ready ⇒ Object
Constructor Details
#initialize(debug: false, name: SecureRandom.uuid, p: NIST_P, g: NIST_G) ⇒ Peer
Returns a new instance of Peer.
4 5 6 7 8 9 10 11 12 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 4 def initialize(debug: false, name: SecureRandom.uuid, p: NIST_P, g: NIST_G) @addresses = {} @channel = Queue.new @name = name @debug = debug @p = p @g = g @received_messages = [] end |
Instance Attribute Details
#addresses ⇒ Object (readonly)
Returns the value of attribute addresses.
126 127 128 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 126 def addresses @addresses end |
#channel ⇒ Object (readonly)
Returns the value of attribute channel.
126 127 128 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 126 def channel @channel end |
#debug ⇒ Object (readonly) Also known as: debug?
Returns the value of attribute debug.
126 127 128 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 126 def debug @debug end |
#g ⇒ Object (readonly)
Returns the value of attribute g.
126 127 128 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 126 def g @g end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
126 127 128 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 126 def name @name end |
#p ⇒ Object (readonly)
Returns the value of attribute p.
126 127 128 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 126 def p @p end |
#received_messages ⇒ Object (readonly)
Returns the value of attribute received_messages.
126 127 128 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 126 def @received_messages end |
Instance Method Details
#add_address(peer) ⇒ Object
38 39 40 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 38 def add_address(peer) @addresses[peer.name] ||= PeerInfo.new(peer: peer, channel: peer.channel ) end |
#datum_response(msg) ⇒ Object
68 69 70 71 72 73 74 75 76 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 68 def datum_response(msg) data = msg.decrypt(key: info_for(msg.peer).session_key) puts "#{name} got message containing #{data} from #{msg.peer.name}" if debug if msg.initial? encrypted = (msg.peer, message: data, initial: false) send_msg(msg.peer, encrypted) end @received_messages << ReceivedMessage.new(from: msg.peer.name, contents: data) end |
#die_response(msg) ⇒ Object
34 35 36 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 34 def die_response(msg) raise ReceivedDie end |
#encrypted_message_for(peer, message:, initial: false) ⇒ Object
111 112 113 114 115 116 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 111 def (peer, message: , initial: false) key = info_for(peer).session_key iv = Random.new.bytes(16) encrypted = (iv + .encrypt_cbc(key: key, iv: iv)) Messages::Datum.new(peer: self, contents: encrypted, initial: initial) end |
#info_for(peer) ⇒ Object
92 93 94 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 92 def info_for(peer) addresses.fetch(peer.name) end |
#invalid_pubkey? ⇒ Boolean
122 123 124 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 122 def invalid_pubkey? !valid_pubkey? end |
#key_exchange_response(msg) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 50 def key_exchange_response(msg) info = info_for(msg.peer) if msg.initial? @p = msg.p @g = msg.g end info.update(p: p, g: g, pubkey: msg.pubkey) info.set_shared_secret(privkey) if debug puts "#{name} will use p = #{p}" puts "#{name} will use g = #{g}" puts "#{name} thinks #{msg.peer.name} has pubkey #{msg.pubkey}" puts "#{name} generated secret #{info.shared_secret} for #{msg.peer.name}" end my_pubkey_msg = Messages::KeyExchange.new(peer: self, pubkey: pubkey, initial: false) send_msg msg.peer, my_pubkey_msg if msg.initial? end |
#my_address_message(initial: false) ⇒ Object
107 108 109 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 107 def (initial: false) Messages::PeerAddress.new(peer: self, channel: self.channel, initial: initial) end |
#peer_address_response(msg) ⇒ Object
42 43 44 45 46 47 48 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 42 def peer_address_response(msg) add_address(msg.peer) if msg.initial? send_msg msg.peer, end puts "#{name} added #{msg.peer.name}" if debug end |
#privkey ⇒ Object
102 103 104 105 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 102 def privkey raise RuntimeError.new("Can't generate private key until p has been set") if p.nil? @privkey ||= rand(1..0xffffffff) % p end |
#process! ⇒ Object Also known as: process
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 14 def process! when_ready do msg = channel.pop = msg.class.to_s.split(':').last if msg.respond_to?(:peer) puts "#{name} got #{} from #{msg.peer.name}" if debug end method = "#{}_response".snakecase unless self.respond_to?(method) raise ArgumentError.new("Don't know how to process method :#{method}") end begin send(method, msg) rescue ReceivedDie break end end end |
#pubkey ⇒ Object
96 97 98 99 100 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 96 def pubkey raise RuntimeError.new("Can't generate public key until p has been set") if p.nil? raise RuntimeError.new("Can't generate public key until g has been set") if g.nil? @pubkey ||= g.modexp(privkey, p) end |
#send_msg(peer, message) ⇒ Object
87 88 89 90 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 87 def send_msg(peer, ) puts "#{name} sends #{.class.to_s.split(':').last} to #{peer.name}" if debug peer.channel.enq() end |
#valid_pubkey? ⇒ Boolean
118 119 120 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 118 def valid_pubkey? pubkey < p end |
#when_ready ⇒ Object
78 79 80 81 82 83 84 85 |
# File 'lib/crypto_toolchain/diffie_hellman/peer.rb', line 78 def when_ready loop do while(channel.empty?) sleep 0.001 end yield end end |