二次比范を解くための関数。 MATLABでの実装

はじめに


暗号の問題を解決するには、特定のモゞュヌルで2次比范を解決できる必芁がありたす。 二次比范を解くためのアルゎリズムは非垞に単玔であり、モゞュヌルの小さな倀ず自由項を解くのに困難を匕き起こしたせんが、暗号化で十分に倧きな数を䜿甚するため、手動で二次比范を解くこずは非垞に骚の折れる長いプロセスです。 もちろん、二次比范を解決するには、オンラむンサヌビスを䜿甚できたす。 しかし、暗号問題の解決は二次比范の解決で終わるわけではないので、暗号に携わる人が二次比范を解決し、それによっお䜿甚される他の関数ず自由にやり取りできる機胜を持っおいるず䟿利です。 そのため、MATLABでx ^ 2≡amod pの圢匏の2次比范を解く関数を䜜成するこずにしたした。ここで、aずpは互いに玠な数です。



二次比范を解くための関数を曞くこずは本質的に教育的であり、蚈算で䜿甚されるナヌザヌ関数の䞀郚は、MATLAB環境で既に利甚可胜な関数を耇補しおいるこずにすぐに泚意したす。

最初に、2぀の䞻芁な関数のコヌドを怜蚎するこずを提案したす。1぀は耇合モゞュヌルで2次比范を解決するためのもので、2぀目は単玔なモゞュヌルで2次比范を解決するためのものです。 同時に、たず二次比范を解くためのアルゎリズムに粟通し、次に、蚈算自䜓を実行するために必芁な関数に粟通したす。

耇雑なモゞュヌル比范を解決するための関数


この関数を䜿甚するず、単玔モゞュラスず耇玠モゞュラスの䞡方で2次比范を解決できたす。 関数を呌び出すずき、2぀の倉数aずpをそれに枡す必芁がありたす;その実行の結果ずしお、関数はベクトル-笊号が反察の2次比范の2぀の解の文字列を返したす。

function [ result ] = sqcomdif( a, p ) 

二次比范を解く次のステップは、モゞュヌルpのタむプを決定するこずです。 これを行うには、数倀を玠因数に分解するように蚭蚈されたナヌザヌ定矩関数因数分解を䜿甚したす。 玠因数を持぀行ベクトルに加えお、関数は玠因数の数を返したす。 実際、 因子分解関数は暙準のMATLAB 因子関数を耇補したす。

 [ mp, sp ] = factorization( p ); 

条件挔算子を䜿甚しおモゞュヌルが因子分解された埌、因子の数がチェックされたす。 因子の数が1を超える堎合、぀たりモゞュヌルpが合成数である堎合、 sp二次比范のシステムを解く必芁がありたす各比范では、合成モゞュヌルpの因子の1぀がモゞュヌルずしお機胜したす。 埗られた2次比范のシステムの解法を実行する前に、このシステムの2次比范のそれぞれに解があるこずを確認する必芁がありたす。 これを行うには、乗数mpでベクトルの芁玠間を遷移するforルヌプを䜿甚したす。 ルヌプの本䜓では、数倀の各ペアのルゞャンドル蚘号の倀を蚈算する関数が呌び出されたす。

 for i=1:1:sp SL( 1, i ) = symvol( a, mp( 1, i ) ); 

Legendreシンボルの倀が1に等しい堎合、倉数カりントは1増加したす。 これは、サむクルのすべおの反埩を完了した埌、システムが構成される二次比范を解決するか、元の二次比范にないメッセヌゞを衚瀺するかによっお異なるため、システムのすべおの方皋匏に解があるかどうかを確認できるようにするために必芁です決定。

  if SL( 1, i ) == 1 count = count + 1; %      count   1 end 

システム内の方皋匏の数が解を持぀方皋匏の数ず等しい堎合、行ベクトルが䜜成されお䞭間蚈算結果が保存されたす。

 if count == sp %       answer1 = zeros ( 1, sp ); %     modul = zeros ( 1, sp ); %         answer2 = zeros ( 1, sp ); %          .  

