Skip to content

Commit

Permalink
double-check range checks in the decodings
Browse files Browse the repository at this point in the history
  • Loading branch information
reneme committed Sep 18, 2024
1 parent dc3d43d commit 22459ba
Showing 1 changed file with 10 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/lib/pubkey/dilithium/dilithium_common/dilithium_algos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ constexpr void poly_unpack(CRYSTALS::Polynomial<PolyTrait, D>& p, ByteSourceT& g
// to the range [-a, b].
CRYSTALS::unpack<a + b>(p, get_bytes, unmap_range<b>);
}

// `check_range` should only be enabled if the requested range is not fully
// covered by the encodeable range, i.e |range| is not a power of 2.
BOTAN_DEBUG_ASSERT(!check_range ||
(a >= 0 && b >= 0 && !is_power_of_2(static_cast<uint64_t>(b) - static_cast<uint64_t>(a) + 1)));

if(check_range && !p.ct_validate_value_range(-a, b)) {
throw Decoding_Error("Decoded polynomial coefficients out of range");
}
Expand Down Expand Up @@ -167,6 +173,10 @@ void poly_pack_t0(const DilithiumPoly& p, BufferStuffer& stuffer) {
*/
void poly_unpack_t1(DilithiumPoly& p, BufferSlicer& slicer) {
constexpr auto b = (1 << (bitlen(DilithiumConstants::Q - 1) - DilithiumConstants::D)) - 1;
// The range of valid output coefficients [0, b] fully covers the encodeable
// range. Hence, no range check is needed despite this being exposed to
// potentially untrusted serialized public keys.
static_assert(b >= 0 && is_power_of_2(static_cast<uint32_t>(b) + 1));
poly_unpack<0, b>(p, slicer);
}

Expand Down

0 comments on commit 22459ba

Please sign in to comment.