4离散数学及其应用(第8版)

数论与密码学

RSA 的数学基础

整除模运算素数RSA 加密哈希函数

🎯 AI 时代的学习建议:不要只读理论。理解这一章的设计动机(为什么需要这个概念?)和边界条件(什么情况下会失效?)。当 AI 生成的代码涉及这些概念时,你能判断它是否用对了场景。AI 能帮你总结内容,但无法替代你亲手阅读、思考、建立直觉的过程。

第4章 数论与密码学 (Number Theory and Cryptography)

一、导读

1.1 本章学习目标

完成本章学习后,你将能够:

理解整除性、素数、最大公约数和最小公倍数的基本概念

掌握欧几里得算法及其扩展版本,能够计算模逆元

熟练运用模运算的性质解决同余方程

理解费马小定理和欧拉定理及其在密码学中的应用

掌握RSA公钥加密算法的原理、实现和安全性分析

理解离散对数问题及其在Diffie-Hellman密钥交换中的应用

掌握哈希函数的性质和在数据完整性验证中的应用

了解椭圆曲线密码学的基本概念

1.2 为什么本章如此重要

数论曾被认为是"最纯粹"的数学分支,如今却是现代信息安全的基石。

在互联网安全中:HTTPS协议依赖RSA或椭圆曲线密码学保护数据传输;SSH使用公钥认证;数字签名确保软件来源可信。

在区块链与加密货币中:比特币使用椭圆曲线数字签名算法(ECDSA)验证交易;以太坊使用Keccak哈希函数。

在日常应用中:密码存储使用加盐哈希;校验和检测数据传输错误;随机数生成用于游戏和模拟。

在算法设计中:模运算用于哈希表设计;中国剩余定理用于大数运算;素数测试用于密钥生成。

对于程序员而言,理解数论不仅有助于实现安全系统,还能避免常见陷阱(如使用弱随机数、错误的模运算实现等)。

1.3 核心问题引导

在学习本章之前,请思考以下问题:

为什么1既不是素数也不是合数?

如何高效判断一个大数是否为素数?

为什么RSA加密是安全的?破解它需要什么?

模运算中的"除法"如何实现?为什么不能直接除?

什么是"陷门函数"?它在密码学中有什么作用?

为什么两个不同的消息可能产生相同的哈希值?这安全吗?

Diffie-Hellman密钥交换如何在不安全的信道上建立共享密钥?

量子计算机对现有密码系统有什么威胁?


二、核心概念详解

4.1 整除性与素数

整除性

定义:如果存在整数k使得 b = ka,则称a整除b,记作 a | b。

例如:3 | 12(因为 12 = 3 × 4),但 5 ∤ 12。

性质:

  • 如果 a | b 且 a | c,则 a | (b + c)
  • 如果 a | b,则 a | bc 对任意整数c成立
  • 如果 a | b 且 b | c,则 a | c

素数

定义:大于1的整数p是素数,如果它的正因子只有1和p本身。

前几个素数:2, 3, 5, 7, 11, 13, 17, 19, 23, 29, ...

注意:1不是素数(这是约定,为了使算术基本定理简洁)。

算术基本定理:每个大于1的整数都可以唯一地表示为素数的乘积(不考虑顺序)。

例如:60 = 2² × 3 × 5

素数判定

试除法:检查从2到√n的所有整数是否整除n。

时间复杂度:O(√n),对于大数效率低下。

米勒-拉宾素性测试:概率性算法,广泛用于实际应用中。

原理基于费马小定理的推广。通过多次测试,可以将错误概率降到任意低。

素数定理:不超过n的素数个数约为 n/ln(n)。

即素数的"密度"随数值增大而降低。

4.2 最大公约数与欧几里得算法

最大公约数(GCD)

定义:gcd(a, b) 是能同时整除a和b的最大正整数。

例如:gcd(12, 18) = 6

性质:

  • gcd(a, 0) = |a|
  • gcd(a, b) = gcd(b, a)
  • gcd(a, b) = gcd(|a|, |b|)

欧几里得算法

