SCTF2023 Barter 复现

news2024/9/20 0:50:15

题目描述:

chal_sage部分:
from Crypto.Util.number import *
from random import *
from secrets import flag


def gen_random(seed, P, Q, r_list, times):
    s = seed
    for i in range(times):
        s = int((s * P)[0])
        r = int((s * Q)[0])
        r_list.append(r)
    return r_list

def gen_seed():
    seed = getRandomNBitInteger(32)
    return seed

def getP_Q():
    Q = Curve.random_point()
    P = 114514*Q
    return P, Q

def enc(flag, rlist):
    seq = list(randint(0, 1) for _ in range(4))
    add = rlist[55]*(seq[0]*rlist[66] + seq[1]*rlist[77] + seq[2]*rlist[88] + seq[3]*rlist[99])
    xor = pow(rlist[114], rlist[514], rlist[233]*rlist[223])
    enc = (bytes_to_long(flag)^^xor)+add
    return enc

nums = 600

seed = gen_seed()

p = 58836547289031152641641668761108233140346455328711205590162376160181002854061
F = GF(p)
a = F(114)
b = F(514)
Curve = EllipticCurve(F, [a, b])
P, Q = getP_Q()
r_list = []
r_list = gen_random(seed, P, Q, r_list, nums)
ENCFLAG = enc(flag, r_list)
print(ENCFLAG)
print(P, Q)
print(r_list[0])

'''
4911741083112145038719536311222612998219730565328651097326896414315857050336523018712625917027324116103593300559128797807261543857571883314990480072241188
#####################################
#####################################
Oh no, P, Q and r_list[0] are accidentally lost, but John seems to know, you can ask him about these missing values ::>_<::
'''
homework部分:
from Crypto.Util.number import *
from params import N, E, D
from leak_data import P, Q, r_1
import re

def challenge():
    meum = '''option:
    1: get pubkey
    2: get sign
    3: verify
    4: exit'''
    print("Hi, I am John. If you help me with my homework, I'll give you the data that I know ( ̄o ̄) . z Z")
    print(meum)
    sign = None

    while True:
        print('[+]input your option: ', end='')
        your_input = input()

        if your_input == '1':
            print(f'[+]N = {N}')
            print(f'[+]e = {E}')
            continue

        elif your_input == '2':
            sign = pow(bytes_to_long(MSG.encode()), D, N)
            print(f'[+]sign = {sign}')
            continue

        elif your_input == '3':
            if sign is None:
                print('[+]Please input option 2 to generate sign first.')
                continue
            msg_user = input("[+]Please input your message: ")
            n = int(input("[+]Please input n: "))
            e = int(input("[+]Please input e: "))
            if e <= 3:
                print('[+]e is invalid')
                break
            else:
                if re.match(r'I can not agree more!!!$', msg_user):
                    if pow(bytes_to_long(msg_user.encode()), e, n) == sign:
                        print("Goooooooood! You are my hero! I can give you the data that I know ╰(*°▽°*)╯")
                        print(f'Leak_data: \n P={P}\n Q={Q}\n first num in r_list={r_1}')
                        break
                    else:
                        print('[+]Error signature!')
                        break
                else:
                    print('[+]Error message!')
                    break

        elif your_input == '4':
            break

if __name__ == '__main__':
    MSG = 'This is an easy challenge'
    challenge()

题目分析:

import gmpy2
from Crypto.Util.number import *
N =   7399403457188876147280737704413998161465702407270784053949887695340528233758555062010898995255039810187699911928866167640259018538192441232641067730711771
E = 65537
sign = 1320070156891033288626051716868212806309097835600533098946778415708131349531482538706467629025443890643255446066240480813053241479563851572261696377893792
MSG = 'This is an easy challenge'
msg_user = 'I can not agree more!!!'

# pow(MSG,D,N) = pow(msg_user,e,n) = sign,要求e,n

