Да, это относительно просто.
Во-первых, похоже, что в Sage есть встроенная функция (см. двойной флаг, хотя не проверял).
Я опишу «математический» способ действий, так как считаю его концептуально более полезным.
Для решетки с основанием $В$, общеизвестно (см. теорема 2) что дуал имеет базис:
$$D = B (B^t B)^{-1}$$
Отсюда следует, что следующий фрагмент кода:
S = sage.crypto.gen_lattice()
D = S * (СТ * S).инверсия ()
будет генерировать желаемую основу. Обратите внимание, что базис в общем случае не является целочисленной матрицей --- для (случайной) матрицы $S$ генерируется при выполнении sage.crypto.gen_lattice()
, я понимаю, что двойная основа:
[ 1/11 0 0 0 -4/11 -3/11 2/11 0]
[ 0 1/11 0 0 -5/11 1/11 -3/11 0]
[ 0 0 1/11 0 0 5/11 -4/11 -5/11]
[ 0 0 0 1/11 -2/11 4/11 4/11 -5/11]
[ 0 0 0 0 1 0 0 0]
[ 0 0 0 0 0 1 0 0]
[ 0 0 0 0 0 0 1 0]
[ 0 0 0 0 0 0 0 1]
(Первичный) базис был выбран таким, чтобы $q$-ary для $q = 11$.
Вы можете заметить, что, увеличивая масштаб на $q = 11$, получаем целочисленную матрицу.
В общем случае это верно, и в этом можно убедиться, заметив, что $q$-арная решетка $L$ удовлетворяет:
\начать{выравнивать*}
q\mathbb{Z}^m&\subseteq L\subseteq \mathbb{Z}^m\
\iff (q\mathbb{Z}^m)^*&\supseteq L^* \supseteq \mathbb{Z}^m\
\iff \frac{1}{q}\mathbb{Z}^m&\supseteq L^*\supseteq \mathbb{Z}^m\
\iff \mathbb{Z}^m &\supseteq qL^*\supseteq q\mathbb{Z}^m
\конец{выравнивание*}
Это к тому, что если $q\mathbb{Z}^m\subseteq L\subseteq \mathbb{Z}^m$, то пока дуальная решетка $L^*$ не может находиться между $q\mathbb{Z}^m$ и $\mathbb{Z}^m$, масштабированный двойная решетка всегда есть.
Это часто можно увидеть в газетах как утверждение:
$$\Lambda_q(A)^* = \frac{1}{q}\Lambda_q^\perp(A)$$
В самом деле, в обозначениях $\Lambda_q(A)$ и $\Lambda_q^\perp(A)$, вы просто спрашиваете, учитывая основание для $\Lambda_q(A)$, построить основу для $\Lambda_q^\perp(A)$.