原理:gcd(a, b) = gcd(b, a mod b)

算法:

输入:a, b(非负整数,a ≥ b)
输出:gcd(a, b)

while b ≠ 0:
    r = a mod b
    a = b
    b = r
return a

示例:gcd(48, 18)

  • 48 mod 18 = 12
  • 18 mod 12 = 6
  • 12 mod 6 = 0
  • gcd = 6

时间复杂度:O(log(min(a, b))),非常高效。

证明正确性:

关键引理:如果 a = bq + r,则 gcd(a, b) = gcd(b, r)。

证明:设 d = gcd(a, b)。则 d | a 且 d | b。

由于 r = a - bq,所以 d | r。

因此 d 是 b 和 r 的公因数。

反之,设 e = gcd(b, r)。则 e | b 且 e | r。

由于 a = bq + r,所以 e | a。

因此 e 是 a 和 b 的公因数。

所以 gcd(a, b) = gcd(b, r)。∎

扩展欧几里得算法

除了计算gcd,还能找到整数x和y使得 ax + by = gcd(a, b)。

这在计算模逆元时非常有用。

算法:

python
def extended_gcd(a, b):
    if b == 0:
        return a, 1, 0
    
    g, x1, y1 = extended_gcd(b, a % b)
    x = y1
    y = x1 - (a // b) * y1
    
    return g, x, y

应用:求解 ax ≡ 1 (mod m),即找a的模逆元。

如果 gcd(a, m) = 1,则存在x使得 ax + my = 1,即 ax ≡ 1 (mod m)。

4.3 模运算

同余

定义:如果 m | (a - b),则称a与b模m同余,记作 a ≡ b (mod m)。

等价地:a mod m = b mod m。

例如:17 ≡ 5 (mod 12),因为 17 - 5 = 12。

模运算的性质

性质公式
加法(a + b) mod m = ((a mod m) + (b mod m)) mod m
减法(a - b) mod m = ((a mod m) - (b mod m)) mod m
乘法(a · b) mod m = ((a mod m) · (b mod m)) mod m
幂运算aⁿ mod m 可通过快速幂高效计算

注意:模运算中没有直接的"除法"。要计算 a/b mod m,需要找到b的模逆元b⁻¹,然后计算 a · b⁻¹ mod m。

快速幂(模幂运算)

计算 aⁿ mod m 的高效算法。

原理:利用二进制分解指数。

例如:a¹³ = a^(1101)₂ = a⁸ · a⁴ · a¹

算法:

python
def modular_exponentiation(base, exp, mod):
    result = 1
    base = base % mod
    
    while exp > 0:
        if exp % 2 == 1:  # 如果当前位为1
            result = (result * base) % mod
        exp = exp >> 1  # 右移一位
        base = (base * base) % mod
    
    return result

时间复杂度:O(log n),远优于朴素方法的 O(n)。

4.4 费马小定理与欧拉定理

费马小定理

定理:如果p是素数,a不是p的倍数,则 a^(p-1) ≡ 1 (mod p)。

等价形式:a^p ≡ a (mod p) 对所有整数a成立。

应用:

  • 素性测试的基础
  • 计算模逆元:a^(p-2) ≡ a⁻¹ (mod p)

示例:p = 7, a = 3

  • 3⁶ = 729
  • 729 mod 7 = 1 ✓

欧拉函数

定义:φ(n) 表示不超过n且与n互质的正整数个数。

计算:

  • 如果p是素数,φ(p) = p - 1
  • 如果p是素数,φ(pᵏ) = pᵏ - pᵏ⁻¹
  • 如果gcd(m, n) = 1,φ(mn) = φ(m)φ(n)

一般公式:如果 n = p₁^k₁ · p₂^k₂ · ... · pᵣ^kᵣ,则

$$\phi(n) = n \prod_{i=1}^{r} \left(1 - \frac{1}{p_i}\right)$$

示例:φ(12) = φ(2² · 3) = 12 · (1 - 1/2) · (1 - 1/3) = 12 · 1/2 · 2/3 = 4

与12互质的数:1, 5, 7, 11(共4个)✓

欧拉定理

定理:如果gcd(a, n) = 1,则 a^φ(n) ≡ 1 (mod n)。

费马小定理是欧拉定理在n为素数时的特例(因为φ(p) = p - 1)。

应用:RSA加密的正确性证明。

4.5 RSA加密算法

历史背景

RSA由Ron Rivest、Adi Shamir和Leonard Adleman于1977年提出,是第一个实用的公钥加密系统。

密钥生成

选择两个大素数 p 和 q

计算 n = pq

计算 φ(n) = (p-1)(q-1)

选择整数 e,使得 1 < e < φ(n) 且 gcd(e, φ(n)) = 1

计算 d,使得 ed ≡ 1 (mod φ(n))

公钥:(e, n)

私钥:(d, n)

加密与解密

加密:c = m^e mod n(使用公钥)

解密:m = c^d mod n(使用私钥)

正确性证明

需要证明:(m^e)^d ≡ m (mod n)

即 m^(ed) ≡ m (mod n)

由于 ed ≡ 1 (mod φ(n)),有 ed = 1 + k·φ(n) 对某个整数k。

所以 m^(ed) = m^(1 + k·φ(n)) = m · (m^φ(n))^k

由欧拉定理,如果 gcd(m, n) = 1,则 m^φ(n) ≡ 1 (mod n)。

所以 m^(ed) ≡ m · 1^k ≡ m (mod n)。

当 gcd(m, n) ≠ 1 时(即 m 是 p 或 q 的倍数),需要使用中国剩余定理证明,结论仍然成立。∎

安全性

RSA的安全性基于大数因数分解问题的难度:给定n = pq,找出p和q。

目前最好的经典算法(通用数域筛法)的时间复杂度约为:

$$\exp\left(\left(\sqrt[3]{\frac{64}{9}} + o(1)\right)(\ln n)^{1/3}(\ln \ln n)^{2/3}\right)$$

对于2048位的n,这在经典计算机上是不可行的。

推荐密钥长度:

  • 1024位:已不安全
  • 2048位:目前安全
  • 4096位:长期安全

4.6 Diffie-Hellman密钥交换

协议描述

Alice和Bob希望在不安全的信道上建立共享密钥。

公开参数:大素数p和原根g(生成元)

Alice选择私钥a,发送 A = g^a mod p 给Bob

Bob选择私钥b,发送 B = g^b mod p 给Alice

Alice计算 s = B^a mod p = g^(ba) mod p

Bob计算 s = A^b mod p = g^(ab) mod p

双方得到相同的共享密钥 s = g^(ab) mod p。

安全性

基于离散对数问题的难度:给定g, p, g^a mod p,求a。

目前没有已知的多项式时间算法解决此问题。

注意:基本的Diffie-Hellman容易受到中间人攻击,需要结合身份认证使用。

4.7 哈希函数

定义与性质

密码学哈希函数 h: {0,1}* → {0,1}ⁿ 将任意长度的输入映射为固定长度的输出。

理想性质:

确定性:相同输入总是产生相同输出

高效性:计算h(x)是高效的

原像抗性(单向性):给定y,找到x使得h(x)=y是困难的

第二原像抗性:给定x,找到x'≠x使得h(x')=h(x)是困难的

