1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| from gmssl import sm3 from random import SystemRandom from ast import literal_eval import os flag = os.environ["FLAG"] def SM3(data): d = [i for i in data] h = sm3.sm3_hash(d) return h
def SM3_n(data, n=1, bits=256): for _ in range(n): data = bytes.fromhex(SM3(data)) return data.hex()[:bits // 4]
class Nepsign(): def __init__(self): self.n = 256 self.hex_symbols = '0123456789abcdef' self.keygen()
def keygen(self): rng = SystemRandom() self.sk = [rng.randbytes(32) for _ in range(48)] self.pk = [SM3_n(self.sk[_], 255, self.n) for _ in range(48)] return self.sk, self.pk
def sign(self, msg, sk=None): sk = sk if sk else self.sk m = SM3(msg) m_bin = bin(int(m, 16))[2:].zfill(256) a = [int(m_bin[8 * i: 8 * i + 8], 2) for i in range(self.n // 8)] step = [0] * 48 qq = [0] * 48 for i in range(32): step[i] = a[i] qq[i] = SM3_n(sk[i], step[i]) sum = [0] * 16 for i in range(16): sum[i] = 0 for j in range(1, 65): if m[j - 1] == self.hex_symbols[i]: sum[i] += j step[i + 32] = sum[i] % 255 qq[i + 32] = SM3_n(sk[i + 32], step[i + 32]) return [i for i in qq]
def verify(self, msg, qq, pk=None): qq = [bytes.fromhex(i) for i in qq] pk = pk if pk else self.pk m = SM3(msg) m_bin = bin(int(m, 16))[2:].zfill(256) a = [int(m_bin[8 * i: 8 * i + 8], 2) for i in range(self.n // 8)] step = [0] * 48 pk_ = [0] * 48 for i in range(32): step[i] = a[i] pk_[i] = SM3_n(qq[i], 255 - step[i]) sum = [0] * 16 for i in range(16): sum[i] = 0 for j in range(1, 65): if m[j - 1] == self.hex_symbols[i]: sum[i] += j step[i + 32] = sum[i] % 255 pk_[i + 32] = SM3_n(qq[i + 32], 255 - step[i + 32]) return True if pk_ == pk else False
print('initializing...') Sign = Nepsign() while 1: match int(input('> ')): case 1: msg = bytes.fromhex(input('msg: ')) if msg != b'happy for NepCTF 2025': print(Sign.sign(msg)) else: print("You can't do that") case 2: qq = literal_eval(input('give me a qq: ')) if Sign.verify(b'happy for NepCTF 2025', qq): print(flag)
|