Skip to content

Instantly share code, notes, and snippets.

@RareSkills
Created July 4, 2024 06:34
Show Gist options
  • Select an option

  • Save RareSkills/0575eb9317c85f6181ce022d8244cd0e to your computer and use it in GitHub Desktop.

Select an option

Save RareSkills/0575eb9317c85f6181ce022d8244cd0e to your computer and use it in GitHub Desktop.
Underconstrained sort algorithm
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