密码学实验——国密SM3的实现

密码学实验——国密SM4的实现


随便写的答辩代码不要太较真

代码

IV = '7380166f4914b2b9172442d7da8a0600a96f30bc163138aae38dee4db0fb0e4e'


def pad(m):
    m += '8'  # 补1000
    lenth = len(m)
    k = 112 - (lenth % 128)
    m += '0' * k  # 补0000
    m += '{:016x}'.format(lenth*4-4)
    return m


def T_j(j):
    if j >= 0 and j <= 15:
        return '79cc4519'
    else:
        return '7a879d8a'

# 异或
def _xor(x, y):
    return '{:08x}'.format(int(x, 16) ^ int(y, 16))

# 与
def _and(x, y):
    return '{:08x}'.format(int(x, 16) & int(y, 16))

# 或
def _or(x, y):
    return '{:08x}'.format(int(x, 16) | int(y, 16))

# 非
def _non(x):
    return '{:08x}'.format(~(int(x, 16)) & 0xFFFFFFFF)

# 32位加法
def _add_32(x, y):
    return '{:08x}'.format((int(x, 16) + int(y, 16)) % (2 ** 32))

# 左循环移位
def L_shift(x, l):
    l %= 32
    x = '{:032b}'.format(int(x, 16))
    x = int(x[l:] + x[:l], 2)
    return '{:08x}'.format(x)

# 布尔函数
def FF_j(X, Y, Z, j):
    if j >= 0 and j <= 15:
        return _xor(_xor(X, Y), Z)
    else:
        return _or(_or(_and(X, Y), _and(X, Z)), _and(Y, Z))


def GG_j(X, Y, Z, j):
    if j >= 0 and j <= 15:
        return _xor(_xor(X, Y), Z)
    else:
        return _or(_and(X, Y), _and(_non(X), Z))

# 置换函数
def P0(X):
    return _xor(_xor(X, L_shift(X, 9)), L_shift(X, 17))


def P1(X):
    return _xor(_xor(X, L_shift(X, 15)), L_shift(X, 23))

# 消息扩展
def expand(B):
    W = ['0'] * 68
    W_0 = ['0'] * 64
    for i in range(16):
        W[i] = B[i * 8:i * 8 + 8]
    for j in range(16, 68):
        a = _xor(W[j - 16], W[j - 9])
        W_j_3 = L_shift(W[j - 3], 15)
        a = _xor(a, W_j_3)
        a = P1(a)
        W_j_13 = L_shift(W[j - 13], 7)
        a = _xor(a, W_j_13)
        a = _xor(a, W[j - 6])
        W[j] = a
    for j in range(64):
        W_0[j] = _xor(W[j], W[j+4])
    return W, W_0

# 压缩
def CF(V, B_):
    W, W_0 = expand(B_)
    A = V[0:8]
    B = V[8:16]
    C = V[16:24]
    D = V[24:32]
    E = V[32:40]
    F = V[40:48]
    G = V[48:56]
    H = V[56:64]
    for j in range(64):
        SS1 = _add_32(_add_32(L_shift(A, 12), E), L_shift(T_j(j), j))
        SS1 = L_shift(SS1, 7)
        SS2 = _xor(SS1, L_shift(A, 12))
        TT1 = _add_32(_add_32(FF_j(A, B, C, j), D), SS2)
        TT1 = _add_32(TT1, W_0[j])
        TT2 = _add_32(_add_32(GG_j(E, F, G, j), H), SS1)
        TT2 = _add_32(TT2, W[j])
        D = C
        C = L_shift(B, 9)
        B = A
        A = TT1
        H = G
        G = L_shift(F, 19)
        F = E
        E = P0(TT2)
    return _xor(V, A+B+C+D+E+F+G+H)

# 迭代
def SM3(m):
    m = pad(m)
    len_B = len(m) // 128
    B = [m[128 * i:128 * i + 128] for i in range(len_B)]
    V = [IV]
    for i in range(len_B):
        V.append(CF(V[i], B[i]))
    return V[-1]


m = input().encode().hex()
print(SM3(m))
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

sh4ngchen

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

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

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

打赏作者

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

抵扣说明:

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

余额充值