diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml index ab65a10..a255c71 100644 --- a/.gitea/workflows/ci.yaml +++ b/.gitea/workflows/ci.yaml @@ -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 diff --git a/.gitignore b/.gitignore index ed0d000..7e9fb11 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/FQA.md b/FQA.md new file mode 100644 index 0000000..54e36c2 --- /dev/null +++ b/FQA.md @@ -0,0 +1,61 @@ +# 答辩问题准备 + +1. **Q:数据安全与隐私**:您的系统在分布式环境中如何确保数据安全和隐私,尤其是在密钥管理方面的挑战? + + **A:** 通过代理服务器来转换密文,使其从一个密钥加密变为另一个密钥加密,而不需要将密文解密为明文;客户端每次启动时会生成新的公私密钥对,在随后的通信中,随机选取一次性对称密钥。 + +2. **Q:国家安全标准的遵循**:您能详细说明您的系统如何符合中国的国家安全标准,特别是对于政府和金融等敏感领域? + + **A:** 使用国产的SM算法,减小对外国算法的依赖,增强自主控制的能力,可以有效防止潜在的后门和安全漏洞。 + +3. **Q:系统架构**:您的分布式架构如何提高系统的性能和可伸缩性? + + **A:** 性能方面,我们采用了门限方案,在解密时不需要接收所有的密文片段;密文重加密和解密使用对称密钥,加快加解密速度。可以认为每次都可以"挑选"较高性能的节点进行计算。可伸缩性方面,动态进行节点的添加与退出,客户端也可以动态更新节点。 + +4. **Q:算法效率**:您能讨论一下您系统中使用的门限代理重加密技术的效率和计算要求吗? + + **A:** 性能开销最大的是重加密密钥的生成和解密,其余步骤开销极小;计算要求:64位CPU,512MB内存,可以运行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:** diff --git a/README_en.md b/README_en.md index 4fe5589..9cbef6d 100644 --- a/README_en.md +++ b/README_en.md @@ -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 diff --git a/doc/README_app_en.md b/doc/README_app_en.md index 42750ac..5daef6c 100644 --- a/doc/README_app_en.md +++ b/doc/README_app_en.md @@ -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 diff --git a/include/gmssl/aead.h b/include/gmssl/aead.h index 01f0ddf..1bc13b5 100644 --- a/include/gmssl/aead.h +++ b/include/gmssl/aead.h @@ -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, diff --git a/include/gmssl/api.h b/include/gmssl/api.h index d6f0d23..d8fd184 100644 --- a/include/gmssl/api.h +++ b/include/gmssl/api.h @@ -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 diff --git a/include/gmssl/rand.h b/include/gmssl/rand.h index 2f433e4..86f5b05 100644 --- a/include/gmssl/rand.h +++ b/include/gmssl/rand.h @@ -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); diff --git a/include/gmssl/sm2_z256.h b/include/gmssl/sm2_z256.h deleted file mode 100644 index 7c928f0..0000000 --- a/include/gmssl/sm2_z256.h +++ /dev/null @@ -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 -#include -#include -#include - -#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 diff --git a/include/gmssl/sm4.h b/include/gmssl/sm4.h index d8a4b11..d4c4678 100644 --- a/include/gmssl/sm4.h +++ b/include/gmssl/sm4.h @@ -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, diff --git a/include/gmssl/version.h b/include/gmssl/version.h index 8eb3708..71ac63b 100644 --- a/include/gmssl/version.h +++ b/include/gmssl/version.h @@ -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); diff --git a/install_docker.sh b/install_docker.sh new file mode 100644 index 0000000..3a1eb85 --- /dev/null +++ b/install_docker.sh @@ -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 diff --git a/lib/linux/amd64/libgmssl.so b/lib/linux/amd64/libgmssl.so index 1692451..77d83a0 100755 Binary files a/lib/linux/amd64/libgmssl.so and b/lib/linux/amd64/libgmssl.so differ diff --git a/lib/linux/amd64/libgmssl.so.3 b/lib/linux/amd64/libgmssl.so.3 index 1692451..77d83a0 100755 Binary files a/lib/linux/amd64/libgmssl.so.3 and b/lib/linux/amd64/libgmssl.so.3 differ diff --git a/lib/linux/amd64/libgmssl.so.3.0 b/lib/linux/amd64/libgmssl.so.3.0 deleted file mode 100755 index 1692451..0000000 Binary files a/lib/linux/amd64/libgmssl.so.3.0 and /dev/null differ diff --git a/lib/linux/amd64/libgmssl.so.3.1 b/lib/linux/amd64/libgmssl.so.3.1 new file mode 100755 index 0000000..77d83a0 Binary files /dev/null and b/lib/linux/amd64/libgmssl.so.3.1 differ diff --git a/lib/linux/amd64/libsdf_dummy.so.3.0 b/lib/linux/amd64/libsdf_dummy.so.3.1 similarity index 100% rename from lib/linux/amd64/libsdf_dummy.so.3.0 rename to lib/linux/amd64/libsdf_dummy.so.3.1 diff --git a/lib/linux/amd64/libskf_dummy.so.3.0 b/lib/linux/amd64/libskf_dummy.so.3.1 similarity index 100% rename from lib/linux/amd64/libskf_dummy.so.3.0 rename to lib/linux/amd64/libskf_dummy.so.3.1 diff --git a/lib/linux/arm64/libgmssl.so b/lib/linux/arm64/libgmssl.so index b394b2a..64eddf8 100755 Binary files a/lib/linux/arm64/libgmssl.so and b/lib/linux/arm64/libgmssl.so differ diff --git a/lib/linux/arm64/libgmssl.so.3 b/lib/linux/arm64/libgmssl.so.3 index b394b2a..64eddf8 100755 Binary files a/lib/linux/arm64/libgmssl.so.3 and b/lib/linux/arm64/libgmssl.so.3 differ diff --git a/lib/linux/arm64/libgmssl.so.3.1 b/lib/linux/arm64/libgmssl.so.3.1 index b394b2a..64eddf8 100755 Binary files a/lib/linux/arm64/libgmssl.so.3.1 and b/lib/linux/arm64/libgmssl.so.3.1 differ diff --git a/lib/linux/arm64/libsdf_dummy.so b/lib/linux/arm64/libsdf_dummy.so index 880afaf..1d88467 100755 Binary files a/lib/linux/arm64/libsdf_dummy.so and b/lib/linux/arm64/libsdf_dummy.so differ diff --git a/lib/linux/arm64/libsdf_dummy.so.3 b/lib/linux/arm64/libsdf_dummy.so.3 index 880afaf..1d88467 100755 Binary files a/lib/linux/arm64/libsdf_dummy.so.3 and b/lib/linux/arm64/libsdf_dummy.so.3 differ diff --git a/lib/linux/arm64/libsdf_dummy.so.3.1 b/lib/linux/arm64/libsdf_dummy.so.3.1 index 880afaf..1d88467 100755 Binary files a/lib/linux/arm64/libsdf_dummy.so.3.1 and b/lib/linux/arm64/libsdf_dummy.so.3.1 differ diff --git a/lib/linux/arm64/libskf_dummy.so b/lib/linux/arm64/libskf_dummy.so index d57e26d..40b1e0e 100755 Binary files a/lib/linux/arm64/libskf_dummy.so and b/lib/linux/arm64/libskf_dummy.so differ diff --git a/lib/linux/arm64/libskf_dummy.so.3 b/lib/linux/arm64/libskf_dummy.so.3 index d57e26d..40b1e0e 100755 Binary files a/lib/linux/arm64/libskf_dummy.so.3 and b/lib/linux/arm64/libskf_dummy.so.3 differ diff --git a/lib/linux/arm64/libskf_dummy.so.3.1 b/lib/linux/arm64/libskf_dummy.so.3.1 index d57e26d..40b1e0e 100755 Binary files a/lib/linux/arm64/libskf_dummy.so.3.1 and b/lib/linux/arm64/libskf_dummy.so.3.1 differ diff --git a/src/client.py b/src/client.py index 2f0e8c9..9a1f16c 100644 --- a/src/client.py +++ b/src/client.py @@ -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 = b"hello world" + random.randbytes(8) - print(f"Generated message: {message}") + + # 根据message name到测试文本查找对应值 + try: + message = test_msessgaes[i_m.message_name] + + except: + message = b"hello world" + random.randbytes(8) + print(f"Message to be send: {message}") # send message to nodes await send_messages(tuple(node_ips), message, dest_ip, pk_B, threshold) diff --git a/src/node.py b/src/node.py index ce1ca21..199e7f0 100644 --- a/src/node.py +++ b/src/node.py @@ -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) @@ -52,13 +57,12 @@ def get_local_ip(): s.close() except: 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) diff --git a/src/server.py b/src/server.py index 3e66739..429f282 100644 --- a/src/server.py +++ b/src/server.py @@ -5,6 +5,7 @@ from contextlib import asynccontextmanager import sqlite3 import asyncio import time +import ipaddress @asynccontextmanager @@ -16,51 +17,65 @@ async def lifespan(app: FastAPI): app = FastAPI(lifespan=lifespan) -# 连接到数据库(如果数据库不存在,则会自动创建) -conn = sqlite3.connect("server.db") -# 创建游标对象,用于执行SQL语句 -cursor = conn.cursor() -# 创建表: id: int; ip: TEXT -cursor.execute( - """CREATE TABLE IF NOT EXISTS nodes ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - ip TEXT NOT NULL, - last_heartbeat INTEGER - )""" -) - def init(): asyncio.create_task(receive_heartbeat_internal()) + conn = sqlite3.connect("server.db") + cursor = conn.cursor() + # init table: id: int; ip: TEXT + cursor.execute( + """CREATE TABLE IF NOT EXISTS nodes ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + ip TEXT NOT NULL, + last_heartbeat INTEGER + )""" + ) + 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 = [] - # 查询数据 - cursor.execute("SELECT * FROM nodes") - rows = cursor.fetchall() + with sqlite3.connect("server.db") as db: + # 查询数据 + 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: """ - 中心服务器与节点交互, 节点发送ip, 中心服务器接收ip存入数据库并将ip转换为int作为节点id返回给节点 - params: - ip: node ip - return: - id: ip按点分割成四部分, 每部分转二进制后拼接再转十进制作为节点id + 中心服务器与节点交互, 节点发送ip, 中心服务器接收ip存入数据库并将ip转换为int作为节点id返回给节点 + params: + ip: node ip + 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) - # 插入数据 - cursor.execute( - "INSERT INTO nodes (id, ip, last_heartbeat) VALUES (?, ?, ?)", - (ip_int, ip, current_time), - ) - conn.commit() + with sqlite3.connect("server.db") as db: + # 插入数据 + db.execute( + "INSERT INTO nodes (id, ip, last_heartbeat) VALUES (?, ?, ?)", + (ip_int, ip, current_time), + ) + db.commit() return ip_int @@ -84,18 +100,21 @@ async def get_node(ip: str) -> int: @app.get("/server/delete_node") async def delete_node(ip: str) -> None: """ - param: - ip: 待删除节点的ip地址 - return: - None + param: + ip: 待删除节点的ip地址 + return: + None """ - # 查询要删除的节点 - cursor.execute("SELECT * FROM nodes WHERE ip=?", (ip,)) - row = cursor.fetchone() + + with sqlite3.connect("server.db") as db: + # 查询要删除的节点 + cursor = db.execute("SELECT * FROM nodes WHERE ip=?", (ip,)) + row = cursor.fetchone() if row is not None: - # 执行删除操作 - cursor.execute("DELETE FROM nodes WHERE ip=?", (ip,)) - conn.commit() + with sqlite3.connect("server.db") as db: + # 执行删除操作 + 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,21 +123,26 @@ 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( - "UPDATE nodes SET last_heartbeat = ? WHERE ip = ?", (time.time(), ip) - ) + with sqlite3.connect("server.db") as db: + db.execute( + "UPDATE nodes SET last_heartbeat = ? WHERE ip = ?", (time.time(), ip) + ) return {"status": "received"} async def receive_heartbeat_internal(): while 1: timeout = 70 - # 删除超时的节点 - cursor.execute( - "DELETE FROM nodes WHERE last_heartbeat < ?", (time.time() - timeout,) - ) - conn.commit() + with sqlite3.connect("server.db") as db: + # 删除超时的节点 + db.execute( + "DELETE FROM nodes WHERE last_heartbeat < ?", (time.time() - timeout,) + ) + db.commit() await asyncio.sleep(timeout) @@ -133,9 +157,11 @@ async def send_nodes_list(count: int) -> list: """ nodes_list = [] - # 查询数据库中的节点数据 - cursor.execute("SELECT * FROM nodes LIMIT ?", (count,)) - rows = cursor.fetchall() + with sqlite3.connect("server.db") as db: + # 查询数据库中的节点数据 + 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__": diff --git a/src/setup.py b/src/setup.py new file mode 100644 index 0000000..923b470 --- /dev/null +++ b/src/setup.py @@ -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], +) diff --git a/src/tpreECC.c b/src/tpreECC.c new file mode 100644 index 0000000..d634832 --- /dev/null +++ b/src/tpreECC.c @@ -0,0 +1,284 @@ +#include +#include +#include +#include + +// 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); +} diff --git a/todolist.md b/todo.md similarity index 87% rename from todolist.md rename to todo.md index 34dde87..6560874 100644 --- a/todolist.md +++ b/todo.md @@ -11,11 +11,11 @@ - [x] 测试不同消息长度的时间 - 测试了10M文本的加密速度,在1s内可以完成全部算法内容 -- [ ] 测试极限(1s)时的节点数 +- [x] 测试极限(1s)时的节点数 - 12th Gen i5 CPU大概是90多个节点时达到1s的时间上限 - [x] 非docker部署需要获取本机ip - 添加了通过网卡获取ip的方法 -- [ ] 复习预备知识 -- [ ] 准备圆场话术 +- [x] 复习预备知识 +- [x] 准备圆场话术