Program: 85854
Project: 85854
Buggy source:
/** 
 * <p>Given the components of a signature and a selector value, recover and return the public key that generated the signature according to the algorithm in SEC1v2 section 4.1.6.</p> <p>The recId is an index from 0 to 3 which indicates which of the 4 possible keys is the correct one. Because the key recovery operation yields multiple potential keys, the correct key must either be stored alongside the signature, or you must be willing to try each recId in turn until you find one that outputs the key you are expecting.</p> <p>If this method returns null it means recovery was not possible and recId should be iterated.</p> <p>Given the above two points, a correct usage of this method is inside a for loop from 0 to 3, and if the output is null OR a key that is not the one you expect, you try again with the next recId.</p>
 * @param recId Which possible key to recover.
 * @param r The R component of the signature.
 * @param s The S component of the signature.
 * @param message Hash of the data that was signed.
 * @param compressed Whether or not the original pubkey was compressed.
 * @return An ECKey containing only the public part, or null if recovery wasn't possible.
 */
public static ECKey recoverFromSignature(int recId,ECDSASignature sig,Sha256Hash message,boolean compressed){
  Preconditions.checkArgument(recId >= 0,"String_Node_Str");
  Preconditions.checkArgument(sig.r.compareTo(BigInteger.ZERO) >= 0,"String_Node_Str");
  Preconditions.checkArgument(sig.s.compareTo(BigInteger.ZERO) >= 0,"String_Node_Str");
  Preconditions.checkNotNull(message);
  BigInteger n=ecParams.getN();
  BigInteger i=BigInteger.valueOf((long)recId / 2);
  BigInteger x=sig.r.add(i.multiply(n));
  ECCurve.Fp curve=(ECCurve.Fp)ecParams.getCurve();
  BigInteger prime=curve.getQ();
  if (x.compareTo(prime) >= 0) {
    return null;
  }
  ECPoint R=decompressKey(x,recId % 2 == 1);
  if (!R.multiply(n).isInfinity())   return null;
  BigInteger e=message.toBigInteger();
  BigInteger eInv=BigInteger.ZERO.subtract(e).mod(n);
  BigInteger rInv=sig.r.modInverse(n);
  BigInteger srInv=rInv.multiply(sig.s).mod(n);
  BigInteger eInvrInv=rInv.multiply(eInv).mod(n);
  ECPoint p1=ecParams.getG().multiply(eInvrInv);
  ECPoint p2=R.multiply(srInv);
  ECPoint.Fp q=(ECPoint.Fp)p2.add(p1);
  if (compressed) {
    q=new ECPoint.Fp(curve,q.getX(),q.getY(),true);
  }
  return new ECKey((byte[])null,q.getEncoded());
}

Fixed version (ground truth):
/** 
 * <p>Given the components of a signature and a selector value, recover and return the public key that generated the signature according to the algorithm in SEC1v2 section 4.1.6.</p> <p>The recId is an index from 0 to 3 which indicates which of the 4 possible keys is the correct one. Because the key recovery operation yields multiple potential keys, the correct key must either be stored alongside the signature, or you must be willing to try each recId in turn until you find one that outputs the key you are expecting.</p> <p>If this method returns null it means recovery was not possible and recId should be iterated.</p> <p>Given the above two points, a correct usage of this method is inside a for loop from 0 to 3, and if the output is null OR a key that is not the one you expect, you try again with the next recId.</p>
 * @param recId Which possible key to recover.
 * @param r The R component of the signature.
 * @param s The S component of the signature.
 * @param message Hash of the data that was signed.
 * @param compressed Whether or not the original pubkey was compressed.
 * @return An ECKey containing only the public part, or null if recovery wasn't possible.
 */
public static ECKey recoverFromSignature(int recId,ECDSASignature sig,Sha256Hash message,boolean compressed){
  Preconditions.checkArgument(recId >= 0,"String_Node_Str");
  Preconditions.checkArgument(sig.r.compareTo(BigInteger.ZERO) >= 0,"String_Node_Str");
  Preconditions.checkArgument(sig.s.compareTo(BigInteger.ZERO) >= 0,"String_Node_Str");
  Preconditions.checkNotNull(message);
  BigInteger n=ecParams.getN();
  BigInteger i=BigInteger.valueOf((long)recId / 2);
  BigInteger x=sig.r.add(i.multiply(n));
  ECCurve.Fp curve=(ECCurve.Fp)ecParams.getCurve();
  BigInteger prime=curve.getQ();
  if (x.compareTo(prime) >= 0) {
    return null;
  }
  ECPoint R=decompressKey(x,(recId & 1) == 1);
  if (!R.multiply(n).isInfinity())   return null;
  BigInteger e=message.toBigInteger();
  BigInteger eInv=BigInteger.ZERO.subtract(e).mod(n);
  BigInteger rInv=sig.r.modInverse(n);
  BigInteger srInv=rInv.multiply(sig.s).mod(n);
  BigInteger eInvrInv=rInv.multiply(eInv).mod(n);
  ECPoint p1=ecParams.getG().multiply(eInvrInv);
  ECPoint p2=R.multiply(srInv);
  ECPoint.Fp q=(ECPoint.Fp)p2.add(p1);
  if (compressed) {
    q=new ECPoint.Fp(curve,q.getX(),q.getY(),true);
  }
  return new ECKey((byte[])null,q.getEncoded());
}