Arytmetyka pola skończonego

W matematyce arytmetyka pola skończonego jest arytmetyką w polu skończonym ( polu zawierającym skończoną liczbę elementów ) w przeciwieństwie do arytmetyki w polu o nieskończonej liczbie elementów, takim jak pole liczb wymiernych .

Istnieje nieskończenie wiele różnych skończonych pól. Ich liczba elementów jest koniecznie postaci p n , gdzie p jest liczbą pierwszą , a n jest dodatnią liczbą całkowitą , a dwa ciała skończone o tej samej wielkości są izomorficzne . Liczbę pierwszą p nazywamy charakterystyką ciała, a dodatnią liczbę całkowitą n nazywamy wymiarem ciała nad jego polem pierwszym .

Pola skończone są wykorzystywane w różnych zastosowaniach, w tym w klasycznej teorii kodowania w liniowych kodach blokowych, takich jak kody BCH i korekcja błędów Reeda-Solomona , w algorytmach kryptograficznych , takich jak algorytm szyfrowania Rijndael ( AES ), w planowaniu turniejów oraz w projektowanie eksperymentów .

Efektywna reprezentacja wielomianowa

Ciało skończone z elementami p n jest oznaczane jako GF( p n ) i nazywane jest także ciałem Galois rzędu p n , na cześć twórcy teorii pola skończonego, Évariste Galois . GF( p ), gdzie p jest liczbą pierwszą, jest po prostu pierścieniem liczb całkowitych modulo p . Oznacza to, że można wykonywać operacje (dodawanie, odejmowanie, mnożenie) przy użyciu zwykłej operacji na liczbach całkowitych, po której następuje redukcja modulo p . Na przykład w GF(5) 4 + 3 = 7 jest zredukowane do 2 modulo 5. Dzielenie to mnożenie przez odwrotność modulo p , które można obliczyć za pomocą rozszerzonego algorytmu euklidesowego .

Szczególnym przypadkiem jest GF(2) , gdzie dodawanie jest wyłącznym LUB (XOR), a mnożenie jest I . Ponieważ jedynym odwracalnym elementem jest 1, dzielenie jest funkcją identyczności .

Elementy GF( p n ) można przedstawić jako wielomiany stopnia dokładnie mniejszego niż n nad GF( p ). Operacje są następnie wykonywane modulo R , gdzie R jest nieredukowalnym wielomianem stopnia n nad GF( p ), na przykład przy użyciu dzielenia wielomianowego przez długi czas . Dodawanie dwóch wielomianów P i Q odbywa się jak zwykle; mnożenie można wykonać w następujący sposób: obliczyć W = P · Q jak zwykle, a następnie obliczyć resztę modulo R . Ta reprezentacja pod względem współczynników wielomianowych nazywana jest podstawą jednomianową (inaczej „bazą wielomianową”).

Istnieją inne reprezentacje elementów GF( p n ); niektóre są izomorficzne z reprezentacją wielomianową powyżej, a inne wyglądają zupełnie inaczej (na przykład przy użyciu macierzy). Korzystanie z normalnej podstawy może mieć zalety w niektórych kontekstach.

Gdy liczba pierwsza wynosi 2, zwykle wyraża się elementy GF( p n ) jako liczby binarne , przy czym współczynnik każdego wyrazu w wielomianie jest reprezentowany przez jeden bit w wyrażeniu binarnym odpowiedniego elementu. Nawiasy klamrowe ( „{” i „}” ) lub podobne ograniczniki są zwykle dodawane do liczb binarnych lub ich odpowiedników szesnastkowych, aby wskazać, że wartość daje współczynniki podstawy pola, reprezentując w ten sposób element pola. Na przykład następujące równoważne reprezentacje tej samej wartości w charakterystycznym 2 polu skończonym:

Wielomian x 6 + x 4 + x + 1
Dwójkowy {01010011}
Szesnastkowy {53}

Pierwotne wielomiany

