EIGamal and ez_Math

EIGamal算法

什么是EIGamal算法

ElGamal公钥密码算法是1985年由塔希尔·盖莫尔提出,是一个基于迪菲-赫尔曼密钥交换的非对称加密算法,是在密码协议中有着重要应用的一类公钥密码算法,其安全性是基于有限域上离散对数学问题的难解性。它至今仍是一个安全性良好的公钥密码算法,是一种既可用于加密又可用于数字签名的公钥密码算法。

数学基础

有限域:对于素数p,整数集合(0,1,2,…,p-1),在mod p意义下,关于求四则代数运算(”+”,”*”)构成域,当域的元素数目有限时称为有限域。

:有限域中元素的个数。如,模19下7的阶为3(7^1≡7mod 19,7^2≡11 mod 19,7^3≡1 mod 19,7^4≡7 mod 19)

本原元:设p为素数,若存在一个正整数g使得g1,g2,…,g^p-1,关于模p互不同余(模p下g的阶=φ§),则g为模p的本原元(又称为原根)。

离散对数:离散对数:是一种基于同余运算和原根的一种对数运算。如果对于一个整数b和质数p的一个原根a,可以找到一个唯一的指数i,使得 b ≡ a i ( mod p ) , 0 ≤ i ≤ p − 1 b \equiv a^i(\text{mod}p),0 ≤i≤p-1 bai(modp),0ip1成立,那么指数i称为b以a为基数的模p的离散对数。离散对数在一些特殊情况下可以快速计算。然而,在一般情况下,还没有有效的方法来计算它们。离散对数难题是指:当已知一个大质数p和它的一个原根a,如果给定一个b,要计算i的值是相当困难的。ElGamal算法的安全性就是基于有限域上离散对数问题的难解性。
在这里插入图片描述
1、参数定义和密钥生成

