Skip to content

Commit f404b8a

Browse files
committed
Reduce side-channels from single-bit reads
1 parent 3d3e5be commit f404b8a

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

src/ecmult_gen_impl.h

+12-5
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,11 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp25
152152
#if COMB_BITS > 256
153153
} else if (EXPECT(bit_pos >= 256, 0)) {
154154
/* Some bit(s) of (mask(block) << comb_off) are outside of [0,256). This means
155-
* we are also done constructing bits, but know its top bit is zero, and no
155+
* we are also done constructing bits, but know its top bit should be zero, and no
156156
* flipping/negating is needed. The table lookup can also be done over a
157157
* smaller number of entries. */
158-
VERIFY_CHECK(bits < (1U << tooth));
158+
/* Mask out junk in bits variable. */
159+
bits &= ((1U << tooth) - 1);
159160
VERIFY_CHECK(bits < COMB_POINTS);
160161
for (index = 0; (index >> tooth) == 0; ++index) {
161162
secp256k1_ge_storage_cmov(&adds, &secp256k1_ecmult_gen_prec_table[block][index], index == bits);
@@ -164,10 +165,16 @@ static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp25
164165
break;
165166
#endif
166167
} else {
167-
/* Gather another bit. */
168-
uint32_t bit = secp256k1_scalar_get_bits(&recoded, bit_pos, 1);
168+
/* Gather another bit. To reduce side-channels from single-bit reads, don't
169+
* actually fetch a single bit, but read higher bits too, which are XOR'ed
170+
* into the upper bits of bits. On every iteration, an addition bits is
171+
* made correct, starting at the bottom. The bits above that contain junk.
172+
* See https://www.usenix.org/system/files/conference/usenixsecurity18/sec18-alam.pdf
173+
*/
174+
uint32_t bitdata = secp256k1_scalar_get_bits(&recoded, bit_pos & ~0x1f, 32) >> (bit_pos & 0x1f);
169175
VERIFY_CHECK(bit_pos < COMB_BITS && bit_pos < 256);
170-
bits |= bit << tooth;
176+
bits &= ~(1 << tooth);
177+
bits ^= bitdata << tooth;
171178
bit_pos += COMB_SPACING;
172179
++tooth;
173180
}

0 commit comments

Comments
 (0)