# 题目中限制条件e > 3,那我就令e = 4或5喽,或者构造光滑数
  • pow(MSG,D,N) = pow(msg,e,n) = sign,求e,n

    题目中限制条件e > 3,那我直接令e = 4或5咯,或者构造光滑数

  • 法一(构造光滑数):

    from Crypto.Util.number import *
    
    def gen_primes(nbit, imbalance):
        """
        :param nbit: 最终光滑数比特数
        :param imbalance: 最小单位比特数
        :return: 比特数
        """
        p = int(2)
        FACTORS = [p]
        while p.bit_length() < nbit - 2 * imbalance:
            factor = getPrime(imbalance)
            FACTORS.append(factor)
            p *= factor
        rbit = (nbit - p.bit_length()) // 2
    
        while True:
            r, s = [getPrime(rbit) for _ in '01']
            _p = p * r * s
            if _p.bit_length() < nbit: rbit += 1
            if _p.bit_length() > nbit: rbit -= 1
            if isPrime(_p + 1):
                FACTORS.extend((r, s))
                p = _p + 1
                break
    
        FACTORS.sort()
        return (p, FACTORS)
    
    MSG = 'This is an easy challenge'
    msg = 'I can not agree more!!!'
    sign = 1320070156891033288626051716868212806309097835600533098946778415708131349531482538706467629025443890643255446066240480813053241479563851572261696377893792
    
    M = bytes_to_long(MSG.encode())
    m = bytes_to_long(msg.encode())
    
    n, n_fac = gen_primes(512, 20)
    # n = 4042948769941627341019324611789396195045815639020219860408774627904312552947443280269093998428541432391837271401229040233775660233089444891431013462995967
    
  • 离散对数sage求解(模数小 / 阶光滑)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IfNXFlc6-1687436645430)(C:\Users\Emma\AppData\Roaming\Typora\typora-user-images\image-20230621233649390.png)]

    # h = g^x mod p
    # c1 = m^e mod n1
    p = n
    g = m
    h = sign
    x = discrete_log(Mod(h,p),Mod(g,p))
    print(pow(m,x,p)==sign)
    print('n =', p)
    print('e =', x)
    
  • 也可以直接:

    n = 4042948769941627341019324611789396195045815639020219860408774627904312552947443280269093998428541432391837271401229040233775660233089444891431013462995967
    G = Zmod(n)
    m1 = G(m)
    c1 = G(sign)
    print(ZZ(discrete_log(c1,m1)))
    
  • 这部分好像好像好像啊!discrete_log:

    a=2275123956203765363233765961297507379124236980967603145079239177208264523438555378298177602517599708533004805369986246098127863480798528206818576888655427591685534478161571717613561380234338516607855593046949
    fac = [2, 136327, 169937, 313351, 321427, 323377,356887, 413783, 519733,792413, 860077, 906289, 976501]
    G=Zmod(N)
    m1=G(m)
    c1=G(a)
    oo=[]
    for i in fac:
        h=(N-1)//i
        dlp1=discrete_log(c1**h,m1**h)
        oo.append(int(dlp1))
    sk=crt(oo,fac)
    mod = prod(fac)
    for i in range(100):
        print(long_to_bytes(int(sk + i * mod)))
        
    # 或:    
    m = 1391372358062724416224243990838035874507346098208831800403257
    a=2275123956203765363233765961297507379124236980967603145079239177208264523438555378298177602517599708533004805369986246098127863480798528206818576888655427591685534478161571717613561380234338516607855593046949
    G=Zmod(N) 
    m1=G(m) 
    c1=G(a) 
    print(long_to_bytes(ZZ(discrete_log(c1,m1))))
    # Neepu{Nsmoothnumber}
    
  • 方法二:

    MSG = 'This is an easy challenge'
    msg = 'I can not agree more!!!'
    sign = 1320070156891033288626051716868212806309097835600533098946778415708131349531482538706467629025443890643255446066240480813053241479563851572261696377893792
    e = 4
    n = bytes_to_long(msg.encode())**e - sign 
    print('e = ',e)
    print('n = ',n)
    
  • 接下来求后面部分:

    s1 = int((s0 * P)[0])
    r1 = int((s1 * Q)[0])
    P  = 114514 * Q 
    
    s1 = (seed * P).x,
    r1 = (s1 * Q).x = rlist[0]
    s2 = (s1 * P).x 
    ===> s2 = (s1 * 114514 * Q).x
            = (114514 * s1 * Q).x 
            = (114514*Curve.lift_x(r0))[0] 
            
    (PS:Curve.lift_x() 方法会在给定的 x 坐标上搜索相应的 y 值,以获得椭圆曲线上的曲线点。
    结果返回的是一个曲线点对象,包含了曲线上的 x 和 y 坐标)
    
    # sage
    from Crypto.Util.number import * 
    nums = 600
     
    p = 58836547289031152641641668761108233140346455328711205590162376160181002854061
    F = GF(p)
    a = F(114)
    b = F(514)
    E = EllipticCurve(F,[a, b])
    
    P=E(24181776889473219401017476947331354458592459788552219617833554538756564211844, 33783050059316681746742286692492975385672807657476634456871855157562656976035)
    Q=E(16104852983623236554878602983757606922134442855643833150623643268638509292839, 3562830444362909774600777083869972812060967068803593091854731534842281574275)
    r0 = 50920555924101118476219158701093345090627150442059647242030060086626996278598
    rlist = [r0]
    for _ in range(600):
        s = (E.lift_x(rlist[-1]) * 114514)[0]
        rlist.append((int(s) * Q)[0])
        
    r_list = [r0]
    for i in range(515):
        R0 = E.lift_x(r_list[-1])
        s1 = ZZ((114514 * R0)[0])
        r1 = ZZ((s1*Q)[0])
        r_list.append(r1)
        
    rlist = [int(i) for i in rlist] # 不可少
    '''
    没加这行rlist中数据类型<class 'sage.rings.integer.Integer'>
    加了这行rlist中数据类型<class 'int'>
    在Sage中,Integer是一个类,而int是Python的内置数据类型。与Java类似,在使用Sage中的Integer时,需要通过调用其方法或属性将其转换为Python的int类型才能进行数值计算或比较等操作。虽然Sage中的Integer与Python的int都可以表示整数,但它们的底层实现略有不同
    '''
    
    for i in range(2 ^ 4):
        seq = [(i >> 3) & 1, (i >> 2) & 1, (i >> 1) & 1, i & 1]
        add = rlist[55]*(seq[0]*rlist[66] + seq[1]*rlist[77] + seq[2]*rlist[88] + seq[3]*rlist[99])
        xor = pow(rlist[114], rlist[514], rlist[233]*rlist[223])
        flag = long_to_bytes(int((enc - add) ^^ xor))
        if b'SCTF' in flag:
            print(flag)
    # b'SCTF{Th1s_i5_my_happy_s0ng_I_like_to_5ing_it_@ll_day_1ong}'
    