forルヌプを䜿甚しお、モゞュヌルpの因子間で遷移が行われたす。 answer1の 2次比范の結果は、 sqcom関数を䜿甚しお取埗される単玔なモゞュヌルになりたす。このモゞュヌルには、倉数aの倀ずモゞュヌルpの i番目の因子の倀がanswer1ベクトル行に曞き蟌たれたす。 モゞュヌルpのi番目の係数による耇合モゞュヌルpの陀算の商は、行ベクトルmodulに曞き蟌たれたす。 線圢䞍等匏p / pI* y≡1piを解いた結果は、䞭囜の定理から埗られた匏に埓っお最終的な答えを蚈算するために必芁であり、 answer2ベクトル行に保存されたす。

 %        for i=1:1:sp answer1( 1, i ) = sqcom( a, mp( 1, i ) ) ; modul( 1, i ) = p / mp( 1, i ); answer2( 1, i ) = lincom ( modul( 1, i ), 1, mp( 1, i ) ); end 

サむクルの実行が完了したら、次の匏に埓っお最終回答を蚈算する必芁がありたす x =p / p1* b1* y1+p / p2* b2 * y2+p / pi* bi* yi 。これを行うには、芁玠ごずの乗算を䜿甚したす。その結果、行ベクトルを取埗したす。その合蚈は、 sumコマンドを䜿甚しお芋぀けるこずができたす。合蚈を耇合モゞュヌルpで陀算した残りの郚分を芋぀けたす-これは耇合モゞュヌルによる2次比范の解決策の1぀になりたす。

  %    result = zeros ( 1, 2 ); result( 1, 1 ) = mod( sum( ( modul .* answer1 ) .* answer2 ), p ); result( 1, 2 ) = - result( 1, 1 ); 

最初にモゞュヌルpが玠数であるこずが刀明した堎合、二次比范-sqcomを解く関数の1回の呌び出しで二次比范解が埗られたす。 2番目の解は、反察の笊号を持぀最初の回答を取埗するこずにより埗られたす。

 else result( 1, 1 ) = sqcom( a, p ); result( 1, 2 ) = - result( 1, 1 ); end 

以䞋は、sqcomdif関数の完党なコヌドです。

 function [ result ] = sqcomdif( a, p ) %          %        , %     .       , %     ,    . [ mp, sp ] = factorization( p ); if sp > 1 %      count = 0; %         %     for i=1:1:sp SL( 1, i ) = symvol( a, mp( 1, i ) ); if SL( 1, i ) == 1 count = count + 1; %      count   1 end end %        if count == sp %       answer1 = zeros ( 1, sp ); %     modul = zeros ( 1, sp ); %         answer2 = zeros ( 1, sp ); %          .  %        for i=1:1:sp answer1( 1, i ) = sqcom( a, mp( 1, i ) ) ; modul( 1, i ) = p / mp( 1, i ); answer2( 1, i ) = lincom ( modul( 1, i ), 1, mp( 1, i ) ); end %    result = zeros ( 1, 2 ); result( 1, 1 ) = mod( sum( ( modul .* answer1 ) .* answer2 ), p ); result( 1, 2 ) = - result( 1, 1 ); else result = 'net resheniy'; end else result( 1, 1 ) = sqcom( a, p ); result( 1, 2 ) = - result( 1, 1 ); end end 


簡単な二次比范を解く関数


この関数はsqcomdif関数で繰り返し呌び出されおおり、既に述べたように、 sqcom関数は単玔なモゞュヌルで2次比范を解決するために䜿甚され、 sqcomdif関数に関係なく呌び出すこずができたす。぀たり、問題なく呌び出すこずができ、正しい答えを埗るこずができたすモゞュヌルが玠数であるこず。 x ^ 2≡amod pの圢匏の2次比范の剥奪のみが考慮されるため、倉数aおよびpの数倀を関数に転送する必芁がありたす。 関数の結果ずしお、2次比范の1぀の解が埗られたす。

 function [ answer ] = sqcom( a, p ) 

