基于背包问题的公钥加密算法

本文介绍了基于背包问题的公钥加密算法。在公钥密码体制中,使用超递增背包问题的特性来实现加解密过程。私钥是超递增向量转化为非超递增向量的参数,公钥是非超递增向量。加密时,通过明文分组与非超递增向量的内积得到密文;解密时,还原超递增向量,利用背包问题的解得到明文。文章还提供了具体的代码实现和加密测试示例。
摘要由CSDN通过智能技术生成

简述:

  1. 公钥密码

公钥密码又称非对称密码,所谓非对称密码即加解密使用的不是同一个密钥。

在公钥密码体系中,使用每个人拥有两种密钥,公钥和私钥,公钥是公开的,用来加密,私钥是私自保存的,用于解密。如:
在这里插入图片描述
只有用自己的私钥才能解开自己公钥加密的信息,而且通过公钥钥是不能推出私钥的。

公钥密码将辅助信息(陷门信息)作为私钥,这类密码的安全强度取决于它所依据的问题的计算复杂度。

常见的公钥密码有RSA公钥密码、ElGamal公钥密码、椭圆曲线密码。

  1. 背包问题

背包问题:假设有一堆物品,体积各不相同,问能否从这堆物品中找出几个正好装满一个给定容量的背包?(假定物品之间不留空隙)
在这里插入图片描述
记物品的体积分别为v1,V2,…,n,背包的容量为C,则背包问题可表示为:b1v1+b2v2+…+bnvn=C,其中,bi(i=1,2,…,n)等于1或者0。

bi = 1表示第i个物品在背包中,bi=0表示第i个物品不在背包中,称物品体积的序列(v1,V2,…,vn)为背包向量。

目前没有一个高效的算法来解决这个问题,只是进行穷举式搜索,但当数据足够多时,达到2的1024或2048位时,穷举式搜索将不再现实,问题就很复杂了。

  1. 超递增背包

并非所有的背包问题都没有有效算法,有一类特殊的背包问题是容易求解的,这就是超递增背包问题。

V=(v1,2,…,vn)是一个背包向量,若V满足V中每一项都大于它前面所有项之和,则称V是一个超递增向量,或者称序列v1,V2,,n是一个超递增序列,以V为背包向量的背包问题被称做超递增背包问题。

比如,序列1,2,4,16,…… ,2^n就是一个超递增序列。

超递增背包问题的解可以通过以下方法找到:

假设背包容量为C,从右到左依次检查超递增背包向量中的每一个元素Vi,如果C >= Vi,则C = C - Vi,并将对应的bi置为1,否则跳过,继续检查下一元素,直至遍历完所有元素。如果此时C等于0,则该超递增背包问题有解,解为bi中的1对应的超递增背包向量中的元素,否则表示该问题无解。

例如:
在这里插入图片描述

加解密:

背包算法具体如下:私有密钥设置为将一个超递增向量 V 转换为非超递增向量 U 的
参数t 、t的逆元和 k,公开密钥设置为非超递增向量 U,具体的加解密过程如下:

  1. 加密

首先将二进制明文消息划分成长度与非超递增向量U长度相等的明文分组b1 b2 …… bn;

然后计算明文分组向量 B =(b1,b2,……,bn)与非超递增向量 U= (u1,u2,……,un)的内积 B * U = b1u1 + b2u2+ ……+bnun,所得结果为密文。

  1. 解密

先还原出超递增背包向量V = t的逆元 * U mod k=t * t的逆元 * V mod k

再将密文 B * U 模 k 乘以 t逆元 的结果作为超递增背包问题的背包容量,求解超递增背包问题,得到消息明文。

代码实现:

import random
from my_modules import modules

# 初始化
def init(length, interval):
    listV = []  # 超递增向量
    listV_b = []  # 每个元素对应的乘数
    bagCapacity = 1000  # 背包容积
    # 初始化超递增向量与listV_b
    for i in range(length):
        listV.append(sum(listV) + random.randrange(1, interval))
        listV_b.append(0)
    # 求超递增背包的解
    bagCapacityTmp = bagCapacity
    for i in range(len(listV)-1, -1, -1):
        if bagCapacityTmp >= listV[i]:
            bagCapacityTmp -= listV[i]
            listV_b[i] = 1
    return listV

# 产生私钥:k、t、t的逆元
def creatPKey(listV):
    # listV = init()
    while True:
        k = int(input("输入私钥k(大于%d):" % (sum(listV))))
        if k <= sum
  • 13
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值