经典密码学算法实现
# AES-128 加密算法的规范实现(不使用外部库)
# ECB模式S_BOX = [0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26,0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,0xB0, 0x54, 0xBB, 0x16
]RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36
]def sub_bytes(state):# 字节替代for i in range(4):for j in range(4):state[i][j] = S_BOX[state[i][j]]def shift_rows(state):# 行移位state[1] = state[1][1:] + state[1][:1]state[2] = state[2][2:] + state[2][:2]state[3] = state[3][3:] + state[3][:3]def xtime(a):# GF(2^8)乘法return ((a << 1) ^ 0x1B) & 0xFF if a & 0x80 else a << 1def mix_single_column(a):# 单列混合t = a[0] ^ a[1] ^ a[2] ^ a[3]u = a[0]a[0] ^= t ^ xtime(a[0] ^ a[1])a[1] ^= t ^ xtime(a[1] ^ a[2])a[2] ^= t ^ xtime(a[2] ^ a[3])a[3] ^= t ^ xtime(a[3] ^ u)def mix_columns(state):# 列混合for i in range(4):col = [state[row][i] for row in range(4)]mix_single_column(col)for row in range(4):state[row][i] = col[row]def add_round_key(state, round_key):# 密钥加for i in range(4):for j in range(4):state[i][j] ^= round_key[i][j]def key_expansion(key):# 密钥扩展expanded = [key[i:i+4] for i in range(0, 16, 4)]for i in range(4, 44):word = expanded[i-1][:]if i % 4 == 0:word = word[1:] + word[:1]word = [S_BOX[b] for b in word]word[0] ^= RCON[i//4]expanded.append([expanded[i-4][j] ^ word[j] for j in range(4)])return [expanded[4*i:4*(i+1)] for i in range(11)]def encrypt_block(plain, key_schedule):# 单个区块(16字节)AES加密state = [plain[i:i+4] for i in range(0, 16, 4)]add_round_key(state, key_schedule[0])for rnd in range(1, 10):sub_bytes(state)shift_rows(state)mix_columns(state)add_round_key(state, key_schedule[rnd])sub_bytes(state)shift_rows(state)add_round_key(state, key_schedule[10])return [byte for row in state for byte in row]def AES_encrypt(plaintext, key):# AES-128 ECB加密,plaintext和key为16字节assert len(plaintext) == 16 and len(key) == 16, "Plaintext and key must be 16 bytes."key_schedule = key_expansion(key)ciphertext = encrypt_block(plaintext, key_schedule)return ciphertext'''
AES 解密算法
'''
INV_S_BOX = [0x52,0x09,0x6A,0xD5,0x30,0x36,0xA5,0x38,0xBF,0x40,0xA3,0x9E,0x81,0xF3,0xD7,0xFB,0x7C,0xE3,0x39,0x82,0x9B,0x2F,0xFF,0x87,0x34,0x8E,0x43,0x44,0xC4,0xDE,0xE9,0xCB,0x54,0x7B,0x94,0x32,0xA6,0xC2,0x23,0x3D,0xEE,0x4C,0x95,0x0B,0x42,0xFA,0xC3,0x4E,0x08,0x2E,0xA1,0x66,0x28,0xD9,0x24,0xB2,0x76,0x5B,0xA2,0x49,0x6D,0x8B,0xD1,0x25,0x72,0xF8,0xF6,0x64,0x86,0x68,0x98,0x16,0xD4,0xA4,0x5C,0xCC,0x5D,0x65,0xB6,0x92,0x6C,0x70,0x48,0x50,0xFD,0xED,0xB9,0xDA,0x5E,0x15,0x46,0x57,0xA7,0x8D,0x9D,0x84,0x90,0xD8,0xAB,0x00,0x8C,0xBC,0xD3,0x0A,0xF7,0xE4,0x58,0x05,0xB8,0xB3,0x45,0x06,0xD0,0x2C,0x1E,0x8F,0xCA,0x3F,0x0F,0x02,0xC1,0xAF,0xBD,0x03,0x01,0x13,0x8A,0x6B,0x3A,0x91,0x11,0x41,0x4F,0x67,0xDC,0xEA,0x97,0xF2,0xCF,0xCE,0xF0,0xB4,0xE6,0x73,0x96,0xAC,0x74,0x22,0xE7,0xAD,0x35,0x85,0xE2,0xF9,0x37,0xE8,0x1C,0x75,0xDF,0x6E,0x47,0xF1,0x1A,0x71,0x1D,0x29,0xC5,0x89,0x6F,0xB7,0x62,0x0E,0xAA,0x18,0xBE,0x1B,0xFC,0x56,0x3E,0x4B,0xC6,0xD2,0x79,0x20,0x9A,0xDB,0xC0,0xFE,0x78,0xCD,0x5A,0xF4,0x1F,0xDD,0xA8,0x33,0x88,0x07,0xC7,0x31,0xB1,0x12,0x10,0x59,0x27,0x80,0xEC,0x5F,0x60,0x51,0x7F,0xA9,0x19,0xB5,0x4A,0x0D,0x2D,0xE5,0x7A,0x9F,0x93,0xC9,0x9C,0xEF,0xA0,0xE0,0x3B,0x4D,0xAE,0x2A,0xF5,0xB0,0xC8,0xEB,0xBB,0x3C,0x83,0x53,0x99,0x61,0x17,0x2B,0x04,0x7E,0xBA,0x77,0xD6,0x26,0xE1,0x69,0x14,0x63,0x55,0x21,0x0C,0x7D
]def inv_sub_bytes(state):for i in range(4):for j in range(4):state[i][j] = INV_S_BOX[state[i][j]]def inv_shift_rows(state):state[1] = state[1][-1:] + state[1][:-1]state[2] = state[2][-2:] + state[2][:-2]state[3] = state[3][-3:] + state[3][:-3]def inv_mix_single_column(a):u = xtime(xtime(a[0] ^ a[2]))v = xtime(xtime(a[1] ^ a[3]))a[0] ^= ua[1] ^= va[2] ^= ua[3] ^= vmix_single_column(a)def inv_mix_columns(state):for i in range(4):col = [state[row][i] for row in range(4)]inv_mix_single_column(col)for row in range(4):state[row][i] = col[row]def decrypt_block(cipher, key_schedule):state = [cipher[i:i+4] for i in range(0, 16, 4)]add_round_key(state, key_schedule[10])for rnd in range(9, 0, -1):inv_shift_rows(state)inv_sub_bytes(state)add_round_key(state, key_schedule[rnd])inv_mix_columns(state)inv_shift_rows(state)inv_sub_bytes(state)add_round_key(state, key_schedule[0])return [byte for row in state for byte in row]def AES_decrypt(ciphertext, key):key_schedule = key_expansion(key)plaintext = decrypt_block(ciphertext, key_schedule)return plaintext# 在你的完整AES加解密函数定义之后,添加如下代码进行测试:def main():# 原始明文(16字节)plaintext = [0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d,0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34]# 密钥(16字节)key = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c]# 加密ciphertext = AES_encrypt(plaintext, key)ciphertext_hex = ''.join('{:02x}'.format(b) for b in ciphertext)print('AES加密后的密文:', ciphertext_hex)# 解密decrypted_text = AES_decrypt(ciphertext, key)decrypted_hex = ''.join('{:02x}'.format(b) for b in decrypted_text)print('AES解密后的明文:', decrypted_hex)# 验证解密结果与原文是否一致if decrypted_text == plaintext:print(' 解密成功,明文与原始数据一致。')else:print(' 解密失败,明文与原始数据不一致。')if __name__ == '__main__':main()
# 标准DES实现(无任何外部库依赖)
# 完整实现DES算法,包括IP、IP逆置换、Feistel轮函数和密钥扩展
# 完全符合FIPS 46-3标准,代码规范、清晰易读IP = [58, 50, 42, 34, 26, 18, 10, 2,60, 52, 44, 36, 28, 20, 12, 4,62, 54, 46, 38, 30, 22, 14, 6,64, 56, 48, 40, 32, 24, 16, 8,57, 49, 41, 33, 25, 17, 9, 1,59, 51, 43, 35, 27, 19, 11, 3,61, 53, 45, 37, 29, 21, 13, 5,63, 55, 47, 39, 31, 23, 15, 7
]IP_INV = [40, 8, 48, 16, 56, 24, 64, 32,39, 7, 47, 15, 55, 23, 63, 31,38, 6, 46, 14, 54, 22, 62, 30,37, 5, 45, 13, 53, 21, 61, 29,36, 4, 44, 12, 52, 20, 60, 28,35, 3, 43, 11, 51, 19, 59, 27,34, 2, 42, 10, 50, 18, 58, 26,33, 1, 41, 9, 49, 17, 57, 25
]S_BOX = [# S1[[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7],[0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8],[4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0],[15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13],],# S2[[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10],[3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5],[0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15],[13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9],],# S3[[10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8],[13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1],[13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7],[1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12],],# S4[[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15],[13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9],[10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4],[3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14],],# S5[[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9],[14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6],[4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14],[11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3],],# S6[[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11],[10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8],[9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6],[4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13],],# S7[[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1],[13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6],[1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2],[6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12],],# S8[[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7],[1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2],[7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8],[2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11],]
]def permute(block, table):return [block[i-1] for i in table]def shift_left(key_half, shifts):return key_half[shifts:] + key_half[:shifts]def xor(bits1, bits2):return [b1 ^ b2 for b1, b2 in zip(bits1, bits2)]def sbox_substitution(block48):output = []for i in range(8):chunk = block48[i*6:(i+1)*6]row = (chunk[0] << 1) | chunk[5]col = (chunk[1] << 3) | (chunk[2] << 2) | (chunk[3] << 1) | chunk[4]val = S_BOX[i][row][col]bin_val = [int(b) for b in f'{val:04b}']output += bin_valreturn outputdef generate_subkeys(key64):# PC-1, PC-2为标准密钥置换表,C和D为分半后的密钥PC1 = [57, 49, 41, 33, 25, 17, 9,1, 58, 50, 42, 34, 26, 18,10, 2, 59, 51, 43, 35, 27,19, 11, 3, 60, 52, 44, 36,63, 55, 47, 39, 31, 23, 15,7, 62, 54, 46, 38, 30, 22,14, 6, 61, 53, 45, 37, 29,21, 13, 5, 28, 20, 12, 4]PC2 = [14, 17, 11, 24, 1, 5,3, 28, 15, 6, 21, 10,23, 19, 12, 4, 26, 8,16, 7, 27, 20, 13, 2,41, 52, 31, 37, 47, 55,30, 40, 51, 45, 33, 48,44, 49, 39, 56, 34, 53,46, 42, 50, 36, 29, 32]SHIFT_SCHEDULE = [1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1]key56 = permute(key64, PC1)C, D = key56[:28], key56[28:]subkeys = []for shift in SHIFT_SCHEDULE:C, D = shift_left(C, shift), shift_left(D, shift)subkey = permute(C + D, PC2)subkeys.append(subkey)return subkeysdef feistel(R, subkey):E = [32, 1, 2, 3, 4, 5,4, 5, 6, 7, 8, 9,8, 9, 10, 11, 12, 13,12, 13, 14, 15, 16, 17,16, 17, 18, 19, 20, 21,20, 21, 22, 23, 24, 25,24, 25, 26, 27, 28, 29,28, 29, 30, 31, 32, 1]P = [16, 7, 20, 21,29, 12, 28, 17,1, 15, 23, 26,5, 18, 31, 10,2, 8, 24, 14,32, 27, 3, 9,19, 13, 30, 6,22, 11, 4, 25]expanded_R = permute(R, E)xor_result = xor(expanded_R, subkey)substituted = sbox_substitution(xor_result)return permute(substituted, P)def DES_encrypt(plaintext64, key64):permuted_text = permute(plaintext64, IP)L, R = permuted_text[:32], permuted_text[32:]subkeys = generate_subkeys(key64)for i in range(16):temp_R = RR = xor(L, feistel(R, subkeys[i]))L = temp_Rpreoutput = permute(R + L, IP_INV) # 注意最后交换一次return preoutputdef DES_decrypt(ciphertext64, key64):"""与加密过程完全对称,子密钥倒序"""permuted = permute(ciphertext64, IP)L, R = permuted[:32], permuted[32:]# 子密钥倒序for subkey in reversed(generate_subkeys(key64)):temp_R = RR = xor(L, feistel(R, subkey)) # ⚠ 这里必须用旧的 RL = temp_R# 轮结束后再交换一次,顺序与加密保持一致return permute(R + L, IP_INV)# 辅助函数,将字符串转化为二进制位数组
def text_to_bits(text):return [int(bit) for char in text for bit in f'{ord(char):08b}']def bits_to_text(bits):chars = [chr(int(''.join(map(str, bits[i:i+8])), 2)) for i in range(0, len(bits), 8)]return ''.join(chars)# 3DES – EDE( Encrypt ▸ Decrypt ▸ Encrypt ) 实现
def triple_des_encrypt(block64, key1, key2, key3=None):"""3DES EDE 加密单个 64‑bit 块- key1, key2, key3: 各自为 64‑bit 位列表- 若未提供 key3,则自动回退为 2‑Key 3DES (K3 = K1)"""if key3 is None:key3 = key1 # 2‑Key 3DES: K1, K2, K1step1 = DES_encrypt(block64, key1) # 第 1 步:E_K1step2 = DES_decrypt(step1, key2) # 第 2 步:D_K2step3 = DES_encrypt(step2, key3) # 第 3 步:E_K3return step3def triple_des_decrypt(block64, key1, key2, key3=None):"""3DES EDE 解密单个 64‑bit 块顺序为 D_K3 ▸ E_K2 ▸ D_K1"""if key3 is None:key3 = key1 # 2‑Key 3DES 解密同理step1 = DES_decrypt(block64, key3) # D_K3step2 = DES_encrypt(step1, key2) # E_K2step3 = DES_decrypt(step2, key1) # D_K1return step3if __name__ == "__main__":# ------------ 测试数据 ------------plaintext = "ABCDEFGH" # 8 字节(64bit)明文k1_ascii = "12345678"k2_ascii = "23456789"k3_ascii = "34567890" # 换成 None 可测试 2‑Key 3DES# ---- ASCII 转位列表 ----def str_to_bits(s):return [int(b) for ch in s for b in f"{ord(ch):08b}"]def bits_to_hex(bits):return hex(int("".join(map(str, bits)), 2))[2:].upper().zfill(16)def bits_to_str(bits):return "".join(chr(int("".join(map(str, bits[i:i+8])), 2))for i in range(0, len(bits), 8))pt_bits = str_to_bits(plaintext)k1_bits, k2_bits, k3_bits = map(str_to_bits, (k1_ascii, k2_ascii, k3_ascii))# ------------ 3DES 加密 ------------ct_bits = triple_des_encrypt(pt_bits, k1_bits, k2_bits, k3_bits)# ------------ 3DES 解密 ------------pt_back_bits = triple_des_decrypt(ct_bits, k1_bits, k2_bits, k3_bits)# ------------ 输出结果 ------------print("密文 (Hex) :", bits_to_hex(ct_bits))print("解密后明文 :", bits_to_str(pt_back_bits))
from typing import ByteString# Pure Python implementation of the ChaCha20 stream cipher (RFC 8439)
# No third-party libraries used.def _rotl32(x: int, n: int) -> int:"""Rotate 32-bit integer x left by n bits."""return ((x << n) & 0xFFFFFFFF) | (x >> (32 - n))def _quarter_round(state: list[int], a: int, b: int, c: int, d: int) -> None:"""Perform the ChaCha20 quarter-round operation on the state.Mutates the state in place."""state[a] = (state[a] + state[b]) & 0xFFFFFFFFstate[d] ^= state[a]state[d] = _rotl32(state[d], 16)state[c] = (state[c] + state[d]) & 0xFFFFFFFFstate[b] ^= state[c]state[b] = _rotl32(state[b], 12)state[a] = (state[a] + state[b]) & 0xFFFFFFFFstate[d] ^= state[a]state[d] = _rotl32(state[d], 8)state[c] = (state[c] + state[d]) & 0xFFFFFFFFstate[b] ^= state[c]state[b] = _rotl32(state[b], 7)def _chacha20_block(key: ByteString, counter: int, nonce: ByteString) -> bytes:"""Generate a single 64-byte ChaCha20 block.:param key: 32-byte key:param counter: 32-bit block counter:param nonce: 12-byte nonce:return: 64-byte keystream block"""if len(key) != 32:raise ValueError("Key must be 32 bytes")if len(nonce) != 12:raise ValueError("Nonce must be 12 bytes")# Constants: "expand 32-byte k" in little-endian wordsconstants = [0x61707865, 0x3320646e, 0x79622d32, 0x6b206574]# Convert key into 8 little-endian 32-bit wordskey_words = [int.from_bytes(key[i:i+4], 'little') for i in range(0, 32, 4)]# Convert nonce into 3 little-endian 32-bit wordsnonce_words = [int.from_bytes(nonce[i:i+4], 'little') for i in range(0, 12, 4)]# Initial state: 16 wordsstate = (constants +key_words +[counter] +nonce_words)working_state = list(state)# 20 rounds: 10 iterations of two rounds eachfor _ in range(10):# Column rounds_quarter_round(working_state, 0, 4, 8, 12)_quarter_round(working_state, 1, 5, 9, 13)_quarter_round(working_state, 2, 6, 10, 14)_quarter_round(working_state, 3, 7, 11, 15)# Diagonal rounds_quarter_round(working_state, 0, 5, 10, 15)_quarter_round(working_state, 1, 6, 11, 12)_quarter_round(working_state, 2, 7, 8, 13)_quarter_round(working_state, 3, 4, 9, 14)# Add original state to working state and serializeblock = bytearray()for i in range(16):word = (working_state[i] + state[i]) & 0xFFFFFFFFblock += word.to_bytes(4, 'little')return bytes(block)def chacha20_encrypt(key: ByteString, nonce: ByteString, plaintext: ByteString, counter: int = 1) -> bytes:"""Encrypt or decrypt data using ChaCha20.Same function for encryption and decryption (XOR with keystream).:param key: 32-byte key:param nonce: 12-byte nonce:param plaintext: data to encrypt/decrypt:param counter: initial block counter (default 1):return: ciphertext/plaintext as bytes"""output = bytearray()block_count = (len(plaintext) + 63) // 64for block_index in range(block_count):block = _chacha20_block(key, counter + block_index, nonce)segment = plaintext[block_index*64:(block_index+1)*64]for i in range(len(segment)):output.append(segment[i] ^ block[i])return bytes(output)def main():# 256-bit(32 字节)密钥key = bytes.fromhex('000102030405060708090a0b0c0d0e0f''101112131415161718191a1b1c1d1e1f')# 96-bit(12 字节)随机数(Nonce)nonce = bytes.fromhex('000000090000004a00000000')# 待加密的明文plaintext = b"Hello, ChaCha20!"print("Plaintext:", plaintext)# 加密ciphertext = chacha20_encrypt(key, nonce, plaintext)print("Ciphertext (hex):", ciphertext.hex())# 解密(使用同样的 key 和 nonce)decrypted = chacha20_encrypt(key, nonce, ciphertext)print("Decrypted:", decrypted)# 验证解密结果assert decrypted == plaintext, "解密结果与明文不一致!"print(" 解密成功,明文一致。")if __name__ == "__main__":main()
# -*- coding: utf-8 -*-
"""
SM4 (GM4) 算法纯 Python 实现
标准来源:GM/T 0002-2012《分组密码算法 SM4 算法》​:contentReference[oaicite:2]{index=2}​:contentReference[oaicite:3]{index=3}
"""# 1. 基础参数定义# 1.1 S-盒
SBOX = [0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05,0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99,0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62,0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6,0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8,0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35,0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87,0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e,0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1,0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3,0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f,0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51,0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8,0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0,0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84,0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48
]# 1.2 系统参数 FK(32 位常量)
FK = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc]# 1.3 固定参数 CK(32 × 轮常量)
CK = [0x00070e15,0x1c232a31,0x383f464d,0x545b6269,0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,0xe0e7eeF5,0xfc030a11,0x181f262d,0x343b4249,0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,0x30373e45,0x4c535a61,0x686f767d,0x848b9299,0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,0x10171e25,0x2c333a41,0x484f565d,0x646b7279
]# 2. 辅助函数
def _rol(x, n):"""32 位循环左移"""return ((x << n) & 0xFFFFFFFF) | (x >> (32 - n))def _tau(a):"""非线性变换:对 32 位分 4×8 位,通过 SBOX 替代"""b = 0for i in range(4):byte = (a >> (24 - 8*i)) & 0xFFsb = SBOX[byte]b |= sb << (24 - 8*i)return bdef _L(b):"""线性变换 L"""return b ^ _rol(b, 2) ^ _rol(b,10) ^ _rol(b,18) ^ _rol(b,24)def _L_key(b):"""轮密钥线性变换 L'"""return b ^ _rol(b,13) ^ _rol(b,23)def _T(x):"""轮函数 T = L∘τ"""return _L(_tau(x))def _T_key(x):"""密钥扩展变换 T' = L'∘τ"""return _L_key(_tau(x))# 3. 轮密钥扩展
def _expand_key(MK):"""MK: 用户输入 128 位主密钥,4×32 位整数列表"""K = [MK[i] ^ FK[i] for i in range(4)]rk = []for i in range(32):tmp = K[i+1] ^ K[i+2] ^ K[i+3] ^ CK[i]K.append(K[i] ^ _T_key(tmp))rk.append(K[i+4])return rk# 4. 单块加密/解密def sm4_encrypt_block(plaintext, rk):"""plaintext: 128-bit 明文,4×32 位整数列表rk: 32 轮子密钥列表返回 4×32 位整数列表为密文"""X = plaintext.copy()for i in range(32):tmp = X[i] ^ _T(X[i+1] ^ X[i+2] ^ X[i+3] ^ rk[i])X.append(tmp)return [X[35], X[34], X[33], X[32]]def sm4_decrypt_block(ciphertext, rk):"""解密时轮密钥倒序"""X = ciphertext.copy()for i in range(32):tmp = X[i] ^ _T(X[i+1] ^ X[i+2] ^ X[i+3] ^ rk[31-i])X.append(tmp)return [X[35], X[34], X[33], X[32]]# 5. 示例测试if __name__ == "__main__":# 测试向量(NIST/GM/T 0002-2012 推荐)MK_hex = "0123456789abcdeffedcba9876543210"PT_hex = "0123456789abcdeffedcba9876543210"# 期望密文:681EDF34D206965E86B3E94F536E4246# 转 4×32 位整数def hex2u32s(h):h = h.replace(" ", "")v = int(h, 16)return [(v >> (96 - 32*i)) & 0xFFFFFFFF for i in range(4)]def u32s2hex(u32s):v = 0for w in u32s:v = (v << 32) | (w & 0xFFFFFFFF)return f"{v:032X}"MK = hex2u32s(MK_hex)PT = hex2u32s(PT_hex)rk = _expand_key(MK)CT = sm4_encrypt_block(PT, rk)PT_back = sm4_decrypt_block(CT, rk)print("密文 (hex):", u32s2hex(CT))print("解密后:", u32s2hex(PT_back))
相关文章:
经典密码学算法实现
# AES-128 加密算法的规范实现(不使用外部库) # ECB模式S_BOX [0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0x…...
git 远程仓库管理详解
Git 的远程仓库管理是多人协作和代码共享的核心功能。以下是 Git 远程仓库管理的详细说明,包括常用操作、命令和最佳实践。 1. 什么是远程仓库? 远程仓库(Remote Repository):存储在网络服务器上的 Git 仓库࿰…...
ABP vNext + gRPC 实现服务间高速通信
ABP vNext gRPC 实现服务间高速通信 💨 在现代微服务架构中,服务之间频繁的调用往往对性能构成挑战。尤其在电商秒杀、金融风控、实时监控等对响应延迟敏感的场景中,传统 REST API 面临序列化负担重、数据体积大、通信延迟高等瓶颈。 本文…...

若依框架Ruoyi-vue整合图表Echarts中国地图标注动态数据
若依框架Ruoyi-vue整合图表Echarts中国地图 概述创作灵感预期效果整合教程前期准备整合若依框架1、引入china.json2、方法3、data演示数据4、核心代码 完整代码[毫无保留]组件调用 总结 概述 首先,我需要回忆之前给出的回答,确保这次的内容不重复&#…...
京东(JD)API 商品详情数据接口讲解及 JSON 示例
前言 京东开放平台提供了多种商品详情相关的 API 接口,开发者可以通过这些接口获取商品的详细信息。以下为接口调用方式及 JSON 返回数据的参考示例。 1. 接口调用方式 京东商品详情接口通常采用以下形式: 请求方式:GET/POST关键参数&…...

算法中的数学:约数
1.求一个整数的所有约数 对于一个整数x,他的其中一个约数若为i,那么x/i也是x的一个约数。而其中一个约数的大小一定小于等于根号x(完全平方数则两个约数都为根号x),所以我们只需要遍历到根号x,然后计算出另…...
Python实例题:Python获取喜马拉雅音频
目录 Python实例题 题目 python-get-ximalaya-audioPython 获取喜马拉雅音频脚本 代码解释 get_audio_info 函数: download_audio 函数: 主程序: 运行思路 注意事项 Python实例题 题目 Python获取喜马拉雅音频 python-get-ximala…...

[监控看板]Grafana+Prometheus+Exporter监控疑难排查
采用GrafanaPrometheusExporter监控MySQL时发现经常数据不即时同步,本示例也是本地搭建采用。 Prometheus面板 1,Detected a time difference of 11h 47m 22.337s between your browser and the server. You may see unexpected time-shifted query res…...

LaTeX印刷体 字符与数学符号的总结
1. 希腊字母(Greek Letters) 名称小写 LaTeX大写 LaTeX显示效果Alpha\alphaAαα, AABeta\betaBββ, BBGamma\gamma\Gammaγγ, ΓΓDelta\delta\Deltaδδ, ΔΔTheta\theta\Thetaθθ, ΘΘPi\pi\Piππ, ΠΠSigma\sigma\Sigmaσσ, ΣΣOmega\omeg…...

剥开 MP4 的 千层 “数字洋葱”:从外到内拆解通用媒体容器的核心
在当今数字化时代,MP4 格式随处可见,无论是在线视频、手机拍摄的短片,还是从各种渠道获取的音频视频文件,MP4 都占据着主流地位。它就像一个万能的 “数字媒体集装箱”,高效地整合和传输着各种视听内容。接下来&#x…...
深度解析语义分割评估指标:从基础到创新实践
一、为什么需要专业评估指标? 在医疗影像分析中,一个3mm的肿瘤漏检可能导致误诊;在自动驾驶场景下,5%的边界识别误差可能引发严重事故。这些真实案例揭示了语义分割评估指标的关键作用。本章将带您深入理解指标背后的数学原理与实践价值。 --- ## 二、基础指标全解析 #…...
浅谈 Shell 脚本编程中引号的妙用
在 Shell 脚本编程中,引号的使用是一项基础却至关重要的技能。无论是单引号、双引号还是不加引号,它们都会显著影响 Shell 对字符串、变量、特殊字符以及命令的解析方式。理解这些差异不仅能帮助开发者编写更健壮的脚本,还能避免因误解引发的…...

从彼得·蒂尔四象限看 Crypto「情绪变迁」:从密码朋克转向「标准化追求者」
作者:Techub 精选编译 撰文:Matti,Zee Prime Capital 编译:Yangz,Techub News 我又带着一篇受彼得蒂尔(Peter Thiel)启发的思想杂烩回来了。作为自封的「蒂尔学派」信徒,我常透过他…...

Java线程安全问题深度解析与解决方案
一、线程安全问题的本质 并发编程的核心挑战:当多个线程同时访问共享资源时,由于操作系统的抢占式调度特性,可能导致不可预期的结果。这种因非原子操作和竞态条件引发的数据不一致问题,称为线程安全问题。 二、经典线程安全问题案…...

Mybatis解决以某个字段存在,批量更新,不存在批量插入(高效)(一)
背景 在开发企业级应用时,我们经常需要处理批量数据的插入和更新操作。传统的逐条处理方式性能低下,而简单的REPLACE INTO或INSERT ... ON DUPLICATE KEY UPDATE在某些场景下又不够灵活。本文将介绍一种基于临时表的高效批量插入/更新方案,解…...
高效C/C++之九:Coverity修复问题:关于数组操作 和 内存操作
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 高效C/C之九:Coverity修复问题:关于数组操作 和 内存操作 目录 【关注我,后…...

【时时三省】(C语言基础)怎样定义和引用二维数组
山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 有的问题需要用二维数组来处理。例如,有3个小分队,每队有6名队员,要把这些队员的工资用数组保存起来以备查。这就需要用到二维数组,如下图&…...
Ubuntu上安装MySQL 8并配置Navicat远程连接
1. 安装MySQL 8 sudo apt update sudo apt install mysql-server -y2. 启动MySQL服务 sudo systemctl start mysql sudo systemctl enable mysql3. 设置root密码 3.1 登录MySQL(默认无密码): sudo mysql3.2 修改root认证方式并设置密码&a…...

杨校老师竞赛课之C++备战蓝桥杯初级组省赛
目录 1. 灯塔 题目描述 输入描述 输出描述 输入样例1 输出样例1 输入样例2 输出样例2 数据说明 2. 子区间 题目描述 输入描述 输出描述 输入样例 输出样例 数据说明 3. 染色 题目描述 输入描述 输出描述 输入样例1 输出样例1 输入样例2 输出样例2 数据…...

Matlab 基于Hough变换的人眼虹膜定位方法
1、内容简介 Matlab220-基于Hough变换的人眼虹膜定位方法 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略...

vfrom表单设计器使用事件机制控制字段显示隐藏
1. 使用表单设计器进行debug调试 依据 vform3.0开发者文档 https://www.ganweicloud.com/docs/6.1.0/pages/d3e6d9/ 对switch组件设置事件逻辑 调试中...

【Redis篇】linux 7.6安装单机Redis7.0(参数优化详解)
💫《博主主页》: 🔎 CSDN主页 🔎 IF Club社区主页 🔥《擅长领域》:擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(MongoDB)有了…...

信号的概念及产生
信号的概念 信号(signal)是一种软件中断机制,用于通知进程发生了特定的事件。信号可以由系统、其他进程或进程自身发送。 在现实生活中,也有许多的信号,比如说:红绿灯、闹钟、上课铃、父母喊你回家吃饭等等…...

巧用python之--模仿PLC(PLC模拟器)
工作中用到了VM(VisionMaster4.3)有时候需要和PLC打交道,但是PLC毕竟是别人的,不方便修改别人的程序,这时候需要一个灵活的PLC模拟器是多么好呀! 先说背景: PLC型号 汇川Easy521: Modbus TCP 192.168.1.10:502 在汇川Easy521中Modbus保持寄存器D寄存器 ,在modbus协议中 0-4区…...

【计算机网络】用户从输入网址到网页显示,期间发生了什么?
1.URL解析 浏览器分解URL:https://www.example.com/page 协议:https域名:www.example.com路径:/page 2.DNS查询: 浏览器向DNS服务器发送查询请求,将域名解析为对应的IP地址。 3.CDN检查(如果有)&#…...
【计算机哲学故事1-3】默认设置:在有限的系统里,决定你想成为什么
她盯着屏幕上熟悉的蓝色窗户,语气里透着一丝无奈:“我发现,不管买多少次新电脑,开机那一刻,看到的永远是同一张桌面。” 我坐在她旁边,看着那台刚装好的电脑,笑了笑:“所以你在感慨…...
【嵌入式开发-UART】
嵌入式开发-UART ■ UART简介 ■ UART简介...

C++ 算法学习之旅:从入门到精通的秘籍
在编程的浩瀚宇宙中,C 算法宛如璀璨的星辰,照亮我们前行的道路。作为一名 C 算法小白,或许你和我一样,怀揣着对算法的好奇与憧憬,却又在学习的道路上感到迷茫。别担心,今天我就和大家分享一下如何学习各种基…...

计算机网络常识:缓存、长短连接 网络初探、URL、客户端与服务端、域名操作 tcp 三次握手 四次挥手
缓存: 缓存是对cpu,内存的一个节约:节约的是网络带宽资源 节约服务器的性能 资源的每次下载和请求都会造成服务器的一个压力 减少网络对资源拉取的延迟 这个就是浏览器缓存的一个好处 表示这个html页面的返回是不要缓存的 忽略缓存 需要每次…...

软件逆向工程核心技术:脱壳原理与实战分析
目录 一、脱壳技术概述:从保护到还原的逆向之旅 1.1 脱壳技术的本质与核心价值 1.2 壳的分类与核心技术解析 1.3 学习路径:从压缩壳到加密壳的渐进式突破 二、脱壳三步法:系统化逆向工程框架 2.1 核心流程总览 2.2 实战案例࿱…...