---
# System prepended metadata

title: Interactions in plonky3

---

# Interactions in plonky3

In the valida/sp1 architecture, STARKs communicate with each other through a bus. This communication is defined as a set of interactions that a STARK sends or receives to a bus. These interactions are compiled to multiset checks and are constrained using logUp.

```rust
pub trait Chip<F: Field> {
    fn sends(&self) -> Vec<Interaction<F>>;

    fn receives(&self) -> Vec<Interaction<F>>;
}
```
An interaction is defined as:

```rust
pub struct Interaction<F: Field> {
    pub fields: Vec<VirtualPairCol<F>>,
    pub count: VirtualPairCol<F>,
    pub argument_index: usize,
}
```

Each interaction consists of:
1. `fields`: Specifies the `VirtualPairCol`s that are involved in the interaction
2. `count`: Specifies the multiplicity of each row in the interaction
3. `argument_index`: A unique integer given to each bus

A `VirtualPairCol` is a linear function over a set of columns of the form $f(\textbf{C}) = b + \sum w_i C_i$.

```rust
pub struct VirtualPairCol<F: Field> {
    column_weights: Vec<(PairCol, F)>,
    constant: F,
}
```

Each interaction adds a new column to the permutation trace. Let the bus index be $b$ and let $f_k(\textbf{C}_k)$ be the $k$th field of an interaction. The added column would then be:


$$
P = \frac{1}{\alpha^{b} + \sum_k \beta^k \cdot f_k(\textbf{C}_k)}
$$

Finally, the values of each added column are combined to form a new partial sum column where each row is calculated as:

$$
S[i] = S[i-1] + \sum_{j\in sends} m_j[i] * P_j[i] - \sum_{j\in receives} m_j[i] * P_j[i]
$$

Here, $m_j$ specifies the count/multiplicity of the interaction

The last value of the partial sum column gives a single `cumulative_sum` value that summarizes all the interactions involved in a STARK.

If each "send" from a STARK is paired with a "receive" from another STARK, then the `cumulative_sum` values across all STARKs will add up to zero. This is checked by the verifier.


##### Why use `VirtualPairCol` instead of specifying a single Column for the interaction?

A case where this is useful is when one STARK stores a value represented as a byte while the other STARK stores the value as bits spread across 8 columns. A `VirtualPairCol` can be used to create a "virtual" column that linearly combines the bit columns from the second STARK to get a byte value. This byte value can then be matched with the byte value from the first STARK.