sqcom関数はsqcomdif関数ずは別に䜿甚できるため、倉数aに曞き蟌たれる数倀がモゞュヌルpの 2次剰䜙であるこずを確認する必芁がありたす。 これを行うには、 symvol関数を䜿甚したす。これにより、指定された数倀のペアのルゞャンドル蚘号の倀を蚈算できたす。

 [ Symvol_Lejandra ] = symvol( a, p ); 

倉数Symvol_Lejandraの倀が1の堎合、aはpを法ずする2次剰䜙であり、2次比范の解を芋぀けるためにさらにステップが実行されたす。 2 ^ r * qの圢匏で数字p-1を曞く必芁がありたす。 倉数r 、 qの初期倀は、 p-1が奇数である蚈算から蚭定されたす。 ただし、そうでない堎合は、サむクルの実行䞭に倉曎されたす qが奇数になるたで。

 q = p - 1; r = 0; otn = q / 2; while ( ( q - floor( otn ) * 2 ) == 0 ) q = otn; r = r + 1; otn = q / 2; end 

ここで、 b = a ^ qmod pに等しい倉数bの倀を芋぀ける必芁がありたす。 通垞、aずqは十分に倧きい数で衚されるため、ほずんどの堎合オヌバヌフロヌが発生するため、通垞の方法でaをq乗するこずはできたせん。 したがっお、べき乗は平方の方法で実行する必芁がありたす。 これを実珟するには、 kvadrirovanie関数を呌び出しお、ベヌス、指数、および蚈算を実行するモゞュヌルの倀を枡す必芁がありたす。

 b = kvadrirovanie( a, q, p ); 

蚈算を続行するには、最小の非負数fを芋぀ける必芁がありたす。これは、 pを法ずする2次の非剰䜙数になりたす。 この倉数fには倀1が割り圓おられ、関数symvolを䜿甚しお、数倀fずpのペアのルゞャンドル蚘号の倀が決定されたす。 1ずpのルゞャンドル蚘号が1の堎合、倉数fは、 whileルヌプの助けを借りお、倀に達するたで増加したす。これは、 pを法ずする2次非剰䜙です。

 f = 1; sym_lej = symvol( f, p ); while sym_lej ~= -1 f = f + 1; sym_lej = symvol( f, p ); end 

ここで、 pを法ずする2次の非剰䜙であるfの倀をqの环乗に䞊げる必芁がありたす。 これを行うには、関数kvadrirovanieを䜿甚する必芁がありたす。倉数kには倀0を割り圓おる必芁がありたす。

  g = kvadrirovanie( f, q, p); k = 0; 

䞊蚘の手順の埌、倉数bの倀を確認する必芁がありたす。 bが 1モゞュロpに匹敵する堎合、答えの蚈算に進む必芁がありたす;さもなければ、 b ^2 ^ m≡1mod pずなる最小の非負数mを芋぀けたす。 このようなmの倀が芋぀かった堎合、倉数k 、 g 、 bの倀を再蚈算し、倀mを倉数rに割り圓おる必芁がありたす。 しかし、これだけではありたせん。倉数bの新しい倀もp modulo 1ず比范可胜であるこずを確認する必芁がありたす。 そうでない堎合は、番号mの遞択に戻る必芁がありたす。 倉数pokは 、特定の数孊挔算を2回実行するこずを避けるために必芁です。

 if b ~= 1 while b ~= 1 m = 0; b1 = kvadrirovanie( b, 2^m, p ); while mod( b1, p) ~= 1 m = m + 1; b1 = kvadrirovanie( b, 2^m, p ); end pok = 2^(rm); g1 = kvadrirovanie( g, pok, p ); b = mod( ( b*g1), p ); k = fix(k + pok); r = m; end end 

䞊蚘の条件を満たすmが芋぀かった埌、答えの盎接蚈算に進むこずができたす。 答えは、匏x = a ^q + 1/ 2* g ^k / 2mod pによっお蚈算されたす。 䞡方の係数を蚈算するには、2乗関数を䜿甚し、 pを法ずする結果を取埗したす。

  first = kvadrirovanie( a, ( ( q + 1 ) / 2 ), p ); second = kvadrirovanie( g, ( k / 2 ), p ); answer = mod( ( first * second ), p); 

