Merge pull request 'main' (#24) from sangge/tpre-python:main into main
All checks were successful
Test CI / test speed (push) Successful in 20s

Reviewed-on: #24
This commit is contained in:
ccyj 2023-12-29 21:54:12 +08:00
commit bd0353731c
33 changed files with 534 additions and 179 deletions

View File

@ -20,4 +20,4 @@ jobs:
- name: Run script in Docker container
run: |
ls $PWD/src
docker run -v .:/app git.mamahaha.work/sangge/tpre:base ls
docker run --rm -v .:/app git.mamahaha.work/sangge/tpre:base ls

2
.gitignore vendored
View File

@ -10,3 +10,5 @@ src/temp_message_file
src/temp_key_file
src/client.db
src/server.db
build
src/tpre.cpython-311-x86_64-linux-gnu.so

61
FQA.md Normal file
View File

@ -0,0 +1,61 @@
# 答辩问题准备
1. **Q:数据安全与隐私**:您的系统在分布式环境中如何确保数据安全和隐私,尤其是在密钥管理方面的挑战?
**A:** 通过代理服务器来转换密文,使其从一个密钥加密变为另一个密钥加密,而不需要将密文解密为明文;客户端每次启动时会生成新的公私密钥对,在随后的通信中,随机选取一次性对称密钥。
2. **Q:国家安全标准的遵循**:您能详细说明您的系统如何符合中国的国家安全标准,特别是对于政府和金融等敏感领域?
**A:** 使用国产的SM算法减小对外国算法的依赖增强自主控制的能力可以有效防止潜在的后门和安全漏洞。
3. **Q:系统架构**:您的分布式架构如何提高系统的性能和可伸缩性?
**A:** 性能方面,我们采用了门限方案,在解密时不需要接收所有的密文片段;密文重加密和解密使用对称密钥,加快加解密速度。可以认为每次都可以"挑选"较高性能的节点进行计算。可伸缩性方面,动态进行节点的添加与退出,客户端也可以动态更新节点。
4. **Q:算法效率**:您能讨论一下您系统中使用的门限代理重加密技术的效率和计算要求吗?
**A:** 性能开销最大的是重加密密钥的生成和解密其余步骤开销极小计算要求64位CPU512MB内存可以运行Docker
5. **Q:兼容性与鲁棒性**:您的系统如何确保与各种环境(如分布式隐私计算)的兼容性,并且如何处理节点故障或恶意节点?
**A:** 兼容性使用容器化部署保证运行环境的一致性兼容多个操作系统和CPU架构鲁棒性在异常和危险情况下系统生存的能力。比如说计算机软件在输入错误、磁盘故障、网络过载或有意攻击情况下能否不死机、不崩溃就是该软件的鲁棒性。体现对恶意数据进行过滤使用python异常处理机制手动捕获错误并防止程序崩溃退出使用心跳包技术检测节点存活状态。对于故障节点使用心跳包检测节点存活状态对于恶意节点我们尚未实现相关功能但是我们计划使用信誉系统对节点进行评分客户端可向中心服务器反馈恶意节点中心服务器通过相关算法降低恶意节点被分配到的权重如果确定是恶意节点则进行黑名单限制。
6. **Q:实际应用场景**:您的系统在哪些实际场景中可以最有效地使用,这些场景中可能的局限性或挑战是什么?
**A:** 区块链中的分布式计算和数据安全共享场景、数据安全授权、分布式密钥管理;计算资源受限,加密算法缺乏软硬件层面的深度定制优化。
7. **Q:代码结构与模块化**:您的项目代码是如何组织的?您如何确保代码的模块化和可读性?
**A:** 我们先实现了算法部份利用函数调用来实现算法的每个步骤。然后我们按照系统角色功能分别编写了客户端、节点、中心服务器的代码。使用前后端分离。可读性方面我们采用了下划线命名法REST编程风格使用类型提示来确保我们在开发过程中有着良好的可读性。
8. **Q:算法实现**:在代码中,您如何实现门限代理重加密算法?有哪些关键的算法优化或创新点?
**A:** 融合了代理重加密和shamir秘密共享以及混合加密机制使用雅各比坐标系加快椭圆曲线上的点的计算。使用fastapi框架实现原生高性能api以及异步编程。使用sqlite减少计算资源开销免去复杂的数据库配置。
9. **Q:性能测试**:您是否对代码进行了性能测试?测试结果显示的主要瓶颈和优化机会是什么?
**A:** 是的我们使用了line_profiler这个工具进行性能测试。测试结果显示的主要瓶颈在于重加密密钥生成和解密这两个步骤。在这两个步骤中涉及到了椭圆曲线上的计算。我们使用了雅各比坐标系加快了计算速度。(雅各比坐标系通过减少在有限域中进行的昂贵的模逆运算,以及优化乘法操作的数量,使得椭圆曲线上的点加和点倍运算更加高效。这些优化对于加密和解密操作的速度至关重要,特别是在资源受限的环境)。再有sqlite不支持高并发场景在写入时存在资源抢占但是我们使用了消息队列将并发的数据转换为串行提高了写入效率。
10. **Q:安全性考虑**:在代码实现中,您如何处理潜在的安全漏洞,特别是与加密和数据传输相关的?
**A:** 我们使用了参数化查询参数化查询避免了将用户输入直接拼接到SQL语句中。可以使用https加密传输数据。
11. **Q:错误处理和日志记录**:您的代码中是否包含了错误处理和日志记录机制?这些机制如何帮助监控和调试系统?
**A:** 我们使用了python内置的异常处理来处理错误。日志使用的是print函数来输出。我们为代码添加了不同的返回值所以在调试的时候如果出错我们可以很方便的定位错误。同时异常处理保证了程序不会异常退出。
12. **Q:项目是如何应用在区块链中的:** 如题
**A:** 加密数据:将使用私钥加密的密文上传到区块链;授权访问:数据请求方发送访问请求给数据持有方;代理重加密:代理节点重加密密文,数据请求方使用自己的私钥进行解密;所有的访问请求和重加密操作都在区块链上记录,提供了完整的审计追踪功能
13. **Q:简单介绍一下代理重加密的数学原理:** 如题
**A:** 代理重加密为一种三方协议可以简单理解为三个人的DHKE。A将秘密拆分为两个部分一部分给B一部分给代理节点。在重加密时代理节点将这部分密码附加进密文此时B收到可以通过另一部分秘密来恢复完整的秘密。
14. **Q:选择密文攻击,选择明文攻击** 如题
**A:**
15. **Q:国密SM2 SM3 SM4** 如题
**A:**

View File

@ -38,7 +38,9 @@ The project relies on the following software:
### Docker installer
```bash
apt update && apt install docker.io mosh -y
apt update && apt install mosh -y
chmod +x install_docker.sh
./install_docker.sh
```
### Docker version

View File

@ -3,13 +3,24 @@
## Run docker
```bash
docker run -it -p 8000:8000 -p 8001:8001 -p 8002:8002 -v ~/mimajingsai:/app -e HOST_IP=110.41.130.197 git.mamahaha.work/sangge/tpre:base bash
docker run -it -p 8000-8002:8000-8002 -v ~/mimajingsai/src:/app -e HOST_IP=60.204.193.58 git.mamahaha.work/sangge/tpre:base bash
docker run -it -p 8000-8002:8000-8002 -v ~/mimajingsai/src:/app -e HOST_IP=119.3.125.234 git.mamahaha.work/sangge/tpre:base bash
docker run -it -p 8000-8002:8000-8002 -v ~/mimajingsai/src:/app -e HOST_IP=124.70.165.73 git.mamahaha.work/sangge/tpre:base bash
```
```bash
tpre3: docker run -it -p 8000:8000 -p 8001:8001 -p 8002:8002 -v ~/mimajingsai:/app -e HOST_IP=60.204.233.103 git.mamahaha.work/sangge/tpre:base bash
```
## Start application
```bash
nohup python server.py &
nohup python node.py &
nohup python client.py &
cat nohup.out
```
## Cloud server ip
**tpre1**: 110.41.155.96
@ -21,7 +32,8 @@ tpre3: docker run -it -p 8000:8000 -p 8001:8001 -p 8002:8002 -v ~/mimajingsai:/a
### Client request message
```bash
python client_cli.py 110.41.21.35 aaa
python client_cli.py 124.70.165.73 name
python client_cli.py 124.70.165.73 environment
```
## Client router

View File

@ -84,9 +84,6 @@ typedef struct {
} SM4_GCM_CTX;
#define SM4_GCM_KEY_SIZE 16
#define SM4_GCM_MIN_IV_SIZE 1
#define SM4_GCM_DEFAULT_IV_SIZE 12
#define SM4_GCM_MAX_IV_SIZE 64
#define SM4_GCM_DEFAULT_TAG_SIZE 16
_gmssl_export int sm4_gcm_encrypt_init(SM4_GCM_CTX *ctx,

View File

@ -13,10 +13,11 @@
#ifdef WIN32
#define _gmssl_export __declspec(dllexport)
#else
#elif defined(__GNUC__)
// use -fvisibility=hidden to change the "default" behavior
#define _gmssl_export __attribute__((visibility("default")))
#else
#define _gmssl_export
#endif
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
@ -19,12 +19,8 @@
extern "C" {
#endif
/*
Rand Public API
rand_bytes
*/
#define RAND_BYTES_MAX_SIZE (256)
_gmssl_export int rand_bytes(uint8_t *buf, size_t buflen);

View File

@ -1,86 +0,0 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
#ifndef GMSSL_SM2_Z256_H
#define GMSSL_SM2_Z256_H
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <gmssl/sm3.h>
#ifdef __cplusplus
extern "C" {
#endif
void sm2_z256_copy(uint64_t r[4], const uint64_t a[4]);
void sm2_z256_copy_conditional(uint64_t dst[4], const uint64_t src[4], uint64_t move);
void sm2_z256_from_bytes(uint64_t r[4], const uint8_t in[32]);
void sm2_z256_to_bytes(const uint64_t a[4], uint8_t out[32]);
int sm2_z256_cmp(const uint64_t a[4], const uint64_t b[4]);
uint64_t sm2_z256_equ(const uint64_t a[4], const uint64_t b[4]);
uint64_t sm2_z256_add(uint64_t r[4], const uint64_t a[4], const uint64_t b[4]);
uint64_t sm2_z256_sub(uint64_t r[4], const uint64_t a[4], const uint64_t b[4]);
void sm2_z256_mul(uint64_t r[8], const uint64_t a[4], const uint64_t b[4]);
uint64_t sm2_z512_add(uint64_t r[8], const uint64_t a[8], const uint64_t b[8]);
int sm2_z256_get_booth(const uint64_t a[4], unsigned int window_size, int i);
void sm2_z256_from_hex(uint64_t r[4], const char *hex);
int sm2_z256_print(FILE *fp, int ind, int fmt, const char *label, const uint64_t a[4]);
int sm2_z512_print(FILE *fp, int ind, int fmt, const char *label, const uint64_t a[8]);
void sm2_z256_modp_add(uint64_t r[4], const uint64_t a[4], const uint64_t b[4]);
void sm2_z256_modp_sub(uint64_t r[4], const uint64_t a[4], const uint64_t b[4]);
void sm2_z256_modp_neg(uint64_t r[4], const uint64_t a[4]);
void sm2_z256_modp_mul_by_2(uint64_t r[4], const uint64_t a[4]);
void sm2_z256_modp_mul_by_3(uint64_t r[4], const uint64_t a[4]);
void sm2_z256_modp_div_by_2(uint64_t r[4], const uint64_t a[4]);
void sm2_z256_mont_mul(uint64_t r[4], const uint64_t a[4], const uint64_t b[4]);
void sm2_z256_mont_sqr(uint64_t r[4], const uint64_t a[4]);
void sm2_z256_mont_inv(uint64_t r[4], const uint64_t a[4]);
void sm2_z256_from_mont(uint64_t r[4], const uint64_t a[4]);
void sm2_z256_to_mont(const uint64_t a[4], uint64_t r[4]);
int sm2_z256_mont_print(FILE *fp, int ind, int fmt, const char *label, const uint64_t a[4]);
typedef struct {
uint64_t X[4];
uint64_t Y[4];
uint64_t Z[4];
} SM2_Z256_POINT;
void sm2_z256_point_dbl(SM2_Z256_POINT *R, const SM2_Z256_POINT *A);
void sm2_z256_point_add(SM2_Z256_POINT *r, const SM2_Z256_POINT *a, const SM2_Z256_POINT *b);
void sm2_z256_point_neg(SM2_Z256_POINT *R, const SM2_Z256_POINT *P);
void sm2_z256_point_sub(SM2_Z256_POINT *R, const SM2_Z256_POINT *A, const SM2_Z256_POINT *B);
void sm2_z256_point_get_affine(const SM2_Z256_POINT *P, uint64_t x[4], uint64_t y[4]);
int sm2_z256_point_print(FILE *fp, int fmt, int ind, const char *label, const SM2_Z256_POINT *P);
typedef struct {
uint64_t x[4];
uint64_t y[4];
} SM2_Z256_POINT_AFFINE;
void sm2_z256_point_copy_affine(SM2_Z256_POINT *R, const SM2_Z256_POINT_AFFINE *P);
void sm2_z256_point_add_affine(SM2_Z256_POINT *r, const SM2_Z256_POINT *a, const SM2_Z256_POINT_AFFINE *b);
void sm2_z256_point_sub_affine(SM2_Z256_POINT *R, const SM2_Z256_POINT *A, const SM2_Z256_POINT_AFFINE *B);
int sm2_z256_point_affine_print(FILE *fp, int fmt, int ind, const char *label, const SM2_Z256_POINT_AFFINE *P);
void sm2_z256_point_mul_generator(SM2_Z256_POINT *R, const uint64_t k[4]);
void sm2_z256_point_mul(SM2_Z256_POINT *R, const SM2_Z256_POINT *P, const uint64_t k[4]);
void sm2_z256_point_mul_sum(SM2_Z256_POINT *R, const uint64_t t[4], const SM2_Z256_POINT *P, const uint64_t s[4]);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -73,17 +73,28 @@ void sm4_ctr_encrypt(const SM4_KEY *key, uint8_t ctr[SM4_BLOCK_SIZE],
#define SM4_GCM_IV_MIN_SIZE 1
#define SM4_GCM_IV_MAX_SIZE ((uint64_t)(1 << (64-3)))
#define SM4_GCM_IV_MAX_SIZE (((uint64_t)1 << (64-3)) - 1) // 2305843009213693951
#define SM4_GCM_IV_DEFAULT_BITS 96
#define SM4_GCM_IV_DEFAULT_SIZE 12
//#define NIST_SP800_GCM_MAX_IV_SIZE (((uint64_t)1 << (64-3)) - 1) // 2305843009213693951
#define SM4_GCM_MAX_IV_SIZE 64
#define SM4_GCM_MIN_IV_SIZE 1
#define SM4_GCM_DEFAULT_IV_SIZE 12
#define SM4_GCM_MIN_AAD_SIZE 0
#define SM4_GCM_MAX_AAD_SIZE ((uint64_t)(1 << (64-3)))
#define SM4_GCM_MAX_AAD_SIZE (((uint64_t)1 << (64-3)) - 1) // 2305843009213693951
#define SM4_GCM_MIN_PLAINTEXT_SIZE 0
#define SM4_GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3)
#define SM4_GCM_MAX_PLAINTEXT_SIZE ((((uint64_t)1 << 39) - 256) >> 3) // 68719476704
#define SM4_GCM_MAX_TAG_SIZE 16
#define SM4_GCM_MIN_TAG_SIZE 12
// For certain applications (voice or video), tag may be 64 or 32 bits
// see NIST Special Publication 800-38D, Appendix C for more details
int sm4_gcm_encrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen,
const uint8_t *aad, size_t aadlen, const uint8_t *in, size_t inlen,

View File

@ -18,15 +18,10 @@
extern "C" {
#endif
/*
Version Public API
gmssl_version_num
gmssl_version_str
*/
// Also update CPACK_PACKAGE_VERSION in CMakeLists.txt
#define GMSSL_VERSION_NUM 30101
#define GMSSL_VERSION_STR "GmSSL 3.1.1 Dev"
#define GMSSL_VERSION_STR "GmSSL 3.1.1 PR1"
_gmssl_export int gmssl_version_num(void);
_gmssl_export const char *gmssl_version_str(void);

8
install_docker.sh Normal file
View File

@ -0,0 +1,8 @@
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do apt-get remove $pkg; done
apt update
apt install apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install docker-ce docker-ce-cli containerd.io

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
lib/linux/amd64/libgmssl.so.3.1 Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -15,6 +15,12 @@ import pickle
from fastapi.responses import JSONResponse
import asyncio
# 测试文本
test_msessgaes = {
"name": b"proxy re-encryption",
"environment": b"distributed environment"
}
@asynccontextmanager
async def lifespan(app: FastAPI):
@ -203,7 +209,8 @@ def check_merge(ct: int, ip: str):
temp_cfrag_cts = []
for i in cfrag_cts:
capsule = pickle.loads(i[0])
temp_cfrag_cts.append((capsule, int(i[1]).to_bytes(32)))
byte_length = (ct.bit_length() + 7) // 8
temp_cfrag_cts.append((capsule, int(i[1]).to_bytes(byte_length)))
cfrags = mergecfrag(temp_cfrag_cts)
@ -211,7 +218,7 @@ def check_merge(ct: int, ip: str):
print("pk:", type(pk))
print("pk_sender:", type(pk_sender))
print("cfrags:", type(cfrags))
message = DecryptFrags(sk, pk, pk_sender, cfrags)
message = DecryptFrags(sk, pk, pk_sender, cfrags) # type: ignore
print("merge success", message)
node_response = True
@ -359,8 +366,14 @@ async def receive_request(i_m: IP_Message):
# message name
# message_name = i_m.message_name
# message = xxxxx
# 根据message name到测试文本查找对应值
try:
message = test_msessgaes[i_m.message_name]
except:
message = b"hello world" + random.randbytes(8)
print(f"Generated message: {message}")
print(f"Message to be send: {message}")
# send message to nodes
await send_messages(tuple(node_ips), message, dest_ip, pk_B, threshold)

View File

@ -8,6 +8,7 @@ from tpre import *
import os
from typing import Any, Tuple
import base64
import logging
@asynccontextmanager
@ -25,6 +26,9 @@ client_ip_src = "" # 发送信息用户的ip
client_ip_des = "" # 接收信息用户的ip
processed_message = () # 重加密后的数据
logger = logging.getLogger("uvicorn")
# class C(BaseModel):
# Tuple: Tuple[capsule, int]
# ip_src: str
@ -32,10 +36,11 @@ processed_message = () # 重加密后的数据
# 向中心服务器发送自己的IP地址,并获取自己的id
def send_ip():
url = server_address + "/get_node?ip=" + ip
url = server_address + "/get_node?ip=" + ip # type: ignore
# ip = get_local_ip() # type: ignore
global id
id = requests.get(url, timeout=3)
logger.info(f"中心服务器返回节点ID为: {id}")
print("中心服务器返回节点ID为: ", id)
@ -54,11 +59,10 @@ def get_local_ip():
raise ValueError("Unable to get IP")
def init():
get_local_ip()
send_ip()
task = asyncio.create_task(send_heartbeat_internal())
asyncio.create_task(send_heartbeat_internal())
print("Finish init")
@ -72,15 +76,16 @@ def clear():
async def send_heartbeat_internal() -> None:
timeout = 30
global ip
url = server_address + "/heartbeat?ip=" + ip
url = server_address + "/heartbeat?ip=" + ip # type: ignore
while True:
# print('successful send my_heart')
try:
folderol = requests.get(url, timeout=3)
requests.get(url, timeout=3)
except:
logger.error("Central server error")
print("Central server error")
# 删除超时的节点(假设你有一个异步的数据库操作函数)
# 删除超时的节点
await asyncio.sleep(timeout)
@ -107,18 +112,29 @@ async def user_src(message: Req):
"rk": rk_list[i],
}
"""
logger.info(f"node: {message}")
print("node: ", message)
source_ip = message.source_ip
dest_ip = message.dest_ip
capsule = message.capsule
ct = message.ct
capsule_ct = (capsule, ct.to_bytes(32))
byte_length = (ct.bit_length() + 7) // 8
capsule_ct = (capsule, ct.to_bytes(byte_length))
rk = message.rk
logger.info(f"Computed capsule_ct: {capsule_ct}")
print(f"Computed capsule_ct: {capsule_ct}")
a, b = ReEncrypt(rk, capsule_ct)
a, b = ReEncrypt(rk, capsule_ct) # type: ignore
processed_message = (a, int.from_bytes(b))
logger.info(f"Re-encrypted message: {processed_message}")
print(f"Re-encrypted message: {processed_message}")
await send_user_des_message(source_ip, dest_ip, processed_message)
logger.info("Message sent to destination user.")
print("Message sent to destination user.")
return HTTPException(status_code=200, detail="message recieved")
@ -130,6 +146,8 @@ async def send_user_des_message(source_ip: str, dest_ip: str, re_message): #
response = requests.post(
"http://" + dest_ip + ":8002" + "/receive_messages", json=data
)
logger.info(f"send stauts: {response.text}")
print("send stauts:", response.text)

View File

@ -5,6 +5,7 @@ from contextlib import asynccontextmanager
import sqlite3
import asyncio
import time
import ipaddress
@asynccontextmanager
@ -16,11 +17,13 @@ async def lifespan(app: FastAPI):
app = FastAPI(lifespan=lifespan)
# 连接到数据库(如果数据库不存在,则会自动创建)
def init():
asyncio.create_task(receive_heartbeat_internal())
conn = sqlite3.connect("server.db")
# 创建游标对象用于执行SQL语句
cursor = conn.cursor()
# 创建表: id: int; ip: TEXT
# init table: id: int; ip: TEXT
cursor.execute(
"""CREATE TABLE IF NOT EXISTS nodes (
id INTEGER PRIMARY KEY AUTOINCREMENT,
@ -30,28 +33,36 @@ cursor.execute(
)
def init():
asyncio.create_task(receive_heartbeat_internal())
def clean_env():
clear_database()
# 关闭游标和连接
cursor.close()
conn.close()
@app.get("/")
async def home():
return {"message": "Hello, World!"}
@app.get("/server/show_nodes")
async def show_nodes() -> list:
nodes_list = []
with sqlite3.connect("server.db") as db:
# 查询数据
cursor.execute("SELECT * FROM nodes")
cursor = db.execute("SELECT * FROM nodes")
rows = cursor.fetchall()
for row in rows:
nodes_list.append(row)
return nodes_list
def validate_ip(ip: str) -> bool:
try:
ipaddress.ip_address(ip)
return True
except ValueError:
return False
@app.get("/server/get_node")
async def get_node(ip: str) -> int:
"""
@ -61,6 +72,10 @@ async def get_node(ip: str) -> int:
return:
id: ip按点分割成四部分, 每部分转二进制后拼接再转十进制作为节点id
"""
if not validate_ip(ip):
content = {"message": "invalid ip "}
return JSONResponse(content, status_code=400) # type: ignore
ip_parts = ip.split(".")
ip_int = 0
for i in range(4):
@ -71,12 +86,13 @@ async def get_node(ip: str) -> int:
current_time = int(time.time())
print("当前时间: ", current_time)
with sqlite3.connect("server.db") as db:
# 插入数据
cursor.execute(
db.execute(
"INSERT INTO nodes (id, ip, last_heartbeat) VALUES (?, ?, ?)",
(ip_int, ip, current_time),
)
conn.commit()
db.commit()
return ip_int
@ -89,13 +105,16 @@ async def delete_node(ip: str) -> None:
return:
None
"""
with sqlite3.connect("server.db") as db:
# 查询要删除的节点
cursor.execute("SELECT * FROM nodes WHERE ip=?", (ip,))
cursor = db.execute("SELECT * FROM nodes WHERE ip=?", (ip,))
row = cursor.fetchone()
if row is not None:
with sqlite3.connect("server.db") as db:
# 执行删除操作
cursor.execute("DELETE FROM nodes WHERE ip=?", (ip,))
conn.commit()
db.execute("DELETE FROM nodes WHERE ip=?", (ip,))
db.commit()
print(f"Node with IP {ip} deleted successfully.")
else:
print(f"Node with IP {ip} not found.")
@ -104,8 +123,12 @@ async def delete_node(ip: str) -> None:
# 接收节点心跳包
@app.get("/server/heartbeat")
async def receive_heartbeat(ip: str):
if not validate_ip(ip):
content = {"message": "invalid ip "}
return JSONResponse(content, status_code=400)
print("收到来自", ip, "的心跳包")
cursor.execute(
with sqlite3.connect("server.db") as db:
db.execute(
"UPDATE nodes SET last_heartbeat = ? WHERE ip = ?", (time.time(), ip)
)
return {"status": "received"}
@ -114,11 +137,12 @@ async def receive_heartbeat(ip: str):
async def receive_heartbeat_internal():
while 1:
timeout = 70
with sqlite3.connect("server.db") as db:
# 删除超时的节点
cursor.execute(
db.execute(
"DELETE FROM nodes WHERE last_heartbeat < ?", (time.time() - timeout,)
)
conn.commit()
db.commit()
await asyncio.sleep(timeout)
@ -133,9 +157,11 @@ async def send_nodes_list(count: int) -> list:
"""
nodes_list = []
with sqlite3.connect("server.db") as db:
# 查询数据库中的节点数据
cursor.execute("SELECT * FROM nodes LIMIT ?", (count,))
cursor = db.execute("SELECT * FROM nodes LIMIT ?", (count,))
rows = cursor.fetchall()
for row in rows:
id, ip, last_heartbeat = row
nodes_list.append(ip)
@ -147,8 +173,9 @@ async def send_nodes_list(count: int) -> list:
# @app.get("/server/clear_database")
def clear_database() -> None:
cursor.execute("DELETE FROM nodes")
conn.commit()
with sqlite3.connect("server.db") as db:
db.execute("DELETE FROM nodes")
db.commit()
if __name__ == "__main__":

14
src/setup.py Normal file
View File

@ -0,0 +1,14 @@
from setuptools import setup, Extension
# 定义您的扩展
ext = Extension(
"tpreECC",
sources=["tpreECC.c"],
)
setup(
name="tpreECC",
version="1.0",
description="basic ECC written in C",
ext_modules=[ext],
)

284
src/tpreECC.c Normal file
View File

@ -0,0 +1,284 @@
#include <Python.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
// define TPRE Big Number
typedef uint64_t TPRE_BN[8]
// GF(p)
typedef TPRE_BN SM2_Fp;
// GF(n)
typedef TPRE_BN SM2_Fn;
// 定义一个结构体来表示雅各比坐标系的点
typedef struct
{
TPRE_BN X;
TPRE_BN Y;
TPRE_BN Z;
} JACOBIAN_POINT;
// 定义一个结构体来表示点
typedef struct
{
uint8_t x[32];
uint8_t y[32];
} TPRE_POINT;
const TPRE_BN SM2_P = {
0xffffffff,
0xffffffff,
0x00000000,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xfffffffe,
};
const TPRE_BN SM2_A = {
0xfffffffc,
0xffffffff,
0x00000000,
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xfffffffe,
};
const TPRE_BN SM2_B = {
0x4d940e93,
0xddbcbd41,
0x15ab8f92,
0xf39789f5,
0xcf6509a7,
0x4d5a9e4b,
0x9d9f5e34,
0x28e9fa9e,
};
// 生成元GX, GY
const SM2_JACOBIAN_POINT _SM2_G = {
{
0x334c74c7,
0x715a4589,
0xf2660be1,
0x8fe30bbf,
0x6a39c994,
0x5f990446,
0x1f198119,
0x32c4ae2c,
},
{
0x2139f0a0,
0x02df32e5,
0xc62a4740,
0xd0a9877c,
0x6b692153,
0x59bdcee3,
0xf4f6779c,
0xbc3736a2,
},
{
1,
0,
0,
0,
0,
0,
0,
0,
},
};
const SM2_JACOBIAN_POINT *SM2_G = &_SM2_G;
const TPRE_BN SM2_N = {
0x39d54123,
0x53bbf409,
0x21c6052b,
0x7203df6b,
0xffffffff,
0xffffffff,
0xffffffff,
0xfffffffe,
};
// u = (p - 1)/4, u + 1 = (p + 1)/4
const TPRE_BN SM2_U_PLUS_ONE = {
0x00000000,
0x40000000,
0xc0000000,
0xffffffff,
0xffffffff,
0xffffffff,
0xbfffffff,
0x3fffffff,
};
const TPRE_BN SM2_ONE = {1, 0, 0, 0, 0, 0, 0, 0};
const TPRE_BN SM2_TWO = {2, 0, 0, 0, 0, 0, 0, 0};
const TPRE_BN SM2_THREE = {3, 0, 0, 0, 0, 0, 0, 0};
#define GETU32(p) \
((uint32_t)(p)[0] << 24 | \
(uint32_t)(p)[1] << 16 | \
(uint32_t)(p)[2] << 8 | \
(uint32_t)(p)[3])
// 点乘
static void multiply(TPRE_POINT r, const TPRE_POINT a, int64_t n)
{
Point result;
// ...实现乘法逻辑...
return result;
}
// 点加
static void add(TPRE_POINT *R, TPRE_POINT *P, TPRE_POINT *Q)
{
JACOBIAN_POINT P_;
JACOBIAN_POINT Q_;
jacobianPoint_from_bytes(&P_, (uint8_t *)P)
jacobianPoint_from_bytes(&Q_, (uint8_t *)Q)
jacobianPoint_add(&P_, &P_, &Q_);
jacobianPoint_to_bytes(&P_, (uint8_t *)R);
}
// 求逆
static void inv()
{
}
// jacobianPoint点加
static void jacobianPoint_add(JACOBIAN_POINT *R, const JACOBIAN_POINT *P, const JACOBIAN_POINT *Q)
{
const uint64_t *X1 = P->X;
const uint64_t *Y1 = P->Y;
const uint64_t *Z1 = P->Z;
const uint64_t *x2 = Q->X;
const uint64_t *y2 = Q->Y;
SM2_BN T1;
SM2_BN T2;
SM2_BN T3;
SM2_BN T4;
SM2_BN X3;
SM2_BN Y3;
SM2_BN Z3;
if (sm2_jacobian_point_is_at_infinity(Q))
{
sm2_jacobian_point_copy(R, P);
return;
}
if (sm2_jacobian_point_is_at_infinity(P))
{
sm2_jacobian_point_copy(R, Q);
return;
}
assert(sm2_bn_is_one(Q->Z));
sm2_fp_sqr(T1, Z1);
sm2_fp_mul(T2, T1, Z1);
sm2_fp_mul(T1, T1, x2);
sm2_fp_mul(T2, T2, y2);
sm2_fp_sub(T1, T1, X1);
sm2_fp_sub(T2, T2, Y1);
if (sm2_bn_is_zero(T1))
{
if (sm2_bn_is_zero(T2))
{
SM2_JACOBIAN_POINT _Q, *Q = &_Q;
sm2_jacobian_point_set_xy(Q, x2, y2);
sm2_jacobian_point_dbl(R, Q);
return;
}
else
{
sm2_jacobian_point_set_infinity(R);
return;
}
}
sm2_fp_mul(Z3, Z1, T1);
sm2_fp_sqr(T3, T1);
sm2_fp_mul(T4, T3, T1);
sm2_fp_mul(T3, T3, X1);
sm2_fp_dbl(T1, T3);
sm2_fp_sqr(X3, T2);
sm2_fp_sub(X3, X3, T1);
sm2_fp_sub(X3, X3, T4);
sm2_fp_sub(T3, T3, X3);
sm2_fp_mul(T3, T3, T2);
sm2_fp_mul(T4, T4, Y1);
sm2_fp_sub(Y3, T3, T4);
sm2_bn_copy(R->X, X3);
sm2_bn_copy(R->Y, Y3);
sm2_bn_copy(R->Z, Z3);
}
// bytes转jacobianPoint
static void jacobianPoint_from_bytes(JACOBIAN_POINT *P, const uint8_t in[64])
{
}
// jacobianPoint转bytes
static void jacobianPoint_to_bytes(JACOBIAN_POINT *P, const uint8_t in[64])
{
}
static void BN_from_bytes(TPRE_BN *r, const uint8_t in[32])
{
int i;
for (i = 7; i >= 0; i--)
{
r[i] = GETU32(in);
in += sizeof(uint32_t);
}
}
// 点乘的Python接口函数
static PyObject *py_multiply(PyObject *self, PyObject *args)
{
return
}
// 点加的Python接口函数
static PyObject *py_add(PyObject *self, PyObject *args)
{
return
}
// 求逆的Python接口函数
static PyObject *py_inv(PyObject *self, PyObject *args)
{
return
}
// 模块方法定义
static PyMethodDef MyMethods[] = {
{"multiply", py_multiply, METH_VARARGS, "Multiply a point on the sm2p256v1 curve"},
{"add", py_add, METH_VARARGS, "Add a point on thesm2p256v1 curve"},
{"inv", py_inv, METH_VARARGS, "Calculate an inv of a number"},
{NULL, NULL, 0, NULL} // 哨兵
};
// 模块定义
static struct PyModuleDef tpreECC = {
PyModuleDef_HEAD_INIT,
"tpreECC",
NULL, // 模块文档
-1,
MyMethods};
// 初始化模块
PyMODINIT_FUNC PyInit_tpre(void)
{
return PyModule_Create(&tpreECC);
}

View File

@ -11,11 +11,11 @@
- [x] 测试不同消息长度的时间
- 测试了10M文本的加密速度在1s内可以完成全部算法内容
- [ ] 测试极限1s时的节点数
- [x] 测试极限1s时的节点数
- 12th Gen i5 CPU大概是90多个节点时达到1s的时间上限
- [x] 非docker部署需要获取本机ip
- 添加了通过网卡获取ip的方法
- [ ] 复习预备知识
- [ ] 准备圆场话术
- [x] 复习预备知识
- [x] 准备圆场话术