ZUC祖冲之序列密码算法

ZUC祖冲之序列密码算法

Rust实现;


ZUC算法概要

ZUC主要由LFSR线性反馈移位寄存器, BR比特重组和F非线性函数三部分组成;

  • 输入: 128位长的密钥, 128位长的初始化向量;
  • 输出: \(n, n \in N^+\)个32位长的字串, \(n\)为节拍数(轮数);
  • 算法过程ZUC(KEY, IV, n):
    • 初始化阶段:
      • for i in 0..32:
        -BitReconstruction();
        • W = F(X_0, X_1, X_2);
        • LFSRWithInitializationMode(W >> 1);
    • 工作阶段:
      • BitReconstruction();
      • F(X_0, X_1, X_2);
      • LFSRWithWorkMode();
      • for i in 0..n:
        • BitReconstruction();
        • z_i = F(X_0, X_1, X_2) ^ X_3;
        • LFSRWithWorkMode();
      • \(z_0||z_1||z_2||z_3\);

LFSR线性反馈移位寄存器

  • \(s_0, s_1, \dots, s_{15}\)为LFSR的16个31位长的寄存器(涉及到s寄存器的是按31位处理的, 注意不是32位, 如循环移位是不同的);

LFSR初始化模式

  • LFSRWithInitilizationMode(u):
    • \(v=2^{15} s_{15} + 2^{17} s_{13} + 2^{21}s_{10} + 2^{20}s_{4}+(1+2^8)s_0 \mod (2^{31}-1)\);
    • \(s_{16} = (v + u)\mod (2^{31} - 1)\);
    • if \(s_{16} = 0\):
      • \(s_{16} = 2^{31} - 1\);
    • \(s_0, s_1, \dots, s_{15} = s_1, s_2,\dots, s_{16}\)

LFSR工作模式

  • LFSRWithWorkMode(u):
    • \(s_{16}=2^{15} s_{15} + 2^{17} s_{13} + 2^{21}s_{10} + 2^{20}s_{4}+(1+2^8)s_0 \mod (2^{31}-1)\);
    • if \(s_{16} = 0\):
      • \(s_{16} = 2^{31} - 1\);
    • \(s_0, s_1, \dots, s_{15} = s_1, s_2,\dots, s_{16}\)

BR比特重组

  • BitReconstruction():
    • \(X_0 = ((s_{15} \land 0x7fff8000) \ll 1) \lor (s_{14} \land 0x0000ffff)\);
    • \(X_1 = ((s_{9} \land 0x7fff8000) \gg 15) \lor ((s_{11} \land 0x0000ffff) \ll 16)\);
    • \(X_2 = ((s_{5} \land 0x7fff8000) \gg 15) \lor ((s_{7} \land 0x0000ffff) \ll 16)\);
    • \(X_3 = ((s_{0} \land 0x7fff8000) \gg 15) \lor ((s_{2} \land 0x0000ffff) \ll 16)\);

