@@ -527,3 +527,107 @@ union ethash_hash256 ethash_keccak256_final(struct ethash_keccak256_context* ctx
527527 keccak_final (ctx , hash .word64s );
528528 return hash ;
529529}
530+
531+ static inline ALWAYS_INLINE void keccak_init_2 (struct ethash_keccak256_context * ctx , size_t bits )
532+ {
533+ __builtin_memset ((uint8_t * )ctx -> state , 0 , sizeof ctx -> state );
534+ ctx -> state_iter = ctx -> state ;
535+
536+ ctx -> hash_size = bits / 8 ;
537+ ctx -> block_size = (1600 - bits * 2 ) / 8 ;
538+ ctx -> last_word = 0 ;
539+ ctx -> last_word_iter = (uint8_t * )& ctx -> last_word ;
540+
541+ __builtin_memset (ctx -> buffer , 0 , sizeof ctx -> buffer );
542+ ctx -> buffer_index = 0 ;
543+ }
544+
545+ static inline ALWAYS_INLINE void keccak_update_2 (
546+ struct ethash_keccak256_context * ctx , const uint8_t * data , size_t size )
547+ {
548+ static const size_t word_size = sizeof (uint64_t );
549+
550+ while (size > 0 )
551+ {
552+ size_t empty_space_size = ctx -> block_size - ctx -> buffer_index ;
553+ size_t data_to_load_size = size >= empty_space_size ? empty_space_size : size ;
554+
555+ __builtin_memcpy (& ctx -> buffer [ctx -> buffer_index ], data , data_to_load_size );
556+ ctx -> buffer_index += data_to_load_size ;
557+ size -= data_to_load_size ;
558+ data += data_to_load_size ;
559+
560+ if (ctx -> buffer_index == ctx -> block_size )
561+ {
562+ size_t i ;
563+ uint8_t * d = & ctx -> buffer [0 ];
564+
565+ for (i = 0 ; i < (ctx -> block_size / word_size ); ++ i )
566+ {
567+ * ctx -> state_iter ^= load_le (d );
568+ ++ ctx -> state_iter ;
569+ d += word_size ;
570+ }
571+
572+ keccakf1600_best (ctx -> state );
573+ ctx -> state_iter = ctx -> state ;
574+ ctx -> buffer_index = 0 ;
575+ }
576+ }
577+ }
578+
579+ static inline ALWAYS_INLINE void keccak_final_2 (struct ethash_keccak256_context * ctx , uint64_t * out )
580+ {
581+ static const size_t word_size = sizeof (uint64_t );
582+ size_t i ;
583+
584+ if (ctx -> buffer_index != 0 )
585+ {
586+ uint8_t * d = ctx -> buffer ;
587+ for (i = 0 ; i < (ctx -> buffer_index / word_size ); ++ i )
588+ {
589+ * ctx -> state_iter ^= load_le (d );
590+ ++ ctx -> state_iter ;
591+ d += word_size ;
592+ }
593+
594+ size_t last_word_size = ctx -> buffer_index % word_size ;
595+ d = & ctx -> buffer [ctx -> buffer_index - last_word_size ];
596+ ctx -> last_word_iter = (uint8_t * )& ctx -> last_word ;
597+
598+ while (last_word_size > 0 )
599+ {
600+ * ctx -> last_word_iter = * d ;
601+ ++ ctx -> last_word_iter ;
602+ ++ d ;
603+ -- last_word_size ;
604+ }
605+ }
606+
607+ * ctx -> last_word_iter = 0x01 ;
608+ * ctx -> state_iter ^= to_le64 (ctx -> last_word );
609+
610+ ctx -> state [(ctx -> block_size / word_size ) - 1 ] ^= 0x8000000000000000 ;
611+
612+ keccakf1600_best (ctx -> state );
613+
614+ for (i = 0 ; i < (ctx -> hash_size / word_size ); ++ i )
615+ out [i ] = to_le64 (ctx -> state [i ]);
616+ }
617+
618+ void ethash_keccak256_init_2 (struct ethash_keccak256_context * ctx )
619+ {
620+ keccak_init_2 (ctx , 256 );
621+ }
622+
623+ void ethash_keccak256_update_2 (struct ethash_keccak256_context * ctx , const uint8_t * data , size_t size )
624+ {
625+ keccak_update_2 (ctx , data , size );
626+ }
627+
628+ union ethash_hash256 ethash_keccak256_final_2 (struct ethash_keccak256_context * ctx )
629+ {
630+ union ethash_hash256 hash ;
631+ keccak_final_2 (ctx , hash .word64s );
632+ return hash ;
633+ }
0 commit comments