-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
163 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Multiplexing | ||
|
||
Multiplexing is a technique to select one of many signals based on a control signal. It is often used to switch between different signals or to select a signal based on a condition. | ||
|
||
## `Mux1` | ||
|
||
```cs | ||
template Mux1() { | ||
signal input in[2]; | ||
signal input sel; | ||
signal output out; | ||
|
||
out <== (in[1] - in[0]) * sel + in[0]; | ||
} | ||
``` | ||
|
||
`Mux1` is actually the same circuit as `IfElse` we defined in this section. Its just that the naming is a bit different, such that it is generalizable to higher multiplexers. | ||
|
||
- `in[0]` is `ifFalse` | ||
- `in[1]` is `ifTrue` | ||
- `sel` is `cond` | ||
- `out` is `out` | ||
|
||
The main idea here is that `in` has number of values equal to the number of bits of `sel`, and `out = in[sel]`. | ||
|
||
To compute this expression, on can construct the truth table and then its corresponding boolean expression. The truth table for `Mux1` is: | ||
|
||
| sel | out | | ||
| --- | ------- | | ||
| 0 | `in[0]` | | ||
| 1 | `in[1]` | | ||
|
||
## `Mux2` | ||
|
||
```cs | ||
template Mux2() { | ||
signal input in[4]; | ||
signal input sel[2]; | ||
signal output out; | ||
|
||
// due to multiplication we need an auxiliary signal | ||
signal sel_0_sel_1 <== sel[1] * sel[0]; | ||
|
||
signal a11 <== (in[3] - in[2] - in[1] + in[0]) * sel_0_sel_1; | ||
signal a10 <== (in[2] - in[0]) * sel[1]; | ||
signal a01 <== (in[1] - in[0]) * sel[0]; | ||
signal a00 <== in[0]; | ||
|
||
out <== (a11 + a10 + a01 + a00); | ||
} | ||
``` | ||
|
||
One can actually construct a `Mux2` using three `Mux1` circuits. | ||
|
||
- `inA <== Mux1(in[0], in[1], sel[0])` | ||
- `inB <== Mux1(in[2], in[3], sel[0])` | ||
- `out <== Mux1(inA, inB, sel[1])` | ||
|
||
## Larger Multiplexers | ||
|
||
There are larger multiplexing circuits, e.g. [`Mux3`](https://github.com/iden3/circomlib/blob/circomlib2/circuits/mux3.circom), [`Mux4`](https://github.com/iden3/circomlib/blob/circomlib2/circuits/mux4.circom), etc. but we will not cover them here. |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// "2-to-1" multiplexer. | ||
// | ||
// Inputs: | ||
// - in: inputs | ||
// - sel: selector bit | ||
// | ||
// Outputs: | ||
// - out: equals in[sel] | ||
template Mux1() { | ||
signal input in[2]; | ||
signal input sel; | ||
signal output out; | ||
|
||
out <== (in[1] - in[0]) * sel + in[0]; | ||
} | ||
|
||
// "4-to-1" multiplexer. | ||
// | ||
// Inputs: | ||
// - in: inputs | ||
// - sel: selector bits | ||
// | ||
// Outputs: | ||
// - out: equals in[2*sel[1] + sel[0]] | ||
template Mux2() { | ||
signal input in[4]; | ||
signal input sel[2]; | ||
signal output out; | ||
|
||
// due to multiplication we need an auxiliary signal | ||
signal sel_0_sel_1 <== sel[1] * sel[0]; | ||
|
||
signal a11 <== (in[3] - in[2] - in[1] + in[0]) * sel_0_sel_1; | ||
signal a10 <== (in[2] - in[0]) * sel[1]; | ||
signal a01 <== (in[1] - in[0]) * sel[0]; | ||
signal a00 <== in[0]; | ||
|
||
out <== (a11 + a10 + a01 + a00); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// auto-generated by circomkit | ||
pragma circom 2.0.0; | ||
|
||
include "../../control-flow/multiplexing.circom"; | ||
|
||
component main = Mux2(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { circomkit } from "../common"; | ||
import { describe, beforeAll, it } from "bun:test"; | ||
|
||
describe("multiplexing", () => { | ||
it("2-to-1 multiplex", async () => { | ||
const circuit = await circomkit.WitnessTester<["in", "sel"], ["out"]>(`mux1`, { | ||
file: "control-flow/multiplexing", | ||
template: "Mux1", | ||
dir: "test/control-flow", | ||
}); | ||
|
||
const input = [101, 202]; | ||
await circuit.expectPass({ in: input, sel: 0 }, { out: input[0] }); | ||
await circuit.expectPass({ in: input, sel: 1 }, { out: input[1] }); | ||
}); | ||
|
||
it("4-to-1 multiplex", async () => { | ||
const circuit = await circomkit.WitnessTester<["in", "sel"], ["out"]>(`mux1`, { | ||
file: "control-flow/multiplexing", | ||
template: "Mux2", | ||
dir: "test/control-flow", | ||
}); | ||
|
||
const input = [234, 678, 123, 987]; | ||
await circuit.expectPass({ in: input, sel: [0, 0] }, { out: input[0] }); | ||
await circuit.expectPass({ in: input, sel: [1, 0] }, { out: input[1] }); | ||
await circuit.expectPass({ in: input, sel: [0, 1] }, { out: input[2] }); | ||
await circuit.expectPass({ in: input, sel: [1, 1] }, { out: input[3] }); | ||
}); | ||
}); |