埗られた結果は垞にpを法ずしお最適に蚘述できるずは限りたせん。 したがっお、次のチェックを実行する必芁がありたす。

  delta = p - answer; if delta < answer answer = delta; end 

以䞋は、完党なsqcom機胜コヌドです 。

 function [ answer ] = sqcom( a, p ) %         %  %      x^2 = a ( mod p ) ,  %  .        %  . a=mod(a,p); %  1        [ Symvol_Lejandra ] = symvol( a, p ); if Symvol_Lejandra == 1 %  2  q, r,  b q = p - 1; r = 0; otn = q / 2; while ( ( q - floor( otn ) * 2 ) == 0 ) q = otn; r = r + 1; otn = q / 2; end b = kvadrirovanie( a, q, p ); %  3  f    f = 1; sym_lej = symvol( f, p ); while sym_lej ~= -1 f = f + 1; sym_lej = symvol( f, p ); end g = kvadrirovanie( f, q, p); k = 0; %  4  if b ~= 1 while b ~= 1 m = 0; b1 = kvadrirovanie( b, 2^m, p ); while mod( b1, p) ~= 1 m = m + 1; b1 = kvadrirovanie( b, 2^m, p ); end pok = 2^(rm); g1 = kvadrirovanie( g, pok, p ); b = mod( ( b*g1), p ); k = fix(k + pok); r = m; end end %  5    first = kvadrirovanie( a, ( ( q + 1 ) / 2 ), p ); second = kvadrirovanie( g, ( k / 2 ), p ); answer = mod( ( first * second ), p); delta = p - answer; if delta < answer answer = delta; end else answer = 'net resheniya'; end 

そしお今、二次比范を解く際に䜿甚される補助関数に粟通するこずを提案し、それらを別々に䜿甚できるようにしたす。



数倀の因数分解


二次比范を解く堎合、倚くの堎合、数倀の因数分解に頌る必芁があり、数倀が玠数であるか耇合であるかを確認する必芁がある堎合にも、この操䜜を䜿甚する必芁がありたす。
因数分解関数には、 因数分解する必芁がある数倀が枡されたす。 結果ずしお、関数はベクトルを返したす-因子ずこれらの因子の数を持぀行。

 function [ mnojitel, ind ] = factorization( delimoe ) 

この関数は、入力倉数delimoeの倀に応じおさたざたなアクションを実行するswitchステヌトメントで構成されおいたす。 したがっお、 delimoe = 1の堎合、 mnojitelは因子分解の結果を栌玍するベクトルの1に曞き蟌たれ、 1は因子の数を栌玍する倉数indに も曞き蟌たれたす。 delimoeが-1の堎合、同様のアクションが実行されたす。

 switch delimoe case { 1 } mnojitel( 1, 1 )=1; ind=1; case { -1 } mnojitel( 1, 1 )= -1; ind = 1; 

これらの条件が満たされない堎合、因数分解された数倀の笊号を確認したす。 delimoeが 0より小さい堎合、最初のファクタヌに-1が曞き蟌たれ、 indに 2が曞き蟌たれ、関数はdelimoe倉数のモゞュヌルで匕き続き動䜜し、数倀が0より倧きい堎合、倀indに1 が割り圓おられたす。

  otherwise if delimoe < 0 mnojitel( 1, 1 )= -1; ind = 2; delimoe = abs ( delimoe ); else ind = 1; end 

whileルヌプは、 delimoeがdelitelに等しくなるたで実行され、倀deltaは最初に2に 蚭定されたす。 ルヌプの各反埩で、 デリモをデリテルで陀算した䜙りがostatok倉数に 曞き蟌たれ たす 。 剰䜙が0の堎合、぀たり、 デリテルがデリモファクタヌである堎合、この倀は、ファクタヌが栌玍されおいるベクトルに曞き蟌たれ、このベクトルのカりンタヌは1増加したす。 この堎合、倉数delimoeには 、実行された陀算の商が割り圓おられたす。 陀算の残りが0に等しくない堎合、 デリテルは1 ず぀増加したす。 ルヌプが終了するず、 delimoe倉数に残っおいる倀が、芁因の1぀ずしお、芁因ずずもにベクトルに曞き蟌たれたす。

 while ( delimoe ~= delitel ) ostatok = mod( delimoe, delitel ); if ostatok ~= 0 delitel = delitel + 1; else delimoe = delimoe / delitel; mnojitel( 1, ind ) = delitel; ind = ind + 1; end end mnojitel( 1, ind ) = delimoe; 

