Ellipse类中常用功能,数论中的常用算法实现

本文中截图来自于《SM2椭圆曲线公钥密码算法》,如有需要,请联系我,源码Utils.java也上传至github,如有需要,也请联系我。

 

package cn.com.shfe.sfit.dong;

 

import java.util.ArrayList;

import java.util.List;

 

/**

 * @ClassName: Utils

 * @Description:常用功能,数论中的某些算法,均为static函数形式;

 * @author: dong.yanchao

 * @date: 2018814 1042

 * @Copyright: v1

 */

public class Utils {

  public static void main(String[] args) {

     long g = 6;

     long q = 23;

     long rankOfNum = Utils.rankOfNum(g, q);

     System.out.println(rankOfNum);

     long aexpB = Utils.AexpB(g,rankOfNum,q);

     System.out.println(aexpB+" "+AmodB(aexpB,q));

  System.out.println(Utils.checkRankOfNum(g, rankOfNum, q));

    

     /*boolean flag = false;

     for(int i = 1;i<100;i++){

       if(Utils.checkProbPrime(17, 10L)==true){

          System.out.println("true");//17素数,93合数,293素数,41素数

          flag = true;

          break;

       }

     }

  if(flag==false)System.out.println(flag);*/

    

  }

  /**

   * @Title: AexpB Fq上的指数运算

   * @param qEq(a,b)中的素数q

   * @Description: 计算a^b的值

   * @return: long ,返回值范围[0,b-1]

   */

  public static long AexpB(long g,long e,long q){

     if(AmodB(e,q)==0)return 1l;

     List<Byte> bins = new ArrayList<Byte>();//e的二进制展开

     while (e != 0) {

       byte tmp = (byte) (e % 2);

       bins.add(tmp);

       e /= 2;

     }

     long x = g;

     for (int i = bins.size() - 2; i >= 0; i--) {

       x = AmodB(x*x,q);//x=x^2

       if (bins.get(i) == 1)x = AmodB(g*x,q);//x=g*x

     }

     return x;

  }

  /**

   * @Title: AmodB 整数求模运算

   * @Description: 计算a mod b的值

   * @return: long ,返回值范围[0,b-1]

   */

  public static long AmodB(long a, long b) {

     long res = a % b;

     if(res<0)return res+b;

     return res;

  }

  /**

   * @Title: square 整数求平方根的运算

   * @param g 满足[0,q)的整数

   * @param q Eq(a,b)中的素数q

   * @Description: retg的平方根,有ret*ret=gmod q)恒成立,若ret成立,则q-ret也成立

   * @return: long ,返回任意一个值,返回值范围[0,q-1],另一个为q-ret;返回q,则代表g不存在平方根

   */

  public static long square(long g,long q){

     if(g<0||g>=q){

       System.err.print("square的参数g应满足[0,q)");

       System.exit(0);

     }

     if(g==0)return 0;

     long u = q/4;

     long ret = AexpB(g,u+1,q);

     if(AmodB(ret*ret,q)==g)return ret;

     return q;

  }

  /**

   * @Title: rankOfNum 确定g(mod p)的阶

   * @param g 整数 范围在[2,q)

   * @param qEq(a,b)中的素数q

   * @Description: 约定返回值为k,满足g^k=1(mod q)恒成立,并且k是最小的正整数

   */

  public static long rankOfNum(long g,long q){

     long b = g,j = 1;

     do{

       b = AmodB(g*b,q);

       j++;

     }while(b>1);

     return j;

  }

  /**

   * @Title: checkRankOfNum 验证k为确定g(mod p)的阶

   * @param g 整数 范围在[2,q)

   * @param qEq(a,b)中的素数q

   * @return kg(mod p)的阶,返回true,否则返回false

   * @Description: 约定返回值为k,满足g^k=1(mod q)恒成立,并且k是最小的正整数

   */

  public static boolean checkRankOfNum(long g,long k,long q){

     if(AmodB(AexpB(g,k,q),q)!=1)return false;

     List<Long> primesFactor = getPrimesFactorList(k);

     for (Long factor : primesFactor) {

       if(AmodB(AexpB(g,factor,q),q)==1)return false;

     }

     return true;

  }

  /**

   * @Title: getPrimesFactorList(k) 返回素k的素数因子

   * @param k ,被要求素因子的数 

   * @return List,包括k的所有素因子,不包括1k本身

   */

  public static List<Long> getPrimesFactorList(long k) {

     List<Long> primesList = getPrimesList(k);

     List<Long> retList = new ArrayList<Long>();

     for (Long prime : primesList) {

       if(k%prime==0)retList.add(prime);

     }

     return retList;

  }

  /**

   * @Title: getPrimesList 返回素数List

   * @param N long,素数区间的右边界 

   * @return [2,N)之间的素数,不包括N

   */

   public static List<Long> getPrimesList(long N) {

     List<Boolean> checks = new ArrayList<Boolean>();

     for(int i = 1;i<=N;i++)checks.add(false);

     List<Long> primes = new ArrayList<Long>();

     for (int i = 2; i <= N - 1; ++i) {

       if (checks.get(i) == true)continue;

       primes.add((long) i);

       for (int j = i*i; j <= N - 1; j += i) checks.set(j,true);

     }

     return primes;

  }

  

   /**

   * @Title: checkProbPrime(u,T) 检查u是否为概率素数,u不为素数的概率小于2^(-2T)

   * @Description u是合数的概率小于2^(-2T),只要T足够大,误差可以忽略

   * @return booleanuT下的概率素数,返回true,否则返回false

   */

   public static boolean checkProbPrime(long u, long T){

     if(u==2)return true;

     if(u%2==0)return false;

     long v = -1,w = -1;

     for(int i = 1;;i++){

        long pow = (long) Math.pow(2.0,i*1.0);

        w = (u-1)/pow;

        if(w%2==0)continue;

        v = (long)i;

        break;

     }

     if(v==-1){

        System.err.println("u-1=2^v*w没有成功");

        System.exit(0);

     }

     for(int j = 1;j<=T;j++){

       long a = (long)(Math.random()*(u-2)+2+1);

       long b = (long) (Math.pow(a, w))%u;

       if(b==1||b==u-1)continue;

       for(int i = 1;i<=v-1;i++){

          b=b*b%u;

          if(b==u-1)break;

          if(b==1)return false;

       }

       if(b==u-1)continue;

       return false;

     }

     return true;

   }

}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值