# **Finding flag**
Đây là bài giới thiệu về CTF, để qua màn cần tìm flag có format `crypto{}`. Họ đã cho sẵn flag để đến màn tiếp theo
```
Flag: crypto{y0ur_f1rst_fl4g}
```
# **Great Snakes**
Đầu tiên họ kiểm tra xem phiên bản có phải Python 2 không? Nếu đúng thì sẽ in ra thông báo nên update lên Python 3.
Bài này là phép Xor từng số trong List 'ords' (base 10) với '0x32' (bằng 50 trong base 10).
`Flag: crypto{z3n_0f_pyth0n}`
# **Networks Attacks**
Đoạn code trên là một đoạn mã Python sử dụng thư viện pwntools để tạo kết nối mạng TCP và gửi và nhận dữ liệu dưới dạng JSON. Mục tiêu của chương trình là gửi yêu cầu để mua "flag" đến một máy chủ được chạy trên socket.cryptohack.org cổng 11112 và nhận lại phản hồi từ máy chủ.
Để giải quyết thử thách này, bạn cần kết nối tới máy chủ socket.cryptohack.org trên cổng 11112. Sau đó, bạn cần gửi một đối tượng JSON với cặp key và value là "buy" và "flag" tương ứng.
`Flag: crypto{sh0pp1ng_f0r_fl4g5}`

# **Encoding**
Bài này họ hướng dẫn cách chuyển từ ascii sang char bằng chr() và ngược lại với ord().
Ta chỉ cần dùng vòng for để lấy từng số trong mảng rồi chuyển thành chữ và ghép lại với nhau để thành flag.
Dùng for như dưới ảnh khi python cần thực hiện nhiều thao tác trên 1 dãy dữ liệu, chuyển số trong array thành chữ, rồi join lại với nhau để thành flag.
`Flag: crypto{ASCII_pr1nt4bl3}`

# **Hex**
Bài này hướng dẫn ta mã hóa 1 dãy hex.
Để giải mã chuỗi hex này, chúng ta cần chuyển đổi nó trở lại thành dạng bytes ban đầu. Trong Python, chúng ta có thể sử dụng phương thức `bytes.fromhex()`. Sau đó giải mã bytes đó để tìm flag.
Flag có thể được mã hóa bằng một số mã hóa khác nhau, nhưng phổ biến nhất là utf-8(là một chuẩn mã hóa ký tự Unicode). Có 1 số mã hóa khác như ascii, utf-16, latin-1...
`Flag: crypto{You_will_be_working_with_hex_strings_a_lot}`

# **Base64**
Base64 là một phương thức mã hóa phổ biến được sử dụng để biểu diễn dữ liệu nhị phân dưới dạng chuỗi ASCII sử dụng một bảng chữ cái gồm 64 ký tự. Mỗi ký tự của chuỗi Base64 mã hóa 6 bit nhị phân.
Trong trường hợp này, chúng ta sẽ chuyển đổi chuỗi hex thành bytes. Sau khi có dữ liệu ở dạng bytes, chúng ta sẽ mã hóa nó thành chuỗi Base64. Cuối cùng là mã hóa ra flag.
`Flag: crypto/Base+64+Encoding+is+Web+Safe/`

# **Bytes and Big Integers**
Để chuyển số nguyên trở lại thành flag, chúng ta cần thực hiện quá trình ngược lại với quá trình mô tả của đề. Chúng ta sẽ chuyển số nguyên thành chuỗi bytes, sau đó giải mã các bytes đó thành một chuỗi sử dụng mã hóa ASCII.

# **Encoding Challenge**
Mình tham khảo cách decode rot13, bigint.
Chúng ta cần phải encode được 100 lần thì sẽ ra được flag. Ta sẽ kết nối tới máy chủ socket.cryptohack.org trên cổng 13377 để nhận được encoded_type và string để decode. Có 5 loại encoded: base64, hex, rot13, bigint, utf-8.

`Flag: crypto{3nc0d3_d3c0d3_3nc0d3}`
# **XOR Starter**
bài này chúng ta cần thực hiện phép XOR giữa mỗi ký tự trong chuỗi với số nguyên 13. Sau đó, chuyển các số nguyên này trở lại thành một chuỗi và ghép lại thành flag có format crypto{}.

`Flag: crypto{aloha}`
# **XOR Properties**
Bài này giới thiệu về XOR là gì.
Ta sẽ sử dụng hàm xor có trong thư viện pwn
Áp dụng A^A=0

`Flag: crypto{x0r_i5_ass0c1at1v3}`
# **Favourite byte**
Bài này đề đã ẩn 1 byte key. Chúng ta dựa vào format flag để tìm key.

`Flag: crypto{0x10_15_my_f4v0ur173_by7e}`
# **You either know, XOR you don't**
Ở bài này thì key không chỉ còn là byte nữa, nên ta sẽ cần xor nhiều byte để tìm key.
Format flag: `crypto{`
Và tìm được key: myXORkey

`Flag: crypto{1f_y0u_Kn0w_En0uGH_y0u_Kn0w_1t_4ll}`
# **Lemur XOR**
Mình không biết xor 2 png nhưng ý tưởng là tạo pixel map xong xor từng pixel.
Mình tìm hiểu thì có câu lệnh xor 2 ảnh.
`gmic a.png b.png -blend xor -o result.png`
Và kết quả ra được bức ảnh chứa flag:

`Flag: crypto{X0Rly_n0t!}`
# **Greatest Common Divisor**
GCD là ước chung lớn nhất, ta dùng thuật toán Euclid: gcd(a, b) = gcd(b, a%b) với a>b.

# **Extended GCD**
Đây là lời giả thích cho đoạn code:


# **Modular Arithmetic 1**
Bài này nói về phép chia lấy dư và ký hiệu cuả nó.
11 ≡ x mod 6
8146798528947 ≡ y mod 17
Ta cần tìm min trong 2 số x=11%6 và y=8146798528947%17

# **Modular Arithmetic 2**
Mình không biết chứng minh nhưng mình nhận ra 1 điều ở dữ kiện họ cho:
với p là số nguyên tố và n không phải là bội của p thì n^p%p=n và n^(p-1)%p=1.
Vì vậy 273246787654^65536 % 65537 = 1
# **Modular Inverting**
Bài này cần tìm phần tử nghịch đảo
g * d ≡ 1 mod p
với g, d nằm trong Fp.
Vậy để tính 3 * d ≡ 1 mod 13

Cách khác:
Với bài trước ta có g^(p-1) ≡ 1 mod p
=> g * g^(p-2) ≡ 1 mod p
=> d = g^(p-2)
=> d = g^(p-2) % p (để cho d nằm trong miền Fp)
`print(pow(g, p-2, p))`