<buttonid="sidebar-toggle"class="icon-button"type="button"title="Toggle Table of Contents"aria-label="Toggle Table of Contents"aria-controls="sidebar">
<ahref="../print.html"title="Print this book"aria-label="Print this book">
<iid="print-button"class="fa fa-print"></i>
</a>
</div>
</div>
<divid="search-wrapper"class="hidden">
<formid="searchbar-outer"class="searchbar-outer">
<inputtype="search"name="search"id="searchbar"name="searchbar"placeholder="Search this book ..."aria-controls="searchresults-outer"aria-describedby="searchresults-header">
<h1><aclass="header"href="#tips-and-tricks"id="tips-and-tricks">Tips and tricks</a></h1>
<p>This section contains various ideas and snippets that you might find useful while writing
halo2 circuits.</p>
<h2><aclass="header"href="#small-range-constraints"id="small-range-constraints">Small range constraints</a></h2>
<p>A common constraint used in R1CS circuits is the boolean constraint: <spanclass="katex"><spanclass="katex-html"aria-hidden="true"><spanclass="base"><spanclass="strut"style="height:0.69444em;vertical-align:0em;"></span><spanclass="mord mathnormal">b</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span><spanclass="mbin">∗</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span></span><spanclass="base"><spanclass="strut"style="height:1em;vertical-align:-0.25em;"></span><spanclass="mopen">(</span><spanclass="mord">1</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span><spanclass="mbin">−</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span></span><spanclass="base"><spanclass="strut"style="height:1em;vertical-align:-0.25em;"></span><spanclass="mord mathnormal">b</span><spanclass="mclose">)</span><spanclass="mspace"style="margin-right:0.2777777777777778em;"></span><spanclass="mrel">=</span><spanclass="mspace"style="margin-right:0.2777777777777778em;"></span></span><spanclass="base"><spanclass="strut"style="height:0.64444em;vertical-align:0em;"></span><spanclass="mord">0</span></span></span></span>.
This constraint can only be satisfied by <spanclass="katex"><spanclass="katex-html"aria-hidden="true"><spanclass="base"><spanclass="strut"style="height:0.69444em;vertical-align:0em;"></span><spanclass="mord mathnormal">b</span><spanclass="mspace"style="margin-right:0.2777777777777778em;"></span><spanclass="mrel">=</span><spanclass="mspace"style="margin-right:0.2777777777777778em;"></span></span><spanclass="base"><spanclass="strut"style="height:0.64444em;vertical-align:0em;"></span><spanclass="mord">0</span></span></span></span> or <spanclass="katex"><spanclass="katex-html"aria-hidden="true"><spanclass="base"><spanclass="strut"style="height:0.69444em;vertical-align:0em;"></span><spanclass="mord mathnormal">b</span><spanclass="mspace"style="margin-right:0.2777777777777778em;"></span><spanclass="mrel">=</span><spanclass="mspace"style="margin-right:0.2777777777777778em;"></span></span><spanclass="base"><spanclass="strut"style="height:0.64444em;vertical-align:0em;"></span><spanclass="mord">1</span></span></span></span>.</p>
<p>In halo2 circuits, you can similarly constrain a cell to have one of a small set of
values. For example, to constrain <spanclass="katex"><spanclass="katex-html"aria-hidden="true"><spanclass="base"><spanclass="strut"style="height:0.43056em;vertical-align:0em;"></span><spanclass="mord mathnormal">a</span></span></span></span> to the range <spanclass="katex"><spanclass="katex-html"aria-hidden="true"><spanclass="base"><spanclass="strut"style="height:1em;vertical-align:-0.25em;"></span><spanclass="mopen">[</span><spanclass="mord">0</span><spanclass="mord">.</span><spanclass="mord">.</span><spanclass="mord">5</span><spanclass="mclose">]</span></span></span></span>, you would create a gate of
<p>while to constraint <spanclass="katex"><spanclass="katex-html"aria-hidden="true"><spanclass="base"><spanclass="strut"style="height:0.43056em;vertical-align:0em;"></span><spanclass="mord mathnormal">c</span></span></span></span> to be either 7 or 13, you would use:</p>
<p>The underlying principle here is that we create a polynomial constraint with roots at
each value in the set of possible values we want to allow. In R1CS circuits, the maximum
supported polynomial degree is 2 (due to all constraints being of the form <spanclass="katex"><spanclass="katex-html"aria-hidden="true"><spanclass="base"><spanclass="strut"style="height:0.46528em;vertical-align:0em;"></span><spanclass="mord mathnormal">a</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span><spanclass="mbin">∗</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span></span><spanclass="base"><spanclass="strut"style="height:0.69444em;vertical-align:0em;"></span><spanclass="mord mathnormal">b</span><spanclass="mspace"style="margin-right:0.2777777777777778em;"></span><spanclass="mrel">=</span><spanclass="mspace"style="margin-right:0.2777777777777778em;"></span></span><spanclass="base"><spanclass="strut"style="height:0.43056em;vertical-align:0em;"></span><spanclass="mord mathnormal">c</span></span></span></span>).
In halo2 circuits, you can use arbitrary-degree polynomials - with the proviso that
higher-degree constraints are more expensive to use.</p>
</blockquote>
<p>Note that the roots don't have to be constants; for example <spanclass="katex"><spanclass="katex-html"aria-hidden="true"><spanclass="base"><spanclass="strut"style="height:1em;vertical-align:-0.25em;"></span><spanclass="mopen">(</span><spanclass="mord mathnormal">a</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span><spanclass="mbin">−</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span></span><spanclass="base"><spanclass="strut"style="height:1em;vertical-align:-0.25em;"></span><spanclass="mord mathnormal">x</span><spanclass="mclose">)</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span><spanclass="mbin">⋅</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span></span><spanclass="base"><spanclass="strut"style="height:1em;vertical-align:-0.25em;"></span><spanclass="mopen">(</span><spanclass="mord mathnormal">a</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span><spanclass="mbin">−</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span></span><spanclass="base"><spanclass="strut"style="height:1em;vertical-align:-0.25em;"></span><spanclass="mord mathnormal"style="margin-right:0.03588em;">y</span><spanclass="mclose">)</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span><spanclass="mbin">⋅</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span></span><spanclass="base"><spanclass="strut"style="height:1em;vertical-align:-0.25em;"></span><spanclass="mopen">(</span><spanclass="mord mathnormal">a</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span><spanclass="mbin">−</span><spanclass="mspace"style="margin-right:0.2222222222222222em;"></span></span><spanclass="base"><spanclass="strut"style="height:1em;vertical-align:-0.25em;"></span><spanclass="mord mathnormal"style="margin-right:0.04398em;">z</span><spanclass="mclose">)</span><spanclass="mspace"style="margin-right:0.2777777777777778em;"></span><spanclass="mrel">=</span><spanclass="mspace"style="margin-right:0.2777777777777778em;"></span></span><spanclass="base"><spanclass="strut"style="height:0.64444em;vertical-align:0em;"></span><spanclass="mord">0</span></span></span></span> will constrain <spanclass="katex"><spanclass="katex-html"aria-hidden="true"><spanclass="base"><spanclass="strut"style="height:0.43056em;vertical-align:0em;"></span><spanclass="mord mathnormal">a</span></span></span></span> to be equal to one of <spanclass="katex"><spanclass="katex-html"aria-hidden="true"><spanclass="base"><spanclass="strut"style="height:1em;vertical-align:-0.25em;"></span><spanclass="mopen">{</span><spanclass="mord mathnormal">x</span><spanclass="mpunct">,</span><spanclass="mspace"style="margin-right:0.16666666666666666em;"></span><spanclass="mord mathnormal"style="margin-right:0.03588em;">y</span><spanclass="mpunct">,</span><spanclass="mspace"style="margin-right:0.16666666666666666em;"></span><spanclass="mord mathnormal"style="margin-right:0.04398em;">z</span><spanclass="mclose">}</span></span></span></span> where the latter can be arbitrary polynomials, as long as the whole expression stays within the maximum degree bound.</p>