NTRU-密码学

在介绍NTRU之前,我需要学习一些格的知识,点击查看

格的基本知识

格的定义
格的困难问题
在离散数学中格的定义:格是其非空有限有限子集都有一个上确界和下确界的偏序集合。
偏序集合:(英语:Partially ordered set,简写poset)是数学中,特别是序理论中,指配备了部分排序关系的集合。 这个理论将排序、顺序或排列这个集合的元素的直觉概念抽象化。这种排序不必然需要是全部的,就是说不必要保证此集合内的所有对象的相互可比较性。部分排序集合定义了部分排拓扑。

线性无关:
在这里插入图片描述

NTRU

NTRU是一个带有专利保护的开源公开密钥加密系统,使用基于格的加密算法来加密数据。它包括两部分算法:NTRUEncrypt用来加密,NTRUSign用来进行数字签名。与其他流行的公钥加密系统不同,它可以防止被Shor算法破解,并显著提升了性能。NTRU算法被认为可以抵抗量子攻击。
NTRU is based on the SVP or CVP in a lattice
算法流程如下:
在这里插入图片描述
文字描述如下:
在这里插入图片描述
详细介绍参考百度文库文章

例子

这个例子计算需要用到center lift这个概念的内容。介绍在最后。






center lift

例子,其实很简单就是取[-q/2,q/2]的数和a_i模q同余的代替即可。
在这里插入图片描述

代码例题

实现如下参数的NTRU算法
(N, p, q) = (7, 2, 29),Alice的公钥为
在这里插入图片描述
Bob希望发送明文消息
Bob的临时密钥为r。
1)输出Bob发送的密文
2)
2)。用私钥解密1)中所得的密文,验证是否等于明文。

package main

import "fmt"

var N int = 7                                   //参数N
var P int = 2                                   //参数P
var Q int = 29                                  //参数Q
var poly_h = [7]int{23, 23, 23, 24, 23, 24, 23} //公钥
var poly_f = [7]int{1, 1, 1, 0, 1, 1, 0}
var poly_f_P = [7]int{1, 0, 0, 0, 0, 1, 1} //和poly_f组成私钥
var poly_m = [7]int{3, 0, 3, 0, 0, 0, 0}   //明文
var poly_r = [7]int{1, 1, 0, 1, 0, 0, 1}   //随机秘钥
var temp_r [7]int                          //存储P*r(x)的值
var poly_cipher map[int]int                //存储加密密文,temp_r(x)*poly_h(x)+poly_m(x)
var temp_m map[int]int                     //存储F(x)*poly_cipher(x)
var expon_cipher map[int]int               //存储对应x位的次方
var decrypt_m map[int]int                  //存储解密的密文,poly_f_P(x)*temp_m(x)

func encrypt() { /*加密函数*/
	var i int
	var j int
	var k int = 0
	for i = 0; i < 7; i++ { /*计算P*r(x),并将结果存储到temp_r*/
		temp_r[i] = P * poly_r[i]
		//fmt.Println(poly_h[i])
	}
	poly_cipher = make(map[int]int)
	expon_cipher = make(map[int]int)
	for i = 0; i < 7; i++ { /*两层for循环,计算temp_r(x)*poly_h(x)+poly_m(x)*/
		for j = 0; j < 7; j++ {
			poly_cipher[k] = temp_r[i] * poly_h[j]
			//fmt.Print(poly_cipher[1])
			if k > 6 { /*将指数相同的位数的系数相加*/
				expon_cipher[k] = (i + j) % 7
				switch expon_cipher[k] {
				case 0:
					poly_cipher[0] += poly_cipher[k]
					//fmt.Println(poly_cipher[0])
				case 1:
					poly_cipher[1] += poly_cipher[k]
				case 2:
					poly_cipher[2] += poly_cipher[k]
				case 3:
					poly_cipher[3] += poly_cipher[k]
					/*fmt.Print("当前次方=%d,对应数字为%d,k=", expon_cipher[k], poly_cipher[k], k, i, j, poly_cipher[1])
					fmt.Println("\n")*/
				case 4:
					poly_cipher[4] += poly_cipher[k]
				case 5:
					poly_cipher[5] += poly_cipher[k]
				case 6:
					poly_cipher[6] += poly_cipher[k]
				default:
					fmt.Printf("未知型")
				}
			}
			//fmt.Println(expon_cipher[k])
			k++
		}
		//fmt.Println("\n")
		poly_cipher[i] += poly_m[i] /*+m(x)操作*/
		//fmt.Println("当前明文为:", poly_m[i])
		//poly_cipher[i] = poly_cipher[i] % Q
		//fmt.Println(poly_cipher[i])
	}
	//fmt.Println(poly_cipher[0])
	for i = 0; i < 7; i++ { /*模Q操作,此时Q=29*/
		poly_cipher[i] = poly_cipher[i] % Q
		//fmt.Println(poly_cipher[i])
	}
	//fmt.Println(k)
}

