1 // GoGOST -- Pure Go GOST cryptographic functions library
2 // Copyright (C) 2015-2016 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 // Size is either 512 or 256 (bits).
282 func New(size int) *Hash {
283 if size != 256 && size != 512 {
284 panic("size must be either 256 or 512")
288 hsh: new([BlockSize]byte),
289 chk: new([BlockSize]byte),
290 tmp: new([BlockSize]byte),
296 func (h *Hash) Reset() {
299 for i := 0; i < BlockSize; i++ {
309 func (h *Hash) BlockSize() int {
313 func (h *Hash) Size() int {
317 func (h *Hash) Write(data []byte) (int, error) {
318 h.buf = append(h.buf, data...)
319 for len(h.buf) >= BlockSize {
320 copy(h.tmp[:], h.buf[:BlockSize])
321 h.hsh = g(h.n, h.hsh, h.tmp)
322 h.chk = add512bit(h.chk, h.tmp)
324 h.buf = h.buf[BlockSize:]
326 return len(data), nil
329 func (h *Hash) Sum(in []byte) []byte {
330 buf := new([BlockSize]byte)
331 copy(h.tmp[:], buf[:])
332 copy(buf[:], h.buf[:])
334 hsh := g(h.n, h.hsh, buf)
335 binary.LittleEndian.PutUint64(h.tmp[:], h.n+uint64(len(h.buf))*8)
336 hsh = g(0, hsh, h.tmp)
337 hsh = g(0, hsh, add512bit(h.chk, buf))
339 return append(in, hsh[BlockSize/2:]...)
341 return append(in, hsh[:]...)
344 func add512bit(chk, data *[BlockSize]byte) *[BlockSize]byte {
346 r := new([BlockSize]byte)
347 for i := 0; i < BlockSize; i++ {
348 ss = uint16(chk[i]) + uint16(data[i]) + (ss >> 8)
349 r[i] = byte(0xFF & ss)
354 func g(n uint64, hsh, data *[BlockSize]byte) *[BlockSize]byte {
355 ns := make([]byte, 8)
356 binary.LittleEndian.PutUint64(ns, n)
357 r := new([BlockSize]byte)
358 for i := 0; i < 8; i++ {
359 r[i] = hsh[i] ^ ns[i]
362 return blockXor(blockXor(e(l(ps(r)), data), hsh), data)
365 func e(k, msg *[BlockSize]byte) *[BlockSize]byte {
366 for i := 0; i < 12; i++ {
367 msg = l(ps(blockXor(k, msg)))
368 k = l(ps(blockXor(k, &c[i])))
370 return blockXor(k, msg)
373 func blockXor(x, y *[BlockSize]byte) *[BlockSize]byte {
374 r := new([BlockSize]byte)
375 for i := 0; i < BlockSize; i++ {
381 func ps(data *[BlockSize]byte) *[BlockSize]byte {
382 r := new([BlockSize]byte)
383 for i := 0; i < BlockSize; i++ {
384 r[tau[i]] = pi[int(data[i])]
389 func l(data *[BlockSize]byte) *[BlockSize]byte {
393 r := new([BlockSize]byte)
394 for i := 0; i < 8; i++ {
395 val = binary.LittleEndian.Uint64(data[i*8 : i*8+8])
397 for j = 0; j < BlockSize; j++ {
398 if val&0x8000000000000000 > 0 {
403 binary.LittleEndian.PutUint64(r[i*8:i*8+8], res64)