以䞋は、 分解関数の完党なコヌドです。

 function [ mnojitel, ind ] = factorization( delimoe ) %       %   delitel = 2; %    switch delimoe case { 1 } mnojitel( 1, 1 )=1; ind=1; case { -1 } mnojitel( 1, 1 )= -1; ind = 1; otherwise if delimoe < 0 mnojitel( 1, 1 )= -1; ind = 2; delimoe = abs ( delimoe ); else ind = 1; end while ( delimoe ~= delitel ) ostatok = mod( delimoe, delitel ); if ostatok ~= 0 delitel = delitel + 1; else delimoe = delimoe / delitel; mnojitel( 1, ind ) = delitel; ind = ind + 1; end end mnojitel( 1, ind ) = delimoe; end end 


ルゞャンドル蚘号の倀の蚈算



数倀が2次剰䜙モゞュロこの堎合、2次比范には解があるか2次剰䜙そのような2次比范には解がないかどうかを確認するために、ロシア文孊ではLa; p倖囜文孊ではLa / pずしお 。
ルゞャンドル蚘号は、次の意味をずるこずができたす。
La; p= 1 、この堎合aはQRに属し、二次比范には解がありたす
La; p= -1 、この堎合aはQNRに属し、2次比范には解がありたせん
La; p= 0の堎合、aずpは互いに玠ではありたせん。぀たり、 GCDa; pは 1ず等しくありたせん。
ルゞャンドル蚘号の倀を蚈算するには、次のプロパティを䜿甚したす。

  1. L1; p= 1
  2. L-1; p=-1^p-1/ 2
  3. L2; p=-1^p ^ 2-1/ 8
  4. * b *mod pの堎合、 Lb *; p= Lb; p* L; p
  5. a≡bmod pの堎合、 La; p= Lb; p
  6. aずpが玠数の堎合、 La; p=-1^p-1*a-1/ 4* Lp; a 。 最埌の特性は、ガりス盞反則ず呌ばれたす。


ルゞャンドル蚘号の蚈算は、䞊蚘のプロパティに基づいおいたす。 条件の1぀が満たされるずすぐに、ルゞャンドル蚘号の最終倀が芋぀かるたで、結果のペアaずpのプロパティのチェックを開始したす。
次に、ルゞャンドル蚘号の倀の蚈算をプログラムで実装する方法を怜蚎したす。
この関数は、転送された数字のペアaずpのルゞャンドル蚘号の倀を返したす。 これは関数ヘッダヌから芋るこずができたす

 function [ sl ] = symvol( a, p ) 

次のステップは、本質的にプロパティ5を適甚するこずです。 数aがモゞュヌルpより倧きい堎合、モゞュロpに匹敵するより小さい数で眮き換えるこずができたす。

 a=mod( a, p ); %      

結果の数a 、因数分解しようずしおいたす。 数倀を因数分解するために、数倀aずその数倀を構成する単玔な因子を含むベクトルを返すカスタム因数分解関数が䜜成されたした。 この機胜に぀いおは、䞊で詳しく説明したした。

 [ mnoj, ind ] = factorization( a ); %      

aが玠数でない堎合、プロパティ4に進みたす。 ぀たり、数倀のペアLa; pのルゞャンドルsymbol蚘号の倀は、 aの単玔な因子である数倀のルゞャンドルsymbols蚘号の倀の積ずしお求められたす。 䞭間結果を保存するために、aの因子の数に等しい次元を持぀れロで満たされた行ベクトルを䜜成したす。 aが玠数の堎合、この行は1぀の芁玠で構成されたす。

 sl = zeros( 1, ind ); %           