又学到了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/674688.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

E. Round Dance(dfs分辨特殊联通块)

Problem - 1833E - Codeforces 有 n 个人来到一个节日并决定跳几个“圆舞”。每个圆舞至少有 2 个人&#xff0c;且每个人恰好有两个邻居。如果圆舞中只有 2 个人&#xff0c;则它们在两侧拥有相同的邻居。 你想要确定有多少个“圆舞”可以跳。但是每个参与者只记得一个邻居。…

【自注意力机制必学】BERT类预训练语言模型(含Python实例)

BERT类预训练语言模型 文章目录 BERT类预训练语言模型1. BERT简介1.1 BERT简介及特点1.2 传统方法和预训练方法1.3 BERT的性质 2. BERT结构2.1 输入层以及位置编码2.2 Transformer编码器层2.3 前馈神经网络层2.4 残差连接层2.5 输出层 3. BERT类模型简要笔记4. 代码工程实践 1.…

利用python绘制端午节的各种图案,例如粽子,赛龙舟等,以及一些端午节的感人小故事

这里写目录标题 1、关于端午节的有趣故事2、关于端午节的趣闻3、利用python绘制龙舟3.1. 代码如下3.2 图形展示 4、利用python绘制大公鸡5、利用python来进行端午节的诗词对弈总结 1、关于端午节的有趣故事 端午节是一个历史悠久的中国传统节日&#xff0c;有很多有趣的故事与…

内存不够用,那你的内存去哪了?

一、前言 近几年开发了一些大型的应用程序&#xff0c;在程序性能调优或者解决一些疑难杂症问题的过程中&#xff0c;遇到最多的还是与内存相关的一些问题。例如glibc内存分配器ptmalloc&#xff0c;google的内存分配器tcmalloc都存在“内存泄漏”&#xff0c;即内存不归还操作…

原来Flutter代码是这样运行在原生系统的!快来了解Flutter标准模板,感受原生系统中Flutter的魅力!

通过Android Studio创建的Flutter应用模板&#xff0c;了解Flutter项目结构&#xff0c;分析Flutter工程与原生Android和iOS工程有哪些联系&#xff0c;体验一个有着基本功能的Flutter应用是如何运转的&#xff0c;从而加深你对构建Flutter应用的关键概念和技术的理解。 Dart只…

深入理解深度学习——GPT(Generative Pre-Trained Transformer):GPT-2与Zero-shot Learning

分类目录&#xff1a;《深入理解深度学习》总目录 相关文章&#xff1a; GPT&#xff08;Generative Pre-Trained Transformer&#xff09;&#xff1a;基础知识 GPT&#xff08;Generative Pre-Trained Transformer&#xff09;&#xff1a;在不同任务中使用GPT GPT&#x…