碰撞抗性:找到x≠x'使得h(x)=h(x')是困难的

常见哈希算法

算法输出长度状态
MD5128位已破解,不应用于安全场景
SHA-1160位已发现碰撞,逐步淘汰
SHA-256256位目前安全,广泛使用
SHA-3可变最新标准

应用

  • 密码存储:存储h(password + salt)而非明文密码
  • 数据完整性:文件哈希验证下载完整性
  • 数字签名:对消息哈希值签名而非整个消息
  • 区块链:工作量证明、Merkle树

4.8 椭圆曲线密码学(简介)

椭圆曲线密码学(ECC)基于椭圆曲线上的离散对数问题。

优势:相比RSA,ECC可以用更短的密钥提供相同的安全性。

安全级别RSA密钥长度ECC密钥长度
80位1024位160位
112位2048位224位
128位3072位256位
256位15360位512位

ECC广泛用于移动设备和物联网设备,以及比特币等加密货币。


三、程序员的视角

3.1 在计算机科学中的应用

哈希表

哈希函数将键映射到数组索引。好的哈希函数应该:

  • 均匀分布
  • 计算快速
  • 对相似输入产生不同输出
python
# Python字典内部使用哈希表
my_dict = {"key": "value"}

随机数生成

线性同余生成器:Xₙ₊₁ = (aXₙ + c) mod m

