Remember that source graphics are rasterized before they're handed to the filter pipeline and hence shed their vectorish nature when they enter the threshold of filterdom.
You are getting that effect because the circle element has an edge of anti-aliasing aka semi-opaque pixels around its edges. When those are multiplied with black, you get grey.
Use shape-rendering="crispEdges" to avoid this. Or use an feMorphology erode filter to clip the edges of the antialiasing. Or use an feFuncA filter to dial those edges up to full opacity first. On second thought -- that first idea.
<circle shape-rendering="crispEdges" stroke-width="0" cx="250" cy="250" r="50"/>