F非线性函数

  • F(X_0, X_1, X_2):

    • \(W = (X_0 \oplus R_1) + R_2 \mod 2^{32}\);
    • \(W_1 = R_1 + X_1 \mod 2^{32}\);
    • \(W_2 = R_2 \oplus X_2\);;
    • \(R_1 = S(L_1(((W_1 \ll 16) \lor (W_2 \gg 16)))\);
    • \(R_2 = S(L_2((W_2 \ll 16) \lor (W_1 \gg 16)))\);
    • 输出\(W\);
  • L_1(X):

    • \(X\oplus (X \lll 2) \oplus (X\lll 10) \oplus (X \lll 18) \oplus (X \lll 24)\);
  • L_2(X):

    • \(X\oplus (X \lll 8) \oplus (X\lll 14) \oplus (X \lll 22) \oplus (X\lll 30)\);
  • S(X):

    • \(S_0, S_1\)是一个大小为256的元素为字节的常量表, 见附录;
    • \(X = x_0 || x_1 || x_2 || x_3, bitslen(x_0)=bitslen(x_1)=bitslen(x_2)=bitslen(x_3)=8\);
    • \(y_0=S_0[x_0]\);
    • \(y_1=S_1[x_1]\);
    • \(y_2=S_0[x_2]\);
    • \(y_3=S_1[x_3]\);
    • \(y_0 || y_1 || y_2 || y_3\);

密钥装入

密钥装入是将128位长的密钥\(K\)和128位长的初始向量\(IV\)扩展为16个31位长的字, 并放入LFSR的16个寄存器\(s_0,s_1,\dots,s_{15}\)中的过程.

  • KeySchedule(K, IV):
    • \(K\)\(IV\)划分为16个均等长度的8位长的字节;
      • \(K = k_0 || k_1 || \dots || k_{15}\);
      • \(IV = iv_0 || iv_1 || \dots || iv_{15}\);
    • \(s_i = k_i || rightmost_{15}(KD[i]) || iv_i\), \(KD\)是大小为16的元素为16位长度的常量表(见附录), \(rightmost_l(x)\)表示取\(x\)的最右边\(l\)位比特位;

基于ZUC的加密算法

ZUCCipher算法描述

输入参数 位长度 附注
COUNT 32 计数器
BEARER 5 承载层标识
DIRECTION 1 传输方向标识
CK 128 密钥
LENGTH 32 明文消息流的位长度
IBS LENGTH 输入比特流
输出参数 位长度 附注
OBS LENGTH 输出比特流

ZUCCipher初始化

  • \(CK = CK[0] || CK[1] || \dots || CK[15], bitslen(CK[i])=8, i \in [0,15]\);
  • \(KEY[i] = CK[i], i\in [0, 15]\);
  • \(COUNT = COUNT[0] || COUNT[1] || COUNT[2] || COUNT[3], bitslen(COUNT[i])=8, i \in [0,3]\);
  • \(IV = IV[0] || IV[1] ||\dots || IV[15], bitslen(IV[i])=8, i\in [0,15]\);
  • \(IV[i] = COUNT[i], i = 0\dots 3\);
  • \(IV[4] = BEARER || DIRECTION || 0 || 0\);
  • \(IV[5]=IV[6] = IV[7] = 0x00\);
  • \(IV[j+8] = IV[j], j\in [0,7]\);

ZUCCipher密钥流生成

  • \(n= \lceil LENGTH / 32 \rceil\);
  • \(K' = ZUC(KEY,IV,n)\);
  • \(K' = k_0 || k_1 || \dots || K_{32\cdot n - 1}, bitslen(k_i)=1, i\in [0, 32\cdot n - 1]\);

ZUCCipher加解密

  • \(IBS = IBS[0]||IBS[1]||\dots ||IBS[LENGTH], bitslen(IBS[i])=1, i\in [0,LENGTH-1]\);
  • \(OBS[i] = ISB[i]\oplus k_i, i\in [0,LENGTH-1]\);
  • \(OBS = OBS[0]||OBS[1]||\dots || OBS[LENGTH-1]\);

基于ZUC的消息认证算法

ZUCMac算法描述

输入参数 位长度 附注
COUNT 32 计数器
BEARER 5 承载层标识
DIRECTION 1 传输方向标识
CK 128 完整性密钥
LENGTH 32 明文消息流的位长度
M LENGTH 输入比特流
输出参数 位长度 附注
MAC 32 消息认证码

ZUCMac初始化

  • \(CK = CK[0] || CK[1] || \dots || CK[15], bitslen(CK[i])=8, i \in [0,15]\);
  • \(KEY[i] = CK[i], i\in [0, 15]\);
  • \(COUNT = COUNT[0] || COUNT[1] || COUNT[2] || COUNT[3], bitslen(COUNT[i])=8, i \in [0,3]\);
  • \(IV = IV[0] || IV[1] ||\dots || IV[15], bitslen(IV[i])=8, i\in [0,15]\);
  • \(IV[i] = COUNT[i], i = 0\dots 3\);
  • \(IV[4]=BEARER || 0 || 0||0\);
  • \(IV[5]=IV[6] = IV[7] = 0x00\);
  • \(IV[8]= IV[0]\oplus (DIRECTION \ll 7)\);
  • \(IV[9] = IV[1]\);
  • \(IV[j+8]=IV[j], j\in [2,5]\);
  • \(IV[14] = IV[6] \oplus (DIRECTION \ll 7)\);
  • \(IV[15] = IV[7]\);

ZUCMac密钥流生成

  • \(n= \lceil LENGTH / 32 \rceil + 2\);
  • \(K' = ZUC(KEY,IV,n)\);
  • \(K' = k_0 || k_1 || \dots || K_{32\cdot n - 1}, bitslen(k_i)=1, i\in [0, 32\cdot n - 1]\);
  • \(k_{i}^{'} = k_i || k_{i+1} || \dots || k_{i+31}, i\in [0,32\cdot n - 1], bitslen(k_{i}^{'})=32\);

ZUCMac消息认证码生成

  • \(T = 0x00000000\);
  • for i in 0..=(LENGTH-1):
    • if \(M[i] = 1\):
      • \(T = T\oplus k_{i}^{'}\);
  • \(T = T\oplus k_{LENGTH}^{'}\);
  • \(MAC = T\oplus k_{32*(n-1)}^{'}\)

附录

说明

  • ZUC和ZUCCipher是国标算法;
  • ZUCMac是行标算法;

\(S_0, S_1\)

const S_0: [u8;256] = [
	0x3e,0x72,0x5b,0x47,0xca,0xe0,0x00,0x33,0x04,0xd1,0x54,0x98,0x09,0xb9,0x6d,0xcb,
	0x7b,0x1b,0xf9,0x32,0xaf,0x9d,0x6a,0xa5,0xb8,0x2d,0xfc,0x1d,0x08,0x53,0x03,0x90,
	0x4d,0x4e,0x84,0x99,0xe4,0xce,0xd9,0x91,0xdd,0xb6,0x85,0x48,0x8b,0x29,0x6e,0xac,
	0xcd,0xc1,0xf8,0x1e,0x73,0x43,0x69,0xc6,0xb5,0xbd,0xfd,0x39,0x63,0x20,0xd4,0x38,
	0x76,0x7d,0xb2,0xa7,0xcf,0xed,0x57,0xc5,0xf3,0x2c,0xbb,0x14,0x21,0x06,0x55,0x9b,
	0xe3,0xef,0x5e,0x31,0x4f,0x7f,0x5a,0xa4,0x0d,0x82,0x51,0x49,0x5f,0xba,0x58,0x1c,
	0x4a,0x16,0xd5,0x17,0xa8,0x92,0x24,0x1f,0x8c,0xff,0xd8,0xae,0x2e,0x01,0xd3,0xad,
	0x3b,0x4b,0xda,0x46,0xeb,0xc9,0xde,0x9a,0x8f,0x87,0xd7,0x3a,0x80,0x6f,0x2f,0xc8,
	0xb1,0xb4,0x37,0xf7,0x0a,0x22,0x13,0x28,0x7c,0xcc,0x3c,0x89,0xc7,0xc3,0x96,0x56,
	0x07,0xbf,0x7e,0xf0,0x0b,0x2b,0x97,0x52,0x35,0x41,0x79,0x61,0xa6,0x4c,0x10,0xfe,
	0xbc,0x26,0x95,0x88,0x8a,0xb0,0xa3,0xfb,0xc0,0x18,0x94,0xf2,0xe1,0xe5,0xe9,0x5d,
	0xd0,0xdc,0x11,0x66,0x64,0x5c,0xec,0x59,0x42,0x75,0x12,0xf5,0x74,0x9c,0xaa,0x23,
	0x0e,0x86,0xab,0xbe,0x2a,0x02,0xe7,0x67,0xe6,0x44,0xa2,0x6c,0xc2,0x93,0x9f,0xf1,
	0xf6,0xfa,0x36,0xd2,0x50,0x68,0x9e,0x62,0x71,0x15,0x3d,0xd6,0x40,0xc4,0xe2,0x0f,
	0x8e,0x83,0x77,0x6b,0x25,0x05,0x3f,0x0c,0x30,0xea,0x70,0xb7,0xa1,0xe8,0xa9,0x65,
	0x8d,0x27,0x1a,0xdb,0x81,0xb3,0xa0,0xf4,0x45,0x7a,0x19,0xdf,0xee,0x78,0x34,0x60,
];

const S_1: [u8;256] = [
	0x55,0xc2,0x63,0x71,0x3b,0xc8,0x47,0x86,0x9f,0x3c,0xda,0x5b,0x29,0xaa,0xfd,0x77,
	0x8c,0xc5,0x94,0x0c,0xa6,0x1a,0x13,0x00,0xe3,0xa8,0x16,0x72,0x40,0xf9,0xf8,0x42,
	0x44,0x26,0x68,0x96,0x81,0xd9,0x45,0x3e,0x10,0x76,0xc6,0xa7,0x8b,0x39,0x43,0xe1,
	0x3a,0xb5,0x56,0x2a,0xc0,0x6d,0xb3,0x05,0x22,0x66,0xbf,0xdc,0x0b,0xfa,0x62,0x48,
	0xdd,0x20,0x11,0x06,0x36,0xc9,0xc1,0xcf,0xf6,0x27,0x52,0xbb,0x69,0xf5,0xd4,0x87,
	0x7f,0x84,0x4c,0xd2,0x9c,0x57,0xa4,0xbc,0x4f,0x9a,0xdf,0xfe,0xd6,0x8d,0x7a,0xeb,
	0x2b,0x53,0xd8,0x5c,0xa1,0x14,0x17,0xfb,0x23,0xd5,0x7d,0x30,0x67,0x73,0x08,0x09,
	0xee,0xb7,0x70,0x3f,0x61,0xb2,0x19,0x8e,0x4e,0xe5,0x4b,0x93,0x8f,0x5d,0xdb,0xa9,
	0xad,0xf1,0xae,0x2e,0xcb,0x0d,0xfc,0xf4,0x2d,0x46,0x6e,0x1d,0x97,0xe8,0xd1,0xe9,
	0x4d,0x37,0xa5,0x75,0x5e,0x83,0x9e,0xab,0x82,0x9d,0xb9,0x1c,0xe0,0xcd,0x49,0x89,
	0x01,0xb6,0xbd,0x58,0x24,0xa2,0x5f,0x38,0x78,0x99,0x15,0x90,0x50,0xb8,0x95,0xe4,
	0xd0,0x91,0xc7,0xce,0xed,0x0f,0xb4,0x6f,0xa0,0xcc,0xf0,0x02,0x4a,0x79,0xc3,0xde,
	0xa3,0xef,0xea,0x51,0xe6,0x6b,0x18,0xec,0x1b,0x2c,0x80,0xf7,0x74,0xe7,0xff,0x21,
	0x5a,0x6a,0x54,0x1e,0x41,0x31,0x92,0x35,0xc4,0x33,0x07,0x0a,0xba,0x7e,0x0e,0x34,
	0x88,0xb1,0x98,0x7c,0xf3,0x3d,0x60,0x6c,0x7b,0xca,0xd3,0x1f,0x32,0x65,0x04,0x28,
	0x64,0xbe,0x85,0x9b,0x2f,0x59,0x8a,0xd7,0xb0,0x25,0xac,0xaf,0x12,0x03,0xe2,0xf2,

];

KD

const KD: [u16;16] = [
	0x44D7,0x26BC,0x626B,0x135E,0x5789,0x35E2,0x7135,0x09AF,
	0x4D78,0x2F13,0x6BC4,0x1AF1,0x5E26,0x3C4D,0x789A,0x47AC,

];

参考资料

  • GM/T 0001-2012 祖冲之序列密码算法;
posted @ 2020-10-15 11:22  mengsuenyan  阅读(3518)  评论(0编辑  收藏  举报