Istnieje wiele nieredukowalnych wielomianów (czasami nazywanych wielomianami redukującymi ), których można użyć do wygenerowania pola skończonego, ale nie wszystkie dają tę samą reprezentację pola.

Moniczny nierozkładalny wielomian stopnia n mający współczynniki w ciele skończonym GF( q ), gdzie q = p t dla pewnej liczby pierwszej p i dodatniej liczby całkowitej t , nazywany jest wielomianem pierwotnym, jeśli wszystkie jego pierwiastki są elementami pierwotnymi GF ( q n ). W wielomianowej reprezentacji pola skończonego implikuje to, że x jest elementem pierwotnym. Istnieje co najmniej jeden nierozkładalny wielomian, dla którego x jest elementem pierwotnym. Innymi słowy, dla prymitywnego wielomianu potęgi x generują każdą niezerową wartość w polu.

W poniższych przykładach najlepiej nie używać reprezentacji wielomianowej, ponieważ znaczenie x zmienia się między przykładami. Moniczny nierozkładalny wielomian x 8 + x 4 + x 3 + x + 1 nad GF(2) nie jest prymitywny. Niech λ będzie pierwiastkiem tego wielomianu (w reprezentacji wielomianowej byłby to x ), to znaczy λ 8 + λ 4 + λ 3 + λ + 1 = 0 . Teraz λ 51 = 1 , więc λ nie jest pierwotnym elementem GF(2 8 ) i generuje multiplikatywną podgrupę rzędu 51. Rozważ element pola λ + 1 (w reprezentacji wielomianowej byłoby to x + 1 ). Teraz ( λ +1) 8 + ( λ +1) 4 + ( λ +1) 3 + ( λ +1) 2 + 1 = λ 8 + λ 4 + λ 3 + λ + 1 = 0 . Ponieważ wszystkie pierwiastki tego pierwotnego wielomianu są elementami pierwotnymi, λ + 1 jest elementem pierwotnym GF(2 8 ) ( ( λ + 1) 255 = 1 i żadna mniejsza potęga nie jest). GF(2 8 ) ma 128 generatorów (patrz Liczba elementów pierwotnych ). Posiadanie x jako generatora pola skończonego jest korzystne dla wielu obliczeniowych operacji matematycznych.

Dodawanie i odejmowanie

Dodawanie i odejmowanie jest wykonywane przez dodanie lub odjęcie dwóch z tych wielomianów razem i zmniejszenie wyniku modulo charakterystyki.

W polu skończonym o charakterystyce 2 dodawanie modulo 2, odejmowanie modulo 2 i XOR są identyczne. Zatem,

Wielomian ( x 6 + x 4 + x + 1) + ( x 7 + x 6 + x 3 + x ) = x 7 + x 4 + x 3 + 1
Dwójkowy {01010011} + {11001010} = {10011001}
Szesnastkowy {53} + {CA} = {99}

Przy regularnym dodawaniu wielomianów suma zawierałaby wyraz 2 x 6 . Ten wyraz staje się 0 x 6 i jest odrzucany, gdy odpowiedź jest zmniejszana modulo 2.

Oto tabela zawierająca zarówno normalną sumę algebraiczną, jak i charakterystyczną 2 skończoną sumę pól kilku wielomianów:

str. 1 str. 2 p 1 + p 2 pod...
K[ x ] GF(2 n )
x 3 + x + 1 x 3 + x 2 2 x 3 + x 2 + x + 1 x 2 + x + 1
x 4 + x 2 x 6 + x 2 x 6 + x 4 + 2 x 2 x 6 + x 4
x + 1 x 2 + 1 x 2 + x + 2 x 2 + x
x 3 + x x 2 + 1 x 3 + x 2 + x + 1 x 3 + x 2 + x + 1
x 2 + x x 2 + x 2x2 + 2x _ _ 0

