首页 > 其他分享 >求解离散对数的方法:BSGS

求解离散对数的方法:BSGS

时间:2023-10-16 13:44:49浏览次数:41  
标签:return 离散 base str print 对数 inf BSGS mod

离散对数问题:

在循环群(循环群的定义见密码协议学习笔记(1.4):密码学的一些数学基础 - Isakovsky - 博客园 (cnblogs.com))$(\mathbb{G},\cdot)$上已知两个元素$g,h\in\mathbb{G}$,求式子$g^x=h$中$x$的值的问题,叫做离散对数问题,亦可记为$x=\log_gh$

BSGS(Baby Step Giant Step,大步小步)算法:

本质上是一种分块.

选取$t$使得群的阶$|\mathbb{G}|\leq t^2$,将$x$表示为$x=At+B$,其中$A,B\in[0,t-1]$.

小步:预处理出$B=0,1,\cdots,t-1$时,$h\cdot g^{-B}$的值保存到dict里.注意,为了方便查找,应当将$h\cdot g^{-B}$作为下标,$B$作为值.

大步:遍历$a=0,1,\cdots,t-1$,计算$g^{At}$的值,然后在预处理信息中查找是否存在$B$满足$g^{At}=h\cdot g^{-B}$,则说明$g^{At+B}=h$,将答案输出即可.

示例代码:在$y^2=x^3+ax+b \mod p$的椭圆曲线循环群$E_p(a,b)$(参见密码协议学习笔记(1.5):几种常用的非对称密码体系 - Isakovsky - 博客园 (cnblogs.com))上求解离散对数

import math
def qpow(base,exp,mod): #快速幂
    ans = 1
    while(exp>0):
        if(exp%2 == 1):
            ans = ans*base%mod
        exp = exp//2
        base = base*base%mod
    return ans

def rev(a,mod): #求整数乘法逆元
    return qpow(a,mod-2,mod)

def ECCAdd(p1,p2,mod,a,b): #椭圆曲线上的加法
    if(p1=='inf'):
        return p2
    elif(p2=='inf'):
        return p1
    # 无穷远点定义为零元
    x1,y1=p1
    x2,y2=p2
    if(x1==x2 and y1+y2==mod):
        return 'inf'
    # 定义关于y轴对称两点(在模意义下实际上是相加得p)互为加法逆元,相加得零元

    if(x1==x2 and y1==y2):
        λ=(3*x1*x1+a)*rev(2*y1,mod)%mod # 两点不重合,过此两点做一条直线
    else:
        λ=(y2-y1)*rev((x2-x1+mod)%mod,mod)%mod # 两点重合,则取其与曲线的切线

    x3=(λ*λ-x1-x2+mod)%mod
    y3=(λ*(x1-x3)-y1+mod)%mod
    # 定义这条直线与曲线的另一个交点为群上加法的结果
    return (x3,y3)

def ECCMinus(p1,p2,mod,a,b): #做减法就是加上加法逆元
    if(p2=='inf'):
        return p1
    else:
        return ECCAdd(p1,(p2[0],mod-p2[1]),mod,a,b)


def ECCMult(k,base,mod,a,b): #椭圆曲线上的数乘(龟速乘)
    ans = 'inf'
    while(k>0):
        if(k%2 == 1):
            ans = ECCAdd(ans,base,mod,a,b)
        k = k//2
        base = ECCAdd(base,base,mod,a,b)
    return ans

def ECCValid(p,mod,a,b): #检查点是否在椭圆曲线上
    if(p=='inf'):
        return True
    else:
        z=(p[0]*p[0]*p[0]+a*p[0]+b)%mod
        if(p[1]*p[1]%mod==z):
            return True
        else:
            return False

mod=11 #定义模数
a=1
b=6 #当4a^3+27b^2 ≠0 mod p 时,可定义一个交换群
print('p =',mod,'a =',a,'b =',b)
if(4*a*a*a+27*b*b%mod==0):
    print("无法构成交换群")
    exit()
else:
    print("可以构成交换群")

# print("群上的元素有:")
# n=0 #统计椭圆曲线上的元素个数
# for x in range(mod):
#     z=(x*x*x+a*x+b)%mod
#     for y in range(mod):
#         if(y*y%mod==z):
#             print((x,y))
#             n=n+1
# print('inf')
# n=n+1 #这个值同时也是(除零元O以外的)所有的点的阶数
# # 即,使得 nP=O 最小的正整数n

g=(5,2)
h=(8,8)


if(ECCValid(g,mod,a,b)==False):
    print("点"+str(g)+"不在曲线上!")
    exit(0)
if(ECCValid(h,mod,a,b)==False):
    print("点"+str(h)+"不在曲线上!")
    exit(0)   

