@@ -10,186 +10,187 @@ 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>
1314
1415namespace digestpp
1516{
1617
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)
18+ namespace detail
4719 {
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 ));
5120
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++)
21+ namespace kupyna_functions
6122 {
62- AP1[column] = h[column] ^ m[column];
63- AQ1[column] = m[column];
64- }
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+ }
65100
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 );
72101 }
73102
74- for ( int column = 0 ; column < R; column++)
103+ class kupyna_provider
75104 {
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)
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+ }
140145 memset (&m[pos], 0 , limit - pos);
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
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
193194
194195} // namespace digestpp
195196
0 commit comments