/// <summary>
 /// Allows calculation of address with a different AddressType
 /// </summary>
 public AddressBase(AddressBase otheraddress, byte addressType)
 {
     // Hash160 setter validates length and throws exception if needed
     Hash160          = otheraddress.Hash160;
     this.AddressType = addressType;
 }
 /// <summary>
 /// Allows calculation of address with a different AddressType
 /// </summary>
 public AddressBase(AddressBase otheraddress, byte addressType)
 {
     // Hash160 setter validates length and throws exception if needed
     Hash160 = otheraddress.Hash160;
     this.AddressType = addressType;
 }
Exemple #3
0
        /// <summary>
        /// Constructor that takes a single Escrow Invitation Code and produces a Payment Invitation Code.
        /// </summary>
        public EscrowCodeSet(string escrowInvitationCode, bool doCompressed = false, byte networkByte = 0)
        {
            byte[] pubpart, privpart;
            int    identifier30;
            string failreason = parseEscrowCode(escrowInvitationCode, out pubpart, out privpart, out identifier30);

            if (failreason != null)
            {
                throw new ArgumentException(failreason);
            }

            // Look for mismatched parity.
            // (we expect LSB of einva's private part to be 0 and LSB of einvb's private part to be 1)
            // (this is to guarantee that einva's and einvb's private parts aren't equal)
            if ((escrowInvitationCode.StartsWith("einva") && (privpart[31] & 0x01) == 1) ||
                (escrowInvitationCode.StartsWith("einvb") && (privpart[31] & 0x01) == 0))
            {
                throw new ArgumentException("This escrow invitation has mismatched parity.  Ask your escrow agent to " +
                                            "generate a new pair using the latest version of the software.");
            }

            // Look for 48 0's or 48 1's
            if (privpart[0] == privpart[1] && privpart[1] == privpart[2] && privpart[2] == privpart[3] &&
                privpart[3] == privpart[4] && privpart[4] == privpart[5] && privpart[5] == privpart[6] &&
                privpart[6] == privpart[7] && privpart[7] == privpart[8])
            {
                if (privpart[0] == 0x00 || privpart[0] == 0xFF)
                {
                    throw new ArgumentException("This escrow invitation is invalid and cannot be used (bad private key).");
                }
            }


            // produce a new factor
            byte[]       z  = new byte[32];
            SecureRandom sr = new SecureRandom();

            sr.NextBytes(z);

            // calculate Gxy then Gxyz
            PublicKey pk   = new PublicKey(pubpart);
            ECPoint   Gxyz = pk.GetECPoint().Multiply(new BigInteger(1, privpart)).Multiply(new BigInteger(1, z));


            // Uncompress it
            Gxyz = PublicKey.GetUncompressed(Gxyz);

            // We can get the Bitcoin address now, so do so
            PublicKey pkxyz = new PublicKey(Gxyz);

            byte[] hash160 = pkxyz.Hash160;
            BitcoinAddress = new AddressBase(hash160, networkByte).AddressBase58;

            // make the payment invitation record
            byte[] invp  = new byte[74];
            long   headP = headbaseP + (long)identifier30;

            for (int i = 7; i >= 0; i--)
            {
                invp[i] = (byte)(headP & 0xff);
                headP >>= 8;
            }
            invp[8] = networkByte;
            Array.Copy(z, 0, invp, 8 + 1 + 1, 32);

            // set flag to indicate if einvb was used to generate this, and make it available in the object
            if (escrowInvitationCode.StartsWith("einvb"))
            {
                invp[8 + 1 + 1 + 32 + 20] = 0x2;
            }

            // copy hash160
            Array.Copy(hash160, 0, invp, 8 + 1 + 1 + 32, 20);

            PaymentInvitationCode = Util.ByteArrayToBase58Check(invp);
            setAddressConfirmationCode(identifier30, networkByte, invp[8 + 1 + 1 + 32 + 20], z, hash160);
        }
