I made a little Android app that generates random keys and signs random data in a loop, then ran it on a Froyo emulator. I couldn't make it spit out negative r/s values unfortunately. So perhaps my theory is incorrect.
It sounds like maybe bitcoinjs could do this:
https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/ecdsa.jsUnfortunately I don't see any way the results can be negative with that code either. I
do see a minor difference between the Bouncy Castle implementation and ecdsa.js which is that Bouncy Castle will keep retrying the signing process until s is not zero, whereas ecdsa.js won't. Otherwise they look the same.
The serialization code in bitcoinjs looks OK too.
https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/ecdsa.js#L302https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/util.js#L43Other than a bug in the underlying platform math libraries or bogus serialization code, what explanations exist for negative r/s values? None of the underlying BigInteger operations can result in negative numbers.