ユークリッド+拡張ユークリッド+RSA
3204 ワード
ユークリッドアルゴリズム:
転がり相除法、小学校のもの、gcd(a,b)=gcd(b,a%b)、
簡単で、用途が広く、テンプレートは以下の通りです.
拡張ユークリッドアルゴリズム:
拡張ユークリッドアルゴリズムはユークリッドアルゴリズム(転がり相除算とも呼ばれる)の拡張である.このアルゴリズムは、a、bの2つの整数の最大公約数を計算することに加えて、整数x、y(そのうちの1つは負の数である可能性が高い)を見つけることができる.通常、最大公因子について述べると、ax+by=gcd(a,b)となる整数xとyが必ず存在するという非常に基本的な事実に言及する.2つの数a,bがあり、それらを転がす相除法を行い、それらの最大公約数を得ることができる-これはよく知られている.そして,転がり相除去法で生じた式を収集し,逆戻りしてax+by=gcd(a,b)の整数解を得ることができる.
ex_gcd(a,b,x,y)はa>bを仮定する.1、b=0であればgcd(a,b)=aとなり、x=1、y=0となる.2、a*b!=0はax 1+by 1=gcd(a,b)である. bx2+(a%b)y2=gcd(b,a%b);ユークリッドアルゴリズムから得られる:gcd(a,b)=gcd(b,a%b);すなわち、ax 1+by 1=bx 2+(a%b)y 2;すなわち、ax 1+by 1=bx 2+[a-(a/b)b]y 2=ay 2+bx 2-b(a/b)y 2;aとbは定値であり、式が一定であるため、x 1=y 2、y 1=x 2-(a/b)y 2;このようにx 2,y 2を解くことによってx 1,y 1が得られる.コードは次のとおりです.
このアルゴリズムはgcd(a,b)を求めることができ,xとyを求めることもできる.
Zn * ={x| x>0 && x< n && gcd(x,n)=1 };
乗算逆要素:集合Zn*の要素に対して、各数aは、ax≡1(mod n)となるように、それに対応する唯一の乗算逆要素xを有する.
1つの数の逆元がある十分な必要条件はgcd(a,n)=1であり,この逆元は唯一存在する.逆元の意味:モードnの意味では、1つの数aに逆元xがある場合、aで割るとxを乗じることに相当する.拡張ユークリッドアルゴリズム乗算逆元:所与のモードn、aを求める逆はax=1(mod n)を解くことに相当し、この方程式はax-my=1に変換することができ、それから二元一次方程式の方法を組み合わせて、拡張ユークリッドアルゴリズムでx 0、y 0とgcdのセットを求める.gcdが1 gcdでないかどうかをチェックすることは、逆元が存在しないことを示し、1であればx 0から0~m-1の範囲で調整すればよい.コードは次のとおりです.
思い出した前にPythonでRSAの解読を求めるブログを書いたことがあります.19年のブルーブリッジカップの省試合の問題です.今、c++の解法を補充します.
タイトルリンク:https://blog.csdn.net/weixin_43107805/article/details/89515994
まず拡張ユークリッドで乗算逆元eを求め、(直接列挙は絶対にだめで、long long範囲を超える).
そして求めて、C^e mod mは高速べき乗で解いて、
(ただしa*a%mもlong longを超え、高速べき乗で高速乗を呼び出すしかなく、a=mult_mod(a,a,m)%m;計算a=(a*a)%m)
だから1つの問題は拡張ユークリッドが乗算逆元を求めなければならないことを総合して、急速にべき乗して、急速に3つの知識点を乗じます.
詳細は次のとおりです.
高速べき乗型取り(数が大きい場合、long longを乗算しても超過する解決策)
https://blog.csdn.net/wrf20162305/article/details/80385438
拡張ユークリッドアルゴリズムと求逆元:
https://blog.csdn.net/greenary/article/details/79343176
転がり相除法、小学校のもの、gcd(a,b)=gcd(b,a%b)、
簡単で、用途が広く、テンプレートは以下の通りです.
int gcd(int a,int b)// long long
{
return b!=0 ? gcd(b,a%b):a;
}
拡張ユークリッドアルゴリズム:
拡張ユークリッドアルゴリズムはユークリッドアルゴリズム(転がり相除算とも呼ばれる)の拡張である.このアルゴリズムは、a、bの2つの整数の最大公約数を計算することに加えて、整数x、y(そのうちの1つは負の数である可能性が高い)を見つけることができる.通常、最大公因子について述べると、ax+by=gcd(a,b)となる整数xとyが必ず存在するという非常に基本的な事実に言及する.2つの数a,bがあり、それらを転がす相除法を行い、それらの最大公約数を得ることができる-これはよく知られている.そして,転がり相除去法で生じた式を収集し,逆戻りしてax+by=gcd(a,b)の整数解を得ることができる.
ex_gcd(a,b,x,y)はa>bを仮定する.1、b=0であればgcd(a,b)=aとなり、x=1、y=0となる.2、a*b!=0はax 1+by 1=gcd(a,b)である. bx2+(a%b)y2=gcd(b,a%b);ユークリッドアルゴリズムから得られる:gcd(a,b)=gcd(b,a%b);すなわち、ax 1+by 1=bx 2+(a%b)y 2;すなわち、ax 1+by 1=bx 2+[a-(a/b)b]y 2=ay 2+bx 2-b(a/b)y 2;aとbは定値であり、式が一定であるため、x 1=y 2、y 1=x 2-(a/b)y 2;このようにx 2,y 2を解くことによってx 1,y 1が得られる.コードは次のとおりです.
#include
int exgcd(int a,int b,int &x,int &y)
{
if(!b)
{
x=1;
y=0;
return a;
}
int r=exgcd(b,a%b,x,y);
int t=x;
x=y;
y=t-(a/b)*y;
return r;
}
int main()
{
int a,b,x,y;
scanf("%d %d",&a,&b);
int c=exgcd(a,b,x,y);//
printf("%d %d
",c,(x+b)%b);
return 0;
}
このアルゴリズムはgcd(a,b)を求めることができ,xとyを求めることもできる.
Zn * ={x| x>0 && x< n && gcd(x,n)=1 };
乗算逆要素:集合Zn*の要素に対して、各数aは、ax≡1(mod n)となるように、それに対応する唯一の乗算逆要素xを有する.
1つの数の逆元がある十分な必要条件はgcd(a,n)=1であり,この逆元は唯一存在する.逆元の意味:モードnの意味では、1つの数aに逆元xがある場合、aで割るとxを乗じることに相当する.拡張ユークリッドアルゴリズム乗算逆元:所与のモードn、aを求める逆はax=1(mod n)を解くことに相当し、この方程式はax-my=1に変換することができ、それから二元一次方程式の方法を組み合わせて、拡張ユークリッドアルゴリズムでx 0、y 0とgcdのセットを求める.gcdが1 gcdでないかどうかをチェックすることは、逆元が存在しないことを示し、1であればx 0から0~m-1の範囲で調整すればよい.コードは次のとおりです.
int mod_reverse(int a,int n)//ax=1(mod n) a x
{
int d,x,y;
d=ex_gcd(a,n,x,y);
if(d==1)
return (x%n+n)%n;
else
return -1;
}
思い出した前にPythonでRSAの解読を求めるブログを書いたことがあります.19年のブルーブリッジカップの省試合の問題です.今、c++の解法を補充します.
タイトルリンク:https://blog.csdn.net/weixin_43107805/article/details/89515994
#include
#define ll long long
using namespace std;
const int N=500000;
ll n=1001733993063167141;
ll p=891234941;
ll q=1123984201;
ll c=20190324; //
ll d=212353; //
ll m=(p-1)*(q-1); // X = c^e mod (p-1)*(q-1);
ll e; // d*e≡1(mod Φ(n))
// e , long long
/*void get_e( )
{
for(int i=1;i<=N;i++)
{
if( (m*i+1)%d==0)
{
cout<>= 1;
}
return res;
}
//
ll quick_mod(ll a,ll b,ll m)
{
ll ans=1;
a=a%m;
while(b!=0)
{
if( b&1 ) ans=mult_mod(ans,a,m)%m;//(ans*a)%m;
a=mult_mod(a,a,m)%m; //a=(a*a)%m;
b>>=1;
}
return ans;
}
int main()
{
cout<
まず拡張ユークリッドで乗算逆元eを求め、(直接列挙は絶対にだめで、long long範囲を超える).
そして求めて、C^e mod mは高速べき乗で解いて、
(ただしa*a%mもlong longを超え、高速べき乗で高速乗を呼び出すしかなく、a=mult_mod(a,a,m)%m;計算a=(a*a)%m)
だから1つの問題は拡張ユークリッドが乗算逆元を求めなければならないことを総合して、急速にべき乗して、急速に3つの知識点を乗じます.
詳細は次のとおりです.
高速べき乗型取り(数が大きい場合、long longを乗算しても超過する解決策)
https://blog.csdn.net/wrf20162305/article/details/80385438
拡張ユークリッドアルゴリズムと求逆元:
https://blog.csdn.net/greenary/article/details/79343176