1 // GoGOST -- Pure Go GOST cryptographic functions library
2 // Copyright (C) 2015-2019 Sergey Matveev <stargrave@stargrave.org>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 // GOST R 34.11-2012 hash function.
30 pi [256]byte = [256]byte{
31 0xfc, 0xee, 0xdd, 0x11, 0xcf, 0x6e, 0x31, 0x16,
32 0xfb, 0xc4, 0xfa, 0xda, 0x23, 0xc5, 0x04, 0x4d,
33 0xe9, 0x77, 0xf0, 0xdb, 0x93, 0x2e, 0x99, 0xba,
34 0x17, 0x36, 0xf1, 0xbb, 0x14, 0xcd, 0x5f, 0xc1,
35 0xf9, 0x18, 0x65, 0x5a, 0xe2, 0x5c, 0xef, 0x21,
36 0x81, 0x1c, 0x3c, 0x42, 0x8b, 0x01, 0x8e, 0x4f,
37 0x05, 0x84, 0x02, 0xae, 0xe3, 0x6a, 0x8f, 0xa0,
38 0x06, 0x0b, 0xed, 0x98, 0x7f, 0xd4, 0xd3, 0x1f,
39 0xeb, 0x34, 0x2c, 0x51, 0xea, 0xc8, 0x48, 0xab,
40 0xf2, 0x2a, 0x68, 0xa2, 0xfd, 0x3a, 0xce, 0xcc,
41 0xb5, 0x70, 0x0e, 0x56, 0x08, 0x0c, 0x76, 0x12,
42 0xbf, 0x72, 0x13, 0x47, 0x9c, 0xb7, 0x5d, 0x87,
43 0x15, 0xa1, 0x96, 0x29, 0x10, 0x7b, 0x9a, 0xc7,
44 0xf3, 0x91, 0x78, 0x6f, 0x9d, 0x9e, 0xb2, 0xb1,
45 0x32, 0x75, 0x19, 0x3d, 0xff, 0x35, 0x8a, 0x7e,
46 0x6d, 0x54, 0xc6, 0x80, 0xc3, 0xbd, 0x0d, 0x57,
47 0xdf, 0xf5, 0x24, 0xa9, 0x3e, 0xa8, 0x43, 0xc9,
48 0xd7, 0x79, 0xd6, 0xf6, 0x7c, 0x22, 0xb9, 0x03,
49 0xe0, 0x0f, 0xec, 0xde, 0x7a, 0x94, 0xb0, 0xbc,
50 0xdc, 0xe8, 0x28, 0x50, 0x4e, 0x33, 0x0a, 0x4a,
51 0xa7, 0x97, 0x60, 0x73, 0x1e, 0x00, 0x62, 0x44,
52 0x1a, 0xb8, 0x38, 0x82, 0x64, 0x9f, 0x26, 0x41,
53 0xad, 0x45, 0x46, 0x92, 0x27, 0x5e, 0x55, 0x2f,
54 0x8c, 0xa3, 0xa5, 0x7d, 0x69, 0xd5, 0x95, 0x3b,
55 0x07, 0x58, 0xb3, 0x40, 0x86, 0xac, 0x1d, 0xf7,
56 0x30, 0x37, 0x6b, 0xe4, 0x88, 0xd9, 0xe7, 0x89,
57 0xe1, 0x1b, 0x83, 0x49, 0x4c, 0x3f, 0xf8, 0xfe,
58 0x8d, 0x53, 0xaa, 0x90, 0xca, 0xd8, 0x85, 0x61,
59 0x20, 0x71, 0x67, 0xa4, 0x2d, 0x2b, 0x09, 0x5b,
60 0xcb, 0x9b, 0x25, 0xd0, 0xbe, 0xe5, 0x6c, 0x52,
61 0x59, 0xa6, 0x74, 0xd2, 0xe6, 0xf4, 0xb4, 0xc0,
62 0xd1, 0x66, 0xaf, 0xc2, 0x39, 0x4b, 0x63, 0xb6,
64 tau [64]int = [64]int{
65 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38,
66 0x01, 0x09, 0x11, 0x19, 0x21, 0x29, 0x31, 0x39,
67 0x02, 0x0a, 0x12, 0x1a, 0x22, 0x2a, 0x32, 0x3a,
68 0x03, 0x0b, 0x13, 0x1b, 0x23, 0x2b, 0x33, 0x3b,
69 0x04, 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c,
70 0x05, 0x0d, 0x15, 0x1d, 0x25, 0x2d, 0x35, 0x3d,
71 0x06, 0x0e, 0x16, 0x1e, 0x26, 0x2e, 0x36, 0x3e,
72 0x07, 0x0f, 0x17, 0x1f, 0x27, 0x2f, 0x37, 0x3f,
74 c [12][BlockSize]byte = [12][BlockSize]byte{
76 0x07, 0x45, 0xa6, 0xf2, 0x59, 0x65, 0x80, 0xdd,
77 0x23, 0x4d, 0x74, 0xcc, 0x36, 0x74, 0x76, 0x05,
78 0x15, 0xd3, 0x60, 0xa4, 0x08, 0x2a, 0x42, 0xa2,
79 0x01, 0x69, 0x67, 0x92, 0x91, 0xe0, 0x7c, 0x4b,
80 0xfc, 0xc4, 0x85, 0x75, 0x8d, 0xb8, 0x4e, 0x71,
81 0x16, 0xd0, 0x45, 0x2e, 0x43, 0x76, 0x6a, 0x2f,
82 0x1f, 0x7c, 0x65, 0xc0, 0x81, 0x2f, 0xcb, 0xeb,
83 0xe9, 0xda, 0xca, 0x1e, 0xda, 0x5b, 0x08, 0xb1,
86 0xb7, 0x9b, 0xb1, 0x21, 0x70, 0x04, 0x79, 0xe6,
87 0x56, 0xcd, 0xcb, 0xd7, 0x1b, 0xa2, 0xdd, 0x55,
88 0xca, 0xa7, 0x0a, 0xdb, 0xc2, 0x61, 0xb5, 0x5c,
89 0x58, 0x99, 0xd6, 0x12, 0x6b, 0x17, 0xb5, 0x9a,
90 0x31, 0x01, 0xb5, 0x16, 0x0f, 0x5e, 0xd5, 0x61,
91 0x98, 0x2b, 0x23, 0x0a, 0x72, 0xea, 0xfe, 0xf3,
92 0xd7, 0xb5, 0x70, 0x0f, 0x46, 0x9d, 0xe3, 0x4f,
93 0x1a, 0x2f, 0x9d, 0xa9, 0x8a, 0xb5, 0xa3, 0x6f,
96 0xb2, 0x0a, 0xba, 0x0a, 0xf5, 0x96, 0x1e, 0x99,
97 0x31, 0xdb, 0x7a, 0x86, 0x43, 0xf4, 0xb6, 0xc2,
98 0x09, 0xdb, 0x62, 0x60, 0x37, 0x3a, 0xc9, 0xc1,
99 0xb1, 0x9e, 0x35, 0x90, 0xe4, 0x0f, 0xe2, 0xd3,
100 0x7b, 0x7b, 0x29, 0xb1, 0x14, 0x75, 0xea, 0xf2,
101 0x8b, 0x1f, 0x9c, 0x52, 0x5f, 0x5e, 0xf1, 0x06,
102 0x35, 0x84, 0x3d, 0x6a, 0x28, 0xfc, 0x39, 0x0a,
103 0xc7, 0x2f, 0xce, 0x2b, 0xac, 0xdc, 0x74, 0xf5,
106 0x2e, 0xd1, 0xe3, 0x84, 0xbc, 0xbe, 0x0c, 0x22,
107 0xf1, 0x37, 0xe8, 0x93, 0xa1, 0xea, 0x53, 0x34,
108 0xbe, 0x03, 0x52, 0x93, 0x33, 0x13, 0xb7, 0xd8,
109 0x75, 0xd6, 0x03, 0xed, 0x82, 0x2c, 0xd7, 0xa9,
110 0x3f, 0x35, 0x5e, 0x68, 0xad, 0x1c, 0x72, 0x9d,
111 0x7d, 0x3c, 0x5c, 0x33, 0x7e, 0x85, 0x8e, 0x48,
112 0xdd, 0xe4, 0x71, 0x5d, 0xa0, 0xe1, 0x48, 0xf9,
113 0xd2, 0x66, 0x15, 0xe8, 0xb3, 0xdf, 0x1f, 0xef,
116 0x57, 0xfe, 0x6c, 0x7c, 0xfd, 0x58, 0x17, 0x60,
117 0xf5, 0x63, 0xea, 0xa9, 0x7e, 0xa2, 0x56, 0x7a,
118 0x16, 0x1a, 0x27, 0x23, 0xb7, 0x00, 0xff, 0xdf,
119 0xa3, 0xf5, 0x3a, 0x25, 0x47, 0x17, 0xcd, 0xbf,
120 0xbd, 0xff, 0x0f, 0x80, 0xd7, 0x35, 0x9e, 0x35,
121 0x4a, 0x10, 0x86, 0x16, 0x1f, 0x1c, 0x15, 0x7f,
122 0x63, 0x23, 0xa9, 0x6c, 0x0c, 0x41, 0x3f, 0x9a,
123 0x99, 0x47, 0x47, 0xad, 0xac, 0x6b, 0xea, 0x4b,
126 0x6e, 0x7d, 0x64, 0x46, 0x7a, 0x40, 0x68, 0xfa,
127 0x35, 0x4f, 0x90, 0x36, 0x72, 0xc5, 0x71, 0xbf,
128 0xb6, 0xc6, 0xbe, 0xc2, 0x66, 0x1f, 0xf2, 0x0a,
129 0xb4, 0xb7, 0x9a, 0x1c, 0xb7, 0xa6, 0xfa, 0xcf,
130 0xc6, 0x8e, 0xf0, 0x9a, 0xb4, 0x9a, 0x7f, 0x18,
131 0x6c, 0xa4, 0x42, 0x51, 0xf9, 0xc4, 0x66, 0x2d,
132 0xc0, 0x39, 0x30, 0x7a, 0x3b, 0xc3, 0xa4, 0x6f,
133 0xd9, 0xd3, 0x3a, 0x1d, 0xae, 0xae, 0x4f, 0xae,
136 0x93, 0xd4, 0x14, 0x3a, 0x4d, 0x56, 0x86, 0x88,
137 0xf3, 0x4a, 0x3c, 0xa2, 0x4c, 0x45, 0x17, 0x35,
138 0x04, 0x05, 0x4a, 0x28, 0x83, 0x69, 0x47, 0x06,
139 0x37, 0x2c, 0x82, 0x2d, 0xc5, 0xab, 0x92, 0x09,
140 0xc9, 0x93, 0x7a, 0x19, 0x33, 0x3e, 0x47, 0xd3,
141 0xc9, 0x87, 0xbf, 0xe6, 0xc7, 0xc6, 0x9e, 0x39,
142 0x54, 0x09, 0x24, 0xbf, 0xfe, 0x86, 0xac, 0x51,
143 0xec, 0xc5, 0xaa, 0xee, 0x16, 0x0e, 0xc7, 0xf4,
146 0x1e, 0xe7, 0x02, 0xbf, 0xd4, 0x0d, 0x7f, 0xa4,
147 0xd9, 0xa8, 0x51, 0x59, 0x35, 0xc2, 0xac, 0x36,
148 0x2f, 0xc4, 0xa5, 0xd1, 0x2b, 0x8d, 0xd1, 0x69,
149 0x90, 0x06, 0x9b, 0x92, 0xcb, 0x2b, 0x89, 0xf4,
150 0x9a, 0xc4, 0xdb, 0x4d, 0x3b, 0x44, 0xb4, 0x89,
151 0x1e, 0xde, 0x36, 0x9c, 0x71, 0xf8, 0xb7, 0x4e,
152 0x41, 0x41, 0x6e, 0x0c, 0x02, 0xaa, 0xe7, 0x03,
153 0xa7, 0xc9, 0x93, 0x4d, 0x42, 0x5b, 0x1f, 0x9b,
156 0xdb, 0x5a, 0x23, 0x83, 0x51, 0x44, 0x61, 0x72,
157 0x60, 0x2a, 0x1f, 0xcb, 0x92, 0xdc, 0x38, 0x0e,
158 0x54, 0x9c, 0x07, 0xa6, 0x9a, 0x8a, 0x2b, 0x7b,
159 0xb1, 0xce, 0xb2, 0xdb, 0x0b, 0x44, 0x0a, 0x80,
160 0x84, 0x09, 0x0d, 0xe0, 0xb7, 0x55, 0xd9, 0x3c,
161 0x24, 0x42, 0x89, 0x25, 0x1b, 0x3a, 0x7d, 0x3a,
162 0xde, 0x5f, 0x16, 0xec, 0xd8, 0x9a, 0x4c, 0x94,
163 0x9b, 0x22, 0x31, 0x16, 0x54, 0x5a, 0x8f, 0x37,
166 0xed, 0x9c, 0x45, 0x98, 0xfb, 0xc7, 0xb4, 0x74,
167 0xc3, 0xb6, 0x3b, 0x15, 0xd1, 0xfa, 0x98, 0x36,
168 0xf4, 0x52, 0x76, 0x3b, 0x30, 0x6c, 0x1e, 0x7a,
169 0x4b, 0x33, 0x69, 0xaf, 0x02, 0x67, 0xe7, 0x9f,
170 0x03, 0x61, 0x33, 0x1b, 0x8a, 0xe1, 0xff, 0x1f,
171 0xdb, 0x78, 0x8a, 0xff, 0x1c, 0xe7, 0x41, 0x89,
172 0xf3, 0xf3, 0xe4, 0xb2, 0x48, 0xe5, 0x2a, 0x38,
173 0x52, 0x6f, 0x05, 0x80, 0xa6, 0xde, 0xbe, 0xab,
176 0x1b, 0x2d, 0xf3, 0x81, 0xcd, 0xa4, 0xca, 0x6b,
177 0x5d, 0xd8, 0x6f, 0xc0, 0x4a, 0x59, 0xa2, 0xde,
178 0x98, 0x6e, 0x47, 0x7d, 0x1d, 0xcd, 0xba, 0xef,
179 0xca, 0xb9, 0x48, 0xea, 0xef, 0x71, 0x1d, 0x8a,
180 0x79, 0x66, 0x84, 0x14, 0x21, 0x80, 0x01, 0x20,
181 0x61, 0x07, 0xab, 0xeb, 0xbb, 0x6b, 0xfa, 0xd8,
182 0x94, 0xfe, 0x5a, 0x63, 0xcd, 0xc6, 0x02, 0x30,
183 0xfb, 0x89, 0xc8, 0xef, 0xd0, 0x9e, 0xcd, 0x7b,
186 0x20, 0xd7, 0x1b, 0xf1, 0x4a, 0x92, 0xbc, 0x48,
187 0x99, 0x1b, 0xb2, 0xd9, 0xd5, 0x17, 0xf4, 0xfa,
188 0x52, 0x28, 0xe1, 0x88, 0xaa, 0xa4, 0x1d, 0xe7,
189 0x86, 0xcc, 0x91, 0x18, 0x9d, 0xef, 0x80, 0x5d,
190 0x9b, 0x9f, 0x21, 0x30, 0xd4, 0x12, 0x20, 0xf8,
191 0x77, 0x1d, 0xdf, 0xbc, 0x32, 0x3c, 0xa4, 0xcd,
192 0x7a, 0xb1, 0x49, 0x04, 0xb0, 0x80, 0x13, 0xd2,
193 0xba, 0x31, 0x16, 0xf1, 0x67, 0xe7, 0x8e, 0x37,
196 a [64]uint64 // It is filled in init()
201 []byte{0x8e, 0x20, 0xfa, 0xa7, 0x2b, 0xa0, 0xb4, 0x70},
202 []byte{0x47, 0x10, 0x7d, 0xdd, 0x9b, 0x50, 0x5a, 0x38},
203 []byte{0xad, 0x08, 0xb0, 0xe0, 0xc3, 0x28, 0x2d, 0x1c},
204 []byte{0xd8, 0x04, 0x58, 0x70, 0xef, 0x14, 0x98, 0x0e},
205 []byte{0x6c, 0x02, 0x2c, 0x38, 0xf9, 0x0a, 0x4c, 0x07},
206 []byte{0x36, 0x01, 0x16, 0x1c, 0xf2, 0x05, 0x26, 0x8d},
207 []byte{0x1b, 0x8e, 0x0b, 0x0e, 0x79, 0x8c, 0x13, 0xc8},
208 []byte{0x83, 0x47, 0x8b, 0x07, 0xb2, 0x46, 0x87, 0x64},
209 []byte{0xa0, 0x11, 0xd3, 0x80, 0x81, 0x8e, 0x8f, 0x40},
210 []byte{0x50, 0x86, 0xe7, 0x40, 0xce, 0x47, 0xc9, 0x20},
211 []byte{0x28, 0x43, 0xfd, 0x20, 0x67, 0xad, 0xea, 0x10},
212 []byte{0x14, 0xaf, 0xf0, 0x10, 0xbd, 0xd8, 0x75, 0x08},
213 []byte{0x0a, 0xd9, 0x78, 0x08, 0xd0, 0x6c, 0xb4, 0x04},
214 []byte{0x05, 0xe2, 0x3c, 0x04, 0x68, 0x36, 0x5a, 0x02},
215 []byte{0x8c, 0x71, 0x1e, 0x02, 0x34, 0x1b, 0x2d, 0x01},
216 []byte{0x46, 0xb6, 0x0f, 0x01, 0x1a, 0x83, 0x98, 0x8e},
217 []byte{0x90, 0xda, 0xb5, 0x2a, 0x38, 0x7a, 0xe7, 0x6f},
218 []byte{0x48, 0x6d, 0xd4, 0x15, 0x1c, 0x3d, 0xfd, 0xb9},
219 []byte{0x24, 0xb8, 0x6a, 0x84, 0x0e, 0x90, 0xf0, 0xd2},
220 []byte{0x12, 0x5c, 0x35, 0x42, 0x07, 0x48, 0x78, 0x69},
221 []byte{0x09, 0x2e, 0x94, 0x21, 0x8d, 0x24, 0x3c, 0xba},
222 []byte{0x8a, 0x17, 0x4a, 0x9e, 0xc8, 0x12, 0x1e, 0x5d},
223 []byte{0x45, 0x85, 0x25, 0x4f, 0x64, 0x09, 0x0f, 0xa0},
224 []byte{0xac, 0xcc, 0x9c, 0xa9, 0x32, 0x8a, 0x89, 0x50},
225 []byte{0x9d, 0x4d, 0xf0, 0x5d, 0x5f, 0x66, 0x14, 0x51},
226 []byte{0xc0, 0xa8, 0x78, 0xa0, 0xa1, 0x33, 0x0a, 0xa6},
227 []byte{0x60, 0x54, 0x3c, 0x50, 0xde, 0x97, 0x05, 0x53},
228 []byte{0x30, 0x2a, 0x1e, 0x28, 0x6f, 0xc5, 0x8c, 0xa7},
229 []byte{0x18, 0x15, 0x0f, 0x14, 0xb9, 0xec, 0x46, 0xdd},
230 []byte{0x0c, 0x84, 0x89, 0x0a, 0xd2, 0x76, 0x23, 0xe0},
231 []byte{0x06, 0x42, 0xca, 0x05, 0x69, 0x3b, 0x9f, 0x70},
232 []byte{0x03, 0x21, 0x65, 0x8c, 0xba, 0x93, 0xc1, 0x38},
233 []byte{0x86, 0x27, 0x5d, 0xf0, 0x9c, 0xe8, 0xaa, 0xa8},
234 []byte{0x43, 0x9d, 0xa0, 0x78, 0x4e, 0x74, 0x55, 0x54},
235 []byte{0xaf, 0xc0, 0x50, 0x3c, 0x27, 0x3a, 0xa4, 0x2a},
236 []byte{0xd9, 0x60, 0x28, 0x1e, 0x9d, 0x1d, 0x52, 0x15},
237 []byte{0xe2, 0x30, 0x14, 0x0f, 0xc0, 0x80, 0x29, 0x84},
238 []byte{0x71, 0x18, 0x0a, 0x89, 0x60, 0x40, 0x9a, 0x42},
239 []byte{0xb6, 0x0c, 0x05, 0xca, 0x30, 0x20, 0x4d, 0x21},
240 []byte{0x5b, 0x06, 0x8c, 0x65, 0x18, 0x10, 0xa8, 0x9e},
241 []byte{0x45, 0x6c, 0x34, 0x88, 0x7a, 0x38, 0x05, 0xb9},
242 []byte{0xac, 0x36, 0x1a, 0x44, 0x3d, 0x1c, 0x8c, 0xd2},
243 []byte{0x56, 0x1b, 0x0d, 0x22, 0x90, 0x0e, 0x46, 0x69},
244 []byte{0x2b, 0x83, 0x88, 0x11, 0x48, 0x07, 0x23, 0xba},
245 []byte{0x9b, 0xcf, 0x44, 0x86, 0x24, 0x8d, 0x9f, 0x5d},
246 []byte{0xc3, 0xe9, 0x22, 0x43, 0x12, 0xc8, 0xc1, 0xa0},
247 []byte{0xef, 0xfa, 0x11, 0xaf, 0x09, 0x64, 0xee, 0x50},
248 []byte{0xf9, 0x7d, 0x86, 0xd9, 0x8a, 0x32, 0x77, 0x28},
249 []byte{0xe4, 0xfa, 0x20, 0x54, 0xa8, 0x0b, 0x32, 0x9c},
250 []byte{0x72, 0x7d, 0x10, 0x2a, 0x54, 0x8b, 0x19, 0x4e},
251 []byte{0x39, 0xb0, 0x08, 0x15, 0x2a, 0xcb, 0x82, 0x27},
252 []byte{0x92, 0x58, 0x04, 0x84, 0x15, 0xeb, 0x41, 0x9d},
253 []byte{0x49, 0x2c, 0x02, 0x42, 0x84, 0xfb, 0xae, 0xc0},
254 []byte{0xaa, 0x16, 0x01, 0x21, 0x42, 0xf3, 0x57, 0x60},
255 []byte{0x55, 0x0b, 0x8e, 0x9e, 0x21, 0xf7, 0xa5, 0x30},
256 []byte{0xa4, 0x8b, 0x47, 0x4f, 0x9e, 0xf5, 0xdc, 0x18},
257 []byte{0x70, 0xa6, 0xa5, 0x6e, 0x24, 0x40, 0x59, 0x8e},
258 []byte{0x38, 0x53, 0xdc, 0x37, 0x12, 0x20, 0xa2, 0x47},
259 []byte{0x1c, 0xa7, 0x6e, 0x95, 0x09, 0x10, 0x51, 0xad},
260 []byte{0x0e, 0xdd, 0x37, 0xc4, 0x8a, 0x08, 0xa6, 0xd8},
261 []byte{0x07, 0xe0, 0x95, 0x62, 0x45, 0x04, 0x53, 0x6c},
262 []byte{0x8d, 0x70, 0xc4, 0x31, 0xac, 0x02, 0xa7, 0x36},
263 []byte{0xc8, 0x38, 0x62, 0x96, 0x56, 0x01, 0xdd, 0x1b},
264 []byte{0x64, 0x1c, 0x31, 0x4b, 0x2b, 0x8e, 0xe0, 0x83},
266 for i := 0; i < 64; i++ {
267 a[i] = binary.BigEndian.Uint64(as[i])
280 // Create new hash object with specified size digest size.
281 func New(size int) *Hash {
282 if size != 32 && size != 64 {
283 panic("size must be either 32 or 64")
287 hsh: new([BlockSize]byte),
288 chk: new([BlockSize]byte),
289 tmp: new([BlockSize]byte),
295 func (h *Hash) Reset() {
298 for i := 0; i < BlockSize; i++ {
308 func (h *Hash) BlockSize() int {
312 func (h *Hash) Size() int {
316 func (h *Hash) Write(data []byte) (int, error) {
317 h.buf = append(h.buf, data...)
318 for len(h.buf) >= BlockSize {
319 copy(h.tmp[:], h.buf[:BlockSize])
320 h.hsh = g(h.n, h.hsh, h.tmp)
321 h.chk = add512bit(h.chk, h.tmp)
323 h.buf = h.buf[BlockSize:]
325 return len(data), nil
328 func (h *Hash) Sum(in []byte) []byte {
329 buf := new([BlockSize]byte)
330 copy(h.tmp[:], buf[:])
331 copy(buf[:], h.buf[:])
333 hsh := g(h.n, h.hsh, buf)
334 binary.LittleEndian.PutUint64(h.tmp[:], h.n+uint64(len(h.buf))*8)
335 hsh = g(0, hsh, h.tmp)
336 hsh = g(0, hsh, add512bit(h.chk, buf))
338 return append(in, hsh[BlockSize/2:]...)
340 return append(in, hsh[:]...)
343 func add512bit(chk, data *[BlockSize]byte) *[BlockSize]byte {
345 r := new([BlockSize]byte)
346 for i := 0; i < BlockSize; i++ {
347 ss = uint16(chk[i]) + uint16(data[i]) + (ss >> 8)
348 r[i] = byte(0xFF & ss)
353 func g(n uint64, hsh, data *[BlockSize]byte) *[BlockSize]byte {
354 ns := make([]byte, 8)
355 binary.LittleEndian.PutUint64(ns, n)
356 r := new([BlockSize]byte)
357 for i := 0; i < 8; i++ {
358 r[i] = hsh[i] ^ ns[i]
361 return blockXor(blockXor(e(l(ps(r)), data), hsh), data)
364 func e(k, msg *[BlockSize]byte) *[BlockSize]byte {
365 for i := 0; i < 12; i++ {
366 msg = l(ps(blockXor(k, msg)))
367 k = l(ps(blockXor(k, &c[i])))
369 return blockXor(k, msg)
372 func blockXor(x, y *[BlockSize]byte) *[BlockSize]byte {
373 r := new([BlockSize]byte)
374 for i := 0; i < BlockSize; i++ {
380 func ps(data *[BlockSize]byte) *[BlockSize]byte {
381 r := new([BlockSize]byte)
382 for i := 0; i < BlockSize; i++ {
383 r[tau[i]] = pi[int(data[i])]
388 func l(data *[BlockSize]byte) *[BlockSize]byte {
392 r := new([BlockSize]byte)
393 for i := 0; i < 8; i++ {
394 val = binary.LittleEndian.Uint64(data[i*8 : i*8+8])
396 for j = 0; j < BlockSize; j++ {
397 if val&0x8000000000000000 > 0 {
402 binary.LittleEndian.PutUint64(r[i*8:i*8+8], res64)