轻量级分组密码LBlock的Python实现

# S-boxes from Table 1
SBOXES = [
    [14, 9, 15, 0, 13, 4, 10, 11, 1, 2, 8, 3, 7, 6, 12, 5],  # s0
    [4, 11, 14, 9, 15, 13, 0, 10, 7, 12, 5, 6, 2, 8, 1, 3],  # s1
    [1, 14, 7, 12, 15, 13, 0, 6, 11, 5, 9, 3, 2, 4, 8, 10],  # s2
    [7, 6, 8, 11, 0, 15, 3, 14, 9, 10, 12, 13, 5, 2, 4, 1],  # s3
    [14, 5, 15, 0, 7, 2, 12, 13, 1, 8, 4, 9, 11, 10, 6, 3],  # s4
    [2, 13, 11, 12, 15, 14, 0, 9, 7, 10, 6, 3, 1, 8, 4, 5],  # s5
    [11, 9, 4, 14, 0, 15, 10, 13, 6, 12, 5, 7, 3, 8, 1, 2],  # s6
    [13, 10, 15, 0, 14, 4, 9, 11, 2, 1, 8, 3, 7, 5, 12, 6],  # s7
]

# s8 and s9 used in key schedule
SBOX_8 = [8, 7, 14, 5, 15, 13, 0, 6, 11, 12, 9, 10, 2, 4, 1, 3]
SBOX_9 = [11, 5, 15, 0, 7, 2, 9, 13, 4, 8, 1, 12, 14, 10, 3, 6]

def s_layer(input32: int) -> int:
    output = 0
    for i in range(8):
        nibble = (input32 >> (4 * (7 - i))) & 0xF
        output = (output << 4) | SBOXES[i][nibble]
    return output

def p_layer(input32: int) -> int:
    Z = [(input32 >> (4 * i)) & 0xF for i in reversed(range(8))]
    U = [0]*8
    U[7] = Z[6]; U[6] = Z[4]; U[5] = Z[7]; U[4] = Z[5]
    U[3] = Z[2]; U[2] = Z[0]; U[1] = Z[3]; U[0] = Z[1]
    output = 0
    for u in U:
        output = (output << 4) | u
    return output

def round_function(X: int, K: int) -> int:
    return p_layer(s_layer(X ^ K))

def rotate_left(val: int, rbits: int, width: int) -> int:
    return ((val << rbits) | (val >> (width - rbits))) & ((1 << width) - 1)

def key_schedule(master_key: int) -> List[int]:
    K = master_key
    round_keys = []
    for i in range(32):
        round_keys.append((K >> 48) & 0xFFFFFFFF)
        K = rotate_left(K, 29, 80)
        high4 = (K >> 76) & 0xF
        next4 = (K >> 72) & 0xF
        K &= ~(0xFFFF << 64)
        K |= (SBOX_9[high4] << 76) | (SBOX_8[next4] << 72)
        K ^= (i + 1) << 15  # i is 0-based
    return round_keys

def encrypt(plaintext: int, key: int) -> int:
    X = [(plaintext >> 32) & 0xFFFFFFFF, plaintext & 0xFFFFFFFF]
    keys = key_schedule(key)
    for i in range(32):
        Xi = round_function(X[1], keys[i]) ^ rotate_left(X[0], 8, 32)
        X[0], X[1] = X[1], Xi
    return (X[0] << 32) | X[1]

def decrypt(ciphertext: int, key: int) -> int:
    X = [(ciphertext >> 32) & 0xFFFFFFFF, ciphertext & 0xFFFFFFFF]
    keys = key_schedule(key)
    for i in reversed(range(32)):
        Xi = rotate_left(round_function(X[0], keys[i]) ^ X[1], 24, 32)
        X[1], X[0] = X[0], Xi
    return (X[0] << 32) | X[1]

# 示例输入
plaintext = 0x0123456789ABCDEF
key = 0x0123456789ABCDEFFEDC  # 80位密钥

cipher = encrypt(plaintext, key)
plain = decrypt(cipher, key)

print(f"密文: {cipher:016X}")
print(f"解密后: {plain:016X}")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Aurion_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值