笔者:YY同学
随机数两大性质
- 随机性(Randomness)
- 均值分布:0 和 1 出现的频率大致相等
- 相互独立:子序列之间毫无联系,无法互相推导
- 不可预测性(Unpredictability)
无法预测下一个序列数的值
TRNG,PRNG,PRF
- 真实随机数生成器(True Random Number Generator,TRNG)
- Non-deterministic source, physical environment
- Detect ionizing radiation events, leaky capacitors, thermal noise from resistors or audio inputs
- Mouse/keyboard activity, I/O operations, interrupts
- Inconvenient, small number of values
- 伪随机数生成器(Pseudo Random Number Generator,PRNG)
- Deterministic algorithms to calculate numbers in relatively random sequence
- Seed is algorithm input
- Produces continuous stream of random bits
- 伪随机函数(Pseudo Random Function,PRF)
Same as PRNG but produces string of bits of some fixed length
随机数生成过程
TRNG,PRNG,PRF生成随机数的方式:
为了保证随机性,一般我们会先通过 TRNG 生成 seed,然后将 seed 作为输入,由 PRNG 生成随机数比特流:
两个 PRNG 实例
-
Linear Congruential (LC)Generator
-
Blum Blum Shub(BBS)Generator
流加密(Stream Cipher)
与块加密(Block Cipher)不同,流加密是将原始 Key 作为 seed,通过 PRNG 生成一串看似随机的比特流从而实现加密任意长度原文的功能。
注意事项:
- Encryption sequence should have large period
- Keystream should approximate true random number stream
- Key must withstand brute force attacks
与 Block Cipher 相比:
- 流加密更快,实现更简单
- 块加密可以重复利用 Key
RC4(Rivest Cipher 4)流加密算法
Python 版实现代码,采用 8 x 3-bit 代替 256 x 8-bit
PS:SIZE、K 和 P 需要自己设置(K、P长度可变),有中间步骤可校对
import numpy as np
# set parameters
SIZE = 8
K = [1, 2, 3, 6]
P = [3, 5, 7, 2, 4, 6]
print("Plaintext :", P)
print("Key :", K)
print()
def swap(S, i, j):
tmp = S[i]
S[i] = S[j]
S[j] = tmp
# 1. S and T initialization
S = np.arange(0, SIZE)
T = np.arange(0, SIZE)
for i in range(0, SIZE):
T[i] = K[i % len(K)]
print("1. Initialize S and T :")
print("S =", S)
print("T =", T)
print()
# 2. Permutation
print("2. Permutation S :")
j = 0
for i in range(0, SIZE):
j = (j + S[i] + T[i]) % SIZE
swap(S, i, j)
print("Step", i, ": S =", S)
print()
# 3. Stream Generation
print("3. Stream Generation :")
i = 0
j = 0
count = 0
k = np.arange(0, len(P))
while count < len(P):
i = (i + 1) % SIZE
j = (j + S[i]) % SIZE
swap(S, i, j)
t = (S[i] + S[j]) % SIZE
k[i-1] = S[t]
print("Step", count, ": i =", i, ", j =", j, ", S =", S, ", t =", t)
count = count + 1
print()
# 4. Encryption & Decryption
print("4. Encryption and Decryption :")
print("k stream :", k)
C = np.arange(0, len(P))
for i in range(0, len(P)):
C[i] = P[i] ^ k[i]
print("Ciphertext :", C)