Проширени Еуклидов алгоритам

Из Википедије, слободне енциклопедије

Проширени Еуклидов алгоритам, поред проналажења највећег заједничког делиоца целих бројева а и b, што ради обични Еуклидов алгоритам, такође налази целе бројеве х и у (од којих је углавном један негативан) који задовољавају Безуов став:

ax + by = nzd(a, b).

Проширени Еуклидов алгоритам је посебно користан када су а и b узајамно прости, пошто је х модуларни мултипликативни инверз од a по модулу b, а y је модуларни мултипликативни инверз од b по модулу a. Ово има значај у израчунавању кључа у РСА алгоритму за шифровање јавног кључа; налажење целобројног експонента за дешифровање d који је модуларни мултипликативни инверз изабраног експонента е по модулу φ(n), где су e и φ(n) узајамно прости.

Неформална формулација алгоритма[уреди]

Дељеник Делилац Количник Остатак
120 23 5 5
23 5 4 3
5 3 1 2
3 2 1 1
2 1 2 0

Да бисмо илустровали проширење Еуклидовог алгоритма, размотримо израчунавање нзд(120, 23), који је приказан у табели лево. Приметимо да је количник у сваком дељењу забележен као и остатак.

У овом случају, делилац у последњем реду (који је једнак 1) нам говори да је нзд 1; то јест, 120 и 23 су узајамно прости (такође се називају и релативно прости). Због једноставности, изабрани примери су пар узајамно простих; али у општијем случају нзд-а који није 1, ово слично функционише.

Постоје два метода у наставку, од којих оба користе алгоритам целобројног дељења као подпоступак, од којих ће сваки бити засебно дискутован.


Итеративна метода[уреди]

Овај метод рачуна изразе облика r_i = a x_i + b y_i за остатак у сваком кораку i Еуклидовог алгоритма. Сваки узастопни број r_i може бити записан као остатак при дељењу претходна два таква броја, чији остатак може бити изражен користећи цео количник qi тог дељења према формули:

r_i = r_{i-2} - q_i r_{i-1}.\,

Када се замене вредности, ово даје:

r_i = (ax_{i-2} + by_{i-2}) - q_i (ax_{i-1} + by_{i-1}),\, што може да се запише као
r_i = a(x_{i-2} - q_i x_{i-1}) + b(y_{i-2} - q_i y_{i-1}).\,

Прве две вредности су полазни аргументи за алгоритам:

r_1 = a = a\times1 + b\times0\,
r_2 = b = a\times0 + b\times1.\,

Дакле, почетни коефицијенти су x1 = 1, y1 = 0, x2 = 0, и y2 = 1, а други су дати као

x_i = x_{i-2} - q_i x_{i-1},\,
y_i = y_{i-2} - q_i y_{i-1}.\,

Израз за последњи не-нула остатак даје жељени резултат, пошто овај метод рачуна сваки остатак у односу на а и b, као што је и жељено.

Пример: израчунати НЗД од 120 и 23

Рачунање тече према наредној табели:

Корак Количник Остатак Замена Комбиновани услови
1 120 120 = 120 × 1 + 23 × 0
2 23 23 = 120 × 0 + 23 × 1
3 5 5 = 120 − 23 × 5 5 = (120 × 1 + 23 × 0) − (120 × 0 + 23 × 1) × 5 5 = 120 × 1 + 23 × −5
4 4 3 = 23 − 5 × 4 3 = (120 × 0 + 23 × 1) − (120 × 1 + 23 × −5) × 4 3 = 120 × −4 + 23 × 21
5 1 2 = 5 − 3 × 1 2 = (120 × 1 + 23 × −5) − (120 × −4 + 23 × 21) × 1 2 = 120 × 5 + 23 × −26
6 1 1 = 3 − 2 × 1 1 = (120 × −4 + 23 × 21) − (120 × 5 + 23 × −26) × 1 1 = 120 × −9 + 23 × 47
7 2 0 Крај алгоритма

У последњем реду стоји 1 = 120 × −9 + 23 × 47, што је тражено решење: x = −9 и y = 47.

Пошто је НЗД 1, ово такође значи да 47 даје мултипликативни инверз од 23 по модулу 120, а такође по модулу 23, -9 (или 14, који представљају исти елемент) даје мултипликативни инверз од 120 (или, еквивалентно, од 5).

47 × 23 ≡ 1 (mod 120) и такође −9 × 120 ≡14 × 5 ≡ 1 (mod 23).

