Рейтинг:0

Как создать ограничение на побитовый оператор сдвига вправо в Circom

флаг nz

Как сгенерировать ограничение на побитовый оператор сдвига вправо в язык обходных цепей?

Я пытаюсь сделать следующее:

прагма цирком 2.0.0;

шаблон ГЛАВНЫЙ() {

    сигнальный вход v;
    тип выхода сигнала;

    введите <== v >> 5;
}

компонент main = MAIN();

Я получаю следующую ошибку:

error[T3001]: Неквадратичные ограничения не допускаются!
   ââ "/Users/ilia/compiling/main-circom/main.circom":68:5
   ✓
68 — тип <== v >> 5;
   ★ ^^^^^^^^^^^^^^^^ найдено здесь
   ✓
   = трассировка вызова:
     -> ГЛАВНЫЙ

Я думаю, это связано с тем, что v >> 5 выражение не может быть повторно выражено как квадратное выражение с помощью компилятор circom.

Я изо всех сил пытаюсь переписать выражение, чтобы оно было квадратичным. Это может включать в себя запись присваивания и ограничения как двух отдельных операций, но я не уверен, что правильное ограничение проверки будет для сдвига вправо.

Что касается тестовых случаев, я ожидаю тип быть $5$ когда в является $168$ Например.

флаг kr
Вопросы по программированию не относятся к теме Crypto SE.
meshcollider avatar
флаг gb
Сдвиг вправо на n бит аналогичен делению на 2 ^ n, поэтому вы можете использовать его для ограничения (умножьте другую сторону на 2 ^ n и используйте маску, чтобы очистить младшие биты). Вы можете просто использовать присваивание с `
флаг nz
Меня направили на эту биржу стека, когда я задал вопрос о Circom на StackOverflow... Я пытался: `тип > 5; введите * 32 === v & 0xE0;` но теперь я получаю «Неквадратичные ограничения не допускаются» в строке `type * 32 === v & 0xE0`
флаг nz
Как я могу сгенерировать ограничение для побитового оператора &? Заглянул в circomlib, но не нашел ничего, что полностью соответствовало бы всем требованиям, видел только `& 1`, но я не думаю, что это достаточно общее.
флаг nz
Я пробовал это, чтобы сгенерировать ограничение для оператора &: `signal check; проверять
kelalaka avatar
флаг in
Кто направил этот вопрос сюда? Там уже есть вопросы и ответы по SageMath, но это не по теме?
флаг nz
Меня направили на этот stackexchange здесь: https://stackoverflow.com/questions/70891895/how-to-pass-function-argument-by-reference-in-circom#comment125326319_70891895 с аргументацией, что «crypto.stackexchange.com может быть более подходящим для вопросов, связанных с ZKP"
Рейтинг:1
флаг gb

Решение с использованием компаратора LessThan из циркомлиб:

//... импортировать компараторы из circomlib ...

шаблон ГЛАВНЫЙ() {

    сигнальный вход v;
    тип выхода сигнала;
    сигнал check_v;
    компонент меньше чем = меньше чем (8);

    введите <-- v >> 5;
    check_v <== тип*32;
    // используем circomlib LessThan, чтобы проверить, что (v - check_v) < 32
    lessThan.in[0] <== v - check_v;
    меньше чем.in[1] <== 32;    
    меньше чем.out === 1;
}

компонент main = MAIN();
```
флаг nz
Да, это сработало. Спасибо! `компонент меньше чем = меньше чем (8); // полные 8 бит меньше чем.in[0]
meshcollider avatar
флаг gb
Сладкий! Затем обновил мой ответ окончательным кодом. Мы должны очистить эти комментарии.
Рейтинг:0
флаг nz

circomlib/схемы/sha256/shift.circom имеет ШР компонент, который выполняет сдвиг вправо.

    вар InputBits = 8;
    вар РезультатБитс = 3;

    // преобразовать v в биты
    компонент n2b = Num2Bits(InputBits);
    n2b.in <== v;

    // сдвиг
    компонент shr = ShR(InputBits, 5); // v >> 5
    for (var i = 0; i < InputBits; i++) {
        shr.in[i] <== n2b.out[i];
    }

    // преобразовать обратно в число
    компонент b2n = Bits2Num(ResultBits);
    for (var i = 0; i < ResultBits; i++) {
        b2n.in[i] <== shr.out[i];
    }
    введите <== b2n.out;
Рейтинг:0
флаг nz

РЕДАКТИРОВАТЬ: Это недостаточно проверяет операцию сдвига. Вместо этого смотрите ответ @meshcollider.

Хорошо, я не совсем уверен, что это правильно, но это то, что я придумал.

прагма цирком 2.0.0;

шаблон ГЛАВНЫЙ() {

    сигнальный вход v;
    тип выхода сигнала;

    // присваиваем сигнал `type`
    // сдвигаем 0bXXXYYYYY на 0b00000XXX
    // v — доверенный сигнал
    введите <-- v >> 5;

    // подготовим проверку ограничений для `type`
    сигнал three_upper_bits;
    // 0b11100000 = 0xE0
    // v доверенный сигнал
    three_upper_bits <-- v & 0xE0; // 3 старших бита v (0bXXX00000). v может быть только 8 бит.

    // должно_only_be_lower_bits равно 0b000YYYYY
    // получаем 0bXXXYYYYY - 0bXXX00000, чтобы получить 0b000YYYYY
    var should_only_be_lower_bits = v - three_upper_bits;
    // мы проверяем, что must_only_be_lower_bits может быть только МЕНЬШЕ 32 (0b00011111)
    // что подтверждает, что three_upper_bits нетронуты и не испорчены.
    // если бы кто-то возился с three_upper_bits, то should_only_be_lower_bits содержал бы старшие биты
    // и быть больше 32 (0b00011111).
    // тем самым мы криптографически утверждаем, что should_only_be_lower_bits имеет вид 0b000YYYYY
    сигнал upper_bit_1;
    сигнал upper_bit_2;
    сигнал upper_bit_3;
    upper_bit_1 <-- should_only_be_lower_bits & 0x80; // 0b10000000. Этот сигнал может быть 0bX0000000
    upper_bit_2 <-- should_only_be_lower_bits & 0x40; // 0b01000000. Этот сигнал может быть 0b0X000000
    upper_bit_3 <-- should_only_be_lower_bits & 0x20; // 0b00100000. Этот сигнал может быть 0b00X00000
    верхний_бит_1 === 0; // Утверждаем, что 0bX0000000 равно 0b00000000
    верхний_бит_2 === 0; // Утверждаем, что 0b0X000000 равно 0b00000000
    верхний_бит_3 === 0; // Утверждаем, что 0b00X00000 равно 0b00000000

    // генерируем ограничение для типа signal
    // 2^5 = 32
    введите * 32 === three_upper_bits;
}

компонент main = MAIN();

Комментарии проходят через мое мышление, но по существу я проверяю назначения сигналов с ограничениями вычитания/умножения.

meshcollider avatar
флаг gb
Вы можете комбинировать три проверки битов `upper_bit_`, если используете 0xE0
флаг nz
Это правда. Я также думаю, что мне нужно перепроверить, что v всего 8 бит и не больше.
meshcollider avatar
флаг gb
Также вы, возможно, просто скрыли проблему здесь: `three_upper_bits
флаг nz
@meshcollider это очень хороший момент! Я понятия не имею, что я делаю. Я до сих пор не знаю, как безопасно проверить операцию `>> 5`.

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.