W zastosowaniach informatycznych operacje są uproszczone dla skończonych pól o charakterystyce 2, zwanych także polami GF(2 n ) Galois , co czyni te pola szczególnie popularnymi wyborami do zastosowań.

Mnożenie

Mnożenie w ciele skończonym to mnożenie modulo, nieredukowalny wielomian redukujący używany do definiowania ciała skończonego. (Tj. jest to mnożenie, po którym następuje dzielenie przy użyciu wielomianu redukującego jako dzielnika — reszta jest iloczynem). Symbol „•” może być użyty do oznaczenia mnożenia w ciele skończonym.

Pole skończone Rijndaela (AES).

Rijndael (znormalizowany jako AES) wykorzystuje charakterystyczne 2 ciało skończone z 256 elementami, które można również nazwać ciałem Galois GF(2 8 ). Wykorzystuje następujący wielomian redukujący do mnożenia:

x 8 + x 4 + x 3 + x + 1.

Na przykład {53} • {CA} = {01} w polu Rijndaela, ponieważ

( x 6 + x 4 + x + 1)( x 7 + x 6 + x 3 + x )
= ( x 13 + x 12 + x 9 + x 7 ) + ( x 11 + x 10 + x 7 + x 5 ) + ( x 8 + x 7 + x 4 + x 2 ) + ( x 7 + x 6 + x 3 + x )
= x 13 + x 12 + x 9 + x 11 + x 10 + x 5 + x 8 + x 4 + x 2 + x 6 + x 3 + x
= x 13 + x 12 + x 11 + x 10 + x 9 + x 8 + x 6 + x 5 + x 4 + x 3 + x 2 + x

I

x 13 + x 12 + x 11 + x 10 + x 9 + x 8 + x 6 + x 5 + x 4 + x 3 + x 2 + x mod x 8 + x 4 + x 3 + x 1 + 1
= (11111101111110 mod 100011011)
= {3F7E mod 11B} = {01}
= 1 (dziesiętny)

To ostatnie można zademonstrować poprzez dzielenie długie (pokazane za pomocą notacji binarnej, ponieważ dobrze nadaje się do zadania. Zwróć uwagę, że w przykładzie zastosowano wyłączne OR , a nie odejmowanie arytmetyczne, jak można by użyć w dzieleniu długim w szkole podstawowej.):

                         11111101111110 (mod) 100011011  ^  100011011 01110000011110  ^  100011011  0110110101110  ^100011011 010101110110 ^100011011  001000 11010  ^  100011011  000000001 

(Elementy {53} i {CA} są wzajemnymi multiplikatywnymi odwrotnościami , ponieważ ich iloczyn wynosi 1 .)

Mnożenie w tym konkretnym ciele skończonym można również wykonać za pomocą zmodyfikowanej wersji „algorytmu chłopskiego ”. Każdy wielomian jest reprezentowany przy użyciu tej samej notacji binarnej, co powyżej. Osiem bitów jest wystarczające, ponieważ w kategoriach każdego (zredukowanego) wielomianu możliwe są tylko stopnie od 0 do 7.

Algorytm ten wykorzystuje trzy zmienne (w sensie programowania komputerowego), z których każda zawiera ośmiobitową reprezentację. aib inicjowane mnożnikami; p gromadzi iloczyn i musi być zainicjowany na 0.