Да би цео број a био инвертибилан по модулу b, потребно је да a и b буду узајамно прости, тако да, када би се пронашао НЗД већи од 1, могло би се закључити да такав модуларни инверз не постоји. Приметимо да су једначине које дефинишу вредности за xi независне од једначина које дефинишу вредности yi, и да Безуов идентитет на крају:

 \mathit{NZD} = r_k = a x_k + b y_k\,

дозвољава дедукцију yk, када знамо xk. Стога можемо изоставити вредности yi из рачунања (мада могу бити корисне за проверу рачунских грешака). Ово је нарочито важно за примене, попут модуларног инверза, које захтевају вредност само једног Безуовог коефицијента.

Рекурзивна метода[уреди]

Овај метод покушава да реши оригиналну једначину директно, редуковањем делиоца и дељеника постепено, од првог до последњег реда, што затим може бити замењено тривијалном вредношћу и може да функционише уназад у трагању за решењем.

Размотримо оригиналну једнакост:

120 x + 23 y = 1
(5×23 + 5) x + 23 y = 1
23 (5x + y) + 5 x = 1
...
1 xk + 0 yk = 1

Приметимо да једнакост остаје неизмењена након разлагања оригиналног дељеника у смислу делиоца са остатком, и прегруписавања услова. Уколико имамо решење једнакости у другом реду, онда можемо да идемо уназад и тражимо х и у као што је и тражено. Иако још увек немамо решење за други ред, приметимо како магнитуда услова опада (120 и 23 у 23 и 5). Стога, уколико наставимо ово да примењујемо, на крају ћемо доћи до последњег реда, који очигледно има (1, 0) као тривијално решење. Онда можемо да идемо уназад и постепено налазимо х и у.

Дељеник = Количник x Делилац + Остатак
120 = 5 x 23 + 5
23 = 4 x 5 + 3
...

У сврху објашњавања овог метода, неће бити приказан читав поступак. Уместо тога, неки кораци који се понављају ће бити описани да би се приказао принцип који стоји у позадини ове методе. Почнимо тако што ћемо поново исписивати редове из прве табеле користећи алгоритам дељења, концентришући се на дељеник овог пута (пошто ћемо дељеник замењивати).

120 x0 + 23 y0 = 1
(5×23+5) x0 + 23 y0 = 1
23 (5x0+y0) + 5 x0 = 1
23 x1 + 5 y1 = 1
(4×5+3) x1 + 5 y1 = 1
5 (4x1+y1) + 3 x1 = 1
5 x2 + 3 y2 = 1
  1. Претпоставимо да нам је већ дато x2 = 2 и y2 = −3 , што заиста јесте валидно решење.
  2. x1 = y2 = −3
  3. Решимо 4x1 + y1 = x2 мењањем x1 = −3, што даје y1 = 2 − 4(−3) = 14
  4. x0 = y1 = 14
  5. Решимо 5x0 + y0 = x1 мењањем x0 = 14, дакле y0 = −3 − 5(14)= −73


Таблична метода[уреди]

Таблични метод, такође познат и као "Магична кутија", је вероватно најједноставнији метод који се може обавити помоћу оловке и папира. Сличан је итеративном методу, мада не захтева директно коришћење алгебре. Нека \operatorname{nzd}(a, b) означава остатак r у дељењу a = bq + r. Основна идеја је да размишљамо о ланцу једнакости

nzd(a, b) = nzd(b, \operatorname{ostatak}(a, b)) = \dots = nzd(c, 1)

као о секвенци делилаца a, b, \operatorname{ostatak}(a, b), \dots, 1. У постојећем примеру имамо секвенцу 120, 23, 5, 3, 2, 1. Било који елемент у овом ланцу се може записати као линеарна комбинација оригиналних a и b, а што је најзначајније, последњи елемент, nzd(a, b), може бити овако записан. Таблични метод укључује одржавање табеле за сваког делиоца, записане као линеарна комбинација. Алгоритам почиње следећом табелом:

x y d
1 0 120
0 1 23

Елементи у d колони табеле ће бити делиоци у секвенци. Свако d_i се може представити као линеарна комбинација

d_i = x_i \cdot a + y_i \cdot b.

x and y вредности су очигледне у прва два реда табеле, и представљају управо a и b. Да бисмо израчунали d_i за било које i > 2, приметимо да

d_i = \operatorname{ostatak}(d_{i-2}, d_{i-1}).

Претпоставимо d_i = d_{i-2} - k_{i-1} \cdot d_{i-1}. Онда мора бити

x_i = x_{i-2} - k_{i-1} \cdot x_{i-1} и
y_i = y_{i-2} - k_{i-1} \cdot y_{i-1}.

Ово је лако алгебарски потврдити једноставном заменом.