Exemple #4
0
        /// <summary>
        /// Constructor that calculates the address given one escrow invitation code and one matching payment invitation code.
        /// They can be provided in any order.
        /// </summary>
        public EscrowCodeSet(string code1, string code2)
        {
            if (code1 == null || code2 == null || code1 == "" || code2 == "")
            {
                throw new ArgumentException("Two codes are required to use this function.");
            }

            string escrowInvitationCode = null, paymentInvitationCode = null;

            if (code1.StartsWith("einva") || code1.StartsWith("einvb"))
            {
                escrowInvitationCode = code1;
            }
            if (code2.StartsWith("einva") || code2.StartsWith("einvb"))
            {
                escrowInvitationCode = code2;
            }
            if (code1.StartsWith("einvp"))
            {
                paymentInvitationCode = code1;
            }
            if (code2.StartsWith("einvp"))
            {
                paymentInvitationCode = code2;
            }


            if (escrowInvitationCode == null || paymentInvitationCode == null)
            {
                throw new ArgumentException("In order to use this function, one code MUST be an Escrow Invitation (starting " +
                                            "with \"einva\" or \"einvb\") and the other code MUST be a Payment Invitation (starting with \"einvp\").");
            }

            byte[] pubpart, privpart;
            int    identifier30;
            string failreason = parseEscrowCode(escrowInvitationCode, out pubpart, out privpart, out identifier30);

            if (failreason != null)
            {
                throw new ArgumentException(failreason);
            }


            // Look for first 40 bits being all 0's or all 1's


            string notvalid  = "Not a valid Payment Invitation Code";
            string notvalid2 = "Code is not a valid Payment Invitation Code or may have a typo or other error.";
            string notvalid3 = "The Payment Invitation does not belong to the provided Escrow Invitation.";

            long head;

            byte[] invbytes;
            string failReason = parseEitherCode(paymentInvitationCode, notvalid, notvalid2, out invbytes, out head);

            if (head < headbaseP)
            {
                throw new ArgumentException(notvalid);
            }
            long identifier30L = head - headbaseP;

            if (identifier30L < 0 || identifier30L > 0x3FFFFFFFL)
            {
                throw new ArgumentException(notvalid);
            }

            if ((long)identifier30 != identifier30L)
            {
                throw new ArgumentException(notvalid3);
            }

            byte[] privpartz = new byte[32];
            Array.Copy(invbytes, 8 + 1 + 1, privpartz, 0, 32);
            byte networkByte    = invbytes[8];
            bool compressedFlag = (invbytes[8 + 1 + 1 + 32 + 20] & 0x1) == 1;


            // get bitcoin address
            PublicKey pk   = new PublicKey(pubpart);
            ECPoint   Gxyz = pk.GetECPoint().Multiply(new BigInteger(1, privpart)).Multiply(new BigInteger(1, privpartz));

            // uncompress if compress is not indicated
            if (compressedFlag == false)
            {
                Gxyz = PublicKey.GetUncompressed(Gxyz);
            }

            // We can get the Bitcoin address now, so do so
            PublicKey pkxyz = new PublicKey(Gxyz);

            byte[] addrhash160 = pkxyz.Hash160;
            BitcoinAddress = new AddressBase(addrhash160, networkByte).AddressBase58;

            // Does the hash160 match?
            for (int i = 0; i < 20; i++)
            {
                if (addrhash160[i] != invbytes[8 + 1 + 1 + 32 + i])
                {
                    throw new ArgumentException(notvalid3);
                }
            }

            this.PaymentInvitationCode = paymentInvitationCode;

            byte expectedabflag = (byte)(escrowInvitationCode.StartsWith("einva") ? 2 : 0);

            if ((invbytes[8 + 1 + 1 + 32 + 20] & 0x2) != expectedabflag)
            {
                SamePartyWarningApplies = true;
            }
        }
        /// <summary>
        /// Constructor that calculates the address given one escrow invitation code and one matching payment invitation code.
        /// They can be provided in any order.
        /// </summary>
        public EscrowCodeSet(string code1, string code2)
        {
            if (code1 == null || code2 == null || code1 == "" || code2 == "") {
                throw new ArgumentException("Two codes are required to use this function.");
            }

            string escrowInvitationCode=null, paymentInvitationCode=null;

            if (code1.StartsWith("einva") || code1.StartsWith("einvb")) escrowInvitationCode = code1;
            if (code2.StartsWith("einva") || code2.StartsWith("einvb")) escrowInvitationCode = code2;
            if (code1.StartsWith("einvp")) paymentInvitationCode = code1;
            if (code2.StartsWith("einvp")) paymentInvitationCode = code2;

            if (escrowInvitationCode == null || paymentInvitationCode == null) {
                throw new ArgumentException("In order to use this function, one code MUST be an Escrow Invitation (starting " +
                    "with \"einva\" or \"einvb\") and the other code MUST be a Payment Invitation (starting with \"einvp\").");
            }

            byte[] pubpart, privpart;
            int identifier30;
            string failreason = parseEscrowCode(escrowInvitationCode, out pubpart, out privpart, out identifier30);
            if (failreason != null) throw new ArgumentException(failreason);

            // Look for first 40 bits being all 0's or all 1's

            string notvalid = "Not a valid Payment Invitation Code";
            string notvalid2 = "Code is not a valid Payment Invitation Code or may have a typo or other error.";
            string notvalid3 = "The Payment Invitation does not belong to the provided Escrow Invitation.";

            long head;
            byte[] invbytes;
            string failReason = parseEitherCode(paymentInvitationCode, notvalid, notvalid2, out invbytes, out head);

            if (head < headbaseP) throw new ArgumentException(notvalid);
            long identifier30L = head - headbaseP;
            if (identifier30L < 0 || identifier30L > 0x3FFFFFFFL) throw new ArgumentException(notvalid);

            if ((long)identifier30 != identifier30L) {
                throw new ArgumentException(notvalid3);
            }

            byte[] privpartz = new byte[32];
            Array.Copy(invbytes, 8 + 1 + 1, privpartz, 0, 32);
            byte networkByte = invbytes[8];
            bool compressedFlag = (invbytes[8+1+1+32+20] & 0x1) == 1;

            // get bitcoin address
            PublicKey pk = new PublicKey(pubpart);
            ECPoint Gxyz = pk.GetECPoint().Multiply(new BigInteger(1, privpart)).Multiply(new BigInteger(1, privpartz));
            // uncompress if compress is not indicated
            if (compressedFlag == false) Gxyz = PublicKey.GetUncompressed(Gxyz);

            // We can get the Bitcoin address now, so do so
            PublicKey pkxyz = new PublicKey(Gxyz);
            byte[] addrhash160 = pkxyz.Hash160;
            BitcoinAddress = new AddressBase(addrhash160, networkByte).AddressBase58;

            // Does the hash160 match?
            for (int i = 0; i < 20; i++) {
                if (addrhash160[i] != invbytes[8+1+1+32+i]) {
                    throw new ArgumentException(notvalid3);
                }
            }

            this.PaymentInvitationCode = paymentInvitationCode;

            byte expectedabflag = (byte)(escrowInvitationCode.StartsWith("einva") ? 2 : 0);
            if ((invbytes[8+1+1+32+20] & 0x2) != expectedabflag) {
                SamePartyWarningApplies = true;
            }
        }
        /// <summary>
        /// Constructor that takes a single Escrow Invitation Code and produces a Payment Invitation Code.
        /// </summary>
        public EscrowCodeSet(string escrowInvitationCode, bool doCompressed=false, byte networkByte = 0)
        {
            byte[] pubpart, privpart;
            int identifier30;
            string failreason = parseEscrowCode(escrowInvitationCode, out pubpart, out privpart, out identifier30);
            if (failreason != null) throw new ArgumentException(failreason);

            // Look for mismatched parity.
            // (we expect LSB of einva's private part to be 0 and LSB of einvb's private part to be 1)
            // (this is to guarantee that einva's and einvb's private parts aren't equal)
            if ((escrowInvitationCode.StartsWith("einva") && (privpart[31] & 0x01) == 1) ||
                (escrowInvitationCode.StartsWith("einvb") && (privpart[31] & 0x01) == 0)) {
                throw new ArgumentException("This escrow invitation has mismatched parity.  Ask your escrow agent to " +
                    "generate a new pair using the latest version of the software.");
            }

            // Look for 48 0's or 48 1's
            if (privpart[0] == privpart[1] && privpart[1] == privpart[2] && privpart[2] == privpart[3] &&
               privpart[3] == privpart[4] && privpart[4] == privpart[5] && privpart[5] == privpart[6] &&
               privpart[6] == privpart[7] && privpart[7] == privpart[8]) {
                if (privpart[0] == 0x00 || privpart[0] == 0xFF) {
                    throw new ArgumentException("This escrow invitation is invalid and cannot be used (bad private key).");
                }
            }

            // produce a new factor
            byte[] z = new byte[32];
            SecureRandom sr = new SecureRandom();
            sr.NextBytes(z);

            // calculate Gxy then Gxyz
            PublicKey pk = new PublicKey(pubpart);
            ECPoint Gxyz = pk.GetECPoint().Multiply(new BigInteger(1, privpart)).Multiply(new BigInteger(1, z));

            // Uncompress it
            Gxyz = PublicKey.GetUncompressed(Gxyz);

            // We can get the Bitcoin address now, so do so
            PublicKey pkxyz = new PublicKey(Gxyz);
            byte[] hash160 = pkxyz.Hash160;
            BitcoinAddress = new AddressBase(hash160, networkByte).AddressBase58;

            // make the payment invitation record
            byte[] invp = new byte[74];
            long headP = headbaseP + (long)identifier30;
            for (int i = 7; i >= 0; i--) {
                invp[i] = (byte)(headP & 0xff);
                headP >>= 8;
            }
            invp[8] = networkByte;
            Array.Copy(z, 0, invp, 8 + 1 + 1, 32);

            // set flag to indicate if einvb was used to generate this, and make it available in the object
            if (escrowInvitationCode.StartsWith("einvb")) {
                invp[8 + 1 + 1 + 32 + 20] = 0x2;
            }

            // copy hash160
            Array.Copy(hash160, 0, invp, 8 + 1 + 1 + 32, 20);

            PaymentInvitationCode = Util.ByteArrayToBase58Check(invp);
            setAddressConfirmationCode(identifier30, networkByte, invp[8 + 1 + 1 + 32 + 20], z, hash160);
        }
