Blind RSA in circl ignored the reader you passed it
Cloudflare's circl has a partially blind RSA signer. Its Blind method takes an io.Reader. The blinding factor used that reader. The salt did not. It read from crypto/rand directly. That breaks the contract. Two calls with the same deterministic reader should give the same blinded message. They did not, because half the randomness came from somewhere else. The sibling code in brsa.go did it right…
Cloudflare's Circl library contains a partially blind RSA signer. This signer's Blind method accepts an io.Reader. The blinding factor is derived from that reader. The salt is not derived from the reader. Instead, it is generated using crypto/rand directly. This deviates from the contract the code follows. Two calls to Blind with the same deterministic reader should produce identical blinded messages.
However, they did not, as half of the randomness was sourced from a different location. The sibling code in brsa.go implemented the correct behavior by using the supplied reader throughout. The fix involves a single line in blindsign/blindrsa/partiallyblindrsa/pbrsa.go: the salt is now generated using io.ReadFull(random, salt). Previously, it was created using rand.Reader.
The test suite verifies the fix. TestBlindUsesSuppliedReader performs Blind twice, using fresh deterministic readers that emit the same byte sequence. Before the fix, the two blinded messages were not identical. After the fix, they match. Callers who pass crypto/rand do not notice any change in behavior. Circl's partially blind RSA signer fix is available at cloudflare/circl#711.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.