@@ -97,31 +97,39 @@ static sha256_midstate mkJetCMR(uint32_t *imr, uint_fast64_t weight) {
9797 * Precondition: 2^n == value->len
9898 */
9999sha256_midstate computeWordCMR (const bitstring * value , size_t n ) {
100- /* 'stack' is an array of 33 hashes consisting of 8 'uint32_t's each. */
101- uint32_t stack [8 * 33 ] = {0 };
100+ /* 'stack' is an array of 30 hashes consisting of 8 'uint32_t's each. */
101+ uint32_t stack [8 * 30 ] = {0 };
102102 uint32_t * stack_ptr = stack ;
103103 sha256_midstate imr = identityIV ;
104104 simplicity_assert (n < 32 );
105105 simplicity_assert ((size_t )1 << n == value -> len );
106106 /* Pass 1: Compute the CMR for the expression that writes 'value'.
107107 * This expression consists of deeply nested PAIRs of expressions that write one bit each.
108- *
109- * :TODO: This can be optimized by a constant factor by precomputing a table of CMRs of expressions
110- * that, for example, write out every possible byte sequence.
111108 */
112109 /* stack[0..7] (8 bytes) is kept as all zeros for later.
113110 * We start the stack_ptr at the second item.
114111 */
115- for (size_t i = 0 ; i < value -> len ; ++ i ) {
116- /* stack_ptr == stack + 8*<count of the number of set bits in the value i> */
112+ if (n < 3 ) {
117113 stack_ptr += 8 ;
118- memcpy (stack_ptr , & bit_cmr [getBit (value , i )], sizeof (uint32_t [8 ]));
119- /* This inner for loop runs in ammortized constant time. */
120- for (size_t j = i ; j & 1 ; j = j >> 1 ) {
121- sha256_midstate pair = cmrIV (PAIR );
122- stack_ptr -= 8 ;
123- sha256_compression (pair .s , stack_ptr );
124- memcpy (stack_ptr , pair .s , sizeof (uint32_t [8 ]));
114+ size_t i ;
115+ switch (n ) {
116+ case 0 : i = getBit (value , 0 ); break ;
117+ case 1 : i = 2 + ((1U * getBit (value , 0 ) << 1 ) | getBit (value , 1 )); break ;
118+ case 2 : i = 6 + ((1U * getBit (value , 0 ) << 3 ) | (1U * getBit (value , 1 ) << 2 ) | (1U * getBit (value , 2 ) << 1 ) | getBit (value , 3 )); break ;
119+ }
120+ memcpy (stack_ptr , & word_cmr [i ], sizeof (uint32_t [8 ]));
121+ } else {
122+ for (size_t i = 0 ; i < value -> len >> 3 ; ++ i ) {
123+ /* stack_ptr == stack + 8*<count of the number of set bits in the value i> */
124+ stack_ptr += 8 ;
125+ memcpy (stack_ptr , & word_cmr [22 + getByte (value , 8 * i )], sizeof (uint32_t [8 ]));
126+ /* This inner for loop runs in amortized constant time. */
127+ for (size_t j = i ; j & 1 ; j = j >> 1 ) {
128+ sha256_midstate pair = cmrIV (PAIR );
129+ stack_ptr -= 8 ;
130+ sha256_compression (pair .s , stack_ptr );
131+ memcpy (stack_ptr , pair .s , sizeof (uint32_t [8 ]));
132+ }
125133 }
126134 }
127135 /* value->len is a power of 2.*/
0 commit comments