— Реализация решателя исключения Гаусса для результата алгоритма Саймона линейных уравнений $с$.
Кроме того, как отмечено в этом ответе, для секрета из $n$ бит необходимо использовать только $n-1$ уравнений. В противном случае единственным решением будет $s=0$, если уравнения линейно независимы.
В вашем случае уравнения не являются линейно независимыми (из-за измерения $00$), так как $11\oplus11=00$, что объясняет, почему возможно истинное решение $11$. Обратите также внимание, что нулевой вектор всегда будет решением системы, поскольку он всегда будет ортогонален всем вашим измерениям.
Таким образом, после решения для $s\neq0$ с использованием $n-1$ уравнений необходимо проверить гипотезу о том, что $s\neq0$. Это довольно просто: запросите $f(x)$ и $f(x\oplus s)$. Если они равны, то $s$ обязательно отличен от $0$. В противном случае это означает, что $s=0$.
Тем не менее, некоторое время назад я написал реализацию на Python. Обратите внимание, что это не гарантирует, что это будут самые быстрые из возможных методов, но они должны работать.
Краткое объяснение следующих строк:
index = np.where(~np.diag(matrix))[0] если index.shape[0]: индекс = индекс [0] еще: индекс = матрица.форма[1] - 1 вернуть np.hstack ((матрица [: индекс, индекс], [1], матрица [индекс:, индекс]))
Когда матрица rref, возможны два случая:
- диагональ заполнена $1$s, например: $$A=\begin{pmatrix}1&0&0&0&1\\0&1&0&0&0&0\\0&0&1&0&0\\0&0&0&1&1\end{pmatrix}$$
- диагональ “пропускает” шаг, например: $$B=\begin{pmatrix}1&1&0&0&0\\0&0&1&0&0\\0&0&0&1&0\\0&0&0&0&1\end{pmatrix}$$
индекс
будет представлять собой индекс, при котором диагональ пропускает шаг, который равен $n-1$ для первого случая и первого нуля на диагонали для второго.
Рассмотрим пока второй случай. Обратите внимание, что последней строкой всегда будет $\begin{pmatrix}0&\cdots&0&1\end{pmatrix}$, что означает, что последний бит $s$ должен быть равен $0$. Действительно, у нас должно быть $Bs=\begin{pmatrix}0\\\vdots\\0\end{pmatrix}$, поэтому последняя строка системы преобразуется в $1\cdot s_n=0$. По сути, это означает, что вы можете удалить последнюю строку матрицы, поскольку каждый из этих элементов будет умножен на последний бит $s$, равный $0$. Затем вы можете выполнить те же рассуждения, пока у вас не останется матрица первого случая. Таким образом, если мы покажем, что в первом случае решение $s$ дается последним столбцом, к которому добавляется $1$, это объяснит метод (поскольку
— вектор, полный нулей).
Теперь о первом случае, поскольку матрица rref, это означает, что каждая строка матрицы содержит не более двух единиц $1$: одну по диагонали и одну в последнем столбце. Таким образом, при записи $As=\begin{pmatrix}0\\\vdots\\0\end{pmatrix}$ все уравнения можно записать в виде $s_i\oplus A_{i,n}\cdot s_n= 0$, откуда следует, что $s_i=A_{i,n}\cdot s_n$.
В общем, как только индекс, в котором диагональ пропускает шаг, найден, нам просто нужно взять столбец, соответствующий этому индексу, до этой строки, добавить $1$ и дополнить $0$, чтобы найти $s$, что объясняет код.
Теперь, если вы хотите использовать этот код, вот как вы можете это сделать. Если вы измерили $10010$, $11010$, $10110$ и $10001$, вы можете найти уникальный ненулевой $s$, который ортогонален всем этим:
t1 = BitString("10010") t2 = Битовая строка ("11010") t3 = Битовая строка ("10110") t4 = Битовая строка ("10001") битовые строки = [t1, t2, t3, t4] res = BitString.solve(bitstrings) # Вычислить s печать (разрешение) print(np.vstack([x.value for x in bitstrings]) @ res % 2) # Должен быть нулевым вектором
Запуск со списком, содержащим только BitString("11")
, возвращает $11$, как и ожидалось.
Python – Gaussian fit – GeeksforGeeks
3.0 , 4.0 , 5. , 6.0 , 7.0 , 8.0 , 9.0 , 10.0 ] 10.6 , 11.7 , 13.5 , 14.5 , 15.7 , 16.1 , 16.6 , 16.0 , 15.4 , 14.4 , 14.2 , 12.7 , 10.3 , 8. , 6.1 3.9 , 2.1 ] = A * np.exp( - 1 * B * x * * 2 ) .![]() |