软考:软件工程:软件维护与项目管理

软考&#xff1a;软件工程:软件维护与管理 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都是需要细心准备的 &…

如何挑选合格的在线教育解决方案?

现在市面上的知识付费系统繁多&#xff0c;你可以说百花齐放&#xff0c;也可以说良莠不齐&#xff0c;如果不具备一定的专业素养&#xff0c;根本就无法从中挑选出真正的好产品&#xff0c;劣币驱逐良币反而成为常态。 本文将从几个常见维度分析一个好产品应该具备的基本要素…

CSS基础总结

CSS基础总结 CSS基础总结基础认知基础选择器**选择器的作用**标签选择器类选择器id选择器**通配符选择器** 字体和文本样式字体样式字体大小&#xff1a;font-size字体粗细&#xff1a;font-weight字体样式&#xff1a;font-style字体类型&#xff1a;font-family字体类型&…

【MYSQL篇】mysql性能优化总结

前言 说到MYSQL性能调优&#xff0c;大部分时候想要实现的目标是让我们的查询更快。一个查询的动作又是由很多个环节组成的&#xff0c;每个环节都会消耗时间&#xff0c;我们要减少查询所消耗的时间&#xff0c;就要从每一个环节入手。 关于MYSQL的sql语句执行流程&#xff0…

ARM-驱动/总结一

Linux设备驱动 驱动&#xff1a;能够控制硬件实现特定功能的软件代码就是驱动 ARM裸机驱动和驱动区别&#xff1f; ARM裸机驱动是不基于操作系统的软件代码&#xff0c;通常这份代码都是有开发者独立编写完成的。 驱动是基于内核&#xff08;Linux&#xff09;架构的基础上的…

chatGPT 指南:秒变 Excel 大神

Excel 是一款功能强大的电子表格软件&#xff0c;而 ChatGPT 则是一种智能语言模型&#xff0c;可以为 Excel 用户提供帮助和指导。本文将探讨 Excel 与 ChatGPT 的关系&#xff0c;并从初级、中级和高级 Excel 用户三个层次&#xff0c;介绍如何利用 ChatGPT 来提升 Excel 技能…

leetcode416. 分割等和子集(动态规划-java)

分割等和子集 leetcode416. 分割等和子集题目描述 暴力递归代码演示 动态规划解题思路代码演示 动态规划专题 leetcode416. 分割等和子集 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/problems/partition-equal-subset-sum 题目…

高级数据结构——平衡二叉树(AVL树)

目录 1. 底层结构 2. AVL数的概念 3. AVL树节点的定义 4. 基本框架 5. AVL树的插入 6. AVL树的旋转 6.1 左单旋 6.2 右单旋 6.3 左右双旋 6.4 右左双旋 7. AVL树的验证 8. AVL树的查找 9. AVL树的删除 10. AVL树的性能 11. 总代码 11.1 AVLTree 11.2 Test.c…

mac本地创建ssh key连接github

起因 今天克隆自己github上面的笔记到新电脑上&#xff0c;用http连接进行克隆&#xff0c;然后要我输入账号密码&#xff0c;输入完报了个提示“remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.”…

JavaScript 手写代码 第一期

文章目录 1.为什么要手写代码&#xff1f;2.手写代码2.1 手写Object.create()方法2.1.1 基本使用2.1.2 使用实例2.1.3 手写实现 2.2 手写实现instanceof方法2.2.1 基本使用2.2.2 使用实例2.2.3 手写实现 2.3 手写实现new操作符2.3.1 基本使用2.3.2 使用实例2.3.3 手写实现 1.为…

分享一个下载按钮

先看效果&#xff1a; 再看代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>下载按钮</title><link href"https://fonts.googleapis.com/css2?familyHind&amp;d…

Redisson源码-单线程加解锁流程

Redisson源码-单线程加解锁流程 以下源码分析基于redisson-3.17.6版本&#xff0c;不同版本源码会有些许不同需注意。 <dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.17.6</version>&l…

推荐5 款好用的 Linux 音乐播放器

目前 Linux 上有几十个音乐播放器&#xff0c;这使得找到一个最好用的变成很困难。之前我们已经回顾了其中的一些播放器&#xff0c;如 Cantata&#xff0c;Exaile&#xff0c;甚至不那么出名的 Clementine&#xff0c;Nightingale 和 Quod Libet。 在本篇文章中我将涵盖更多的…