取大素数 p ,要求p-1有大素数因子,再选择一个模p的本原元g;
随机选取一整数 x (2 <= x <= (p - 2),
计算 y = g^x (mod p)
(p,g,x) 是私钥、((p,g,y) 是公钥

2、加、解密

加密M:

  • 假定:用户A发送明文M给用户B,A加密明文M得到密文C;
  • A将M编码为一个在0到p-1之间的整数m作为传输的明文;
  • 随机选取一整数 r (2 <= r<= (p - 2) 且 k 与 (p - 1) 互素);
  • 计算 c1= g^r mod p,c2 = m*y^r mod p(y为用户B的公钥);
  • 得到密文 C = (c1, c2);
  • 用户A把密文C传给用户B;

解密C:

  • 用户B接受到密文,计算明文m;
  • m = c2 * c1^(-x) mod p ;(x为用户B的私钥)
  • c2 * c1^(-x) mod p Ξ m * y^r * g^(-xr) Ξ m * g^(xr) * g^(-xr) Ξ m

ez_Math

from Crypto.Util.number import *
from secret import flag

m1, m2 = bytes_to_long(flag[:len(flag)//2]), bytes_to_long(flag[len(flag)//2:])
p, q, r, s = [getStrongPrime(512) for _ in range(4)]
e = 0x10001

n = p * q * r * s
x = pow(q + r, p, n)
y = pow(p * q + r, p, n)
z = pow(s + 1, m1, s ** 3)
c = pow(m2, e * (s - 1), n)

print(f'{n = }')
print(f'{x = }')
print(f'{y = }')
print(f'{z = }')
print(f'{c = }')

# n = 16063619267258988011034805988633616492558472337115259037200126862563048933118401979462064790962157697989038876156970157178132518189429914950166878537819575544418107719419007799951815657212334175336430766777427972314839713871744747439745897638084891777417411340564312381163685003204182743581513722530953822420925665928135283753941119399766754107671729392716849464530701015719632309411962242638805053491529098780122555818774774959577492378249768503656934696409965037843388835948033129997732058133842695370074265039977902884020467413323500218577769082193651281154702147769044514475692164145099161948955990463002411473013
# x = 3021730035236300354492366560252387204933590210661279960796549263827016146230329262559940840168033978439210301546282150367717272453598367244078695402717500358042032604007007155898199149948267938948641512214616076878271433754986480186150178487625316601499002827958344941689933374158456614113935145081427421623647242719093642478556263121508238995676370877385638074444859047640771188280945186355013165130171802867101829647797879344213688981448535289683363612035513789240264618036062440178755665951650666056478493289870170026121826588708849844053588998886259091357236645819074078054595561158630194224419831088510266212458
# y = 8995787142441643101775260550632842535051686960331455373408888374295557050896156890779515089927839904014859222004906681231525326673182671984194300730575609496770604394218160422560576866112460837985407931067753009696969997384839637927957848613356269534870170452152926447601781637641134982178028922559652443398183848786034348994249923007092159192374765197460466878587635412657807328348343062302127490267456095927890461140420639805398464266081441243108883599713672104446500850203779995739675784794478089863001309614674686652597236324659979849324914804032046113978246674538411441434320732570934185579553749616238819583998
# z = 1283646988194723153191718393109711130382429329041718186548715246082834666179475883560020086589684603980734305610989683434078096863563033623169666389076830792095374856743015929373461198718962686411467443788047511292138922700655772772117855226419561159782734009961921473456332468653898105909729309377890721920937410781006337057478451806364879679045839945032594716202888196404203782734864187890231653321470085251
# c = 4988583141177813116287729619098477713529507701428689219486720439476625736884177254107631282807612305211904876847916760967188201601494592359879509876201418493870112712105543214178376471651715703062382025712952561985261461883133695993952914519494709871429166239968478488380137336776740647671348901626710334330855078254188539448122493675463406596681080368929986034772169421577420193671300532508625180845417164660544286332963072804192276425664877337357353975758574262657585309762422727680851018467657523970318042829660721433987195369353660020476598195375492128671951807024027929490113371463210453342974983253996717176870

因为 x ≡ y ≡ r p mod q x\equiv y \equiv r^p \text{mod} q xyrpmodq,所以kq = x-y,q = gcd \text{gcd} gcd(kq,n)
然后 x ≡ q + r mod p x\equiv q+r\text{mod} p xq+rmodp,我直接把 y ≡ r mod p y \equiv r \text{mod}p yrmodp,然后kp = y-x+q,gcd(kp,n)算出来数据太大,不对,就一直卡在这了。
然后看wp才知道,可以 y ≡ p q + r mod p y \equiv pq +r\text{mod} p ypq+rmodp, y − x + q ≡ p q mod p y - x + q \equiv pq \text{mod}p yx+qpqmodp,pq = gcd(y-x+q,n),p = pq /q
然后根据别人的思路算出来了
在这里插入图片描述

import gmpy2
from Crypto.Util.number import *

e = 0x10001
n = 16063619267258988011034805988633616492558472337115259037200126862563048933118401979462064790962157697989038876156970157178132518189429914950166878537819575544418107719419007799951815657212334175336430766777427972314839713871744747439745897638084891777417411340564312381163685003204182743581513722530953822420925665928135283753941119399766754107671729392716849464530701015719632309411962242638805053491529098780122555818774774959577492378249768503656934696409965037843388835948033129997732058133842695370074265039977902884020467413323500218577769082193651281154702147769044514475692164145099161948955990463002411473013
x = 3021730035236300354492366560252387204933590210661279960796549263827016146230329262559940840168033978439210301546282150367717272453598367244078695402717500358042032604007007155898199149948267938948641512214616076878271433754986480186150178487625316601499002827958344941689933374158456614113935145081427421623647242719093642478556263121508238995676370877385638074444859047640771188280945186355013165130171802867101829647797879344213688981448535289683363612035513789240264618036062440178755665951650666056478493289870170026121826588708849844053588998886259091357236645819074078054595561158630194224419831088510266212458
y = 8995787142441643101775260550632842535051686960331455373408888374295557050896156890779515089927839904014859222004906681231525326673182671984194300730575609496770604394218160422560576866112460837985407931067753009696969997384839637927957848613356269534870170452152926447601781637641134982178028922559652443398183848786034348994249923007092159192374765197460466878587635412657807328348343062302127490267456095927890461140420639805398464266081441243108883599713672104446500850203779995739675784794478089863001309614674686652597236324659979849324914804032046113978246674538411441434320732570934185579553749616238819583998
z = 1283646988194723153191718393109711130382429329041718186548715246082834666179475883560020086589684603980734305610989683434078096863563033623169666389076830792095374856743015929373461198718962686411467443788047511292138922700655772772117855226419561159782734009961921473456332468653898105909729309377890721920937410781006337057478451806364879679045839945032594716202888196404203782734864187890231653321470085251
c = 4988583141177813116287729619098477713529507701428689219486720439476625736884177254107631282807612305211904876847916760967188201601494592359879509876201418493870112712105543214178376471651715703062382025712952561985261461883133695993952914519494709871429166239968478488380137336776740647671348901626710334330855078254188539448122493675463406596681080368929986034772169421577420193671300532508625180845417164660544286332963072804192276425664877337357353975758574262657585309762422727680851018467657523970318042829660721433987195369353660020476598195375492128671951807024027929490113371463210453342974983253996717176870

kq = y - x
q = gmpy2.gcd(kq,n)
# print(q)
pq = gmpy2.gcd(kq + q,n)
p = pq // q
# print(p)
r = (x - q)%p
# print(r)
s = n // p // q // r
# print(s)
z %= s * s;
# print(z)
# print(p * q * r * s)
m1 = (z - 1) // s
#print(m1)
phi = (p - 1) * (q - 1)
d = gmpy2.invert(e * ( s - 1) // 4, phi)
mm = pow(c % (p * q), d, p * q)
m2, _ = gmpy2.iroot(mm,4)
print(long_to_bytes(m1),long_to_bytes(m2))





b'nkctf{cb5b7392-cca4-4' b'ce2-87e7-930cf6b29959}'
  • 14
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值