注意本篇大多数的题解都是直接在VsCode点击按钮运行的,假如控制台终端输入python ABC.py(ABC.py为你写的脚本的名称)很大概会报一些小错误。这里我也不知道为什么,真的想不懂。
LSFR
标题:3级线性反馈移位寄存器在c3=1时有4种线性反馈函数,设其初始状态为(a1,a2,a3)=(1,0,1),求各线性反馈函数的输出序列及周期,输出他们的密钥流,并利用天生的密钥流对明文'0x0123456789ABCDEF'举行加密,输出加密后的效果,再对密文举行解密,输出解密后的效果。
已知:
- 寄存器长度:n = 3
- 状态:(a1, a2, a3)
- 初始状态:(1, 0, 1)
- 条件:c3 = 1
LFSR 的反馈函数是:f=c1a1⊕c2a2⊕c3a3。由于:c3=1,以是:f=c1a1⊕c2a2⊕a3
由于:\(c_1 \in \{0,1\}\) ,\(c_2 \in \{0,1\}\),以是一共有4种情况,对应4 个反馈函数。
编号\((c_1,c_2,c_3)\)反馈函数周期1\((0,0,1)\)\(a_3\)很短2\((0,1,1)\)\(a_2 \oplus a_3\)较短3\((1,0,1)\)\(a_1 \oplus a_3\)大概最大4\((1,1,1)\)\(a_1 \oplus a_2 \oplus a_3\)最大周期7(m序列)状态更新原则:
\[(a_1, a_2, a_3) \rightarrow (a_2, a_3, f)\]
每一轮输出值:
\[\text{输出值} 为 a_1\]- def lfsr_step(state, c1, c2):
- a1, a2, a3 = state
- f = (c1 & a1) ^ (c2 & a2) ^ a3
- return (a2, a3, f)
- def generate_sequence(init_state, c1, c2):
- state = init_state
- seen = []
- output = []
- while state not in seen:
- seen.append(state)
- output.append(state[0])
- state = lfsr_step(state, c1, c2)
- return output, len(seen)
- def bits_to_bytes(bits):
- res = []
- for i in range(0, len(bits), 8):
- byte = 0
- for j in range(8):
- if i + j < len(bits):
- byte = (byte << 1) | bits[i + j]
- res.append(byte)
- return res
- def encrypt(hex_str, keystream_bits):
- data = bytes.fromhex(hex_str[2:])
- ks = bits_to_bytes(keystream_bits)
- return bytes([d ^ ks[i] for i, d in enumerate(data)]).hex()
- def decrypt(cipher_hex, keystream_bits):
- data = bytes.fromhex(cipher_hex)
- ks = bits_to_bytes(keystream_bits)
- return bytes([d ^ ks[i] for i, d in enumerate(data)]).hex()
- # ==========================
- # 主程序
- # ==========================
- init_state = (1, 0, 1)
- plaintext = "0x0123456789ABCDEF"
- configs = [
- (0, 0),
- (0, 1),
- (1, 0),
- (1, 1)
- ]
- for c1, c2 in configs:
- print("=" * 40)
- print(f"反馈函数: f = {c1}*a1 ⊕ {c2}*a2 ⊕ a3")
- seq, period = generate_sequence(init_state, c1, c2)
- print("输出序列:", seq)
- print("周期:", period)
- # 生成64bit密钥流
- keystream = (seq * (64 // len(seq) + 1))[:64]
- print("密钥流(bit):", keystream)
- # 加密
- cipher = encrypt(plaintext, keystream)
- print("密文:", cipher)
- # 解密
- plain = decrypt(cipher, keystream)
- print("解密:", plain)
复制代码
ElGamal
标题:编程实现ElGamal的加密息争密,假设用户A选择素数p=11和本原根g=2,而且选择私钥α=5,输出A的公钥;若用户B向用户A发送消息m=6,随机数k=7,输出对该消息加密后的密文,以及对密文举行解密的明文。
已知:
- 素数:p=11
- 本原根:g=2
- A 的私钥:α=5
- def nlfsr_step(state):
- a1, a2, a3, a4 = state
- # 非线性反馈函数
- f = (a1 & a4) ^ (a2 & a3)
- # 移位
- return (a2, a3, a4, f)
- def generate_sequence(init_state):
- state = init_state
- seen = []
- output_seq = []
- while state not in seen:
- seen.append(state)
- output_seq.append(state[0]) # 输出 a1
- state = nlfsr_step(state)
- period = len(seen)
- return output_seq, period
- def bits_to_bytes(bits):
- res = []
- for i in range(0, len(bits), 8):
- byte = 0
- for j in range(8):
- if i + j < len(bits):
- byte = (byte << 1) | bits[i + j]
- res.append(byte)
- return res
- def encrypt(plaintext_hex, keystream_bits):
- plaintext = bytes.fromhex(plaintext_hex[2:])
- keystream_bytes = bits_to_bytes(keystream_bits)
- cipher = bytes([p ^ keystream_bytes[i] for i, p in enumerate(plaintext)])
- return cipher.hex()
- def decrypt(cipher_hex, keystream_bits):
- cipher = bytes.fromhex(cipher_hex)
- keystream_bytes = bits_to_bytes(keystream_bits)
- plain = bytes([c ^ keystream_bytes[i] for i, c in enumerate(cipher)])
- return plain.hex()
- # ==========================
- # 主流程
- # ==========================
- init_state = (1, 1, 0, 1)
- # 生成序列
- seq, period = generate_sequence(init_state)
- print("输出序列:", seq)
- print("周期:", period)
- # 生成足够长的密钥流(明文8字节=64bit)
- keystream_bits = (seq * (64 // len(seq) + 1))[:64]
- print("密钥流(bit):\n", keystream_bits)
- # 明文
- plaintext = "0x0123456789ABCDEF"
- # 加密
- cipher = encrypt(plaintext, keystream_bits)
- print("密文:", cipher)
- # 解密
- decrypted = decrypt(cipher, keystream_bits)
- print("解密结果:", decrypted)
复制代码- #include <stdio.h>
- #define p 11
- #define a 1
- #define b 6
- typedef struct {
- int x;
- int y;
- } Point;
- int isOnCurve(Point point) {
- int left = (point.y * point.y) % p;
- int right = (point.x * point.x * point.x + a * point.x + b) % p;
- return left == right;
- }
- int main() {
- int count = 0;
- for (int x = 0; x < p; x++) {
- for (int y = 0; y < p; y++) {
- Point point = {x, y};
- if (isOnCurve(point)) {
- printf("(%d, %d)\n", point.x, point.y);
- count++;
- }
- }
- }
- printf("Point at infinity: O\n"); //注意,必须添加无穷远点。
- printf("Total points (including O): %d\n", count + 1);
- return 0;
- }
复制代码
RSA
标题:编程实现RSA的加密息争密,选择参数p=71593,q=77041,e=1757316971,输出公钥和私钥,并对消息“I need your best time”举行加密,输出密文。末了对密文举行解密,输出明文。
已知:
- 两个大素数 p=71593,q=77041
- 公钥指数 e=1757316971
- p = 11
- a = 1
- b = 6
- points = []
- for x in range(p):
- rhs = (x**3 + a*x + b) % p
- for y in range(p):
- if (y*y) % p == rhs:
- points.append((x, y))
- # 加上无穷远点
- points.append("O")
- print("椭圆曲线上的点:")
- for pt in points:
- print(pt)
- print("\n点的总数:", len(points))
复制代码- 加解密原理:
- 超递增序列(私钥)。A = [1, 3, 5, 11, 21, 44, 87, 175, 349, 701] 。 满足每个元素 > 前面所有元素之和
- 保证子集和可唯一反推(贪心)。
- ↓
- 公钥生成 Bi=(t⋅Ai)mod k , k = 1590,t = 43(i是下标)
- ↓
- 加密。把字符 → 二进制(10 bit,对应 A 长度) C=∑bi⋅Bi
- ↓
- 解密。1. 求逆元:t^-1 modk
- 2. 还原:C′=C⋅t^−1 modk
- 3. 用 A 贪心恢复 bit
复制代码
DH
标题:编程盘算25的全部本原根。
对于整数 \(n\) 和 \(g\)(模 \(n\)),假如 \(g\) 的阶便是欧拉函数 \(\phi(n)\),则称 \(g\) 是 \(n\) 的本原根:
\[g^1, g^2, ..., g^{\phi(n)} \mod n\]
会天生模 \(n\) 的全部互质剩余类(即整数 1 到 \(n-1\) 与 \(n\) 互质的整数)。
- \(n = 25\)
- 盘算 \(\phi(25) = 25 \cdot (1 - 1/5) = 20\)
- 查抄每个 \(g \in [1, 24]\),若:
\[g^{20/p} \neq 1 \pmod{25} \quad \forall p \text{ 是 } 20 \text{ 的质因子}\]
则 \(g\) 是本原根。
- # 私钥
- A = [1, 3, 5, 11, 21, 44, 87, 175, 349, 701]
- # 参数
- k = 1590
- t = 43
- # 求逆元(扩展欧几里得)
- def modinv(a, m):
- def egcd(a, b):
- if b == 0:
- return a, 1, 0
- g, x1, y1 = egcd(b, a % b)
- return g, y1, x1 - (a // b) * y1
- g, x, _ = egcd(a, m)
- if g != 1:
- raise Exception("无逆元")
- return x % m
- # 生成公钥
- B = [(t * ai) % k for ai in A]
- print("公钥 B:", B)
- # 字符转10bit
- def char_to_bits(c):
- val = ord(c)
- return [(val >> i) & 1 for i in reversed(range(10))]
- # bits转字符
- def bits_to_char(bits):
- val = 0
- for b in bits:
- val = (val << 1) | b
- return chr(val)
- # 加密
- def encrypt(plaintext):
- ciphertext = []
- for ch in plaintext:
- bits = char_to_bits(ch)
- c = sum(b * bi for b, bi in zip(bits, B))
- ciphertext.append(c)
- return ciphertext
- # 解密
- def decrypt(ciphertext):
- inv_t = modinv(t, k)
- plaintext = ""
- for c in ciphertext:
- c_prime = (c * inv_t) % k
- # 贪心恢复
- bits = [0] * len(A)
- for i in reversed(range(len(A))):
- if c_prime >= A[i]:
- bits[i] = 1
- c_prime -= A[i]
- plaintext += bits_to_char(bits)
- return plaintext
- # ==========================
- # 主程序
- # ==========================
- plaintext = "SAUNA AND HEALTH"
- print("明文:", plaintext)
- cipher = encrypt(plaintext)
- print("密文:", cipher)
- decrypted = decrypt(cipher)
- print("解密:", decrypted)
复制代码
标题:编程实现Diffie-Hellman密钥交换协议,假设共享素数p=19,它的一个本原元g =3,A选机密的随机数x=5,B选机密的随机数y=7,输出A和B共享的密钥。
- 素数:p=19
- 本原元:g=3
- A 的私钥:x=5
- B 的私钥:y=7
A盘算并发送15
\[A = g^x \mod p = 3^5 \mod 19 = 15\]
B盘算并发送2
\[B = g^y\mod p = 3^7 \mod 19 =2\]
盘算共享密钥
A盘算
\[K = B^x \mod p = 2^5 \mod 19 = 13\]
B盘算
\[K = A^y \mod p = 15^7 \mod 19 = 13\]
以是终极的共享密钥就是K=13
[code]生成公钥。β=g^α modp,计算β=2^5 mod 11= 32 mod 11= 10,所以A的公钥为(p, g, β) = (11, 2, 10)
↓
加密(B → A)。给定,明文:m = 6,随机数:k = 7。计算 c1=g^k mod p= 2^7 mod 11= 7,c2=m⋅β^k mod p=6*10^7 mod 11=5。所以密文为(c1, c2) = (7, 5)
↓
|