mirror of
https://github.com/arnaucube/sonobe-playground.git
synced 2026-01-13 17:41:28 +01:00
Bring grayscale circuit from vimz
This commit is contained in:
97
circuit/grayscale_step.circom
Normal file
97
circuit/grayscale_step.circom
Normal file
@@ -0,0 +1,97 @@
|
||||
pragma circom 2.0.0;
|
||||
|
||||
include "utils/row_hasher.circom";
|
||||
include "utils/pixels.circom";
|
||||
include "node_modules/circomlib/circuits/bitify.circom";
|
||||
|
||||
|
||||
template GrayscaleChecker(n) {
|
||||
signal input orig[n][3];
|
||||
signal input gray[n];
|
||||
|
||||
signal output n_check;
|
||||
|
||||
component lt[n][2];
|
||||
|
||||
for (var i = 0; i < n; i++) {
|
||||
var inter = 299 * orig[i][0] + 587 * orig[i][1] + 114 * orig[i][2];
|
||||
|
||||
lt[i][0] = LessEqThan(18);
|
||||
lt[i][1] = LessEqThan(18);
|
||||
|
||||
lt[i][0].in[1] <== 1000;
|
||||
lt[i][0].in[0] <== inter - 1000 * gray[i];
|
||||
lt[i][0].out === 1;
|
||||
|
||||
lt[i][1].in[1] <== 1000;
|
||||
lt[i][1].in[0] <== 1000 * gray[i] - inter;
|
||||
lt[i][1].out === 1;
|
||||
}
|
||||
n_check <== n;
|
||||
}
|
||||
|
||||
template GrayScale(width){
|
||||
|
||||
signal input original[width];
|
||||
signal input transformed[width];
|
||||
|
||||
component decompressor[width];
|
||||
component decompressor_grey[width];
|
||||
component greychecker[width];
|
||||
|
||||
for (var j=0; j<width; j++) {
|
||||
decompressor[j] = Decompressor();
|
||||
decompressor[j].in <== original[j];
|
||||
|
||||
decompressor_grey[j] = DecompressorGrey();
|
||||
decompressor_grey[j].in <== transformed[j];
|
||||
|
||||
greychecker[j] = GrayscaleChecker(10);
|
||||
greychecker[j].orig <== decompressor[j].out;
|
||||
greychecker[j].gray <== decompressor_grey[j].out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template GrayScaleHash(width){
|
||||
signal input ivc_input[2];
|
||||
// signal input prev_orig_hash;
|
||||
// signal input prev_gray_hash;
|
||||
signal output ivc_output[2];
|
||||
// signal output next_orig_hash;
|
||||
// signal output next_gray_hash;
|
||||
|
||||
// Private inputs
|
||||
signal input external_inputs [2 * width];
|
||||
|
||||
signal row_orig [width];
|
||||
signal row_tran [width];
|
||||
|
||||
for (var i = 0; i < width; i++) {
|
||||
row_orig[i] <== external_inputs[i];
|
||||
row_tran[i] <== external_inputs[i + width];
|
||||
}
|
||||
|
||||
component orig_row_hasher = RowHasher(width);
|
||||
component gray_row_hasher = RowHasher(width);
|
||||
component orig_hasher = Hasher(2);
|
||||
component gray_hasher = Hasher(2);
|
||||
|
||||
orig_row_hasher.img <== row_orig;
|
||||
orig_hasher.values[0] <== ivc_input[0]; // prev_orig_hash
|
||||
orig_hasher.values[1] <== orig_row_hasher.hash;
|
||||
ivc_output[0] <== orig_hasher.hash; // next_orig_hash
|
||||
|
||||
gray_row_hasher.img <== row_tran;
|
||||
gray_hasher.values[0] <== ivc_input[1]; // prev_gray_hash
|
||||
gray_hasher.values[1] <== gray_row_hasher.hash;
|
||||
ivc_output[1] <== gray_hasher.hash; // next_grey_hash
|
||||
|
||||
// grayscale code here ...
|
||||
component checker = GrayScale(width);
|
||||
checker.original <== row_orig;
|
||||
checker.transformed <== row_tran;
|
||||
|
||||
}
|
||||
|
||||
component main { public [ivc_input] } = GrayScaleHash(128);
|
||||
9
circuit/package.json
Normal file
9
circuit/package.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "circom",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"circomlib": "^2.0.5"
|
||||
}
|
||||
}
|
||||
153
circuit/utils/pixels.circom
Normal file
153
circuit/utils/pixels.circom
Normal file
@@ -0,0 +1,153 @@
|
||||
pragma circom 2.0.0;
|
||||
include "../node_modules/circomlib/circuits/bitify.circom";
|
||||
include "../node_modules/circomlib/circuits/mux1.circom";
|
||||
include "../node_modules/circomlib/circuits/comparators.circom";
|
||||
|
||||
template Decompressor(){
|
||||
signal input in;
|
||||
signal output out[10][3];
|
||||
|
||||
component toBits = Num2Bits(240);
|
||||
component toNum[10][3];
|
||||
|
||||
toBits.in <== in;
|
||||
|
||||
for (var i=0; i<10; i++) {
|
||||
for (var j=0; j<3; j++) {
|
||||
toNum[i][j] = Bits2Num(8);
|
||||
toNum[i][j].in[0] <== toBits.out[i*24+j*8];
|
||||
toNum[i][j].in[1] <== toBits.out[i*24+j*8+1];
|
||||
toNum[i][j].in[2] <== toBits.out[i*24+j*8+2];
|
||||
toNum[i][j].in[3] <== toBits.out[i*24+j*8+3];
|
||||
toNum[i][j].in[4] <== toBits.out[i*24+j*8+4];
|
||||
toNum[i][j].in[5] <== toBits.out[i*24+j*8+5];
|
||||
toNum[i][j].in[6] <== toBits.out[i*24+j*8+6];
|
||||
toNum[i][j].in[7] <== toBits.out[i*24+j*8+7];
|
||||
out[i][j] <== toNum[i][j].out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template DecompressorKernel(kernel_size){
|
||||
signal input in;
|
||||
signal output out[kernel_size][kernel_size];
|
||||
|
||||
component toBits = Num2Bits(kernel_size*kernel_size*9); // 8-bit value, 1-bit sign
|
||||
component toNum[kernel_size][kernel_size];
|
||||
component selector[kernel_size][kernel_size];
|
||||
|
||||
toBits.in <== in;
|
||||
|
||||
for (var i=0; i<kernel_size; i++) {
|
||||
for (var j=0; j<kernel_size; j++) {
|
||||
toNum[i][j] = Bits2Num(8);
|
||||
toNum[i][j].in[0] <== toBits.out[i*kernel_size*9+j*9];
|
||||
toNum[i][j].in[1] <== toBits.out[i*kernel_size*9+j*9+1];
|
||||
toNum[i][j].in[2] <== toBits.out[i*kernel_size*9+j*9+2];
|
||||
toNum[i][j].in[3] <== toBits.out[i*kernel_size*9+j*9+3];
|
||||
toNum[i][j].in[4] <== toBits.out[i*kernel_size*9+j*9+4];
|
||||
toNum[i][j].in[5] <== toBits.out[i*kernel_size*9+j*9+5];
|
||||
toNum[i][j].in[6] <== toBits.out[i*kernel_size*9+j*9+6];
|
||||
toNum[i][j].in[7] <== toBits.out[i*kernel_size*9+j*9+7];
|
||||
|
||||
var value = toNum[i][j].out; // value
|
||||
var sign = toBits.out[i*kernel_size*9+j*9+8]; // sign
|
||||
|
||||
selector[i][j] = Mux1();
|
||||
selector[i][j].c[0] <== value;
|
||||
selector[i][j].c[1] <== 0 - value;
|
||||
selector[i][j].s <== sign;
|
||||
|
||||
out[i][j] <== selector[i][j].out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template DecompressorGrey(){
|
||||
signal input in;
|
||||
signal output out[10];
|
||||
|
||||
component toBits = Num2Bits(240);
|
||||
component toNum[10];
|
||||
|
||||
toBits.in <== in;
|
||||
|
||||
for (var i=0; i<10; i++) {
|
||||
var j=0;
|
||||
toNum[i] = Bits2Num(8);
|
||||
toNum[i].in[0] <== toBits.out[i*24];
|
||||
toNum[i].in[1] <== toBits.out[i*24+1];
|
||||
toNum[i].in[2] <== toBits.out[i*24+2];
|
||||
toNum[i].in[3] <== toBits.out[i*24+3];
|
||||
toNum[i].in[4] <== toBits.out[i*24+4];
|
||||
toNum[i].in[5] <== toBits.out[i*24+5];
|
||||
toNum[i].in[6] <== toBits.out[i*24+6];
|
||||
toNum[i].in[7] <== toBits.out[i*24+7];
|
||||
out[i] <== toNum[i].out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template CompressorCrop(){
|
||||
signal input in[10];
|
||||
signal output out;
|
||||
|
||||
component toNum = Bits2Num(240);
|
||||
component toBits[10];
|
||||
|
||||
for (var i=0; i<10; i++) {
|
||||
toBits[i] = Num2Bits(24);
|
||||
toBits[i].in <== in[i];
|
||||
for (var j=0; j<24; j++) {
|
||||
toNum.in[i*24+j] <== toBits[i].out[j];
|
||||
}
|
||||
}
|
||||
out <== toNum.out;
|
||||
}
|
||||
|
||||
template DecompressorCrop(){
|
||||
signal input in;
|
||||
signal output out[10];
|
||||
|
||||
component decomp = DecompressorGrey();
|
||||
|
||||
decomp.in <== in;
|
||||
out <== decomp.out;
|
||||
}
|
||||
|
||||
template CropInfoDecompressor(){
|
||||
|
||||
signal input in;
|
||||
signal output row_index;
|
||||
signal output x;
|
||||
signal output y;
|
||||
|
||||
component toBits = Num2Bits(36);
|
||||
component toNumX = Bits2Num(12);
|
||||
component toNumY = Bits2Num(12);
|
||||
component toNumIndex = Bits2Num(12);
|
||||
|
||||
toBits.in <== in;
|
||||
for (var i=0; i<12; i++) {
|
||||
toNumX.in[i] <== toBits.out[i];
|
||||
toNumY.in[i] <== toBits.out[i+12];
|
||||
toNumIndex.in[i] <== toBits.out[i+24];
|
||||
}
|
||||
|
||||
x <== toNumX.out;
|
||||
y <== toNumY.out;
|
||||
row_index <== toNumIndex.out;
|
||||
}
|
||||
|
||||
|
||||
template Test () {
|
||||
signal input sig1;
|
||||
signal input sig2;
|
||||
|
||||
component decom = Decompressor();
|
||||
decom.in <== sig1;
|
||||
sig2 === decom.out[2][2];
|
||||
}
|
||||
|
||||
// component main = Test();
|
||||
30
circuit/utils/row_hasher.circom
Normal file
30
circuit/utils/row_hasher.circom
Normal file
@@ -0,0 +1,30 @@
|
||||
pragma circom 2.0.0;
|
||||
include "../node_modules/circomlib/circuits/poseidon.circom";
|
||||
|
||||
template Hasher(inputSize) {
|
||||
signal input values[inputSize];
|
||||
signal output hash;
|
||||
|
||||
component hasher = Poseidon(inputSize);
|
||||
for (var i = 0; i < inputSize; i++) {
|
||||
hasher.inputs[i] <== values[i];
|
||||
}
|
||||
hash <== hasher.out;
|
||||
}
|
||||
|
||||
|
||||
template RowHasher (width) {
|
||||
signal input img[width];
|
||||
signal output hash;
|
||||
|
||||
component hasher[width-1];
|
||||
|
||||
for(var i=0; i < width-1; i++) {
|
||||
hasher[i] = Hasher(2);
|
||||
hasher[i].values[0] <== i == 0 ? img[0] : hasher[i-1].hash;
|
||||
hasher[i].values[1] <== img[i+1];
|
||||
}
|
||||
|
||||
hash <== hasher[width-2].hash;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user