Lab1 RSA算法实践
素数筛法
线性筛法,输出素数到 .dat 文件,素数个数回显。
#include <iostream>
#include <fstream>
#include <vector>
static const int NUM = int(1e6 + 1);
static bool isSieved[NUM] = {
false};
std::vector<int> prime;
void linear_sieve() {
isSieved[1] = true;
for (int curr = 2; curr < NUM; ++curr) {
if (!isSieved[curr]) prime.emplace_back(curr);
for (int multi = 0; multi < prime.size() && prime[multi] * curr < NUM; ++multi) {
isSieved[prime[multi] * curr] = true;
if (curr % prime[multi] == 0) break;
}
}
}
int main() {
linear_sieve();
std::cout << "The number of primes between 1 and 1e6 is: " << prime.size() << std::endl;
std::ofstream outfile("./prime_list.dat");
for (int i : prime) outfile << i << std::endl;
outfile.close();
return 0;
}
openssl
openssl genrsa -out rsa_2048_priv.pem 2048
openssl rsa -pubout -in rsa_2048_priv.pem -out rsa_2048_pub.pem
vim .\plaintext.txt
# write something
openssl pkeyutl -encrypt -inkey .\rsa_2048_pub.pem -pubin -in .\plaintext.txt -out .\ciphertext.txt
vim .\ciphertext.txt
openssl pkeyutl -decrypt -inkey .\rsa_2048_priv.pem -in .\ciphertext.txt -out .\plaintext2.txt
vim .\plaintext2.txt
factorize
.\yafu-x64 "factor(@)" -batchfile .\pcat.txt
pcat.txt 末尾须换行。
966808932627497190635859236054960349099463975227350564265384373280336699853387254070662881265937565163000758606154308757944030571837175048514574473061401566330836334647176655282619268592560172726526643074499534129878217409046045533656897050117438496357231575999185527675071002803951800635220029015932007465117818739948903750200830856115668691007706836952244842719419452946259275251773298338162389930518838272704908887016474007051397194588396039111216708866214614779627566959335170676055025850932631053641576566165694121420546081043285806783239296799795655191121966377590175780618944910532816988143056757054052679968538901460893571204904394975714081055455240523895653305315517745729334114549756695334171142876080477105070409544777981602152762154610738540163796164295222810243309051503090866674634440359226192530724635477051576515179864461174911975667162597286769079380660782647952944808596310476973939156187472076952935728249061137481887589103973591082872988641958270285169650803792395556363304056290077801453980822097583574309682935697260204862756923865556397686696854239564541407185709940107806536773160263764483443859425726953142964148216209968437587044617613518058779287167853349364533716458676066734216877566181514607693882375533
Lab2 AES侧信道攻击
环境配置
miniConda 实验环境已打包:cryptLab-conda-24.7.1.tar.gz,解压到 .\envs 目录下即可激活使用(存在部分问题,待更新)。
AES程序
补全主程序密钥,可选择为:
uint8_t key[] = {
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f
};
补全 AES.c 文件中加密函数实现:
// 轮密钥加启动
add_round_key(state, w, 0);
// 前9轮:字节代换,行位移,列混淆,轮密钥加
for (r = 1; r < Nr; r++) {
sub_bytes(state);
shift_rows(state);
mix_columns(state);
add_round_key(state, w, r);
}
// 最后一轮:字节代换,行位移,轮密钥加
sub_bytes(state);
shift_rows(state);
add_round_key(state, w, Nr);
补全 .ipynb 文件:
import serial
import numpy as np
# 根据实际情况更改串行接口
mega = serial.Serial('COM3', 115200, timeout=1)
def get_meta():
p = np.random.randint(0, 256, 16, dtype=np.uint8)
send = p.tobytes()
mega.write(send)
recv = mega.read(16)
c = np.frombuffer(recv, dtype=np.uint8)
# 关闭接口
mega.close()
return p, c
# 如显示不存在 Crypto module,删除 crypto 库及 pycryptodome 库,并重新安装 pycryptodome 库
from Crypto.Cipher import AES
# 与开发板密钥一致
key = bytes([0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f])
aes = AES.new(key,AES.MODE_ECB)
def verify(p, c):
c_correct = aes.encrypt(p.tobytes())
if c.tobytes() == c_correct:
return True
else:
return False
# 记录循环运行的性能和加密结果
import time
def verify_multiple_runs(num_runs):
results = []
for _ in range(num_runs):
start_time = time.time()
p, c = get_meta()
elapsed_time = time.time() - start_time
is_valid = verify(p, c)
results.append((p, c, is_valid, elapsed_time))
sleep(0.05)
return results
results_100 = verify_multiple_runs(100)
results_1000 = verify_multiple_runs(1000)
results_10000 = verify_multiple_runs(10000)
def save_results_to_file(results, filename='result.dat'):
with open(filename, 'w') as file:
for p, c, is_valid, elapsed_time in results:
file.write(f'p: {
p.tolist()}, c: {
c.tolist()}, valid: {
is_valid}, time: {
elapsed_time:.6f}\n')
save_results_to_file(results_100, 'result_100.dat')
save_results_to_file(results_1000, 'result_1000.dat')
save_results_to_file(results_10000, 'result_10000.dat')
轨迹采集
补全 .ipynb 文件:TOE 部分与上述一致;导出轨迹文件;补全引用库和相关参数。
import matplotlib.pyplot as plt
for i in tnrange(100):
plaintext = np.empty((pico.sequence_num, 10000), dtype=np.uint8)
ciphertext = np.empty((pico.sequence_num, 10000), dtype=np.uint8)
侧信道攻击
补全 .ipynb 文件:补全引用库;导入轨迹文件。
import matplotlib.pyplot as plt