func decrypt() { /*解密函数*/
	var i int
	var j int
	var k int = 0
	temp_m = make(map[int]int)
	for i = 0; i < 7; i++ { /*双层for循环计算poly_f(x)*poly_cipher(x)*/
		//fmt.Println(poly_cipher[1])
		for j = 0; j < 7; j++ {
			temp_m[k] = poly_f[i] * poly_cipher[j]
			//fmt.Println("location=", k)
			//fmt.Println("对应数字为=", temp_m[k])
			if k > 6 { /*将指数相同的位数的系数相加*/
				expon_cipher[k] = (i + j) % 7
				switch expon_cipher[k] {
				case 0:
					temp_m[0] += temp_m[k]
				case 1:
					//fmt.Println(temp_m[1])
					temp_m[1] += temp_m[k]
					//fmt.Print("当前次方=%d,对应数字为%d,k=", expon_cipher[k], i, j, temp_m[k], temp_m[1])
					//fmt.Println("\n")
				case 2:
					temp_m[2] += temp_m[k]
				case 3:
					temp_m[3] += temp_m[k]
					/*fmt.Print("当前次方=%d,对应数字为%d,k=", expon_cipher[k], temp_m[k], k, i, j, temp_m[1])
					fmt.Println("\n")*/
				case 4:
					temp_m[4] += temp_m[k]
				case 5:
					temp_m[5] += temp_m[k]
				case 6:
					temp_m[6] += temp_m[k]
				default:
					fmt.Printf("未知型")
				}
			}
			k++
		}
	}
	//fmt.Println(k)
	for i = 0; i < 7; i++ { /*模Q操作,此时Q=29
		由于此时的结果均在[-Q/2,Q/2]之间,所以没有进行center lift操作。*/
		temp_m[i] = temp_m[i] % Q
		//fmt.Println(temp_m[i])
	}
	var half_Q int = Q / 2
	for i = 0; i < 7; i++ { /*center lift操作,不在[-Q/2,Q/2]之间的,正数-Q,负数+Q。前提对Q已经取模*/
		if temp_m[i] > half_Q && temp_m[i] > 0 {
			temp_m[i] = temp_m[i] - Q
			fmt.Println(temp_m[i])
		} else if temp_m[i] < -half_Q && temp_m[i] < 0 {
			temp_m[i] = temp_m[i] + Q
		}
	}
	decrypt_m = make(map[int]int)
	k = 0
	for i = 0; i < 7; i++ { /*双层for循环计算poly_f_P(x)*temp_m(x)*/
		//fmt.Println(poly_cipher[1])
		for j = 0; j < 7; j++ {
			decrypt_m[k] = poly_f_P[i] * temp_m[j]
			//fmt.Println("location=", k)
			//fmt.Println("对应数字为=", decrypt_m[k])
			if k > 6 { /*将指数相同的位数的系数相加*/
				expon_cipher[k] = (i + j) % 7
				switch expon_cipher[k] {
				case 0:
					decrypt_m[0] += decrypt_m[k]
				case 1:
					//fmt.Println(decrypt_m[1])
					decrypt_m[1] += decrypt_m[k]
					//fmt.Print("当前次方=%d,对应数字为%d,k=", expon_cipher[k], i, j, decrypt_m[k], decrypt_m[1])
					//fmt.Println("\n")
				case 2:
					decrypt_m[2] += decrypt_m[k]
				case 3:
					decrypt_m[3] += decrypt_m[k]
					/*fmt.Print("当前次方=%d,对应数字为%d,k=", expon_cipher[k], decrypt_m[k], k, i, j, decrypt_m[1])
					fmt.Println("\n")*/
				case 4:
					decrypt_m[4] += decrypt_m[k]
				case 5:
					decrypt_m[5] += decrypt_m[k]
				case 6:
					decrypt_m[6] += decrypt_m[k]
				default:
					fmt.Printf("未知型")
				}
			}
			k++
		}
	}
	//fmt.Println(k)
	for i = 0; i < 7; i++ { /*模P操作,此时P=2*/
		decrypt_m[i] = decrypt_m[i] % P
		fmt.Println(decrypt_m[i])
	}
}
func main() {
	encrypt()
	decrypt()
}

