Efficient Monitoring of Hyperproperties using Prefix Trees

Hyperproperties, such as non-interference and observational determinism, relate multiple computation traces with each other and are thus not monitorable by tools that consider computations in isolation. We present the monitoring approach implemented in the latest version of RVHyper, a runtime verification tool for hyperproperties. The input to the tool are specifications given in the temporal logic HyperLTL, which extends linear-time temporal logic (LTL) with trace quantifiers and trace variables. RVHyper processes execution traces sequentially until a violation of the specification is detected. In this case, a counter example, in the form of a set of traces, is returned. RVHyper employs a range of optimizations: a preprocessing analysis of the specification and a procedure that minimizes the traces that need to be stored during the monitoring process. In this article, we introduce a novel trace storage technique that arranges the traces in a tree-like structure to exploit partially equal traces. We evaluate RVhyper on existing benchmarks on secure information-flow control, error correcting codes and symmetry in hardware designs. As an example application outside of security, we show how RVHyper can be used to detect spurious dependencies in hardware designs.


Introduction
Hyperproperties [10] are widely studied in (but not limited to) the context of secure information-flow control. They generalize trace properties in that they not only check the correctness of individual computation traces in isolation, but relate multiple computation traces to each other. Examples include information-flow policies, such as observational determinism [33,34,42], (quantitative) noninterference [33,36,41] as well as symmetry [26] and spurious dependencies in hardware designs [23], error correcting codes [26], and anti-doping of automotive software [14].
In this article, we present the monitoring approach implemented in the latest version of RVHyper, an automata-based monitoring tool for hyperproperties [24]. In dynamic verification of hyperproperties, efficient and light-weight monitoring techniques are instrumented in systems, which are usually far beyond the scope of static verification approaches. By doing so, countermeasures are enacted before, for example, irreparable information leaks happen. A runtime verification tool for hyperproperties is in particular useful if the implementation of a security critical system is not available. Even without access to the source code, monitoring the observable execution traces still detects insecure information flow. RVHyper also supports the verification workflow by providing a method to test and develop specifications: Specifications can be checked on sample traces without the need for a complete model. Based on the feedback of RVHyper, the specification can be refined until it matches the intended meaning.
The input of RVHyper is given in the temporal logic HyperLTL [9], which expresses temporal hyperproperties by extending linear-time temporal logic with explicit trace quantification (see [11] for a recent study of hyperlogics). HyperLTL has been used extensively to specify hyperproperties of practical interest (e.g [14,21,[23][24][25][26]). For example, observational determinism is expressed as the following formula: stating that every trace pair π, π ′ has to agree on the output as long as it agrees on the inputs as well. When detecting a violation, RVHyper outputs a counter example, which is a set of traces that does not satisfy the input formula.
Efficient model checking, synthesis and satisfiability checking tools for HyperLTL already exist [12,[19][20][21][22]25,26]. Implementing an efficient runtime verification tool for HyperLTL specifications is, despite recent theoretical progress [1, 5-7, 24, 28, 29, 37] difficult: In principle, the monitor not only needs to process every observed trace, but must also store every trace observed so far, so that future traces can be compared with the traces seen so far.
The previous version of RVHyper tackles this challenging problem by implementing two optimizations [23,24]: a specification analysis to detect exploitable properties of a hyperproperty, such as symmetry and a trace analysis, which detects all redundant traces that can be omitted during the monitoring process. A limitation of the trace analysis, which is based on a language inclusion check, is that only entire traces can be analyzed and pruned. For example, consider the traces t 1 = {a}{a}{} and t 2 = {a}{}{a} of length 3 and the HyperLTL formula ∀π.∀π ′ . (a π → ¬b π ′ ). Neither t 1 nor t 2 is dominated by the other trace, in the sense of the trace analysis, i.e., that one of the traces poses strictly less requirements on future traces [24]. The traces, however, are equal on the first position. This provides an opportunity for optimization, which our new approach exploits. We introduce a novel trace storage technique (that also has massive impact on the running time), such that RVHyper can also handle partially equal traces by storing them in a tree structure.
We evaluate RVHyper on existing benchmarks such as classical information-flow security by checking for violations of noninterference or monitoring error-resistant encoder. HyperLTL is, however, not limited to security policies. As an example of such an application beyond security, we show how RVHyper can be used to detect spurious dependencies in hardware designs.
Structure of this Article. The remainder of this article is structured as follows. We begin by giving preliminaries on HyperLTL, its finite trace semantics and notation in Section 2. In Section 3, we present automatabased monitoring approach implemented in RVHyper, before discussing optimizations in Section 4 that make the monitoring feasible in practice. In Section 5, we evaluate RVHyper with a focus on the novel storage optimization technique using our tree data structure. This is a revised and extended version of a paper that appeared at TACAS 2018 [23]. Our contribution and extension compared to [23] is the inclusion of a new trace storage optimization technique presented in Sec. 4.2 and an extended evaluation in Sec. 5.
Related Work. The temporal logic HyperLTL was introduced to model check security properties of reactive systems [9,26]. For one of its predecessors, SecLTL [16], there has been a proposal for a white-box monitoring approach [17] based on alternating automata. A recent survey on algorithms for monitoring hyperproperties is given in [28]. Agrawal and Bonakdarpour [1] were the first to study the monitoring problem of HyperLTL for the sequential model. They give a syntactic characterization of monitorable HyperLTL formulas. They present a first monitoring algorithm based on a progression logic expressing trace interdependencies and the composition of an LTL 3 monitor. A first constraintbased approach has been outlined in [7], which works for a subclass of HyperLTL specifications. The idea is to identify a set of propositions of interest and store corresponding constraints. A constraint-based algorithm for the complete fragment of ∀ 2 HyperLTL formulas has been proposed in [29]. The algorithms rewrites a HyperLTL formula and an incoming event into a constraint composed of a plain LTL requirement as well as a HyperLTL requirement. An constraint system is built incrementally: the HyperLTL part is encoded with variables, which will be incrementally defined with more incoming events of a trace. Like with our monitoring algorithm, they do not have access to the implementation (black box), but in contrast to our work, they do not provide witnessing traces as a monitor verdict.
In [5], the authors study the complexity of monitoring hyperproperties. They show that the form and size of the input, as well as the formula have a significant impact on the feasibility of the monitoring process. They differentiate between several input forms and study their complexity: a set of linear traces, treeshaped Kripke structures, and acyclic Kripke structures. For acyclic structures and alternation-free Hy-perLTL formulas, the problems complexity gets as low as NC. In [6,37], the authors study where static analysis can be combined with runtime verification techniques to monitor HyperLTL formulas beyond the alternationfree fragment.
For certain information flow policies, like noninterference and some extensions, dynamic enforcement mechanisms have been proposed. Techniques for the enforcement of information flow policies include tracking dependencies at the hardware level [38], language-based monitors [2-4, 35, 40], and abstraction-based dependency tracking [8,27,30]. Secure multi-execution [15] is a technique that can enforce non-interference by executing a program multiple times in different security levels. To enforce non-interference, the inputs are replaced by default values whenever a program tries to read from a higher security level.

Preliminaries
Let AP be a finite set of atomic propositions and let Σ = 2 AP be the corresponding alphabet. An infinite trace t ∈ Σ ω is an infinite sequence over the alphabet. A subset T ⊆ Σ ω is called a trace property. A hyperproperty H ⊆ 2 (Σ ω ) is a generalization of a trace property. A finite trace t ∈ Σ + is a finite sequence over Σ. In the case of finite traces, |t| denotes the length of a trace. We use the following notation to access and manipulate traces: Let t be a trace and i be a natural number. t[i] denotes the i-th element of t. Therefore, t[0] represents the first element of the trace. Let j be natural number. If j ≥ i and i ≤ |t|, then t[i, j] denotes the sequence t[i]t[i + 1] · · · t[min(j, |t| − 1)]. Otherwise it denotes the empty trace ǫ. t[i denotes the suffix of t starting at position i. For two finite traces s and t, we denote their concatenation by s · t.
HyperLTL Syntax. HyperLTL [9] extends LTL with trace variables and trace quantifiers. Let V be a finite set of trace variables. The syntax of HyperLTL is given by the grammar where a ∈ AP is an atomic proposition and π ∈ V is a trace variable. Atomic propositions are indexed by trace variables. The explicit trace quantification enables us to express properties like "on all traces ϕ must hold", expressed by ∀π. ϕ. Dually, we can express "there exists a trace such that ϕ holds", expressed by ∃π. ϕ. We use the standard derived operators release ϕ R ψ := ¬(¬ϕ U ¬ψ), eventually ϕ := true U ϕ, globally ϕ := ¬ ¬ϕ, and weak until ϕ 1 W ϕ 2 := (ϕ 1 U ϕ 2 ) ∨ ϕ 1 . As we use the finite trace semantics, ϕ denotes the strong version of the next operator, i.e., if a trace ends before the satisfaction of ϕ can be determined, the satisfaction relation, defined below, evaluates to false. To enable duality in the finite trace setting, we additionally use the weak next operator ϕ which evaluates to true if a trace ends before the satisfaction of ϕ can be determined and is defined as ϕ := ¬ ¬ϕ. We call ψ of a HyperLTL formula Q.ψ, with an arbitrary quantifier prefix Q, the body of the formula. A HyperLTL formula Q.ψ is in the alternation-free fragment if either Q consists solely of universal quantifiers or solely of existential quantifiers. We also denote the respective alternation-free fragments as the ∀ n fragment and the ∃ n fragment, with n being the number of quantifiers in the prefix.
Finite Trace Semantics. We recap the finite trace semantics for HyperLTL [7], which is itself based on the finite trace semantics of LTL [32]. Let Π fin : V → Σ + be a partial function mapping trace variables to finite traces. We define ǫ[0] as the empty set. Π fin [i denotes the trace assignment that is equal to Π fin (π)[i for all π ∈ dom(Π fin ). By slight abuse of notation, we write t ∈ Π fin to access traces t in the image of Π fin . The satisfaction of a HyperLTL formula ϕ over a finite trace assignment Π fin and a set of finite traces T , denoted by Π fin T ϕ, is defined as follows: The hyperproperty represented by a HyperLTL formula ϕ, denoted by H(ϕ), is the set {T ⊆ Σ ω | T ϕ}.

Runtime Verification of Hyperproperties with RVHyper
In this section, we present an overview over RVHyper, before describing the implementation setup, present the monitoring algorithm, and discuss our optimization techniques.
The input of RVHyper is given as a universally quantified HyperLTL formula and, in addition, the observed behavior of the system under consideration. The observed behavior is represented as a trace set T , where each t ∈ T represents a previously observed execution of the system to monitor. RVHyper can therefore detect violations of every monitorable k-safety hyperproperty (see [24] for an extensive study of monitorability of hyperproperties). If RVHyper detects that the system violates the hyperproperty, it outputs a counter example, i.e, a k-ary tuple of traces, where k is the number of quantifiers in the HyperLTL formula.

Implementation Details
RVHyper 1 is written in C ++ . We use spot [18] for building the deterministic monitor automata and the Buddy BDD library for handling symbolic constraints. We use the HyperLTL satisfiability solver EAHyper [19,22] to determine whether the input formula is reflexive, symmetric, or transitive. Depending on those results, we omit redundant tuples in the monitoring algorithm.

Online Monitoring Algorithm
For the online algorithm, we use standard techniques for building LTL monitoring automata and use this to instantiate this monitor by the traces as specified by the HyperLTL formula. Let AP be a set of atomic propositions and V = {π 1 , . . . , π n } a set of trace variables. A deterministic monitor template M = (Σ, Q, δ, q 0 , F ) is a tuple of a finite alphabet Σ = 2 (AP×V) , a nonempty set of states Q, a partial transition function δ : Q × Σ ֒→ Q, a designated initial state q 0 ∈ Q, and a set of accepting states F ⊆ Q. The instantiated automaton runs in parallel over traces in (2 AP ) * , thus we define a run with respect to a n-ary tuple N ∈ ((2 AP ) * ) n of finite traces. A run of N is a sequence of states q 0 q 1 · · · q m ∈ Q * , where m is the length of the smallest trace in N , starting in the initial state q 0 such that for all i with 0 ≤ i < m it holds that A tuple N is accepted if there is a run on M that ends in an accepting state. For LTL, such a deterministic monitor can be constructed in doubly-exponential time in the size of the formula [13,39].

Example 1
As an example formula, consider again the observational determinism formula introduced in the introduction: The corresponding monitor template is depicted in Fig. 1.
The algorithm for monitoring HyperLTL formulas when traces are given sequentially to the monitor is presented as Algorithm 1. After building the deterministic monitoring automaton M ϕ , the algorithm accepts new traces and afterwards proceeds with the pace of the incoming stream. We have a variable S that maps 1 The implementation is available at https://react.uni-saarland.de/tools/rvhyper/ .
Visualization of a monitor template corresponding to the formula given in Example 1. We use a symbolic representation of the transition function δ. We depict a sink rejecting state q ⊥ .
tuples of traces to states of the deterministic monitor. Whenever the current trace t progresses, we progress every tuple (t 1 , . . . , t n ) that contains t with one of the following outcomes: 1. One of the traces t 1 , . . . , t n may have ended, thus, we check if the monitor is in an accepting state and report a violation if this is not the case. 2. There is a successor state in the monitor, thus we update S. 3. There is no successor state, hence, we report a violation.
When a new trace t starts, only new tuples are considered for S, that are tuples t ∈ (T ∪ {t}) n containing the new trace t.
Example 2 We continue Example 1 by showing how the algorithm progresses on the given formula. Assume for the sake of readability that we have a single input proposition i and a single output proposition o. Furthermore, assume that we have already seen the trace t 0 = {i}{i, o}{o}, that is, T = {t 0 } and S(t 0 , t 0 ) = q 0 . We now show how the algorithm continues with a fresh trace t 1 . In lines 6-8 we add the pairs (t 0 , t 1 ), (t 0 , t 1 ), and (t 1 , t 1 ) with the initial state q 0 to S. Let p = {i} be the first input proposition, thus, , the monitor remains in q 0 for every tuple. Let p = {i} be the next input proposition, thus, t 1 = {i}{i}. Consider the tuple (t 0 , t 1 ). As t 0 [1] and t 1 [1] are equal with respect to i but differ in o, the monitor progresses to the rejecting state q ⊥ and the algorithm terminates by reporting the violation. If, the previous input proposition is p = {}, both tuples, (t 0 , t 1 ) and (t 1 , t 0 ) would progress to the accepting sink state q ⊤ as the input proposition is different to t 0 [1]. Assume two more inputs, e.g., t 1 = {i}{i}{}{}, then the pairs (t 0 , t 0 ), (t 0 , t 1 ), and (t 1 , t 0 ) are removed from S as t 1 is strict longer than t 0 .

Optimizations
In this section, we present three optimizations implemented in RVHyper, which, as we will see in the evalua-input : ∀ n HyperLTL formula ϕ output: satisfied or n-ary tuple witnessing violation 3 S : T n → Q // initially empty; 4 t // container for the subsequently incoming event traces 5 while there is a new event trace do  Algorithm 1: Online monitoring algorithm for ∀ n HyperLTL: The algorithm subsequently reads event traces and monitors them against already seen traces. Already seen traces are stored in T before continuing with a new event trace.
tion section, are necessary to make the automata-based monitoring approach feasible in practice. We begin by explaining a specification analysis, which is a preprocessing step that exploits properties of the specification to reduce the algorithmic workload. In the subsequent section, we show how RVHyper tackles the problem of potentially unbounded memory consumption: We recap the trace analysis, which was so far the only storage optimization implemented in RVHyper. We then provide a novel storage optimization technique based on prefixtrees, so-called tries, to exploit partial equality of the given traces.

Specification Analysis
In the example execution in Example 2 we have seen that the algorithm had to do more work than necessary to monitor observational determinism. For example, a tuple (t, t) for some trace t cannot violate observational determinism as the traces are equal. Further, from the pairs (t, t ′ ) and (t ′ , t) for some traces t and t ′ , we only need to check one of them as a violation in one of them implies the violation in the other pair. We can automatically check for such conditions and, thus, omit unnecessary work.
RVHyper implements the specification analysis with the HyperLTL satisfiability solver EAHyper [19,22]. The specification analysis is a preprocessing step that analyzes the HyperLTL formula under consideration. EAHyper can detect whether a formula is (1) symmetric, i.e., we halve the number of instantiated monitors, (2) transitive, i.e, we reduce the number of instantiated monitors to two, or (3) reflexive, i.e., we can omit the self comparison of traces.
Symmetry is particularly interesting since many information flow policies satisfy this property. Consider, for example, observational determinism: ∀π. ∀π ′ . (o π = o π ′ ) W (i π = i π ′ ). RVHyper detects symmetry by translating this formula to a formula that is unsatisfiable if there exists no set of traces for which every trace pair violates the symmetry condition: . If the resulting formula turns out to be unsatisfiable, RVHyper omits the symmetric instantiations of the monitor automaton.
Definition 2 [24] Let ψ be the quantifier-free part of some HyperLTL formula ϕ over trace variables {π 1 , π 2 }. Let T = {t 1 , t 2 , t 3 } ∈ Σ ω be a three-elemented set of traces. We define the assignment Π i,j : While symmetric HyperLTL formulas allow us to prune half of the monitor instances, transitivity of a Hyper-LTL formula has an even larger impact on the required memory. Equality, i.e, ∀π.∀π ′ . (a π ↔ a π ′ ), for example, is transitive and symmetric and allows us to reduce the number of monitor instances to one, since we can check equality against any reference trace.
Lastly, if a formula is reflexive, RVHyper omits the composition of a trace with itself during the monitoring process. For example, equality and observational determinism have reflexive HyperLTL formulas.
Example 3 Consider again the observational determinism formula from Example 1. We have seen that this formula is both, reflexive and symmetric, thus, we can omit those instances in the algorithm.

Optimizing Trace Storage
The main obstacle in monitoring hyperproperties is the potentially unbounded space consumption. Previously, RVHyper employed a trace analysis technique to detect redundant traces, with respect to a given HyperLTL formula, i.e., traces that can be safely discarded without losing any information and without losing the ability to return a counter example.

Definition 4 [24] Given a HyperLTL formula ϕ, a trace set T and an arbitrary t ∈ TR, we say that t is (T, ϕ)-redundant if T is a model of ϕ if and only if T ∪ {t} is a model of ϕ as well, formally
Definition 5 [24] Given t, t ′ ∈ Σ ω , we say t dominates t ′ with respect to ϕ (or simply t dominates t ′ if it is clear from the context) if t ′ is ({t}, ϕ)-redundant.
Example 4 For observational determinism, a trace t is dominated by a trace t ′ if |t| < |t ′ | and both traces agree on the input propositions. This is efficiently implemented in RVHyper (cf. Algorithm 2) and is guaranteed to catch all redundant traces. In our experiments [23,24], we made the observation that traces often share the same prefixes, leading to a lot of redundant monitor automaton instantiations, repetitive computations and duplicated information when those traces get stored.
The trace analysis, as it is based on a language inclusion check of the entire traces, cannot handle partial redundancy, for example, in the case that traces have redundant prefix requirements. This leaves room for optimization, which we address by implementing a trie data structure for managing the storage of incoming traces.
input : HyperLTL formula ϕ, redundancy free trace set T , fresh trace t output: redundancy free set of traces T min ⊆ T ∪ {t} 1 Mϕ = build_template(ϕ) Tries, also known as prefix trees are a tree data structure, which can represent a set of words over an alphabet in a compact manner. The root of a trie is identified with the empty word ǫ, additionally each node can have several child nodes, each of which corresponds to a unique letter getting appended to the representing word of the parent node. So the set of words of a trie is identified with the set of words the leaf nodes represent. Definition 6 A trie is a four tuple (Σ, T , −→, τ 0 ) consisting of a finite alphabet Σ, -a non-empty set of states T , -a transition function −→: T × Σ → T , -and a designated initial state τ 0 ∈ T called the root.
Instead of ((τ, a), τ ′ ) ∈−→ we will write τ a −→ τ ′ in the following. For a trie to be of valid form we restrict −→ such that, ∀τ, τ ′ ∈ T .|{τ a −→ τ ′ |a ∈ Σ}| ≤ 1. In our case the alphabet would be the set of propositions used in the specification, and the word built by the trie represents the traces. Instead of storing each trace individually, we store all of them in one trie structure, branching only in case of deviation. This means equal prefixes only have to be stored once. Besides the obvious benefits for memory, we also can make use of the maintained trie data structure to improve the runtime of our monitoring algorithms. As traces with same prefixes end up corresponding to the same path in the trie, we only have to instantiate the monitor automaton as much as the trie contains branches.

Trie-based Monitoring Algorithm
We depict a trie-based offline monitoring algorithm in Fig. 3. For the sake of readability, we assume that there are as many traces as universal quantifiers, that we progress through all traces in parallel, and that all traces have the same length. This is merely a simplification in the presentation, one can build the trie in a sequential fashion for online monitoring by a slight modification of the presented algorithm. Without using tries, our monitoring algorithm was based on instantiating the deterministic monitor template M ϕ with tuples of traces. Now we instantiate M ϕ with tuples of tries. Initially we only have to create the single instance having the the root of our trie.
The trie-based algorithm has much in common with its previously discussed trace-based counterpart. Initially, we have to build the deterministic monitor automaton M ϕ = (Σ V , Q, q 0 , δ, F ). We instantiate the monitor with a fresh trie root τ 0 . A mapping from trie instantiations to a state in M ϕ S : T n → Q, stores the current state of every active branch of the trie, stored in the set I. For each of the incoming traces, we provide an entry in a tuple of tries τ , each entry gets initialized to τ 0 . During the run of our algorithm these entries are updated such that they always correspond to the word built by the traces up to this point. For as long as there are traces left, which have not yet ended, and we have not yet detected a violation, we will proceed updating the entries in i as follows. Having entry τ and the correspond trace sequence proceeds with a, if ∃τ ′ ∈ T .τ a −→ τ ′ , we update the entry to τ ′ otherwise we create such a child node of τ (add_child in line 8). Creating a new node in the trie always occurs when the prefix of the incoming trace starts to differ from already seen prefixes. After having moved one step in our traces sequences, we have to reflect this step in our trie structure, in order for the trie-instantiated automata to correctly monitor the new propositions. As a trie node can branch to multiple child nodes, each monitor instantiation are replaced by the set of instantiations, where all possible child combinations of the different assigned tries are existent (update of I in line 11). Afterwards, we update S in the same way as in Algorithm 2, thus, we omit algorithmic details here. If a violation is detected here, that is there is no transition in the monitor corresponding to i, we will return the corresponding counter example as a tuple of traces, as those can get reconstructed by stepping upwards in the tries of i. If the traces end, we check if every open branch i ∈ I is in an accepting state.

Evaluation
In the following, we evaluate the new version of RVHyper, especially the novel trace storage optimization. We use several benchmarks: an encoder that guarantees a Hamming-distance of 2, violations of noninterference on randomly generated traces, and a symmetry input : ∀ n HyperLTL formula ϕ output: satisfied or n-ary tuple witnessing violation 1 Mϕ = (Σ V , Q, q 0 , δ, F ) = build_template(ϕ) 2 S : T n → Q 3 τ 0 :=new_trie() 4 i := (τ 0 , . . . , τ 0 ) ∈ T n 5 I := {i} // set of not-yet terminated branches // add child with value p(j) to i(j) if needed 9 end 10 // update set of active branches property on an implementation of the Bakery protocol. As an example how RVHyper can be used outside security runtime verification, we give a case study on detecting spurious dependencies in hardware designs.

Error Correcting Codes
We monitored whether an encoder preserves a Hamming-distance of 2. We randomly built traces of length 50. In each position of the trace, the corresponding bit had a 1% chance to be flipped. The specification can be encoded as the following HyperLTL formula [26]: The right plot of Figure 2 shows the results of our experiments. We compared the naive monitoring approach to different combinations of RVHyper's optimizations. The specification analysis returns in under one second with the result that the formula is symmetric and reflexive. Hence, as expected, this preprocessing step has a major impact on the running time of the monitoring process as more than half of the, in general necessary, monitor instantiations can be omitted. A combination of the specification and trace analysis performs nearly equally well as naively storing the traces in our trie data structure. Combining the trie data structure with the specification analysis performs best and results in a tremendous speed-up compared to the naive approach.

Checking Noninterference
Non-interference [33] is an important information flow policy demanding that an observer of a system cannot infer any high security input of a system by observing only low security input and output. Formally, we specify that all low security outputs o low have to be equal on all system executions as long as the low security inputs i low of those executions are the same: ∀π, π ′ . ( o low π ↔ o low π ′ ) W( i low π i low π ′ ). This class of benchmarks has previously been used to evaluated RVHyper [23]. We repeated the experiments, to show that using the trie data structure is a valid optimization. The results are depicted in Table 1. We chose a trace length of 50 and monitored non-interference on 2000 randomly generated traces, where we distinguish between an input range of 8 to 64 bits. The results show, that the trie optimization has an enormous impact compared to a naive approach that solely relies on the specification analysis. As expected, the difference in runtime is especially high on experiments where traces collapse heavily in the trie data structure, i.e., producing almost no instances that must be considered during the monitoring process.

Symmetry in Mutual Exclusion Protocols
In this benchmark (introduced as a case study in [26]), we monitor whether a Verilog implementation of the bakery protocol [31] from the VIS verification bench-   mark satisfies a symmetry property. Symmetry violations indicate that certain clients are privileged. The Bakery protocol is a classical protocol implementing mutual exclusion, working as follows: every process that wishes to access a critical resource draws a ticket, which is consecutively numbered. The process with the smallest number may access the resource first. If two processes draw a ticket concurrently, i.e., obtaining the same number, the process with the smaller process ID may access the resource first. We monitored the following HyperLTL formula [26]: where select indicates the process ID that runs in the next step and pause indicates whether the step is stuttering. Each process i has a program counter pc(i) and when process i is selected, pc(i) is executed. sym(select π , select π ′ ) states that process 0 is selected on trace π and process 1 is selected on trace π ′ . Unsurprisingly, the implementation violates the specification, as it is provably impossible to implement a mutual exclusion protocol that is entirely symmetric [32]. Figure 3 shows the results of our experiment. In this benchmark, we can observe that the language inclusion check, on which the trace optimization is based on, produces an overhead during the monitoring. Since the traces differ a lot, the trace analysis cannot prune enough traces to be valuable. As there are only a few instances (in this case 4), the trie optimization outperforms the previous version of RVHyper massively on such a low instance count. The specification analysis, however, is always a valuable optimization.

Case Study: Detecting Spurious Dependencies in Hardware Designs
While HyperLTL has been applied to a range of domains, including security and information flow properties, we focus in the following on a classical verification problem, the independence of signals in hardware designs. We demonstrate how RVHyper can automatically detect such dependencies from traces generated from hardware designs.
Input & Output. The input to RVHyper is a set of traces and a HyperLTL formula. For the following experiments, we generate a set of traces from the Ver- ilog description of several example circuits by random simulation. If a set of traces violates the specification, RVHyper returns a counter example.
Specification. We consider the problem of detecting whether input signals influence output signals in hardware designs. We write i o to denote that the inputs i do not influence the outputs o. Formally, we specify this property as the following HyperLTL formula: where i denotes all inputs except i. Intuitively, the formula asserts that for every two pairs of execution traces (π 1 , π 2 ) the value of o has to be the same until there is a difference between π 1 and π 2 in the input vector i, i.e., the inputs on which o may depend. Sample Hardware Designs. We apply RVHyper to traces generated from the following hardware designs. Note that, since RVHyper observes traces and treats the system that generates the traces as a black box, the performance of RVHyper does not depend on the size of the circuit. Example 6 ( xor) As a first example, consider the xor function o = i ⊕ i ′ . In the corresponding circuit, every j-th output bit o j is only influenced by the j-the input bits i j and i ′ j . Example 7 ( mux) This example circuit is depicted in Figure 4. There is a black box combinatorial circuit, guarded by a multiplexer that selects between the two input vectors i and i ′ and an inverse multiplexer that forwards the output of the black box either towards o or o ′ . Despite there being a syntactic dependency between o and i ′ , there is no semantic dependency, i.e., the output o does solely depend on i and the selector signal. When using the same example, but with a sequential circuit as black box, there may be information flow from the input vector i ′ to the output vector o because the state of the latches may depend on it. We construct such a circuit that leaks information about i ′ via its internal state.
The left part of Fig. 2 shows the total runtime of RVHyper with the different optimizations and a combination thereof. As observed in our previous experiments, the specification analysis, if applicable as in this case, is a valuable optimization consistently reducing the runtime and does so also when combined with the trace analysis. As expected, the runtime is halved by exploiting symmetry and reflexivity in the formula. From the plot we can also infer that the trace analysis is effective in a context with a majority of redundant traces. For such a highly redundant setup the trace analysis reduces the overall runtime of the monitoring algorithm by several magnitudes. With a decrease of similarity and redundancy in the traces the positive effect of the trace analysis steadily decreases up until the overhead of the trace analysis itself gets noticeable. The decrease in runtime for configurations without trace analysis, which comes with reduced traces similarity, is explained by the fact that the more the input of the monitored traces is different the earlier trace tuples can get pruned as they satisfy the specification and thereby reduce the computational burden of the algorithm. This is also the reason why the configurations with trace analysis show decreasing runtime behavior again as soon as the afore-mentioned effects dominate the runtime characteristics of the monitoring approach. In contrast to that, the trie optimization provides a stable improvement on the running time.
Example 8 (counter) Our last example is a binary counter with two input control bits incr and decr that increments and decrements the counter. The corresponding Verilog design is shown in Figure 5. The counter has a single output, namely a signal that is set to one when the counter value overflows. Both inputs influence the output, but timing of the overflow depends on the number of counter bits.
Results. The results of multiple random simulations are given in Table 2. Even the previous version of RVHyper was able to scale up to thousands of input traces with millions of monitor instantiations. The novel implemented optimization of RVHyper, i.e., storing the traces in a prefix tree data structure combined with our specification analysis, results in a remarkable speed-up. Especially interesting is the reduction of the number of instances in the counter example. As there is only one input, the traces collapse in our trie data structure. For the two instances where the property is satisfied (xor and mux), RVHyper has not found a violation for any of the runs. For instances where the property is violated, RVHyper was able to find counter examples.

Conclusion
RVHyper monitors a running system for violations of a HyperLTL specification. We have introduced a novel trace storage optimization, based on a prefix-tree data structure, to existing optimizations implemented in RVHyper.
We demonstrated the impact of the optimizations on RVHypers performance on several benchmarks of runtime verification problems. By providing a use case on how RVHyper can be used to detect spurious dependencies in hardware design, we showed how RVHyper can be used outside of classical security monitoring problems. The functionality of RVHyper thus complements model checking tools for HyperLTL, like MCHyper [26], tools for satisifability checking, like EAHyper [22], and tools for synthesis, like BoSyHyper [21].
RVHyper is in particular useful during the development of a HyperLTL specification, where it can be used to check the HyperLTL formula on sample traces without the need for a complete model. Based on the feedback of the tool, the user can refine the HyperLTL formula until it captures the intended policy.
In our current approach, the trace analysis and the trie representation are separate optimizations that cannot be applied at the same time. The integration of the two optimization is an interesting challenge for future work.