虽然不适合密码学用途,但在模拟和游戏中广泛使用。

校验和

CRC(循环冗余校验)使用模2多项式除法检测数据传输错误。

3.2 常见陷阱与误区

使用弱随机数

python
# 不安全!
import random
secret_key = random.randint(0, 2**128)

# 安全
import secrets
secret_key = secrets.randbits(128)

模运算中的负数

在不同语言中,-5 mod 3 的结果可能不同:

  • Python: 1(始终非负)
  • C/C++: -2(符号跟随被除数)

定时攻击

比较哈希值时使用普通字符串比较可能泄露信息:

python
# 不安全:可能在第一个不匹配字符处提前返回
if user_hash == correct_hash:
    ...

# 安全:恒定时间比较
import hmac
if hmac.compare_digest(user_hash, correct_hash):
    ...

3.3 与其他层级的联系

  • 硬件层:AES-NI指令集加速加密运算
  • 操作系统层:/dev/random 提供熵源
  • 网络层:TLS握手使用公钥密码学
  • 应用层:JWT令牌使用数字签名

四、代码实战

4.1 欧几里得算法与扩展版本

python
"""
欧几里得算法及其扩展版本的实现
"""


def gcd(a, b):
    """
    计算最大公约数
    
    时间复杂度: O(log(min(a, b)))
    """
    a, b = abs(a), abs(b)
    while b:
        a, b = b, a % b
    return a


def lcm(a, b):
    """计算最小公倍数"""
    return abs(a * b) // gcd(a, b)


