예제 #1
0
        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));
        }
예제 #2
0
        /// *** This is a temporary work-around. ***
        /// We do not know which of the two possible public keys from the commit to use,
        /// so here we try both of them and succeed if either works.
        /// This is sub-optimal in terms of performance.
        /// I believe apoelstra has a strategy for fixing this in the secp256k1-zkp lib.
        public static void verify_from_commit(this Secp256K1 self, Message msg, Signiture sig, Commitment commit)
        {
            if (self.Caps != ContextFlag.Commit)
            {
                throw new Exception("IncapableContext");
            }

            // If we knew which one we cared about here we would just use it,
            // but for now return both so we can try them both.
            var pubkeys = commit.to_two_pubkeys(self);

            // Attempt to verify with the first public key,
            // if verify fails try the other one.
            // The first will fail on average 50% of the time.

            try
            {
                self.Verify(msg, sig, pubkeys[0]);
            }
            catch (Exception)
            {
                self.Verify(msg, sig, pubkeys[1]);
            }
        }