用python语言实现带输出的可以对某消息进行数字签名NTRUsign算法,使用到的函数要自己编写,阶数N为107
时间: 2024-01-24 22:16:42 浏览: 177
基于python+django的基于RSA算法的数字签名生成软件的实现.zip
好的,实现数字签名NTRUsign算法,需要先生成公私钥对,然后对要签名的消息进行签名,最后验证签名是否正确。下面是一个简单的实现:
```python
import random
# 定义NTRU参数
N = 107
p = 3
q = 107
# 生成随机多项式f
def gen_rand_poly():
poly = [0] * N
for i in range(N):
poly[i] = random.randint(-(p-1), p-1)
return poly
# 计算多项式a和b的乘积
def poly_mul(a, b):
c = [0] * N
for i in range(N):
for j in range(N):
if i+j < N:
c[i+j] += a[i] * b[j]
return c
# 计算多项式x的模q剩余
def mod_q(x):
for i in range(N):
x[i] = x[i] % q
if x[i] > q//2:
x[i] -= q
elif x[i] < -q//2:
x[i] += q
return x
# 计算多项式f的逆元
def poly_inv(f):
g = [0] * N
g[0] = pow(f[0], q-2, q)
for i in range(1, N):
tmp = [0] * N
for j in range(i+1):
tmp[j] = f[j]
for j in range(i):
tmp[j] += g[j] * f[i-j]
g[i] = -tmp[i] * pow(tmp[0], q-2, q)
g = mod_q(g)
return g
# 生成公私钥对
def gen_key_pair():
f = gen_rand_poly()
g = gen_rand_poly()
while True:
f_inv = poly_inv(f)
h = mod_q(poly_mul(f_inv, g))
if h.count(0) < N//2:
break
return (f, g), h
# 对消息m进行签名,返回签名s
def sign(sk, m):
r = gen_rand_poly()
e = gen_rand_poly()
a = mod_q(poly_mul(sk[0], r) + e)
b = mod_q(poly_mul(sk[1], r) + mod_q(poly_mul(sk[0], e)) + m)
s = mod_q(poly_mul(a, sk[1]) - poly_mul(b, sk[0]))
return s
# 验证签名s是否正确,返回True或False
def verify(pk, m, s):
a = mod_q(poly_mul(s, pk[0]) + poly_mul(pk[1], m))
b = mod_q(poly_mul(pk[0], a) - s)
return b.count(0) >= N//2
# 测试
sk, pk = gen_key_pair()
m = [1, 2, 3, 4, 5]
s = sign(sk, m)
print(verify(pk, m, s))
```
在上面的代码中,我们用`gen_key_pair()`函数生成公私钥对,用`sign()`函数对消息进行签名,用`verify()`函数验证签名是否正确。具体实现过程中,我们需要用到多项式的加减乘运算,以及多项式的模q剩余和多项式的逆元计算。
阅读全文