线性k

题目1:

import hashlib
from Crypto.Util.number import *
from gmpy2 import *
FLAG = b'******************'
assert FLAG.startswith(b'NSSCTF{') and FLAG.endswith(b'}')
FLAG = FLAG[7:-1]

def sign(msg, pub, pri, k):
    (p,q,g,y) = pub
    x = pri
    r = int(pow(g, k, p) % q)
    h = int(hashlib.sha256(msg).digest().hex(),16)
    s = int((h + x * r) * invert(k, q) % q)
    return (r, s)

p = 12521300600879647215212622604478307167614802603722694432672492518732844280050451647647783544918670551333939947202324314036106883627652934658092246151569719841172139651756731975948641752941369320985906043813128667949407263418091261521078015038472125264708315959943830171678415621896727622381651264882655845219115471323352719455064712014904581019529062436850895982568432772820884304927292484611574315452532539622439874476205201585972439739033662281856954069390915294301650596122027017512657387126870291348326594014789938826560641601265413964203409968207292456857314148848395645091850604205535043035332961436498283695843
q = 89333150710898097819726085329049525002843220030438497258487456281988064920981
g = 4659169190462665152432024005060362819268084070474399613244522271693166269703240438309526888954293382169994621221386886590606442329876391429681914154130453072540079426475110538234340272617964838185872575922598867083747162403217264242469640383596415974818773608247780785279490355462362699968367544837511541267300331418420849521244364899679912282991493675152166261501255315036943693486335864565853496499243373834189894710718862409646613179068080762011713847012853815796678705445232715083564615906424779193638984542271665075749327914765645357163924702265124479067028868769369414557728443665123548337757950887923116453268
x = bytes_to_long(FLAG)
y = powmod(g, x, p)

pub = (p,q,g,y)
pri = x

nonce = getPrime(64)
print('y =', y)
print(sign(b'nssctfround#1', pub, pri, nonce))
print(sign(b'nssctfround#1', pub, pri, 12345*nonce + 67890))

'''
y = 516079379252376231001717898324355848864109868582016554029703521946402522000955354396295307046881971504216991061930299508521161039333927590076006514531946316725453062373440451679354041777376121961468715242703413529070177041819221792817124111175287475946526246377103779752133378942603534385789689950337366490082828044596711426514502752548887337695502949798115745655734033592905036846835127551577851715558217775334831352232997052342694255476534837857477388530834954919414905007702912216496977764789386913244009912368937860550222726279524193115767983754873150853915852619223039800432272818237552774389220137762595332280
(81900716895065212453759953296615257914462909922962929287345063257120550453427, 45144894416226080526306932143570511284754744855790908537643986192724824691890)
(60471460394555700734359895323450929800168788093422384886037011624642263106556, 74754852228035293908666429128869604520827363733944834534730568060790683199921)
'''

解题思路:

两次签名用的k存在线性关系,k2=ak1+b

解答:

法1:

from Crypto.Util.number import *
import hashlib
import gmpy2

y = 516079379252376231001717898324355848864109868582016554029703521946402522000955354396295307046881971504216991061930299508521161039333927590076006514531946316725453062373440451679354041777376121961468715242703413529070177041819221792817124111175287475946526246377103779752133378942603534385789689950337366490082828044596711426514502752548887337695502949798115745655734033592905036846835127551577851715558217775334831352232997052342694255476534837857477388530834954919414905007702912216496977764789386913244009912368937860550222726279524193115767983754873150853915852619223039800432272818237552774389220137762595332280
r1,s1 = (81900716895065212453759953296615257914462909922962929287345063257120550453427, 45144894416226080526306932143570511284754744855790908537643986192724824691890)
r2,s2 = (60471460394555700734359895323450929800168788093422384886037011624642263106556, 74754852228035293908666429128869604520827363733944834534730568060790683199921)
p = 12521300600879647215212622604478307167614802603722694432672492518732844280050451647647783544918670551333939947202324314036106883627652934658092246151569719841172139651756731975948641752941369320985906043813128667949407263418091261521078015038472125264708315959943830171678415621896727622381651264882655845219115471323352719455064712014904581019529062436850895982568432772820884304927292484611574315452532539622439874476205201585972439739033662281856954069390915294301650596122027017512657387126870291348326594014789938826560641601265413964203409968207292456857314148848395645091850604205535043035332961436498283695843
q = 89333150710898097819726085329049525002843220030438497258487456281988064920981
g = 4659169190462665152432024005060362819268084070474399613244522271693166269703240438309526888954293382169994621221386886590606442329876391429681914154130453072540079426475110538234340272617964838185872575922598867083747162403217264242469640383596415974818773608247780785279490355462362699968367544837511541267300331418420849521244364899679912282991493675152166261501255315036943693486335864565853496499243373834189894710718862409646613179068080762011713847012853815796678705445232715083564615906424779193638984542271665075749327914765645357163924702265124479067028868769369414557728443665123548337757950887923116453268
msg = b'nssctfround#1'
h = int(hashlib.sha256(msg).digest().hex(),16)

