NTL密码算法开源库——大整数ZZ类(三)

2021SC@SDUSC

 jacobi符号

数学原理:中国剩余定理,同余式,二次同余式,勒让德符号

中国剩余定理

//中国剩余定理模板代码

typedef long long ll;

ll china(ll a[],ll b[],int n)//a[]为除数,b[]为余数

{

    ll M=1,y,x=0;

    for(int i=0;i<n;++i)  //算出它们累乘的结果

        M*=a[i];

    for(int i=0;i<n;++i)

    {

        ll w=M/a[i];

        ll tx=0;

        int t=exgcd(w,a[i],tx,y);  //计算逆元

        x=(x+w*(b[i]/t)*x)%M;

    }

    return (x+M)%M;

}

 

同余式

定义3.11设m是一个正整数.设f(x)=anx^n++a1^x+a为多项式,其中a是整数,则f(x)≡0(modm)叫做模m同余式.若an≠0(modm),则n叫做f(x)的次数,记为degf.此时,(2)式又叫做模m的n次同余式如果整数x=a使得(2)成立,

即f(a)≡0(modm),则a叫做该同余式(2)的解。

事实上,满足xa(modm)的所有整数都使得同余式(2)成立,即a所在剩余类

C a = {c | c ∈ Z, c a (mod m)}

中的每个剩余都使得同余式(2)成立,因此,同余式(2)的解a通常写成(mod m)在模m的完全剩余系中,使得同余式(2)成立的剩余个数叫做同余式(2)的解数

二次同余式

求解形如 x^2 = a (mod p) 这样的同余式

代码:              

/*

模P平方根:

    求 X ^2 = a (mod p)

    定理:当P为奇素数的时候

    先判断(a / p )的勒让德符号, 若为-1则无解,若为1则有解

    分解P-1,然后求B,然后求出X(t-1),和a的逆元

    然后开始求 ans = ( a的逆元 * 上一个X的平方(t-k))的(t-k-1)次方对P取模

    如果  ans == -1 则 J = 1;

    如果  ans ==  1 则 J = 0;

    然后开始求现在的 X = (上一个X * B的(J*2的k次方)次方

    直到求出X0,也就是最后的解

*/

#include<bits/stdc++.h>

using namespace std;



void Divide(int p, int &t, int &s)

{

    t = 0, s= 0;

    while(p % 2 == 0)

    {

        t++;

        p /= 2;

    }

    s = p;

    return ;

}



int Pow(int a, int b, int mod)

{

    int ans = 1, base = a;

    while(b != 0)

    {

        if(b & 1)

            ans = (ans * base) % mod;

        base = (base * base) % mod;

        b >>= 1;

    }

    return ans;

}



int Legendre(int a, int p)

{

    if(a == 2)

    {

        int x = (p+1)*(p-1)/8;

        if(x % 2 == 0)

            return 1;

        else

            return -1;

    }

    else

    {

        int ans = Pow(a, (p-1)/2, p);

        if(ans == p-1)

            return -1;

        else

            return 1;

    }

}

具体代码见@元解~殇怀

  勒让德符号

勒让德符号可以计算当p为素数的情况的二次剩余判别问题,而雅可比符号判定条件为a为任意整数,p为任意奇数。

高斯推导出著名的二次互反律。

通过二次互反律解决了勒让德符号的计算问题,可以通过递归调用解决计算。

int Legrend(int a, int p)



{if (a == 1)



              return1;



       if (p % a== 0)



              return0;



       if (a % 2== 0)



              returnLegrend(a / 2, p) * pow(-1, (pow(p, 2) - 1) / 8);



       return Legrend(p%a, a)*pow(-1, (a - 1)*(p - 1) / 4);}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值