Exemple #7
0
        /// <summary>
        /// Constructor that takes a single Escrow Invitation Code and produces a Payment Invitation Code.
        /// </summary>
        public EscrowCodeSet(string escrowInvitationCode, bool doCompressed=false, byte networkByte = 0)
        {
            byte[] pubpart, privpart;
            int identifier30;
            string failreason = parseEscrowCode(escrowInvitationCode, out pubpart, out privpart, out identifier30);
            if (failreason != null) throw new ArgumentException(failreason);

            // produce a new factor
            byte[] z = new byte[32];
            SecureRandom sr = new SecureRandom();
            sr.NextBytes(z);

            // calculate Gxy then Gxyz
            PublicKey pk = new PublicKey(pubpart);
            ECPoint Gxyz = pk.GetECPoint().Multiply(new BigInteger(1, privpart)).Multiply(new BigInteger(1, z));

            // Uncompress it
            Gxyz = PublicKey.GetUncompressed(Gxyz);

            // We can get the Bitcoin address now, so do so
            PublicKey pkxyz = new PublicKey(Gxyz);
            byte[] hash160 = pkxyz.Hash160;
            BitcoinAddress = new AddressBase(hash160, networkByte).AddressBase58;

            // make the payment invitation record
            byte[] invp = new byte[74];
            long headP = headbaseP + (long)identifier30;
            for (int i = 7; i >= 0; i--) {
                invp[i] = (byte)(headP & 0xff);
                headP >>= 8;
            }
            invp[8] = networkByte;
            Array.Copy(z, 0, invp, 8 + 1 + 1, 32);

            // set flag to indicate if einvb was used to generate this, and make it available in the object
            if (escrowInvitationCode.StartsWith("einvb")) {
                invp[8 + 1 + 1 + 32 + 20] = 0x2;
            }

            // copy hash160
            Array.Copy(hash160, 0, invp, 8 + 1 + 1 + 32, 20);

            PaymentInvitationCode = Util.ByteArrayToBase58Check(invp);
            setAddressConfirmationCode(identifier30, networkByte, invp[8 + 1 + 1 + 32 + 20], z, hash160);
        }
 public KeyCollectionItem(AddressBase address)
 {
     this.Address = address;
 }
 public KeyCollectionItem(AddressBase address)
 {
     this.Address = address;
 }