a = 12345
b = 67890

k = ((h*(r2 - r1) + b*r1*s2)*gmpy2.invert((r2*s1-a*r1*s2),q)) % q

m1 = (k*s1 - h)*gmpy2.invert(r1,q) % q
print(long_to_bytes(m1))

k1 = a*k+b

m2 = (k1*s2 - h)*gmpy2.invert(r2,q) % q
print(long_to_bytes(m2))
#43fe-bd64-68b4bc1c4845
#43fe-bd64-68b4bc1c4845

法2:

给了大把参数,但只需关注<font style="color:rgb(48, 49, 51);">s = int((h + x * r) * invert(k, q) % q)</font>一行就行了,给了两组<font style="color:rgb(48, 49, 51);">(r,s)</font>,根据这个可以列出两组关于<font style="color:rgb(48, 49, 51);">k</font>,<font style="color:rgb(48, 49, 51);">x</font>的模<font style="color:rgb(48, 49, 51);">q</font>等式,即可求出<font style="color:rgb(48, 49, 51);">x</font>

from hashlib import sha256
q = 89333150710898097819726085329049525002843220030438497258487456281988064920981
h = int(sha256(b'nssctfround#1').hexdigest(), 16)
r1,s1 = (81900716895065212453759953296615257914462909922962929287345063257120550453427, 45144894416226080526306932143570511284754744855790908537643986192724824691890)
r2,s2 = (60471460394555700734359895323450929800168788093422384886037011624642263106556, 74754852228035293908666429128869604520827363733944834534730568060790683199921)
P.<k,x>=GF(q)[]
f1=k*s1-h-r1*x
f2=(12345*k+67890)*s2-h-r2*x
m=f1.sylvester_matrix(f2).det(k).univariate_polynomial().roots()[0][0]
flag=bytes(ZZ(m).digits(256)[::-1])
print(flag.decode())
#43fe-bd64-68b4bc1c4845

和上面那个差不多,本质上是求多项式

import hashlib
from Crypto.Util.number import *

y = 516079379252376231001717898324355848864109868582016554029703521946402522000955354396295307046881971504216991061930299508521161039333927590076006514531946316725453062373440451679354041777376121961468715242703413529070177041819221792817124111175287475946526246377103779752133378942603534385789689950337366490082828044596711426514502752548887337695502949798115745655734033592905036846835127551577851715558217775334831352232997052342694255476534837857477388530834954919414905007702912216496977764789386913244009912368937860550222726279524193115767983754873150853915852619223039800432272818237552774389220137762595332280
r1,s1 = (81900716895065212453759953296615257914462909922962929287345063257120550453427, 45144894416226080526306932143570511284754744855790908537643986192724824691890)
r2,s2 = (60471460394555700734359895323450929800168788093422384886037011624642263106556, 74754852228035293908666429128869604520827363733944834534730568060790683199921)
p = 12521300600879647215212622604478307167614802603722694432672492518732844280050451647647783544918670551333939947202324314036106883627652934658092246151569719841172139651756731975948641752941369320985906043813128667949407263418091261521078015038472125264708315959943830171678415621896727622381651264882655845219115471323352719455064712014904581019529062436850895982568432772820884304927292484611574315452532539622439874476205201585972439739033662281856954069390915294301650596122027017512657387126870291348326594014789938826560641601265413964203409968207292456857314148848395645091850604205535043035332961436498283695843
q = 89333150710898097819726085329049525002843220030438497258487456281988064920981
g = 4659169190462665152432024005060362819268084070474399613244522271693166269703240438309526888954293382169994621221386886590606442329876391429681914154130453072540079426475110538234340272617964838185872575922598867083747162403217264242469640383596415974818773608247780785279490355462362699968367544837511541267300331418420849521244364899679912282991493675152166261501255315036943693486335864565853496499243373834189894710718862409646613179068080762011713847012853815796678705445232715083564615906424779193638984542271665075749327914765645357163924702265124479067028868769369414557728443665123548337757950887923116453268

h = int(hashlib.sha256(b'nssctfround#1').digest().hex(),16)
a = 12345*s2*r1-r2*s1
b = (r1-r2)*h-67890*s2*r1
k = (b%q*inverse(a,q))%q
x = ((k*s1-h)%q*inverse(r1,q))%q
print(bytes.fromhex(hex(x)[2:]))
#43fe-bd64-68b4bc1c4845

题目2:


解题思路:

解答:


posted @ 2025-03-12 10:49  sevensnight  阅读(25)  评论(0)    收藏  举报