# Thực hành tuần 2: Mã hóa

## INTRODUCTION
### Finding Flags

- Flag: **`crypto{y0ur_f1rst_fl4g}`**
### Great Snakes

- Tải và mở file `great_snakes.py` rồi chạy `python3`:

- Flag: **`crypto{z3n_0f_pyth0n}`**
### Network Attacks

- Sử dụng `nc socket.cryptohack.org 11112` để kết nối với `socket.cryptohack.org` cổng `11112`
- Gửi một đối tượng JSON có khóa `buy` và giá trị `flag`:
- `{"buy": "flag"}`

- Flag: **`crypto{sh0pp1ng_f0r_fl4g5}`**
## SYMMETRIC CIPHERS
### Round Keys

- What is the mathematical term for a one-to-one correspondence?
- Trong toán học, hàm `bijective` được gọi là hàm song ánh hoặc hàm tương ứng một-một
- Flag: **`crypto{bijection}`**
### Resisting Bruteforce

- What is the name for the best single-key attack against AES?
- Các cuộc tấn công bằng `Biclique` được biết đến là đã làm suy yếu cả AES và IDEA đầy đủ.
- Flag: **`crypto{biclique}`**
### Structure of AES

- File [matrix.py](https://cryptohack.org/static/challenges/matrix_e1b463dddbee6d17959618cf370ff1a5.py)
- Hoàn thành hàm `matrix2bytes()` bằng cách chuyển lần lượt từng phần tử của `matrix` từ số về dạng kí tự ascii của chúng:
```py
def matrix2bytes(matrix):
return bytes(sum(matrix, []))
```
- Flag: **`crypto{inmatrix}`**
## RSA
### RSA Starter 1

- `10117 mod 22663 = 19906`
### RSA Starter 2

- Sử dụng hàm `pow()` trong `python`

- `301`
## DIFFIE-HELLMAN
### Diffie-Hellman Starter 1

- Tính nghịch đảo module của ***g*** với ***𝑝*** bằng hàm pow() trong python
```py
print(pow(g, -1, 991))
```
- `569`
### Diffie-Hellman Starter 2
- Bruteforce để tìm ***g*** sao cho `g^n mod p = g` (1<g<p)
```py
def is_generator(k, p):
for n in range(2, p):
if pow(k, n, p) == k:
return False
return True
p = 28151
for k in range(p):
if is_generator(k, p):
print(k)
break
```

- `7`
## ELLIPTIC CURVES
### Point Addition

- Viết script để thực hiện phép tính cộng hai điểm trên đường cong Elliptic. Quy ước điểm vô cùng là 𝑂(−1,−1)
```py
def add_point(P, Q, a, b, p, O=(-1,-1)):
x1, y1 = P
x2, y2 = Q
if Q == O:
return P
if P == O:
return Q
if y1 == -y2:
return O
elif P==Q:
lamda = (3*x1**2 + a) * pow(2*y1, -1, p)
else:
lamda = (y2 - y1) * pow(x2-x1, -1, p)
x3 = (lamda**2 - x1 - x2) % p
y3 = (lamda*(x1 - x3) - y1) % p
return x3, y3
P = (493, 5564)
Q = (1539, 4742)
R = (4403,5202)
K = add_point(P, P, 497, 1768, 9739)
M = add_point(K, Q, 497, 1768, 9739)
N = add_point(M, R, 497, 1768, 9739)
print(N)
```

- Flag: **`crypto{4215, 2162}`**
- Nguồn: [Quanda](https://hackmd.io/@quanda/rJSUYehnp#CryptoHack:~:text=crypto(8045%2C%202803)-,Point%20Addition,-V%E1%BB%9Bi%20challange%20n%C3%A0y)
## HASH FUNCTIONS
### Jack's Birthday Hash

- Vì giá trị hash là chuỗi nhị phân 11 bits nên có tất cả 𝑛=2^11=2048 giá trị hash
- Gọi 𝑝(𝑛) là xác suất để nhóm n secret có ít nhất 1 cái gặp collision với secret của Jack.
- Khi đó  là xác suất để không có secret nào trong n cái gặp collision với secret của Jack
- Suy ra 
```py
n = 1 << 11
P = 1
for i in range(1, n):
P = pow((1 - 1/n), i)
nP = 1 - P
if nP > 0.5:
print(i)
break
```

- `1420`
- Nguồn: [DSA_Cryptoack](https://hackmd.io/@DSAteam/BJP-3LfgC#:~:text=Jack%27s%20Birthday%20Hash)