Рейтинг:-1

Переполнения в классической схеме обмена секретами Шамира

флаг co

Я реализовал классическую схему обмена секретами Шамира, которая выглядит так:

  • получить пароль на вход (любой длины)
  • преобразовать текст пароля в большое целое число
  • генерировать полиномиальные коэффициенты (an ... a1)
  • генерировать разбиения - пары (xi, yi) с заданным порогом

Это прекрасно работает, и вот как генерируются новые публикации секретных работ:

  • получение акций и порога в качестве входных данных
  • нахождение коэффициентов с помощью гаусса (поэтому я знаю исходный полином)
  • поиск секретного значения <-- это проблема
  • генерация большего количества акций - с использованием временной метки как xi

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

Так как же преодолеть этот классический подход? Что нужно изменить в схеме, чтобы она не была чувствительна к длине секретного текста?

kelalaka avatar
флаг in
https://math.stackexchange.com/q/4329986/338051, и это превращается в проблему с параметром и кодировкой, которая может больше подойти [так].
Vadym Fedyukovych avatar
флаг in
Использовали ли вы какое-то конечное поле для представления ваших паролей?
Macko avatar
флаг co
@VadymFedyukovych нет пока, подскажите варианты как правильно сделать? Как закодировать пароль в образце конечного поля
Рейтинг:1
флаг my

Что нужно изменить в схеме, чтобы она не была чувствительна к длине секретного текста?

Ну, Вадим уже упомянул, что Shamir Secret Sharing должен выполняться в конечном поле; однако это не касается вашего вопроса.

В схеме Шамира один экземпляр может совместно использовать любое значение между $0$ и $p^k - 1$ (куда $p^k$ — это размер конечного поля, которое вы используете [1]). А с Шамиром нет разницы в безопасности между различными конечными полями, поэтому мы можем выбрать одно из практических соображений (например, количество секретов, которые вы хотите иметь возможность выдать, размер секрета, простота реализации различные операции с конечным полем).

Однако то, что вы хотите сделать, это поделиться паролем в качестве секрета; этот пароль довольно длинный и имеет переменную длину. Что ж, есть две очевидные альтернативы:

  • Выберите $p^k$ (или премьер $р$ если ты пойдешь с $к-1$) достаточно большой, чтобы вместить любой пароль, которым вы хотите поделиться; например, если вы используете $р=2^{521}-1$ (что является простым), вы можете делиться паролями длиной до 65 символов. Это работает, однако недостатком является то, что такие большие значения необходимо обрабатывать с помощью библиотеки bignum. Если вы используете язык со встроенной библиотекой bignum (например, Python), это не проблема, а если нет, то, вероятно, будет проще использовать вторую идею.

С этой идеей, если бы у нас был пароль «letmein» (0x6c 0x65 0x74 0x6d 0x65 0x69 0x6e в ASCII), мы могли бы закодировать его как целое число 0x6c65746d65696e = 30510848210725230.

  • Разделите пароль на несколько секретов и делитесь каждым секретом отдельно. Например, для 14-символьного пароля мы можем разделить его на 14 отдельных секретов (каждый секрет представляет собой один символ из пароля) и поделиться каждым символом, используя $р=257$ и $к=1$ (таким образом, каждая сторона получит в общей сложности 14 долей, по одной доле для каждого из 14 символов). С этой идеей безопасно использовать один и тот же идентификатор для всех акций, которые получает сторона; однако важно, чтобы каждый секрет генерировался с использованием независимой случайности (то есть каждый из 14 случайных полиномов генерировался отдельно).

С этой идеей мы закодировали бы пароль «letmein» как 8 независимых секретов 0x6c 0x65 0x74 0x6d 0x65 0x69 0x6e.

С этой второй идеей, если вы не хотите раскрывать длину секрета, вы можете всегда делиться фиксированным количеством секретов (это будет максимальная длина пароля, которым вы можете поделиться, скажем, 32) и для более коротких паролей заполните дополнительные секретные символы значением, которое не может встречаться в реальном пароле (для моего примера $р=257$, очевидным значением для использования будет $256$).


[1]: Для любого простого $р$ и любое целое число $к$, существует конечное поле размера $p^k$. Вероятно, вам было бы проще начать с использования поля с $к=1$ и $р$ простое число соответствующего размера - это делает операции сложения, вычитания и умножения намного ближе к стандартным алгоритмам, с которыми вы знакомы (деление все еще шаткое).

Macko avatar
флаг co
хм, вторая идея кажется мне странной, потому что у каждой стороны, которая получает общий доступ, не должно быть достаточного количества общих ресурсов для восстановления защищенного пароля (секрета). Во-вторых, я не понимаю, как совместное использование отдельных символов пароля впоследствии может быть восстановлено до полного пароля. Такой подход выглядит более эластичным.
Macko avatar
флаг co
похоже, что первый подход - хороший вариант, но для этого нужны попытки и ошибки, чтобы найти золотую середину структур, используемых внутри, - чтобы определить, насколько длинный или сложный пароль может обрабатываться письменным алгоритмом.
poncho avatar
флаг my
@Macko: если вы не понимаете вторую идею, вы слишком много обдумываете. С его помощью вы создаете схему обмена секретами для первой буквы и раздаете эти доли. Параллельно вы генерируете ss для второй буквы, и отдаете эти доли той же стороне, и то же самое для третьей, четвертой и т.д. Когда придет время рекомбинации, возьмите все доли, которые есть у сторон, и объедините их первые доли вместе (ген первой буквы); то же самое со вторым и т. д. Когда у вас есть все буквы, просто соедините их вместе, и все готово.
Macko avatar
флаг co
Я думаю, что второй вариант — это чрезмерный дизайн, и стороны получат слишком много акций, которыми будет трудно управлять. Я пока придерживаюсь классического варианта 1...
Рейтинг:0
флаг in

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

Пожалуйста, рассмотрите арифметику по модулю некоторого простого числа, переопределите стандарт С++ плюс, минус, умножение и деление. Выберите учебник, который вы можете прочитать. Это долгий путь. Удачи.

Macko avatar
флаг co
Конечно, вы правы, но мне нужно больше деталей или подтверждения, как это сделать правильно: сначала закодировать пароль в большое число (в Java это будет BigInteger), а затем преобразовать это значение в число в некотором конечном поле? Отныне все расчеты типа (генерация коэффициентов, интерполяция) нужно делать только в определенном поле?

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

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