Na początku i na końcu algorytmu oraz na początku i na końcu każdej iteracji ten niezmiennik jest prawdziwy: a b + p to iloczyn. Jest to oczywiście prawdą, gdy algorytm się uruchamia. Kiedy algorytm się zakończy, a lub b będzie równe zero, więc p będzie zawierało iloczyn.

  • Uruchom następującą pętlę osiem razy (raz na bit). Można zatrzymać się, gdy a lub b wynosi zero przed iteracją:
    1. Jeśli skrajny prawy bit b jest ustawiony, wyłączne LUB iloczyn p o wartość a . To jest dodawanie wielomianów.
    2. 0 Przesuń b o jeden bit w prawo, odrzucając najbardziej wysunięty na prawo bit i sprawiając, że skrajny lewy bit ma wartość zero. To dzieli wielomian przez x , odrzucając wyraz x .
    3. Śledź, czy skrajny lewy bit a jest ustawiony na jeden i nazwij tę wartość carry .
    4. Przesuń o jeden bit w lewo, odrzucając skrajny lewy bit i ustawiając nowy skrajny prawy bit na zero. To mnoży wielomian przez x , ale nadal musimy wziąć pod uwagę przeniesienie , które reprezentuje współczynnik x 7 .
    5. Jeśli przeniesienie miało wartość jeden, wyłączność lub a z liczbą szesnastkową 0x1b (00011011 w systemie binarnym). 0x1b odpowiada nieredukowalnemu wielomianowi z wyeliminowanym wysokim wyrazem. Koncepcyjnie, górny termin nieredukowalnego wielomianu i przeniesienie dodaj modulo 2 do 0.
  • p ma teraz produkt

odpowiednio zmieniając długości a , b i p oraz wartość 0x1b .

Odwrotność mnożenia

Zobacz także algorytm inwersji Itoh – Tsujii .

Multiplikatywną odwrotność elementu a skończonego pola można obliczyć na kilka różnych sposobów:

  • Mnożąc a przez każdą liczbę w polu, aż iloczyn będzie równy jeden. To jest wyszukiwanie metodą brute-force .
  • Ponieważ niezerowe elementy GF( p n ) tworzą grupę skończoną względem mnożenia, a p n −1 = 1 (dla a ≠ 0 ), więc odwrotnością a jest a p n −2 .
  • Korzystając z rozszerzonego algorytmu euklidesowego .
  • Tworząc tablice logarytmów i potęgowania dla ciała skończonego, odejmując logarytm od p n −1 i potęgując wynik.
  • Tworząc modułową multiplikatywną tablicę odwrotną dla ciała skończonego i przeprowadzając wyszukiwanie.
  • Poprzez mapowanie do pola złożonego , gdzie inwersja jest prostsza, i mapowanie z powrotem.
  • Konstruując specjalną liczbę całkowitą (w przypadku ciała skończonego rzędu pierwszego) lub specjalny wielomian (w przypadku ciała skończonego rzędu innego niż pierwsza) i dzieląc ją przez .

Triki wdrożeniowe

Tabele oparte na generatorze

Podczas opracowywania algorytmów do obliczeń pola Galois na małych polach Galois, powszechnym podejściem do optymalizacji wydajności jest znalezienie generatora g i użycie tożsamości:

zaimplementować mnożenie jako sekwencję przeszukiwań tablicy dla funkcji log g ( a ) i g y oraz operację dodawania liczb całkowitych. Wykorzystuje to właściwość, że każde pole skończone zawiera generatory. W przykładzie pola Rijndaela wielomian x + 1 (lub {03}) jest jednym z takich generatorów. Warunkiem koniecznym, ale niewystarczającym, aby wielomian był generatorem, jest nieredukowalność .

Implementacja musi przetestować specjalny przypadek a lub b równy zero, ponieważ iloczyn również będzie równy zero.

Tej samej strategii można użyć do określenia odwrotności multiplikatywnej z tożsamością:

Tutaj kolejność generatora, | g |, to liczba niezerowych elementów pola. W przypadku GF(2 8 ) jest to 2 8 − 1 = 255 . To znaczy dla przykładu Rijndaela: ( x + 1) 255 = 1 . Można to więc wykonać za pomocą dwóch tabel przeglądowych i odejmowania liczb całkowitych. Wykorzystanie tego pomysłu do potęgowania również przynosi korzyści:

Wymaga to dwóch przeszukań tabeli, mnożenia liczb całkowitych i operacji modulo na liczbach całkowitych. Ponownie należy przeprowadzić test dla szczególnego przypadku a = 0 .

