@@ -97,31 +97,39 @@ static sha256_midstate mkJetCMR(uint32_t *imr, uint_fast64_t weight) {
97
97
* Precondition: 2^n == value->len
98
98
*/
99
99
sha256_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 };
102
102
uint32_t * stack_ptr = stack ;
103
103
sha256_midstate imr = identityIV ;
104
104
simplicity_assert (n < 32 );
105
105
simplicity_assert ((size_t )1 << n == value -> len );
106
106
/* Pass 1: Compute the CMR for the expression that writes 'value'.
107
107
* 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.
111
108
*/
112
109
/* stack[0..7] (8 bytes) is kept as all zeros for later.
113
110
* We start the stack_ptr at the second item.
114
111
*/
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 ) {
117
113
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
+ }
125
133
}
126
134
}
127
135
/* value->len is a power of 2.*/
0 commit comments