| 816 | }; |
| 817 | |
| 818 | struct TreeHashInput |
| 819 | { |
| 820 | var::variant<LeafNodeHashInput, ParentNodeHashInput> node; |
| 821 | TLS_SERIALIZABLE(node); |
| 822 | TLS_TRAITS(tls::variant<NodeType>) |
| 823 | }; |
| 824 | |
| 825 | const bytes& |
| 826 | TreeKEMPublicKey::get_hash(NodeIndex index) |
| 827 | { |
| 828 | if (hashes.count(index) > 0) { |
| 829 | return hashes.at(index); |
| 830 | } |
| 831 | |
| 832 | auto hash_input = bytes{}; |
| 833 | const auto& node = node_at(index); |
| 834 | if (index.level() == 0) { |
| 835 | auto input = LeafNodeHashInput{ LeafIndex(index), {} }; |
| 836 | if (!node.blank()) { |
| 837 | input.leaf_node = node.leaf_node(); |
| 838 | } |
| 839 | |
| 840 | hash_input = tls::marshal(TreeHashInput{ input }); |
| 841 | } else { |
| 842 | auto input = ParentNodeHashInput{ |
| 843 | {}, |
| 844 | get_hash(index.left()), |
| 845 | get_hash(index.right()), |
| 846 | }; |
| 847 | |
| 848 | if (!node.blank()) { |
| 849 | input.parent_node = node.parent_node(); |
| 850 | } |
| 851 | |
| 852 | hash_input = tls::marshal(TreeHashInput{ input }); |
| 853 | } |
| 854 | |
| 855 | auto hash = suite.digest().hash(hash_input); |
| 856 | hashes.insert_or_assign(index, hash); |
| 857 | return hashes.at(index); |
| 858 | } |
| 859 | |
| 860 | // struct { |
| 861 | // HPKEPublicKey encryption_key; |
| 862 | // opaque parent_hash<V>; |
| 863 | // opaque original_sibling_tree_hash<V>; |
| 864 | // } ParentHashInput; |
| 865 | struct ParentHashInput |
| 866 | { |
| 867 | const HPKEPublicKey& public_key; |
| 868 | const bytes& parent_hash; |
| 869 | const bytes& original_child_resolution; |
| 870 | |
| 871 | TLS_SERIALIZABLE(public_key, parent_hash, original_child_resolution) |
| 872 | }; |
| 873 | |
| 874 | bytes |
| 875 | TreeKEMPublicKey::parent_hash(const ParentNode& parent, |
nothing calls this directly
no test coverage detected