Jednak w implementacjach kryptograficznych należy być ostrożnym z takimi implementacjami, ponieważ architektura pamięci podręcznej wielu mikroprocesorów prowadzi do zmiennego taktowania dostępu do pamięci. Może to prowadzić do implementacji, które są podatne na atak czasowy .

Mnożenie bez noszenia

W przypadku pól binarnych GF(2 n ) mnożenie pola można zaimplementować przy użyciu mnożenia bez przenoszenia, takiego jak zestaw instrukcji CLMUL , co jest dobre dla n ≤ 64. Mnożenie wykorzystuje jedno mnożenie bez przenoszenia, aby uzyskać iloczyn (do 2 n - 1 bitów ). wielomian) ⌊produkt / (wielomian pola)⌋). Ostatnie 3 kroki (pclmulqdq, pclmulqdq, xor) są używane w kroku redukcji Barretta do szybkiego obliczania CRC przy użyciu x86 pclmulqdq.

Pole złożone

Gdy k jest liczbą złożoną , będą istniały izomorfizmy ciała binarnego GF(2 k ) do pola rozszerzenia jednego z jego podciał, to znaczy GF((2 m ) n ), gdzie k = m n . Wykorzystanie jednego z tych izomorfizmów może uprościć rozważania matematyczne, ponieważ stopień rozszerzenia jest mniejszy, przy czym elementy są teraz reprezentowane na większym podpolu. Aby zmniejszyć liczbę bramek dla implementacji sprzętowych, proces może obejmować wielokrotne zagnieżdżanie, takie jak mapowanie z GF(2 8 ) na GF(((2 2 ) 2 ) 2 ). Istnieje ograniczenie implementacyjne, operacje w dwóch reprezentacjach muszą być kompatybilne, dlatego potrzebne jest wyraźne użycie izomorfizmu. Dokładniej, izomorfizm będzie oznaczony przez map(), jest to bijekcja , która odwzorowuje element GF(2 k ) na GF((2 m ) n ), spełniając: map( a + b ) = map( a ) + map( b ) i map( a b ) = map( a ) map( b ) , gdzie operacje po lewej stronie występują w GF(2 k ) przed mapowaniem, a operacje po prawej stronie występują w GF(2 m ) n ) po mapowaniu. Izomorfizm jest zwykle realizowany z k wierszy na k bitów, używaną do wykonywania mnożenia macierzy przez GF(2) elementu GF(2 k ) traktowanego jako macierz k wierszy na 1 bit. Zdefiniujmy α jako element pierwotny GF(2 k ), a β jako element pierwotny GF((2 m ) n ). Wtedy β j = mapa ( α j ) i α j = mapa −1 ( β j ). Wartości α i β określają macierz odwzorowania i jej odwrotność. Ponieważ rzeczywista matematyka jest wykonywana w GF((2 m ) n ), wielomian redukujący dla GF((2 m ) n ) jest zwykle prymitywny i β = x w GF((2 m ) n ). Aby spełnić ograniczenie zgodności dla dodawania i mnożenia, przeprowadzane jest wyszukiwanie w celu wybrania dowolnego pierwotnego elementu α z GF(2 k ), który spełni to ograniczenie. W przypadku, gdy wielomian redukujący dla GF(2 k ) jest prymitywny, możliwa jest alternatywna metoda odwzorowania: 1-bitowe współczynniki wielomianu redukującego dla GF(2 k ) są interpretowane jako m elementów bitowych 0 lub 1 z GF(2 m ) i będzie m czynników pierwotnych stopnia n , z których każdy może być użyty jako wielomian redukujący dla GF((2 m ) n ). Mapowanie na pole złożone można uogólnić na mapowanie GF( p k ) na pole złożone, takie jak GF(( pm ) n ) , dla p dowolnej liczby pierwszej.

Przykłady programów

Przykład programowania w C