手动验证计算过程:
手动验证计算过程确实有误,后面给我弟讲的时候发现的。当时博文也写好,后面就一直没有改!大家先把上面英文例子看懂了,可以自己手动验证计算过程的。
在这里插入图片描述


### NTRU加密算法简介 NTRU 是一种基于多项式环理论的公钥密码系统,其设计初衷是为了提供高效的安全通信方案。它具有密钥短、易于生成以及快速计算等特点[^2]。这些特性使得 NTRU 成为现代密码学领域中的一个重要研究方向。 --- ### NTRU 加密算法原理 #### 数学背景 NTRU 的核心依赖于代数结构——整系数多项式环 \( R = \mathbb{Z}[X]/(X^N - 1) \),其中 \( X^N - 1 \) 表示模运算下的约化关系。该环由次数小于 \( N \) 的多项式组成,并支持加法和乘法操作[^3]。 #### 密钥生成过程 1. **参数定义**: 设定三个正整数 \( (N, p, q) \),满足 \( N \geq 3 \), \( p < q \),并选择两个概率分布用于随机选取多项式的系数。 2. **私钥生成**: - 私钥 \( f(x) \in R_q \) 和 \( g(x) \in R_p \) 被分别选自特定的概率分布。 - 计算逆元 \( F_p(x) \equiv f^{-1}(x) (\text{mod }p) \) 及 \( F_q(x) \equiv f^{-1}(x)(\text{mod }q) \)[^1]。 3. **公钥生成**: - 使用公式 \( h(x) = pf(x)^{-1}g(x) (\text{mod }q) \) 构造公钥 \( h(x) \) 并公开发布。 #### 加密与解密机制 - **加密阶段**: 发送方通过随机挑选一个小多项式 \( r(x) \) 来掩盖消息 \( m(x) \),随后利用接收者的公钥 \( h(x) \) 进行如下变换: \[ e(x) = prh(x)+m(x)\quad(\text{mod}\;q) \] - **解密阶段**: 接收者使用自己的私钥 \( f(x) \) 对收到的数据执行以下两步还原原始信息: \[ a(x)=f(x)e(x)=(pm(x)+prf(x)g(x))\;\mathrm{(mod)}\;q \] 继续取模得到最终明文: \[ b(x)=a(x)\;\mathrm{(mod)}\;p=m(x). \] --- ### NTRU 加密算法实现 以下是 Python 中的一个简化版 NTRU 实现例子,仅作演示用途: ```python import numpy as np class Ntru: def __init__(self, N=7, p=3, q=49): self.N, self.p, self.q = N, p, q def gen_keys(self): from sympy import symbols, div x = symbols('x') # Example polynomials for simplicity. f_poly = [-1, 0, 1, 0, -1, 0, 1] # Private key polynomial coefficients g_poly = [1, 1, -1, 0, 0, 1, -1] # Randomly chosen public component inv_f_mod_p = ... # Compute inverse of `f` modulo `p`. inv_f_mod_q = ... # Compute inverse of `f` modulo `q`. h_poly = [(self.p * gi % self.q) for gi in map(lambda c: sum(c), zip(f_poly, g_poly))] return {'private': f_poly, 'public': h_poly} ntru_instance = Ntru() keys = ntru_instance.gen_keys() print("Public Key:", keys['public']) print("Private Key:", keys['private']) ``` 上述代码片段展示了如何初始化基本参数并生成一对简单的公私钥对。 ---
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值