Class: SelfSDK::Crypto
- Inherits:
-
Object
- Object
- SelfSDK::Crypto
- Defined in:
- lib/crypto.rb
Instance Method Summary collapse
- #decrypt(message, sender, sender_device) ⇒ Object
- #encrypt(message, recipient, recipient_device) ⇒ Object
-
#initialize(client, device, storage_folder, storage_key) ⇒ Crypto
constructor
A new instance of Crypto.
Constructor Details
permalink #initialize(client, device, storage_folder, storage_key) ⇒ Crypto
Returns a new instance of Crypto.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/crypto.rb', line 7 def initialize(client, device, storage_folder, storage_key) @client = client @device = device @storage_key = storage_key @storage_folder = "#{storage_folder}/#{@client.jwt.key_id}" if File.exist?(account_path) # 1a) if alice's account file exists load the pickle from the file @account = SelfCrypto::Account.from_pickle(File.read(account_path), @storage_key) else # 1b-i) if create a new account for alice if one doesn't exist already @account = SelfCrypto::Account.from_seed(@client.jwt.key) # 1b-ii) generate some keys for alice and publish them @account.gen_otk(100) # 1b-iii) convert those keys to json keys = @account.otk['curve25519'].map{|k,v| {id: k, key: v}}.to_json # 1b-iv) post those keys to POST /v1/identities/<selfid>/devices/1/pre_keys/ res = @client.post("/v1/apps/#{@client.jwt.id}/devices/#{@device}/pre_keys", keys) raise 'unable to push prekeys, please try in a few minutes' if res.code != 200 # 1b-v) store the account to a file File.write(account_path, @account.to_pickle(storage_key)) end end |
Instance Method Details
permalink #decrypt(message, sender, sender_device) ⇒ Object
[View source]
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 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 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/crypto.rb', line 79 def decrypt(, sender, sender_device) session_file_name = session_path(sender, sender_device) if File.exist?(session_file_name) # 7a) if carol's session file exists load the pickle from the file session_with_bob = SelfCrypto::Session.from_pickle(File.read(session_file_name), @storage_key) else # 7b-i) if you have not previously sent or received a message to/from bob, # you should extract the initial message from the group message intended # for your account id. m = SelfCrypto::GroupMessage.new(.to_s).("#{@client.jwt.id}:#{@device}") # 7b-ii) use the initial message to create a session for bob or carol session_with_bob = @account.inbound_session(m) # 7b-iii) remove the session's prekey from the account @account.remove_one_time_keys(session_with_bob) current_one_time_keys = @account.otk['curve25519'] # 7b-iv) if the number of remaining prekeys is below a certain threshold, publish new keys if current_one_time_keys.length < 10 @account.gen_otk(100) keys = Array.new @account.otk['curve25519'].each do |k,v| keys.push({id: k, key: v}) if current_one_time_keys[k].nil? end res = @client.post("/v1/apps/#{@client.jwt.id}/devices/#{@device}/pre_keys", keys.to_json) raise 'unable to push prekeys, please try in a few minutes' if res.code != 200 end File.write(account_path, @account.to_pickle(@storage_key)) end # 8) create a group session and set the identity of the account you're using gs = SelfCrypto::GroupSession.new("#{@client.jwt.id}:#{@device}") # 9) add all recipients and their sessions gs.add_participant("#{sender}:#{sender_device}", session_with_bob) # 10) decrypt the message ciphertext pt = gs.decrypt("#{sender}:#{sender_device}", ).to_s # 11) store the session to a file File.write(session_file_name, session_with_bob.to_pickle(@storage_key)) pt end |
permalink #encrypt(message, recipient, recipient_device) ⇒ Object
[View source]
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/crypto.rb', line 35 def encrypt(, recipient, recipient_device) session_file_name = session_path(recipient, recipient_device) if File.exist?(session_file_name) # 2a) if bob's session file exists load the pickle from the file session_with_bob = SelfCrypto::Session.from_pickle(File.read(session_file_name), @storage_key) else # 2b-i) if you have not previously sent or recevied a message to/from bob, # you must get his identity key from GET /v1/identities/bob/ ed25519_identity_key = @client.device_public_key(recipient, recipient_device) # 2b-ii) get a one time key for bob res = @client.get("/v1/identities/#{recipient}/devices/#{recipient_device}/pre_keys") if res.code != 200 b = JSON.parse(res.body) ::SelfSDK.logger.error "identity response : #{b['message']}" raise "could not get identity pre_keys" end one_time_key = JSON.parse(res.body)["key"] # 2b-iii) convert bobs ed25519 identity key to a curve25519 key curve25519_identity_key = SelfCrypto::Util.ed25519_pk_to_curve25519(ed25519_identity_key.raw_public_key) # 2b-iv) create the session with bob session_with_bob = @account.outbound_session(curve25519_identity_key, one_time_key) end # 3) create a group session and set the identity of the account youre using gs = SelfCrypto::GroupSession.new("#{@client.jwt.id}:#{@device}") # 4) add all recipients and their sessions gs.add_participant("#{recipient}:#{recipient_device}", session_with_bob) # 5) encrypt a message ct = gs.encrypt().to_s # 6) store the session to a file File.write(session_file_name, session_with_bob.to_pickle(@storage_key)) ct end |