Oto kod C , który doda i pomnoży liczby w charakterystycznym 2 skończonym polu rzędu 2 8 , używanym na przykład przez algorytm Rijndaela lub Reeda-Solomona, używając rosyjskiego algorytmu mnożenia chłopskiego :


     
	   






     
	   0 
	   0    0 
            
               

            
                   
        
               
          
	
	 
 /* Dodaje dwie liczby do ciała skończonego GF(2^8) */  uint8_t  gadd  (  uint8_t  a  ,  uint8_t  b  )  {  return  a  ^  b  ;  }  /* Pomnóż dwie liczby w ciele skończonym GF(2^8) zdefiniowanym  * przez wielomian modulo x^8 + x^4 + x^3 + x + 1 = 0  * (innym sposobem jest mnożenie bez przenoszenia po której następuje redukcja modularna)  */  uint8_t  gmul  (  uint8_t  a  ,  uint8_t  b  )  {  uint8_t  p  =  ;  /* akumulator dla iloczynu mnożenia */  while  (  a  !=  &&  b  !=  )  {  if  (  b  &  1  )  /* jeśli wielomian dla b ma stały wyraz, dodaj odpowiednie a do p */  p  ^ =  za  ;  /* dodanie w GF(2^m) jest XOR współczynników wielomianu */  if  (  a  &  0x80  )  /* GF modulo: jeśli a ma niezerowy wyraz x^7, to musi zostać zredukowany, gdy stanie się x^8 */  za  =  (  za  <<  1  )  ^  0x11b  ;  /* odejmij (XOR) pierwotny wielomian x^8 + x^4 + x^3 + x + 1 (0b1_0001_1011) – możesz go zmienić, ale musi być on nieredukowalny */ else  a  <<  =  1  ;  /* odpowiednik a*x */  b  >>=  1  ;  }  powrót  p  ;  } 

Ten przykład ma przecieki kanału bocznego dotyczące pamięci podręcznej, synchronizacji i przewidywania rozgałęzień i nie nadaje się do użycia w kryptografii.

Przykład programowania D

Ten program D pomnoży liczby w skończonym polu Rijndaela i wygeneruje obraz PGM :





       
       0

        0   
              a
               
        
                
          
    

     


  
      
            

        
      
       0  
           0   
                 
            
        
 /**  Pomnóż dwie liczby w ciele skończonym GF(2^8) zdefiniowanym  przez wielomian x^8 + x^4 + x^3 + x + 1.  */  ubyte  gMul  (  ubyte  a  ,  ubyte  b  )  pure  nothrow  {  ubajt  p  =  ;  foreach  (  niezmienny  licznik  ubajtów  ;  ..  8  )  {  p  ^=  -(  b  &  1  )  & a  ;  automaska  ​​=  -  ((  a  >>  7  )  &  1  );  // 0b1_0001_1011 to x^8 + x^4 + x^3 + x + 1.  a  =  rzut  (  ubyte  )((  a  <<  1  )  ^  (  0b1_0001_1011  &  maska  ​​));  b  >>=  1  ;  }  powrót  p  ;  }  void  main  ()  {  import  std  .  std.  ,  std  .  konw  .;  szerokość  wyliczenia  =  ubajt  .  maks  +  1  ,  wysokość  =  szerokość  ;  auto  f  =  Plik  (  "rijndael_finite_field_multiplication.pgm"  ,  "wb"  );  fa  .  writefln  (  "P5\n%d%d\n255"  ,  szerokość  ,  wysokość  );  foreach  (  niezmienny  y  ;  ..  wysokość  )  foreach  (  niezmienny  x  ;  ..  szerokość  )  {  niezmienny  znak  c  =  gMul  (  x  .  do  !  ubajt  ,  y  .  do  !  ubajt  );  fa  .  pisać  (  c  );  }  } 

Ten przykład nie wykorzystuje żadnych rozgałęzień ani przeszukiwań tabel w celu uniknięcia kanałów bocznych i dlatego nadaje się do zastosowania w kryptografii.

Zobacz też

Źródła

Linki zewnętrzne