Заправо, обављање табличног метода је једноставније него што се то да закључити из горенаведених једнакости. За налажење трећег реда у табели у примеру, само приметимо да се 120 подељено са 23 појављује 5 пута са остатком. То нам даје k, мултипликативни фактор за овај ред. Сада, свака од вредности у табели је вредност два реда изнад ње, минус k пута вредност одмах испод ње. Ово коректно води до

x_3 = 1 - 5 \cdot 0 = 1,
y_3 = 0 - 5 \cdot 1 = -5, и
d_3 = 120 - 5 \cdot 23 = 5.

Након понављања овог метода у циљу налажења сваког реда табеле (приметимо да су остатак записан у табели и мултипликативни фактор два различита броја!), коначне вредности за x и y ће решити ax + by = nzd(a, b)\,:

x y d k
1 0 120
0 1 23 5
1 -5 5 4
-4 21 3 1
5 -26 2 1
-9 47 1 2

Овај метод је једноставан и захтева само поновљену примену једног правила, и даје одговор у последњем реду без трагања уназад. Приметимо такође да уколико имамо намеру да пронађемо модуларни инверз за а по модулу b и добијемо негативно х, треба да додамо модул b х-у да бисмо га довели у опсег. Ово не утиче на валидност решења, пошто имамо a(x+b)+b(y-a)=ax+by.

Формални опис алгоритма[уреди]

Итеративна метода[уреди]

Према рутини алгебре о проширењу и груписању као условима (погледати последњу секцију), добијен је следећи алгоритам за итеративну методу:

  1. Применити Еуклидов алгоритам, и поставити qn (n почиње од 1) као коначну листу количника у дељењу.
  2. Иницијализовати x0, x1 на 1, 0, и y0, y1 на 0,1.
    1. Затим за свако i докле год је qi дефинисано,
    2. Израчунати xi+1 = xi-1qixi
    3. Израчунати yi+1 = yi−1qiyi
    4. Понављати горенаведено након повећања вредности i за 1
  3. Одговори су од другог до последњег од xn и yn.

Псеудо-код за овај метод је приказан испод:

function prosireni_nzd(a, b)
    x := 0    poslednji_x := 1
    y := 1    poslednji_y := 0
    while b ≠ 0
        kolicnik := a div b
        (a, b) := (b, a mod b)
        (x, poslednji_x) := (poslednji_x - kolicnik*x, x)
        (y, poslednji_y) := (poslednji_y - kolicnik*y, y)       
    return (poslednji_x, poslednji_y)

Додатни кораци су неопходни када радимо са негативним a и/или b.

Рекурзивна метода[уреди]

Решавајући општи случај једнакости у последњој одговарајућој секцији, наредни алгоритам даје решење. Ако је дат било који пар ненегативних целих бројева а и b, он проналази целобројне вредности х и у такве да је ax + by ненегативно и дели а и b, што имплицира да је то највећи заједнички делилац за а и b.

  1. Ако је b = 0, алгоритам се завршава, а као повратну вредност враћа x = 1, y = 0.
  2. Иначе:
    • Одредити количник q и остатак r дељењем а са b користећи алгоритам целобројног дељења
    • Затим рекурзивно пронаћи коефицијенте s, t такве да bs + rt дели и b и r.
    • Коначно, алгоритам враћа решење x = t, и y = sqt.

Ово се у псеудо коду може записати овако:

function prosireni_nzd(a, b)
    if b == 0
        return (1, 0)
    else
        (q, r) := podeli (a, b)
        (s, t) := prosireni_nzd(b, r)
        return (t, s - q * t)

Овим претпостављамо да постоји поступак дељења који враћа (количник, остатак) пар (могло би се ставити q := a div b, а затим r = ab * q).

Доказ коректности[уреди]

Нека су a и b ненегативни цели бројеви. Желимо да докажемо да се алгоритам завршава, и враћа (х, у) такве да ax + by дели и а и b. Настављамо индукцијом по b.

  • Ако је b = 0, алгоритам одмах стаје са извршавањем са х = 1 и у = 0, тако да ax + by = a; ово је очигледно ненегативно и дели и а и 0 (јер је а0 = 0).
  • Иначе, нека су q, r добијени дељењем а са b као у опису алгоритма, тако да a = bq + r и r < b према својствима Еуклидовог дељења.
    • Неједнакост r < b значи да можемо да применимо индуктивну претпоставку за (b,r) на месту (a,b), и ово нам гарантује да се рекурзивна примена завршава.
    • Нека су (s,t) вредности које враћа; према индукцији знамо да је bs + rt ненегативно и дели и b и r.
    • Сада алгоритам враћа x = t и y = sqt. Имамо ax + by = at + b(sqt) = bs + (abq)t = bs + rt, што је (још увек) ненегативно и дели и b и r. Исти број стога дели r + bq = a, чиме се доказ завршава.

