Rabin加密

QQ图片20230416185314.png

[NSSRound#11 Basic]ez_signin

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

p = getPrime(512)
q = getPrime(512)
assert p > q
n = p*q
e = 65536
m = bytes_to_long(flag)
num1 = (pow(p,e,n)-pow(q,e,n)) % n
num2 = pow(p-q,e,n)
c = pow(m,e,n)

print("num1=",num1)
print("num2=",num2)
print("n=",n)
print("c=",c)

QQ图片20230416190102.png

我的解答

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

num1= 272862669171474396396346320044652981819641446895896259048760571202880701946816194621292378789553813990527252202593627409090108658126752853095133937756584319743618683075636273175295512837302880904708130820889988379507919111761986607349784417775005751393682844805190426434696242078340475392961106508937811566
num2= 34232812347968455856831076583522084771897754029863151152576650134413405663246929271965499563534059810310755948919124902737740910396366145723725169679562125884220944285623073035973389322178917320950312088905211769141473722907668799740465400147776589294849843633307848989273671006177136460638863297454577348372
n= 101041915402371268562539864391230558209018773341751828731097302946455960816468442318971537237532932589285827603020517675291956691309668029525760296017908673381150418459764499447724506114116163197166174909161359478495861591920749082693491285803326797990496585528516999626793686927001772331673338109924364148573
c= 98498440419285405132379532222038197349093970292969688148442636409863654318610296605795615484920674902479244901779412903340424597753355605790140770272076966193568118040994956336580247900526084471936779882586951112711099502637426488794349726185073973638506930983094554968102888784905597559122745754481155302566
e = 65536

p=gcd(num1+num2,n)
assert n%p==0
q=n//int(p)

for i in range(16):
    c1=pow(c,(p+1)//4,p)
    c2=pow(c,(q+1)//4,q)
    c=crt([int(c1),int(c2)],[p,q])
print(long_to_bytes(c))

Cipolla算法

QQ图片20230416195603.png过程

QQ图片20230416195607.png代码实现

def square_root_of_quadratic_residue(n, modulo):
    def generate_quadratic_field(d, modulo=0):
        class QuadraticFieldNumber:
            def __init__(self, x, y):
                self.x = x % modulo
                self.y = y % modulo

            def __mul__(self, another):
                x = self.x * another.x + d * self.y * another.y
                y = self.x * another.y + self.y * another.x
                return self.__class__(x, y)

            def __pow__(self, exponent):
                result = self.__class__(1, 0)
                if exponent:
                    temporary = self.__class__(self.x, self.y)
                    while exponent:
                        if exponent & 1:
                            result *= temporary
                        temporary *= temporary
                        exponent >>= 1
                return result

            def __str__(self):
                return '({}, {} \\sqrt({}))'.format(self.x, self.y, d)

        return QuadraticFieldNumber

    if modulo == 2:
        return 1
    if n % modulo == 0:
        return 0
    Legendre = lambda n: pow(n, modulo - 1 >> 1, modulo)
    if Legendre(n) == modulo - 1:
        return -1
    t = 0
    while Legendre(t ** 2 - n) != modulo - 1:
        t += 1
    w = (t ** 2 - n) % modulo
    return (generate_quadratic_field(w, modulo)(t, 1) ** (modulo + 1 >> 1)).x
def convert_to_base(n, b):
    if n < 2:
        return [n]

    temp = n
    ans = []

    while temp != 0:
        ans = [temp % b] + ans
        temp //= b

    return ans


def cipolla(n, p):
    n %= p

    if n == 0 or n == 1:
        return [n, (p - n) % p]

    phi = p - 1

    if pow(n, phi // 2, p) != 1:
        return []

    if p % 4 == 3:
        ans = int(pow(n, (p + 1) // 4, p))
        return [ans, (p - ans) % p]

    aa = 0
    for i in range(1, p):
        temp = pow(((i * i - n) % p), phi // 2, p)

        if temp == phi:
            aa = i
            break

    exponent = convert_to_base((p + 1) // 2, 2)

    def cipolla_mult(ab, cd, w, p):
        a, b = ab
        c, d = cd
        return (a * c + b * d * w) % p, (a * d + b * c) % p

    x1 = (aa, 1)
    x2 = cipolla_mult(x1, x1, aa * aa - n, p)

    for i in range(1, len(exponent)):
        if exponent[i] == 0:
            x2 = cipolla_mult(x2, x1, aa * aa - n, p)
            x1 = cipolla_mult(x1, x1, aa * aa - n, p)
        else:
            x1 = cipolla_mult(x1, x2, aa * aa - n, p)
            x2 = cipolla_mult(x2, x2, aa * aa - n, p)
    return [x1[0], (p - x1[0]) % p]
文章作者: x1ao
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 x1ao
CTF Crypto
喜欢就支持一下吧