Da, acest lucru este relativ simplu.
În primul rând, se pare că Sage are acest lucru încorporat (vezi steag dublu, deși nu l-am testat).
Voi descrie modul „matematic” de a proceda, deoarece cred că este mai util din punct de vedere conceptual.
Pentru o zăbrele cu bază $B$, este binecunoscut (vezi teorema 2) că dualul are bază:
$$D = B (B^t B)^{-1}$$
Rezultă că următorul fragment de cod:
S = sage.crypto.gen_lattice()
D = S * (S.T * S).invers()
va genera baza dorită. Rețineți că baza nu este o matrice întreagă în general --- pentru o matrice (aleatorie). $S$ generate într-o execuție a sage.crypto.gen_lattice()
, înțeleg că baza duală este:
[ 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]
Baza (principală) a fost aleasă să fie $q$-ary pentru $q = 11$.
S-ar putea să observați asta extinzând lucrurile cu $q = 11$, obținem o matrice întreagă.
Acest lucru este valabil în general și poate fi văzut notând că a $q$zăbrele -ary $L$ satisface:
\begin{align*}
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
\end{align*}
Aceasta înseamnă că dacă $q\mathbb{Z}^m\subseteq L\subseteq \mathbb{Z}^m$, apoi în timp ce rețeaua duală $L^*$ nu poate fi cuprins între $q\mathbb{Z}^m$ și $\mathbb{Z}^m$, cel scalat zăbrele dublă este întotdeauna.
Adesea, cineva vede acest lucru în ziare ca fiind afirmația:
$$\Lambda_q(A)^* = \frac{1}{q}\Lambda_q^\perp(A)$$
De fapt, în notația de $\Lambda_q(A)$ și $\Lambda_q^\perp(A)$, ceri pur și simplu, dat o bază pentru $\Lambda_q(A)$, pentru a construi o bază pentru $\Lambda_q^\perp(A)$.