def extended_gcd(a, b):
    """
    扩展欧几里得算法
    
    返回: (g, x, y) 使得 ax + by = g = gcd(a, b)
    """
    if a == 0:
        return b, 0, 1
    
    g, x1, y1 = extended_gcd(b % a, a)
    x = y1 - (b // a) * x1
    y = x1
    
    return g, x, y


def modular_inverse(a, m):
    """
    计算a模m的逆元
    
    前提: gcd(a, m) = 1
    
    返回: a^(-1) mod m
    """
    g, x, _ = extended_gcd(a % m, m)
    
    if g != 1:
        raise ValueError(f"模逆元不存在 (gcd({a}, {m}) = {g})")
    
    return x % m


def demonstrate_euclidean():
    """演示欧几里得算法"""
    
    print("=== 欧几里得算法 ===")
    
    test_cases = [
        (48, 18),
        (1071, 462),
        (123456789, 987654321),
    ]
    
    for a, b in test_cases:
        g = gcd(a, b)
        l = lcm(a, b)
        print(f"gcd({a}, {b}) = {g}")
        print(f"lcm({a}, {b}) = {l}")
        print()
    
    print("=== 扩展欧几里得算法 ===")
    
    a, b = 35, 15
    g, x, y = extended_gcd(a, b)
    print(f"{a}×{x} + {b}×{y} = {g}")
    print(f"验证: {a*x + b*y} = {g}")
    print()
    
    print("=== 模逆元 ===")
    
    a, m = 3, 11
    inv = modular_inverse(a, m)
    print(f"{a}^(-1) mod {m} = {inv}")
    print(f"验证: {a} × {inv} mod {m} = {(a * inv) % m}")


if __name__ == "__main__":
    demonstrate_euclidean()

4.2 RSA算法实现

python
"""
RSA加密算法的简化实现(用于教学目的)

注意:这不是生产级实现!实际应用中应使用经过审计的库。
"""

import random
import math


def is_prime_miller_rabin(n, k=10):
    """
    米勒-拉宾素性测试
    
    返回: True(可能是素数)或 False(一定是合数)
    """
    if n < 2:
        return False
    if n == 2 or n == 3:
        return True
    if n % 2 == 0:
        return False
    
    # 将 n-1 写为 2^r × d
    r, d = 0, n - 1
    while d % 2 == 0:
        r += 1
        d //= 2
    
    # 进行k轮测试
    for _ in range(k):
        a = random.randrange(2, n - 1)
        x = pow(a, d, n)
        
        if x == 1 or x == n - 1:
            continue
        
        for _ in range(r - 1):
            x = pow(x, 2, n)
            if x == n - 1:
                break
        else:
            return False
    
    return True


def generate_prime(bits):
    """生成指定比特数的随机素数"""
    while True:
        candidate = random.getrandbits(bits)
        candidate |= (1 << bits - 1) | 1  # 确保最高位和最低位为1
        if is_prime_miller_rabin(candidate):
            return candidate


def gcd(a, b):
    while b:
        a, b = b, a % b
    return a


def extended_gcd(a, b):
    if a == 0:
        return b, 0, 1
    g, x1, y1 = extended_gcd(b % a, a)
    x = y1 - (b // a) * x1
    y = x1
    return g, x, y


def modular_inverse(a, m):
    g, x, _ = extended_gcd(a % m, m)
    if g != 1:
        raise ValueError("模逆元不存在")
    return x % m


class RSACipher:
    """RSA加密解密类"""
    
    def __init__(self, key_bits=512):
        """生成密钥对"""
        # 生成两个大素数
        self.p = generate_prime(key_bits // 2)
        self.q = generate_prime(key_bits // 2)
        
        # 计算n和φ(n)
        self.n = self.p * self.q
        self.phi_n = (self.p - 1) * (self.q - 1)
        
        # 选择公钥指数e
        self.e = 65537  # 常用值,是素数且二进制只有两个1
        
        # 确保e与φ(n)互质
        while gcd(self.e, self.phi_n) != 1:
            self.e += 2
        
        # 计算私钥指数d
        self.d = modular_inverse(self.e, self.phi_n)
        
        self.public_key = (self.e, self.n)
        self.private_key = (self.d, self.n)
    
    def encrypt(self, message):
        """
        加密消息
        
        参数: message (int) < n
        返回: ciphertext (int)
        """
        if message >= self.n:
            raise ValueError("消息太大")
        return pow(message, self.e, self.n)
    
    def decrypt(self, ciphertext):
        """
        解密密文
        
        参数: ciphertext (int)
        返回: message (int)
        """
        return pow(ciphertext, self.d, self.n)
    
    def encrypt_string(self, text):
        """将字符串转换为整数并加密"""
        # 简单编码:每个字符转为ASCII值拼接
        message_int = int.from_bytes(text.encode('utf-8'), 'big')
        if message_int >= self.n:
            raise ValueError("文本太长,需要更大的密钥")
        ciphertext = self.encrypt(message_int)
        return ciphertext
    
    def decrypt_string(self, ciphertext):
        """解密并还原为字符串"""
        message_int = self.decrypt(ciphertext)
        # 计算需要的字节数
        byte_length = (message_int.bit_length() + 7) // 8
        message_bytes = message_int.to_bytes(byte_length, 'big')
        return message_bytes.decode('utf-8')


def demonstrate_rsa():
    """演示RSA加密解密"""
    
    print("=== RSA密钥生成 ===")
    rsa = RSACipher(key_bits=64)  # 小密钥用于演示
    
    print(f"p = {rsa.p}")
    print(f"q = {rsa.q}")
    print(f"n = {rsa.n}")
    print(f"φ(n) = {rsa.phi_n}")
    print(f"公钥 (e, n) = ({rsa.e}, {rsa.n})")
    print(f"私钥 (d, n) = ({rsa.d}, {rsa.n})")
    print()
    
    print("=== 整数加密解密 ===")
    message = 42
    print(f"原始消息: {message}")
    
    ciphertext = rsa.encrypt(message)
    print(f"密文: {ciphertext}")
    
    decrypted = rsa.decrypt(ciphertext)
    print(f"解密消息: {decrypted}")
    print(f"验证: {message == decrypted}")
    print()
    
    print("=== 字符串加密解密 ===")
    text = "Hello RSA!"
    print(f"原始文本: {text}")
    
    try:
        ct = rsa.encrypt_string(text)
        print(f"密文: {ct}")
        
        dt = rsa.decrypt_string(ct)
        print(f"解密文本: {dt}")
        print(f"验证: {text == dt}")
    except ValueError as e:
        print(f"错误: {e}")


if __name__ == "__main__":
    demonstrate_rsa()

4.3 哈希函数与数据完整性

python
"""
哈希函数应用:数据完整性验证和密码存储
"""

import hashlib
import os
import json


def compute_sha256(data):
    """计算SHA-256哈希值"""
    if isinstance(data, str):
        data = data.encode('utf-8')
    return hashlib.sha256(data).hexdigest()


def verify_file_integrity(file_path, expected_hash):
    """
    验证文件完整性
    
    返回: True如果哈希匹配,False否则
    """
    with open(file_path, 'rb') as f:
        file_hash = hashlib.sha256(f.read()).hexdigest()
    return file_hash == expected_hash


class PasswordHasher:
    """
    安全的密码哈希类
    
    使用PBKDF2-HMAC-SHA256进行密钥派生
    """
    
    def __init__(self, iterations=100000):
        self.iterations = iterations
    
    def hash_password(self, password):
        """
        哈希密码,生成随机盐
        
        返回: (salt_hex, hash_hex)
        """
        salt = os.urandom(32)  # 256位盐
        hash_value = hashlib.pbkdf2_hmac(
            'sha256',
            password.encode('utf-8'),
            salt,
            self.iterations
        )
        return salt.hex(), hash_value.hex()
    
    def verify_password(self, password, salt_hex, hash_hex):
        """
        验证密码
        
        返回: True如果密码正确
        """
        salt = bytes.fromhex(salt_hex)
        expected_hash = bytes.fromhex(hash_hex)
        
        computed_hash = hashlib.pbkdf2_hmac(
            'sha256',
            password.encode('utf-8'),
            salt,
            self.iterations
        )
        
        return hashlib.compare_digest(computed_hash, expected_hash)


def demonstrate_hashing():
    """演示哈希函数应用"""
    
    print("=== SHA-256哈希 ===")
    
    messages = [
        "Hello, World!",
        "Hello, World",
        "",
        "a" * 1000,
    ]
    
    for msg in messages:
        hash_val = compute_sha256(msg)
        print(f"'{msg[:30]}{'...' if len(msg) > 30 else ''}' -> {hash_val[:16]}...")
    
    print("\n=== 雪崩效应 ===")
    
    msg1 = "password"
    msg2 = "passwore"  # 只改变一个字符
    
    hash1 = compute_sha256(msg1)
    hash2 = compute_sha256(msg2)
    
    print(f"'{msg1}' -> {hash1}")
    print(f"'{msg2}' -> {hash2}")
    
    # 计算哈希值的差异位数
    diff_bits = sum(
        bin(int(a, 16) ^ int(b, 16)).count('1')
        for a, b in zip(hash1, hash2)
    )
    total_bits = len(hash1) * 4
    print(f"差异位数: {diff_bits}/{total_bits} ({100*diff_bits/total_bits:.1f}%)")
    
    print("\n=== 密码哈希 ===")
    
    hasher = PasswordHasher(iterations=10000)  # 减少迭代次数以加快演示
    
    password = "MySecurePassword123!"
    salt, hash_val = hasher.hash_password(password)
    
    print(f"盐: {salt[:16]}...")
    print(f"哈希: {hash_val[:16]}...")
    
    # 验证正确密码
    correct = hasher.verify_password(password, salt, hash_val)
    print(f"正确密码验证: {correct}")
    
    # 验证错误密码
    wrong = hasher.verify_password("WrongPassword", salt, hash_val)
    print(f"错误密码验证: {wrong}")


if __name__ == "__main__":
    demonstrate_hashing()

五、深入思考

5.1 历史背景

数论有着悠久的历史:

  • 欧几里得(约公元前300年):《几何原本》中包含欧几里得算法
  • 费马(1601-1665):提出费马小定理和费马大定理
  • 欧拉(1707-1783):发展模运算理论
  • 高斯(1777-1855):《算术研究》系统化数论

密码学的历史:

  • 凯撒密码:移位替换
  • 恩尼格玛机:二战期间德国使用
  • Diffie-Hellman(1976):公钥密码学开端
  • RSA(1977):第一个实用公钥加密系统

5.2 前沿方向

  • 后量子密码学:抵抗量子计算机攻击的算法

- 基于格的密码学(Lattice-based)

- 基于编码的密码学(Code-based)

- 多变量密码学

  • 同态加密:在加密数据上直接计算
  • 零知识证明:证明某事为真而不泄露额外信息
  • 安全多方计算:多方联合计算而不泄露各自输入

5.3 延伸阅读

  • 《An Introduction to the Theory of Numbers》by Hardy and Wright
  • 《Handbook of Applied Cryptography》by Menezes, van Oorschot, Vanstone
  • 《Understanding Cryptography》by Paar and Pelzl

六、实验笔记

实验1:RSA实现与分析

目标:完整实现RSA算法并分析其安全性。

任务:

实现素数生成(米勒-拉宾测试)

实现密钥生成、加密、解密

测试小密钥(32-64位)的因数分解难度

分析不同密钥长度下的性能

(进阶)实现简单的计时侧信道攻击

提交物:源代码、性能数据、安全分析报告。

实验2:哈希碰撞探索

目标:理解哈希函数的碰撞抗性。

任务:

实现生日攻击:寻找MD5的部分碰撞

分析不同哈希算法的输出分布

实现一个简单的密码破解工具(针对弱密码)

研究彩虹表原理

注意:仅在教育环境中进行,不得用于非法目的。

提交物:源代码、实验结果、伦理讨论。


七、本章小结

本章介绍了数论基础及其在密码学中的应用。整除性、素数、最大公约数是数论的基本概念,欧几里得算法提供了高效计算GCD的方法。

模运算构成了现代密码学的数学基础。费马小定理和欧拉定理是理解RSA算法的关键。RSA的安全性依赖于大数因数分解的困难性,而Diffie-Hellman密钥交换基于离散对数问题。

哈希函数在数据完整性验证、密码存储和数字签名中有广泛应用。理想的密码学哈希函数应具备单向性和碰撞抗性。

随着量子计算机的发展,现有公钥密码系统面临威胁,后量子密码学正在成为研究热点。


八、习题

习题1(基础):计算下列各题:

(a) gcd(1234, 5678)

(b) 17 mod 5

(c) 3¹⁰ mod 7

(d) φ(100)

习题2(基础):使用扩展欧几里得算法,找到整数x和y使得 35x + 15y = gcd(35, 15)。

习题3(中等):证明:如果p是素数,则 (p-1)! ≡ -1 (mod p)。(威尔逊定理)

习题4(中等):在RSA中,设p=61, q=53, e=17。计算:

(a) n和φ(n)

(b) 私钥d

(c) 加密消息m=65

(d) 验证解密正确性

习题5(中等):解释为什么基本的Diffie-Hellman协议容易受到中间人攻击,并提出改进方案。

习题6(较难):实现米勒-拉宾素性测试,并用它生成100位的素数。

习题7(较难):研究中国剩余定理,并用它优化RSA解密过程。

习题8(挑战):实现一个简单的哈希碰撞寻找程序(针对简化哈希函数),分析生日悖论。

习题9(挑战):研究并报告一种后量子密码算法的原理和现状。

习题10(开放):设计一个安全的用户认证系统,包括注册、登录、密码重置功能,详细说明使用的密码学技术及其理由。

4/13数论与密
0%