1use std::vec;
2
3fn sm3_ff_j(x: u32, y: u32, z: u32, j: u32) -> u32 {
4 let mut ret = 0;
5 if j < 16 {
6 ret = x ^ y ^ z;
7 } else if 16 <= j && j < 64 {
8 ret = (x & y) | (x & z) | (y & z);
9 }
10 ret
11}
12
13fn sm3_gg_j(x: u32, y: u32, z: u32, j: u32) -> u32 {
14 let mut ret = 0;
15 if j < 16 {
16 ret = x ^ y ^ z;
17 } else if 16 <= j && j < 64 {
18 ret = (x & y) | (!x & z)
19 }
20 ret
21}
22
23fn sm3_p_0(x: u32) -> u32 {
24 x ^ x.rotate_left(9) ^ x.rotate_left(17)
25}
26
27fn sm3_p_1(x: u32) -> u32 {
28 x ^ x.rotate_left(15) ^ x.rotate_left(23)
29}
30
31fn sm3_cf(v_i: &Vec<u32>, b_i: &Vec<u32>) -> Vec<u32> {
32 let t_j: Vec<u32> = vec![
33 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169,
34 2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169,
35 2043430169, 2043430169, 2043430169, 2043430169, 2055708042, 2055708042,
36 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
37 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
38 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
39 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
40 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
41 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
42 2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
43 2055708042, 2055708042, 2055708042, 2055708042
44 ];
45 let mut w: Vec<u32> = Vec::with_capacity(68);
46 for i in 0..16 {
47 let mut weight = 0x1000000;
48 let mut data: u32 = 0;
49 for k in (i * 4)..((i + 1) * 4) {
50 data = data.wrapping_add(b_i[k] * weight);
51 weight /= 0x100;
52 }
53 w.push(data);
54 }
55 for j in 16..68 {
56 w.push(sm3_p_1(w[j - 16] ^ w[j - 9] ^ w[j - 3].rotate_left(15)) ^ w[j - 13].rotate_left(7) ^ w[j - 6]);
57 }
58 let mut w_1: Vec<u32> = Vec::with_capacity(64);
59 for j in 0..64 {
60 w_1.push( w[j] ^ w[j + 4]);
61 }
62 let mut a = v_i[0];
63 let mut b = v_i[1];
64 let mut c = v_i[2];
65 let mut d = v_i[3];
66 let mut e = v_i[4];
67 let mut f = v_i[5];
68 let mut g = v_i[6];
69 let mut h = v_i[7];
70 for j in 0..64 {
71 let ss_1 = ((a.rotate_left(12).wrapping_add(e).wrapping_add(t_j[j].rotate_left(j as u32))) & 0xffffffff).rotate_left(7);
72 let ss_2 = ss_1 ^ a.rotate_left(12);
73 let tt_1 = (sm3_ff_j(a, b, c, j as u32).wrapping_add(d).wrapping_add(ss_2).wrapping_add(w_1[j])) & 0xffffffff;
74 let tt_2 = (sm3_gg_j(e, f, g, j as u32).wrapping_add(h).wrapping_add(ss_1).wrapping_add(w[j])) & 0xffffffff;
75 d = c;
76 c = b.rotate_left(9);
77 b = a;
78 a = tt_1;
79 h = g;
80 g = f.rotate_left(19);
81 f = e;
82 e = sm3_p_0(tt_2);
83 a = a & 0xFFFFFFFF;
84 b = b & 0xFFFFFFFF;
85 c = c & 0xFFFFFFFF;
86 d = d & 0xFFFFFFFF;
87 e = e & 0xFFFFFFFF;
88 f = f & 0xFFFFFFFF;
89 g = g & 0xFFFFFFFF;
90 h = h & 0xFFFFFFFF;
91 }
92 let mut cf: Vec<u32> = Vec::with_capacity(8);
93 let v_j: Vec<u32> = vec![a, b, c, d, e, f, g, h];
94 for i in 0..8 {
95 cf.push(v_j[i] ^ v_i[i]);
96 }
97 cf
98}
99
100pub fn sm3_hash_raw(msg: &[u8]) -> Vec<u8> {
101 let iv: Vec<u32> = vec![
102 1937774191, 1226093241, 388252375, 3666478592,
103 2842636476, 372324522, 3817729613, 2969243214,
104 ];
105 let len = msg.len();
106 let reserve = len % 64 + 1;
107 let len_pad = match reserve > 56 {
108 true => len + 130 - reserve,
109 false => len + 66 - reserve
110 };
111 let range_end = match reserve > 56 {
112 true => 120,
113 false => 56
114 };
115 let mut msg_pad: Vec<u8> = Vec::with_capacity(len_pad);
116 msg_pad.extend_from_slice(msg);
117 msg_pad.push(0x80);
118 for _ in reserve..range_end {
119 msg_pad.push(0x00);
120 }
121 let mut bit_length: usize = len * 8;
122 let mut bit_length_str: Vec<usize> = Vec::with_capacity(8);
123 bit_length_str.push(bit_length % 0x100);
124 for _ in 0..7 {
125 bit_length /= 0x100;
126 bit_length_str.push(bit_length % 0x100);
127 }
128 for i in 0..8 {
129 msg_pad.push(bit_length_str[7 - i] as u8);
130 }
131 let group_count: usize = len_pad / 64;
132 let mut b: Vec<Vec<u32>> = Vec::with_capacity(group_count);
133 for _ in 0..group_count {
134 b.push(Vec::with_capacity(64));
135 }
136 for i in 0..group_count {
137 b[i] = msg_pad[(i * 64)..((i + 1) * 64)].iter().map(|x| x.to_be() as u32).collect();
138 }
139 let mut v: Vec<Vec<u32>> = Vec::with_capacity(group_count + 1);
140 for _ in 0..(group_count + 1) {
141 v.push(Vec::with_capacity(8));
142 }
143 v[0] = iv;
144 for i in 0..group_count {
145 v[i + 1] = sm3_cf(&v[i], &b[i]);
146 }
147 let y = &v[group_count];
148 y.into_iter().flat_map(|x| x.to_be_bytes()).collect()
149}
150
151pub fn sm3_hash(msg: &[u8]) -> String {
152 let hash = sm3_hash_raw(msg);
153 hash.iter().map(|x| format!("{:02x}", x)).collect()
154}
155
156pub fn sm3_hash_file(input_file: &str) -> String {
157 let input_file = std::path::Path::new(input_file);
158 let input_data = std::fs::read(input_file).unwrap();
159 sm3_hash(&input_data)
160}
161
162pub fn sm3_hash_string(msg_str: &str) -> String {
163 let msg = msg_str.as_bytes();
164 sm3_hash(msg)
165}