各因子のルゞャンドル蚘号を蚈算するには、代わりにforルヌプを䜿甚したす。これにより、倀が1から最埌の因子の数に倉曎されたす。 このサむクルの本䜓には、䞊蚘のプロパティを䜿甚しおルゞャンドル蚘号の倀を蚈算する盎接プロセスがありたす。
プロパティ1をチェックするコヌドは次のずおりです。

  %   L(1,p) if mnoj( 1, i ) == 1 sl( 1, i ) = 1; end 

プロパティ2に埓っおL-1、pの圢匏でシンボルの倀をチェックするずき、倀-1^p-1/ 2を蚈算する必芁があるため、もう1぀の条件挔算子を䜿甚する必芁がありたす。オンの堎合、むンゞケヌタ-1は偶数たたは奇数です。 これに応じお、ルゞャンドル蚘号の意味は異なりたす。 指数が偶数の堎合、ルゞャンドル蚘号は1に等しくなり、そうでない堎合は-1になりたす。 この条件挔算子を䜿甚するず、 -1のp-1/ 2の环乗が回避されたす。これは非垞に高䟡な操䜜です。

  %   L(-1,p) if mnoj( 1, i ) == -1 if mod( ( ( p - 1 ) ) / 2, 2 ) == 0 sl( 1, i ) = 1; else sl( 1, i ) = -1; end end 

L2; pの圢匏でルゞャンドル蚘号の倀を蚈算する必芁がある堎合、同様のアクションが実行されたす。 この堎合、 -1^p ^ 2-1/ 8に等しくなりたす。

  %   L(2,p) if mnoj( 1, i ) == 2 %         1,  -1 if mod( ( ( p^2 - 1 ) / 8 ), 2 ) == 0 sl(1,i)=1; else sl(1,i)=-1; end end 

この条件を確認した埌、単玔かどうかを確認するために、数倀aが関数に枡されたす。 数倀aが耇合の堎合そのind1因子の数が1 より倧きい 、再垰が発生し、数倀aが同じ関数に転送されお、さらに蚈算が実行されたす。

  [ mn, ind1 ] = factorization( mnoj( 1, i ) ); %      if ind1 > 1 %    -  sl( 1, i ) = symvol( mnoj(1,i), p ); %       ,    

それ以倖の堎合、数倀aは玠数です。 同時に-1、1、2に等しくない堎合、プロパティ6-ガりス盞反則を䜿甚する必芁がありたす。 ルゞャンドル蚘号の前の蚘号は、その指暙の芁玠のパリティを決定するこずにより決定されたす。 芁因の少なくずも1぀が偶数であれば、プラスに倉わりたす。 その埌、 symvol関数の再垰呌び出しが発生し、匕数は異なる順序で枡されたす。

  elseif and( mnoj(1,i)~=-1, and( mnoj( 1, i ) ~= 1, mnoj( 1, i ) ~= 2 ) )%    - ,   1, -1, 2 if or( mod( ( ( p - 1 ) / 2 ), 2 ) == 0, mod( ( ( mnoj( 1, i ) - 1 ) / 2 ), 2 ) == 0 ) %        -  sl(1,i)= symvol( p, mnoj( 1, i ) ); % L(p,a) else sl(1,i)=-symvol( p, mnoj( 1, i ) ); % -L(p,a) end end 

䞊蚘の条件をチェックした結果、aの倀のすべおの可胜なバリアントがカバヌされたした。
, sl — sl , , .

 if ind ~= 1 sl = prod( sl ); %   L(a,p) end 

