@@ -10,187 +10,186 @@ This code is written by kerukuro and released into public domain.
1010#include " ../../detail/validate_hash_size.hpp"
1111#include " constants/kupyna_constants.hpp"
1212#include < array>
13- #include < cstdint>
1413
1514namespace digestpp
1615{
1716
18- namespace detail
17+ namespace detail
18+ {
19+
20+ namespace kupyna_functions
21+ {
22+ template <int R>
23+ static inline void G (uint64_t * x, uint64_t * y)
24+ {
25+ for (int c = 0 ; c != R; ++c)
26+ y[c] = kupyna_constants<void >::T[0 ][static_cast <unsigned char >(x[(c + R) % R])]
27+ ^ kupyna_constants<void >::T[1 ][static_cast <unsigned char >(x[(c + R - 1 ) % R] >> 8 )]
28+ ^ kupyna_constants<void >::T[2 ][static_cast <unsigned char >(x[(c + R - 2 ) % R] >> 16 )]
29+ ^ kupyna_constants<void >::T[3 ][static_cast <unsigned char >(x[(c + R - 3 ) % R] >> 24 )]
30+ ^ kupyna_constants<void >::T[4 ][static_cast <unsigned char >(x[(c + R - 4 ) % R] >> 32 )]
31+ ^ kupyna_constants<void >::T[5 ][static_cast <unsigned char >(x[(c + R - 5 ) % R] >> 40 )]
32+ ^ kupyna_constants<void >::T[6 ][static_cast <unsigned char >(x[(c + R - 6 ) % R] >> 48 )]
33+ ^ kupyna_constants<void >::T[7 ][static_cast <unsigned char >(x[(c + R - (R == 16 ? 11 : 7 )) % R] >> 56 )];
34+ }
35+
36+ template <int R>
37+ static inline void roundP (uint64_t * x, uint64_t * y, uint64_t i)
38+ {
39+ for (int idx = 0 ; idx < R; idx++)
40+ x[idx] ^= (static_cast <uint64_t >(idx) << 4 ) ^ i;
41+
42+ G<R>(x, y);
43+ }
44+
45+ template <int R>
46+ static inline void roundQ (uint64_t * x, uint64_t * y, uint64_t i)
1947 {
48+ for (int j = 0 ; j < R; ++j)
49+ x[j] += (0x00F0F0F0F0F0F0F3ULL
50+ ^ ((static_cast <uint64_t >(((R - 1 - j) * 0x10 ) ^ static_cast <unsigned char >(i))) << 56 ));
2051
21- namespace kupyna_functions
52+ G<R>(x, y);
53+ }
54+
55+ template <int R>
56+ static inline void transform (uint64_t * h, const uint64_t * m)
57+ {
58+ uint64_t AQ1[R], AQ2[R], AP1[R], AP2[R];
59+
60+ for (int column = 0 ; column < R; column++)
2261 {
23- template <int R>
24- static inline void G (uint64_t * x, uint64_t * y)
25- {
26- for (int c = 0 ; c != R; ++c)
27- y[c] = kupyna_constants<void >::T[0 ][static_cast <unsigned char >(x[(c + R) % R])]
28- ^ kupyna_constants<void >::T[1 ][static_cast <unsigned char >(x[(c + R - 1 ) % R] >> 8 )]
29- ^ kupyna_constants<void >::T[2 ][static_cast <unsigned char >(x[(c + R - 2 ) % R] >> 16 )]
30- ^ kupyna_constants<void >::T[3 ][static_cast <unsigned char >(x[(c + R - 3 ) % R] >> 24 )]
31- ^ kupyna_constants<void >::T[4 ][static_cast <unsigned char >(x[(c + R - 4 ) % R] >> 32 )]
32- ^ kupyna_constants<void >::T[5 ][static_cast <unsigned char >(x[(c + R - 5 ) % R] >> 40 )]
33- ^ kupyna_constants<void >::T[6 ][static_cast <unsigned char >(x[(c + R - 6 ) % R] >> 48 )]
34- ^ kupyna_constants<void >::T[7 ][static_cast <unsigned char >(x[(c + R - (R == 16 ? 11 : 7 )) % R] >> 56 )];
35- }
36-
37- template <int R>
38- static inline void roundP (uint64_t * x, uint64_t * y, uint64_t i)
39- {
40- for (int idx = 0 ; idx < R; idx++)
41- x[idx] ^= (static_cast <uint64_t >(idx) << 4 ) ^ i;
42-
43- G<R>(x, y);
44- }
45-
46- template <int R>
47- static inline void roundQ (uint64_t * x, uint64_t * y, uint64_t i)
48- {
49- for (int j = 0 ; j < R; ++j)
50- x[j] += (0x00F0F0F0F0F0F0F3ULL
51- ^ ((static_cast <uint64_t >(((R - 1 - j) * 0x10 ) ^ static_cast <unsigned char >(i))) << 56 ));
52-
53- G<R>(x, y);
54- }
55-
56- template <int R>
57- static inline void transform (uint64_t * h, const uint64_t * m)
58- {
59- uint64_t AQ1[R], AQ2[R], AP1[R], AP2[R];
60-
61- for (int column = 0 ; column < R; column++)
62- {
63- AP1[column] = h[column] ^ m[column];
64- AQ1[column] = m[column];
65- }
66-
67- for (uint64_t r = 0 ; r < (R == 16 ? 14 : 10 ); r += 2 )
68- {
69- roundP<R>(AP1, AP2, r);
70- roundP<R>(AP2, AP1, r + 1 );
71- roundQ<R>(AQ1, AQ2, r);
72- roundQ<R>(AQ2, AQ1, r + 1 );
73- }
74-
75- for (int column = 0 ; column < R; column++)
76- {
77- h[column] = AP1[column] ^ AQ1[column] ^ h[column];
78- }
79- }
80-
81- template <int R>
82- static inline void outputTransform (uint64_t * h)
83- {
84- uint64_t t1[R];
85- uint64_t t2[R];
86-
87- for (int column = 0 ; column < R; column++) {
88- t1[column] = h[column];
89- }
90-
91- for (uint64_t r = 0 ; r < (R == 16 ? 14 : 10 ); r += 2 ) {
92- roundP<R>(t1, t2, r);
93- roundP<R>(t2, t1, r + 1 );
94- }
95-
96- for (int column = 0 ; column < R; column++) {
97- h[column] ^= t1[column];
98- }
99- }
62+ AP1[column] = h[column] ^ m[column];
63+ AQ1[column] = m[column];
64+ }
10065
66+ for (uint64_t r = 0 ; r < (R == 16 ? 14 : 10 ); r += 2 )
67+ {
68+ roundP<R>(AP1, AP2, r);
69+ roundP<R>(AP2, AP1, r + 1 );
70+ roundQ<R>(AQ1, AQ2, r);
71+ roundQ<R>(AQ2, AQ1, r + 1 );
10172 }
10273
103- class kupyna_provider
74+ for ( int column = 0 ; column < R; column++)
10475 {
105- public:
106- static const bool is_xof = false ;
107-
108- kupyna_provider (size_t hashsize)
109- : hs(hashsize)
110- {
111- validate_hash_size (hashsize, { 256 , 512 });
112- }
113-
114- ~kupyna_provider ()
115- {
116- clear ();
117- }
118-
119- inline void init ()
120- {
121- pos = 0 ;
122- total = 0 ;
123- memset (&h[0 ], 0 , sizeof (uint64_t ) * 16 );
124- h[0 ] = block_bytes (); // state in bytes
125- }
126-
127- inline void update (const unsigned char * data, size_t len)
128- {
129- detail::absorb_bytes (data, len, block_bytes (), block_bytes (), m.data (), pos, total,
130- [this ](const unsigned char * data, size_t len) { transform (data, len); });
131- }
132-
133- inline void final (unsigned char * hash)
134- {
135- total += pos * 8 ;
136- m[pos++] = 0x80 ;
137- size_t limit = block_bytes ();
138- if (pos > limit - 12 )
139- {
140- if (limit != pos)
141- memset (&m[pos], 0 , limit - pos);
142- transform (m.data (), 1 );
143- pos = 0 ;
144- }
76+ h[column] = AP1[column] ^ AQ1[column] ^ h[column];
77+ }
78+ }
79+
80+ template <int R>
81+ static inline void outputTransform (uint64_t * h)
82+ {
83+ uint64_t t1[R];
84+ uint64_t t2[R];
85+
86+ for (int column = 0 ; column < R; column++) {
87+ t1[column] = h[column];
88+ }
89+
90+ for (uint64_t r = 0 ; r < (R == 16 ? 14 : 10 ); r += 2 ) {
91+ roundP<R>(t1, t2, r);
92+ roundP<R>(t2, t1, r+1 );
93+ }
94+
95+ for (int column = 0 ; column < R; column++) {
96+ h[column] ^= t1[column];
97+ }
98+ }
99+
100+ }
101+
102+ class kupyna_provider
103+ {
104+ public:
105+ static const bool is_xof = false ;
106+
107+ kupyna_provider (size_t hashsize)
108+ : hs(hashsize)
109+ {
110+ validate_hash_size (hashsize, { 256 , 512 });
111+ }
112+
113+ ~kupyna_provider ()
114+ {
115+ clear ();
116+ }
117+
118+ inline void init ()
119+ {
120+ pos = 0 ;
121+ total = 0 ;
122+ memset (&h[0 ], 0 , sizeof (uint64_t )*16 );
123+ h[0 ] = block_bytes (); // state in bytes
124+ }
125+
126+ inline void update (const unsigned char * data, size_t len)
127+ {
128+ detail::absorb_bytes (data, len, block_bytes (), block_bytes (), m.data (), pos, total,
129+ [this ](const unsigned char * data, size_t len) { transform (data, len); });
130+ }
131+
132+ inline void final (unsigned char * hash)
133+ {
134+ total += pos * 8 ;
135+ m[pos++] = 0x80 ;
136+ size_t limit = block_bytes ();
137+ if (pos > limit - 12 )
138+ {
139+ if (limit != pos)
145140 memset (&m[pos], 0 , limit - pos);
146- memcpy (&m[limit - 12 ], &total, sizeof (uint64_t ));
147- memset (&m[limit - 4 ], 0 , 4 );
148-
149- transform (m.data (), 1 );
150- outputTransform ();
151-
152- memcpy (hash, reinterpret_cast <const unsigned char *>(h.data ()) + limit - hash_size () / 8 , hash_size () / 8 );
153- }
154-
155- inline void clear ()
156- {
157- zero_memory (h);
158- zero_memory (m);
159- }
160-
161- inline size_t hash_size () const { return hs; }
162-
163- private:
164- inline size_t block_bytes () const { return hs > 256 ? 128 : 64 ; }
165-
166- inline void outputTransform ()
167- {
168- if (hs > 256 )
169- kupyna_functions::outputTransform<16 >(&h[0 ]);
170- else
171- kupyna_functions::outputTransform<8 >(&h[0 ]);
172- }
173-
174- inline void transform (const unsigned char * mp, size_t num_blks)
175- {
176- for (size_t blk = 0 ; blk < num_blks; blk++)
177- {
178- if (hs > 256 )
179- kupyna_functions::transform<16 >(&h[0 ], reinterpret_cast <const uint64_t *>(mp + block_bytes () * blk));
180- else
181- kupyna_functions::transform<8 >(&h[0 ], reinterpret_cast <const uint64_t *>(mp + block_bytes () * blk));
182- }
183- }
184-
185- std::array<uint64_t , 16 > h;
186- std::array<unsigned char , 128 > m;
187- size_t hs;
188- size_t pos;
189- uint64_t total;
190-
191- };
192-
193- } // namespace detail
141+ transform (m.data (), 1 );
142+ pos = 0 ;
143+ }
144+ memset (&m[pos], 0 , limit - pos);
145+ memcpy (&m[limit - 12 ], &total, sizeof (uint64_t ));
146+ memset (&m[limit - 4 ], 0 , 4 );
147+
148+ transform (m.data (), 1 );
149+ outputTransform ();
150+
151+ memcpy (hash, reinterpret_cast <const unsigned char *>(h.data ()) + limit - hash_size () / 8 , hash_size () / 8 );
152+ }
153+
154+ inline void clear ()
155+ {
156+ zero_memory (h);
157+ zero_memory (m);
158+ }
159+
160+ inline size_t hash_size () const { return hs; }
161+
162+ private:
163+ inline size_t block_bytes () const { return hs > 256 ? 128 : 64 ; }
164+
165+ inline void outputTransform ()
166+ {
167+ if (hs > 256 )
168+ kupyna_functions::outputTransform<16 >(&h[0 ]);
169+ else
170+ kupyna_functions::outputTransform<8 >(&h[0 ]);
171+ }
172+
173+ inline void transform (const unsigned char * mp, size_t num_blks)
174+ {
175+ for (size_t blk = 0 ; blk < num_blks; blk++)
176+ {
177+ if (hs > 256 )
178+ kupyna_functions::transform<16 >(&h[0 ], reinterpret_cast <const uint64_t *>(mp + block_bytes () * blk));
179+ else
180+ kupyna_functions::transform<8 >(&h[0 ], reinterpret_cast <const uint64_t *>(mp + block_bytes () * blk));
181+ }
182+ }
183+
184+ std::array<uint64_t , 16 > h;
185+ std::array<unsigned char , 128 > m;
186+ size_t hs;
187+ size_t pos;
188+ uint64_t total;
189+
190+ };
191+
192+ } // namespace detail
194193
195194} // namespace digestpp
196195
0 commit comments