public static RangeProof range_proof(this Secp256K1 self, ulong min, ulong value, SecretKey blind, Commitment commit, ProofMessage message) { var retried = false; var proof = new byte[Constants.Constants.MaxProofSize]; var plen = Constants.Constants.MaxProofSize; // IntPtr proofPtr= Marshal.AllocHGlobal(proof.Length); var proofPtr = Marshal.AllocCoTaskMem(plen); Marshal.Copy(proof, 0, proofPtr, proof.Length); // Marshal.Copy(proof, 0, proofPtr, proof.Length); // use a "known key" as the nonce, specifically the blinding factor // of the commitment for which we are generating the range proof // so we can later recover the value and the message by unwinding the range proof // with the same nonce var nonce = blind.Clone(); var extraCommit = ByteUtil.Get_bytes(0, 33); // TODO - confirm this reworked retry logic works as expected // pretty sure the original approach retried on success (so twice in total) // and just kept looping forever on error do { var success = Proxy.secp256k1_rangeproof_sign( self.Ctx, proofPtr, ref plen, min, commit.Value, blind.Value, nonce.Value, 0, 64, value, message.Value, message.Value.Length, extraCommit, 0, Constants.Constants.GeneratorH) == 1; if (success || retried) { break; } retried = true; } while (true); var proof2 = new byte[plen]; Marshal.Copy(proofPtr, proof2, 0, plen); Marshal.FreeCoTaskMem(proofPtr); return(new RangeProof(proof2, plen)); }