Created
July 4, 2024 06:34
-
-
Save RareSkills/0575eb9317c85f6181ce022d8244cd0e to your computer and use it in GitHub Desktop.
Underconstrained sort algorithm
This file contains hidden or 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
| pragma circom 2.1.8; | |
| include "./node_modules/circomlib/circuits/multiplexer.circom"; | |
| include "./node_modules/circomlib/circuits/comparators.circom"; | |
| // checks if the second array is a | |
| // permutation of the first based on | |
| // the advice | |
| template ForceIsPermutation(n) { | |
| signal input in1[n]; | |
| signal input in2[n]; | |
| signal input advice[n]; | |
| component mux[n]; | |
| // for each input in1... | |
| for (var i = 0; i < n; i++) { | |
| // load all of in1 into the mux | |
| mux[i] = Multiplexer(1, n); | |
| for (var j = 0; j < n; j++) { | |
| mux[i].inp[j][0] <== in1[j]; | |
| } | |
| // select the index from the advice | |
| mux[i].sel <== advice[i]; | |
| // check that in2[i] == in1[advice[i]] | |
| in2[i] === mux[i].out[0]; | |
| } | |
| } | |
| template ForceIsSorted(n, bitSize) { | |
| signal input in[n]; | |
| component leq[n]; | |
| // each item is ≤ the next | |
| for (var i = 0; i < n - 1; i++) { | |
| leq[i] = LessEqThan(bitSize); | |
| leq[i].in[0] <== in[i]; | |
| leq[i].in[1] <== in[i + 1]; | |
| 1 === leq[i].out; | |
| } | |
| } | |
| template Sort(n, bitSize) { | |
| signal input in[n]; | |
| // each index of advice corresponds to | |
| // the index of ouput. The element in the | |
| // array tells where input index. For example, | |
| // if the output is [5,6,7] and the input is [5,7,6] | |
| // then the advice will be [0,2,1] or "5 was originally | |
| // at 0, 6 was originally at 2, and 7 was originaly at 1 | |
| signal output advice[n]; | |
| signal output out[n]; | |
| var arr[n]; | |
| var advice_[n]; | |
| // copy in to arr | |
| for (var i = 0; i < n; i++) { | |
| arr[i] = in[i]; | |
| advice_[i] = i; | |
| } | |
| // selection sort arr | |
| for (var i = 0; i < n; i++) { | |
| // find the minimum element and where | |
| // it is located | |
| var min_at = i; | |
| for (var j = i; j < n; j++) { | |
| if (arr[j] < arr[min_at]) { | |
| min_at = j; | |
| } | |
| } | |
| // swap with the minimum | |
| var temp = arr[i]; | |
| arr[i] = arr[min_at]; | |
| arr[min_at] = temp; | |
| // swap advice | |
| var temp2 = advice_[i]; | |
| advice_[i] = advice_[min_at]; | |
| advice_[min_at] = temp2; | |
| } | |
| // copy sorted arr to out | |
| for (var i = 0; i < n; i++) { | |
| out[i] <-- arr[i]; | |
| advice[i] <-- advice_[i]; | |
| } | |
| ForceIsSorted(n, bitSize)(out); | |
| ForceIsPermutation(n)(in, out, advice); | |
| } | |
| component main = Sort(10, 252); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment