You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Reed-Solomon实现McEliece加密解密报错求助

基于Reed-Solomon实现McEliece加密器的解密问题

我正在使用rs-ecc库尝试基于Reed-Solomon码实现McEliece加密器,当前遇到以下问题:

  • 解密阶段应用置换矩阵逆P_inv后,解码器无法识别编码数据并抛出错误
  • 因矩阵尺寸不匹配,无法提前应用混淆矩阵逆S_inv

我清楚该库专注于纠错功能而非密码学场景,但仍希望借助它实现比Goppa码更安全的McEliece方案。已尝试更换库、调整密钥生成逻辑,但问题未解决。

代码实现

from ecc import galois as g
from ecc import reed_solomon as rs
from ecc import polynomial as p
from Crypto.Random import get_random_bytes
import numpy as np
import random
import os

def generate_permutation_matrix(n):
    # 创建单位矩阵
    P = np.eye(n, dtype=int)

    # 生成随机置换
    perm = np.random.permutation(n)

    # 根据置换重新排列单位矩阵的行
    P = P[perm]

    return P

def generate_keys(key_length, priv_key_name, pub_key_name):
    # 创建GF(2^8)有限域
    field = g.Field(reversed([1, 0, 0, 0, 1, 1, 1, 0, 1]), p=2)

    # G是Reed-Solomon码的生成矩阵
    k = key_length  
    n = 254  
    gen = rs.generator(field, n)

    msg = [0] * k
    rev = msg[:]
    msg_encoded = msg[:] * k

    # 构建生成矩阵
    G = np.zeros((k, n), dtype=int)
    for i in range(k):
        G[i, i] = 1  # 单位矩阵部分
        for j in range(k):  # 构建校验位矩阵
            msg[j] = G[i, j]
        for j in range(k):  # 反转消息
            rev[k-1-j] = msg[j]
        rev_encoded = rs.encode(rev, gen)
        for j in range(n):  # 反转回来
            msg_encoded[n-1-j] = rev_encoded[j]
        for j in range(n-k):
            G[i, k+j] = msg_encoded[k+j]  

    # 生成k×k的可逆混淆矩阵S
    S = np.random.randint(0, 2, size=(k, k))
    while np.linalg.det(S) == 0:  # 确保矩阵可逆(行列式不为0)
        S = np.random.randint(0, 2, size=(k, k))
    # 生成n×n的置换矩阵P
    P = generate_permutation_matrix(n)

    # 步骤3:生成密钥
    # 公钥是G1 = SGP
    if not os.path.exists(priv_key_name):
        with open(pub_key_name, 'wb') as f:
                pass
        
        with open(priv_key_name, 'wb') as f:
                pass

    pub_key = np.dot(S, np.dot(G, P))
    np.savez_compressed(pub_key_name, pub_key=pub_key)
    # 私钥是三元组(S, gen, P)
    np.savez_compressed(priv_key_name, S=S, gen_coeffs=gen.coeffs, P=P)

def encrypt(pub_key_name, msg):
    pub_key_data = np.load(str(pub_key_name), allow_pickle=True)

    pub_key = pub_key_data['pub_key']
    
    print(np.shape(pub_key))
    print(len(msg))
    msg_encrypted = np.dot(msg, pub_key)

    for _ in range(111):
        # 随机选择编码数据中的一个位置
        pos = random.randint(0, len(msg_encrypted) - 1)
        # 将该位置的字节改为有限域内的随机值
        msg_encrypted[pos] = random.randint(0, 1)
    return msg_encrypted

def decrypt(priv_key_name, msg_encrypted, password):
    private_key_data = np.load(str(priv_key_name), allow_pickle=True)
    S = private_key_data['S']
    gen_coeffs = private_key_data['gen_coeffs']
    P = private_key_data['P']
    field = g.Field(reversed([1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1]), p=2)
    gen = p.Polynomial(field, gen_coeffs)
    print(gen.field)
    S_inv = np.linalg.inv(S)
    P_inv = np.linalg.inv(P)
    # 对密文应用置换矩阵逆
    msg_encrypted = np.dot(msg_encrypted, P_inv)

    # 使用生成矩阵解码
    msg_encrypted = rs.decode(msg_encrypted, gen)

    # 应用混淆矩阵逆得到原始消息
    msg = np.dot(msg_encrypted, S_inv)

    return msg

def main():
    key = get_random_bytes(32)
    password =  ''
    generate_keys(32, 'priv_key.npz', 'pub_key.npz')
    key_enc = encrypt('pub_key.npz', list(key))
    key_dec = decrypt('priv_key.npz', key_enc, password)

    assert key==key_dec

if __name__ == "__main__":
    main()

报错信息

Traceback (most recent call last):
  File "test.py", line 25, in <module>
    main()
  File "\test.py", line 17, in main
    decrypted_key = decrypt(priv_key_name, encrypted_key, password)
  File "\mceliece.py", line 106, in decrypt
    msg_encrypted = rs.decode(msg_encrypted, gen)
  File "C:\Users\x\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\ecc\reed_solomon.py", line 27, in decode
    synd = syndrome(msg, gen)
  File "C:\Users\x\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\ecc\reed_solomon.py", line 48, in syndrome
    return [p.eval(field.exp[i]) for i in range(degree)]
  File "C:\Users\x\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\ecc\reed_solomon.py", line 48, in <listcomp>
    return [p.eval(field.exp[i]) for i in range(degree)]
  File "C:\Users\x\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\ecc\polynomial.py", line 43, in eval
    result = self.field.add(result, c)
  File "C:\Users\x\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\ecc\galois.py", line 52, in add
    pairs = zip(self.to_poly[x], self.to_poly[y])
KeyError: 31869579.0

内容的提问来源于stack exchange,提问作者Junior1373

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 05:18:10