Module: Melos::SecretTree
- Defined in:
- lib/melos/secret_tree.rb
Class Method Summary collapse
- .create(suite, n_leaves, encryption_secret) ⇒ Object
- .populate_tree(suite, tree, root_secret) ⇒ Object
- .populate_tree_impl(suite, tree, index, secret) ⇒ Object
- .ratchet_and_get(suite, content_type, tree, leaf_index) ⇒ Object
- .ratchet_application(suite, tree, leaf_index) ⇒ Object
- .ratchet_application_until(suite, tree, leaf_index, generation) ⇒ Object
- .ratchet_handshake(suite, tree, leaf_index) ⇒ Object
- .ratchet_handshake_until(suite, tree, leaf_index, generation) ⇒ Object
- .ratchet_until_and_get(suite, content_type, tree, leaf_index, generation) ⇒ Object
Class Method Details
.create(suite, n_leaves, encryption_secret) ⇒ Object
5 6 7 8 9 |
# File 'lib/melos/secret_tree.rb', line 5 def self.create(suite, n_leaves, encryption_secret) st = Melos::Tree.empty_tree(n_leaves) populate_tree(suite, st, encryption_secret) st end |
.populate_tree(suite, tree, root_secret) ⇒ Object
11 12 13 |
# File 'lib/melos/secret_tree.rb', line 11 def self.populate_tree(suite, tree, root_secret) populate_tree_impl(suite, tree, tree.root, root_secret) end |
.populate_tree_impl(suite, tree, index, secret) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/melos/secret_tree.rb', line 15 def self.populate_tree_impl(suite, tree, index, secret) tree.array[index] = { 'handshake_ratchet_secret' => Melos::Crypto.(suite, secret, "handshake", "", suite.kdf.n_h), 'application_ratchet_secret' => Melos::Crypto.(suite, secret, "application", "", suite.kdf.n_h), 'next_handshake_ratchet_secret_generation' => 0, 'next_application_ratchet_secret_generation' => 0 } unless Melos::Tree.leaf?(index) left_secret = Melos::Crypto.(suite, secret, "tree", "left", suite.kdf.n_h) right_secret = Melos::Crypto.(suite, secret, "tree", "right", suite.kdf.n_h) populate_tree_impl(suite, tree, Melos::Tree.left(index), left_secret) populate_tree_impl(suite, tree, Melos::Tree.right(index), right_secret) end end |
.ratchet_and_get(suite, content_type, tree, leaf_index) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/melos/secret_tree.rb', line 50 def self.ratchet_and_get(suite, content_type, tree, leaf_index) # TODO: clear the value on tree when getting case content_type when 0x02, 0x03 ratchet_handshake(suite, tree, leaf_index) [ tree.leaf_at(leaf_index)['handshake_key'], tree.leaf_at(leaf_index)['handshake_nonce'], tree.leaf_at(leaf_index)['next_handshake_ratchet_secret_generation'] - 1, # returns current generation ] else ratchet_application(suite, tree, leaf_index) [ tree.leaf_at(leaf_index)['application_key'], tree.leaf_at(leaf_index)['application_nonce'], tree.leaf_at(leaf_index)['next_application_ratchet_secret_generation'] - 1, # returns current generation ] end end |
.ratchet_application(suite, tree, leaf_index) ⇒ Object
84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/melos/secret_tree.rb', line 84 def self.ratchet_application(suite, tree, leaf_index) node_index = leaf_index * 2 generation = tree.array[node_index]['next_application_ratchet_secret_generation'] application_ratchet_secret = tree.array[node_index]['application_ratchet_secret'] application_nonce = Melos::Crypto.derive_tree_secret(suite, application_ratchet_secret, "nonce", generation, suite.hpke.n_n) application_key = Melos::Crypto.derive_tree_secret(suite, application_ratchet_secret, "key", generation, suite.hpke.n_k) next_application_ratchet_secret = Melos::Crypto.derive_tree_secret(suite, application_ratchet_secret, "secret", generation, suite.kdf.n_h) tree.array[node_index]['next_application_ratchet_secret_generation'] = generation + 1 tree.array[node_index]['application_ratchet_secret'] = next_application_ratchet_secret tree.array[node_index]['application_nonce'] = application_nonce tree.array[node_index]['application_key'] = application_key end |
.ratchet_application_until(suite, tree, leaf_index, generation) ⇒ Object
70 71 72 73 74 |
# File 'lib/melos/secret_tree.rb', line 70 def self.ratchet_application_until(suite, tree, leaf_index, generation) while (tree.leaf_at(leaf_index)['next_application_ratchet_secret_generation'] <= generation) ratchet_application(suite, tree, leaf_index) end end |
.ratchet_handshake(suite, tree, leaf_index) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/melos/secret_tree.rb', line 97 def self.ratchet_handshake(suite, tree, leaf_index) node_index = leaf_index * 2 generation = tree.array[node_index]['next_handshake_ratchet_secret_generation'] handshake_ratchet_secret = tree.array[node_index]['handshake_ratchet_secret'] handshake_nonce = Melos::Crypto.derive_tree_secret(suite, handshake_ratchet_secret, "nonce", generation, suite.hpke.n_n) handshake_key = Melos::Crypto.derive_tree_secret(suite, handshake_ratchet_secret, "key", generation, suite.hpke.n_k) next_handshake_ratchet_secret = Melos::Crypto.derive_tree_secret(suite, handshake_ratchet_secret, "secret", generation, suite.kdf.n_h) tree.array[node_index]['next_handshake_ratchet_secret_generation'] = generation + 1 tree.array[node_index]['handshake_ratchet_secret'] = next_handshake_ratchet_secret tree.array[node_index]['handshake_nonce'] = handshake_nonce tree.array[node_index]['handshake_key'] = handshake_key end |
.ratchet_handshake_until(suite, tree, leaf_index, generation) ⇒ Object
76 77 78 79 80 81 82 |
# File 'lib/melos/secret_tree.rb', line 76 def self.ratchet_handshake_until(suite, tree, leaf_index, generation) raise ArgumentError.new('cannot generate past generation') if generation < tree.leaf_at(leaf_index)['next_handshake_ratchet_secret_generation'] - 1 # if current generation, do nothing while (tree.leaf_at(leaf_index)['next_handshake_ratchet_secret_generation'] <= generation) ratchet_handshake(suite, tree, leaf_index) end end |
.ratchet_until_and_get(suite, content_type, tree, leaf_index, generation) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/melos/secret_tree.rb', line 30 def self.ratchet_until_and_get(suite, content_type, tree, leaf_index, generation) # TODO: clear the value on tree when getting case content_type when 0x02, 0x03 ratchet_handshake_until(suite, tree, leaf_index, generation) [ tree.leaf_at(leaf_index)['handshake_key'], tree.leaf_at(leaf_index)['handshake_nonce'], generation ] else ratchet_application_until(suite, tree, leaf_index, generation) [ tree.leaf_at(leaf_index)['application_key'], tree.leaf_at(leaf_index)['application_nonce'], generation ] end end |