Доказ показује да се рекурзивни алгоритам може прилагодити за рад са произвољним целим бројевима а, b незнатном модификацијом: у завршном случају b = 0 би требало да испита знак од а, и ако је негативан враћа х = -1, уместо х = 1, да би се осигурало да ax + by увек буде ненегативна вредност. Овим се претпоставља да изабрани алгоритам дељења функционише ако су а и/или b негативни, и осигурава да је |r| < |b| у свим случајевима (уобичајена спецификација Еуклидовог дељења заправо захтева да r буде ненегативно, али ово није неопходно у доказу, као што јесте сада по рекуренцији по |b|).

Израчунавање мултипликативног инверза у коначном пољу[уреди]

Проширени Еуклидов алгоритам се такође може користити за рачунање модуларног мултипликативног инверза у коначном пољу.

Псеудокод[уреди]

С обзиром да несводљива полиномијална функција f(x) дефинише поље, и елемент a(x) чији инверз желимо, облик алгоритма који одговара одређивању инверза је дат у наставку. ПАЖЊА: ostatak() и kolicnik() су функције другачије од ниски ostatak[] и kolicnik[]. ostatak() се односи на остатак при дељењу два броја, а kolicnik() на целобројни количник при дељењу два броја. Дељење (са остатком) се мора израчунати под условима полиномијалне аритметике а не "нормалних" бројева.

псеудокод:

ostatak[1] := f(x)
ostatak[2] := a(x)
pomocni[1] := 0
pomocni[2] := 1
i := 2
while ostatak[i] > 1
    i := i + 1
    ostatak[i] := ostatak(ostatak[i-2] / ostatak[i-1])
    kolicnik[i] := kolicnik(ostatak[i-2] / ostatak[i-1])
    pomocni[i] := -kolicnik[i] * pomocni[i-1] + pomocni[i-2]
inverz := pomocni[i]
Напомена: у неким коначним пољима, на пример GF(2n), ), операције додавања (+) и одузимања (−) су исте. Као последица, неки алгоритми намењени таквим пољима неће приказивати знак минус пре
-quotient[i].

Пример[уреди]

На пример, ако се коначно поље GF(28) дефинише полиномијално са f(x) = x8 + x4 + x3 + x + 1, и x6 + x4 + x + 1 = {53}, у big endian хексадецималној нотацији, је елемент чији инверз желимо, извршивши алгоритам добијамо следеће:

i ostatak[i]  kolicnik[i]  pomocni[i]
 1   x8 + x4 + x3 + x + 1     0
2  x6 + x4 + x + 1    1
3  x2  x2 + 1  x2 + 1
4  x + 1  x4 + x2  x6 + x4 + x4 + x2 + 1
5  1  x + 1  x7 + x6 + x3 + x2 + x2 + x + 1 + 1 
6  0  x + 1  
Напомена: Додавање у бинарном коначном пољу је XOR[1].

Према овоме, инверз је x7 + x6 + x3 + x = {CA}, што се може потврдити множењем ова два елемента.

Случај више од два броја[уреди]

Можемо решити случај више од два броја итеративно. Прво, покажемо да nzd(a,b,c) = nzd(nzd(a,b),c). Да бисмо доказали ово, нека је d=nzd(a,b,c). По дефиницији nzd-а, d је делилац од a и b. Према томе nzd(a,b)=k d за неко k. Слично, d је делилац за c тако да је c=jd за неко j. Нека је u=nzd(k,j). Према нашој конструкцији u-a, ud | a,b,c али пошто је d највећи делилац u-a је јединица. И пошто је ud=nzd(nzd(a,b),c) резултат је доказан.

Тако, ако na + mb = nzd(a,b), онда постоје x и y такви да xnzd(a,b) + yc = nzd(a,b,c) па ће крајња једначина бити

x(na + mb) + yc = (xn)a + (xm)b + yc =  nzd(a,b,c).\,

Да би применили на n бројева користимо индукцију

nzd(a_1,a_2,\dots,a_n) =nzd(a_1,\, nzd(a_2,\, nzd(a_3,\dots, nzd(a_{n-1}\,,a_n)))\dots),

уз директно праћење једнакости.

Референце[уреди]

Литература[уреди]

  • Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. Introduction to Algorithms, Second Edition. MIT Press and McGraw-Hill, 2001. ISBN 0-262-03293-7. Pages 859-861 of section 31.2: Greatest common divisor.

Спољашње везе[уреди]