print('求解log('+str(g)+','+str(h)+')')
if(h=='inf'):
    print('log('+str(g)+','+str(h)+')=0')
elif(g=='inf'):
    print('无解!')
else:
    t=math.ceil(math.sqrt(2*mod+1))
    dict0={}
    #预处理
    for B in range(t):
        val=ECCAdd(h,ECCMult(B,ECCMinus('inf',g,mod,a,b),mod,a,b),mod,a,b) # h*g^{-B}
        dict0[val]=B
    for A in range(t):
        val=ECCMult(t*A,g,mod,a,b)
        if(dict0.get(val) is not None):
            print('log('+str(g)+','+str(h)+')='+str(A*t+dict0[val]))
            exit(0)

 

标签:return,离散,base,str,print,对数,inf,BSGS,mod
From: https://www.cnblogs.com/isakovsky/p/17766395.html

相关文章

  • 7713: 离散化去重 map
    描述 “离散化”是指把一个无穷大的集合映射到一个有限的集合中。如有n个整数,其中可能存在相同的数,现在需要你将其去重后得到的m个数用1~m来表示,同时保持原始的大小顺序不变,即在不改变数据相对大小的条件下,对数据进行相应的缩小。如:原数据:1,999,100000,15处理后:1,3,4......
  • 算法0506 对数器 二分搜索
    对数器非常重要的自我验证代码正确性的方法在面试时或机试时写算法题,没有测试用例或者测试用例太少,导致巨大的数据量无法进行测试时。需要自己写测试用例数据时可以使用对数器。......
  • 基于凸多边形离散点排序的研究
    OrderBy(){varvertices1=_.cloneDeep(this.polygon);varxArray=vertices1.map((item)=>item.x);varyArray=vertices1.map((item)=>item.y);const[minX,maxX,minY,maxY]=[_.min(xArray),_.max(xArray),_.min(yArray),_.m......
  • EM@对数@对数函数
    文章目录abstract从幂到对数的引入介绍对数相关性质公式对数函数及其性质幂指数和对数在指数函数中,对于实数集内的每一个指,正实数集内都有唯一确定的值和它对应;反之,对于正实数集内的每一个确定的值,在内部都有唯一确定的值和它对应**幂指数**又称为"以为底的对数",例如,那么......
  • FAST角点检测离散圆形扫描
    FAST角点检测离散圆形扫描目的是扫描离散圆内所有点,计算灰度质心,过程为小半径到大半径极坐标形式扫描,最终如下,对圆内所有坐标进行扫描代码:clcclearallcloseall%%初始化参数%正方形绘图边长Side=11;%当前扫描坐标current=zeros(1,2);%上次坐标last=zero......
  • 力扣-2744-最大字符串配对数目
    给你一个下标从0开始的数组words,数组中包含互不相同的字符串。如果字符串words[i]与字符串words[j]满足以下条件,我们称它们可以匹配:字符串words[i]等于words[j]的反转字符串。0<=i<j<words.length请你返回数组words中的最大匹配数目。注意,每个字符串最......
  • 力扣-2006-差的绝对值为 K 的数对数目
    给你一个整数数组nums和一个整数k,请你返回数对(i,j)的数目,满足i<j且|nums[i]-nums[j]|==k。|x|的值定义为:如果x>=0,那么值为x。如果x<0,那么值为-x。示例1:输入:nums=[1,2,2,1],k=1输出:4解释:差的绝对值为1的数对为:-[1,2,2,1]-[1,2,2,1]-......
  • LntonGBS针对数据库删除级联数据后的无效数据进行的优化
    LntonGBS国标视频云服务可支持通过国标GB28181协议将设备接入,实现视频的实时监控直播、录像、语音对讲、云存储、告警、级联等功能,同时也支持将接入的视频流进行全终端、全平台分发,分发的视频流包括RTSP、RTMP、FLV、HLS、WebRTC等格式。同时LntonGBS平台也支持海康Ehome协议及SDK......
  • fastapi-----SQLAlchemy对数据的增删改查操作(不使用crud+schemas)
     fromsqlalchemyimportcreate_engine,Column,String,Integerfromsqlalchemy.ext.declarativeimportdeclarative_basefromsqlalchemy.ormimportsessionmakerHOSTNAME='127.0.0.1'PORT="3306"USERNAME="root"PASSWORD=&......
  • 一种对数据库友好的GUID的变种使用方法
    概述.NET生成的GUID唯一性很好,用之方便,但是,缺少像雪花算法那样的有序性。虽然分布式系统中做不到绝对的有序,但是,相对的有序对于目前数据库而言,索引效率等方面的提升还是有明显效果的(当然,我认为,这是数据库的问题,而非编程的问题,数据库应该处理好任何类型数据作为主键索引时的性能,除......