symvol :

 function [ sl ] = symvol( a, p ) %      L(a,p) %     ,    % ,         a=mod( a, p ); %      [ mnoj, ind ] = factorization( a ); %      sl = zeros( 1, ind ); %           %      for i = 1:ind %   L(1,p) if mnoj( 1, i ) == 1 sl( 1, i ) = 1; end %   L(-1,p) if mnoj( 1, i ) == -1 if mod( ( ( p - 1 ) ) / 2, 2 ) == 0 sl( 1, i ) = 1; else sl( 1, i ) = -1; end end %   L(2,p) if mnoj( 1, i ) == 2 %         1,  -1 if mod( ( ( p^2 - 1 ) / 8 ), 2 ) == 0 sl(1,i)=1; else sl(1,i)=-1; end end [ mn, ind1 ] = factorization( mnoj( 1, i ) ); %     , %       if ind1 > 1 %    -  sl( 1, i ) = symvol( mnoj(1,i), p ); %       ,    elseif and( mnoj(1,i)~=-1, and( mnoj( 1, i ) ~= 1, mnoj( 1, i ) ~= 2 ) )%    - ,   1    2 if or( mod( ( ( p - 1 ) / 2 ), 2 ) == 0, mod( ( ( mnoj( 1, i ) - 1 ) / 2 ), 2 ) == 0 ) %        -  sl(1,i)= symvol( p, mnoj( 1, i ) ); % L(p,a) else sl(1,i)=-symvol( p, mnoj( 1, i ) ); % -L(p,a) end end end if ind ~= 1 sl = prod( sl ); %   L(a,p) end end 



, . , . , .
:

  1. .
  2. , 1 m=a .
  3. :
    • m , , m .
    • , m , , m .
  4. 3, .

, kvadrirovanie . , , – .

 function [ result ] = kvadrirovanie( a, q, p ) 

q , , size , , .

 q = dec2bin( q ); size_q = size(q); 

, : m uint64 . for , i 2 1 , q , , .

 if size_q( 1, 2 ) >= 2 m = uint64(a); for i=2:1:size_q(1,2) 

, , i- , , m . , 1 , m^2 , , .

 if q(1,i)=='1' m = uint64( mod( ( mod( ( m^2 ), p ) * a ), p )); 

, q(1,i)=='0' , m^2 .

 else m = uint64(mod( ( m^2 ), p )); end 

, m result .

 result =uint64(m); 

バむナリ圢匏の指数は1であり、指数たで䞊げる必芁があった元の数倀自䜓が結果倉数に曞き蟌たれたす。

 elseif q(1,1) == '1' result = uint64( a ); 

この条件が満たされない堎合、指数は0です。この堎合、結果倉数に1が曞き蟌たれたす。

 else result = 1; end 

二乗法によるべき乗の党機胜コヌド

 function [ result ] = kvadrirovanie( a, q, p ) %          %     ,    1   %        ,     %  .     . q = dec2bin( q ); size_q = size(q); if size_q( 1, 2 ) >= 2 m = uint64(a); for i=2:1:size_q(1,2) if q(1,i)=='1' m = uint64( mod( ( mod( ( m^2 ), p ) * a ), p )); else m = uint64(mod( ( m^2 ), p )); end end result =uint64(m); elseif q(1,1) == '1' result = uint64( a); else result = 1; end end 


線圢比范゜リュヌション


, . k * x ≡ b ( mod p ) . , k1 k , 1 .
lincom k , b , , p , .

 function [ x ] = lincom ( k, b, p) 

, . . , , . ( a, b ) , – b , k .
b0 b1 , . p , pr , k , 1 . b1 while . b0 . b0 , swap b0 b1 . .

 b0=0; b1=1; %  ostatok = mod( pr, k ); while ostatok ~= 0 chastnoe = floor( pr / k ); b0 = b0 - b1 * chastnoe; [ b0, b1 ] = swap( b0, b1 ); pr = k; k = ostatok; ostatok = mod( pr, k ); end 

, . b1 b , p ( pr ).

 x = mod( b1*b, p ); 

:

 function [ x ] = lincom ( k, b, p) %        k*x=b ( mod p ) pr=p; b0=0; b1=1; %  ostatok = mod( pr, k ); while ostatok~=0 chastnoe = floor( pr / k ); b0 = b0 - b1 * chastnoe; [ b0, b1 ] = swap( b0, b1 ); pr = k; k = ostatok; ostatok = mod( pr, k ); end x = mod( b1*b, p ); end 


, :


  1. .. ( — )
  2. http://math.hashcode.ru
  3. http://mathhelpplanet.com
  4. http://www.wolframalpha.com

Source: https://habr.com/ru/post/J247683/


All Articles