# Easy
Writer : [Laikaさん](https://twitter.com/ki4l_)
[Wanictf2021 top](https://hackmd.io/bHFMMX0PQIqhd6IjAv5Otg)
Problem
---
手始めに
`encrypto.py`
```python=
with open("flag.txt") as f:
flag = f.read().strip()
A = REDACTED
B = REDACTED
plaintext_space = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_{}"
assert all(x in plaintext_space for x in flag)
def encrypt(plaintext: str, a: int, b: int) -> str:
ciphertext = ""
for x in plaintext:
if "A" <= x <= "Z":
x = ord(x) - ord("A")
x = (a * x + b) % 26
x = chr(x + ord("A"))
ciphertext += x
return ciphertext
if __name__ == "__main__":
ciphertext = encrypt(flag, a=A, b=B)
print(ciphertext)
```
Output
---
```=txt
HLIM{OCLSAQCZASPYFZASRILLCVMC}
```
Solve
---
暗号化処理を行うプログラムとFLAGを暗号化した結果が得られるので復号処理をしてFLAGを得る
プログラムを見ると`x=(a*x+b)%26`が重要な部分であり、線形変換なので逆変換すれば良さそう!
しかし、逆変換するには`a`と`b`が分からないと復号できない
そこで、aとbについて全探索する
`(a*x+b)`に対して`%26`しているのでaもbも0~25の範囲を探索すれば良い
線形のシフト暗号なのでシフトし続ければ元に戻る。
つまりencrypt関数がそのまま使える!
```python=
# main内に追記する形
if __name__="__main__":
c='HLIM{OCLSAQCZASPYFZASRILLCVMC}'
for a in range(26):
for b in range(26):
print(encrypt(c,a,b))
```
全探索すると候補が沢山出てきてFLAGを探すのが大変なので
```
$ python3 encrpt.py | grep FLAG
```
のようにすると`FLAG`という文字列を含む行だけを抜き出してくれる
Flag
---
`FLAG{WELCOMETOCRYPTOCHALLENGE}`
###### tags: `CTF` `WANICTF2021`