Esempio n. 1
0
        public static string GenerateSecp256k1PublicKey(string privateKey, bool useCompression)
        {
            var        Ecc          = SecNamedCurves.GetByName("secp256k1");
            var        DomainParams = new ECDomainParameters(Ecc.Curve, Ecc.G, Ecc.N, Ecc.H);
            var        bytes        = Hex.Hex2Bytes(privateKey);
            BigInteger d            = new BigInteger(bytes);
            ECPoint    q            = DomainParams.G.Multiply(d);

            q = q.Normalize();
            var     publicParams = new ECPublicKeyParameters(q, DomainParams);
            FpPoint fp           = new FpPoint(Ecc.Curve, q.AffineXCoord, q.AffineYCoord);

            return(Hex.Bytes2Hex(fp.GetEncoded(useCompression)));
        }
Esempio n. 2
0
        private ExtendedKey GenerateKey(uint index)
        {
            Thrower.Condition <AddressException>((index & HardendIndex) != 0 && !this.Master.HasPrivateKey, "A public key can't derivate an hardened child");

            byte[] extended;
            byte[] pub = this.Master.PublicKey.Bytes;
            if ((index & HardendIndex) == 0)
            {
                var sequenceBytes = BitHelper.GetBytes(index, false);
                extended = pub.ToArray().Concat(sequenceBytes).ToArray();
            }
            else
            {
                var priv          = this.Master.PrivateKey.Bytes;
                var sequenceBytes = BitHelper.GetBytes(index, false);
                extended = (new byte[] { 0 }).Concat(priv.ToArray()).Concat(sequenceBytes).ToArray();
            }

            var leftRight = CryptoUtil.ComputeHmac512(this.ChainCode, extended);
            var leftKey   = leftRight.Take(32).ToArray();
            var rightKey  = leftRight.Skip(32).ToArray();

            BigInteger bigIntegerLeft = new BigInteger(1, leftKey);

            Thrower.Condition <AddressException>(bigIntegerLeft.CompareTo(EcKey.EcParams.N) >= 0, "This is rather unlikely, but it did just happen");

            if (this.Master.HasPrivateKey)
            {
                BigInteger key = bigIntegerLeft.Add(new BigInteger(1, this.Master.PrivateKey.Bytes)).Mod(EcKey.EcParams.N);
                Thrower.Condition <AddressException>(key.Equals(BigInteger.Zero), "This is rather unlikely, but it did just happen");

                ////  fix the private key in case it needs padding
                var keyBytes = new EcKey(key).GetPrivKeyBytes();

                return(new ExtendedKey(new BitcoinPrivateKey(keyBytes), rightKey, (byte)(this.Depth + 1), this.GenerateFingerPrint(), index));
            }
            else
            {
                var qdecoded = EcKey.EcParams.Curve.DecodePoint(this.Master.PublicKey.Bytes);
                var key      = new ECPublicKeyParameters("EC", qdecoded, EcKey.EcParams);

                var qkey = EcKey.EcParams.G.Multiply(bigIntegerLeft).Add(key.Q);
                Thrower.Condition <AddressException>(qkey.IsInfinity, "This is rather unlikely, but it did just happen");

                var point = new FpPoint(EcKey.EcParams.Curve, qkey.Normalize().XCoord, qkey.Normalize().YCoord, true);

                return(new ExtendedKey(new BitcoinPublicKey(point.GetEncoded()), rightKey, (byte)(this.Depth + 1), this.GenerateFingerPrint(), index));
            }
        }
Esempio n. 3
0
        public PubKey Derivate(byte[] cc, uint nChild, out byte[] ccChild)
        {
            byte[] lr = null;
            var    l  = new byte[32];
            var    r  = new byte[32];

            if (nChild >> 31 == 0)
            {
                var pubKey = ToBytes();
                lr = Hashes.BIP32Hash(cc, nChild, pubKey[0], pubKey.Skip(1).ToArray());
            }
            else
            {
                throw new InvalidOperationException("A public key can't derivate an hardened child");
            }

            Array.Copy(lr, l, 32);
            Array.Copy(lr, 32, r, 0, 32);
            ccChild = r;


            var N          = ECKey.CURVE.N;
            var parse256LL = new BigInteger(1, l);

            if (parse256LL.CompareTo(N) >= 0)
            {
                throw new InvalidOperationException(
                          "You won a prize ! this should happen very rarely. Take a screenshot, and roll the dice again.");
            }

            var q = ECKey.CURVE.G.Multiply(parse256LL).Add(this.ECKey.GetPublicKeyParameters().Q);

            if (q.IsInfinity)
            {
                throw new InvalidOperationException(
                          "You won the big prize ! this would happen only 1 in 2^127. Take a screenshot, and roll the dice again.");
            }

            q = q.Normalize();
            var p = new FpPoint(ECKey.CURVE.Curve, q.XCoord, q.YCoord, true);

            return(new PubKey(p.GetEncoded()));
        }
Esempio n. 4
0
 public override byte[] ToByteArray()
 {
     return(point.GetEncoded());
 }
    public void OnClickCreateWalletButton()
    {
        if (nodeIP == null)
        {
            return;
        }
        // packet.GetString();
        bool isVerify = false;

        while (!isVerify)
        {
            string sendJson       = null;
            string sendJsonHeader = null;
            string sendJsonBody   = null;

            JsonData packet = new JsonData();
            JsonData header = new JsonData();
            JsonData body   = new JsonData();

            packet["Header"] = header;
            packet["Body"]   = body;

            //"secp256k1" 세부설정.
            X9ECParameters     ec           = SecNamedCurves.GetByName("secp256k1");
            ECDomainParameters domainParams = new ECDomainParameters(ec.Curve, ec.G, ec.N, ec.H);
            SecureRandom       random       = new SecureRandom();

            // Generate EC KeyPair
            ECKeyPairGenerator        keyGen    = new ECKeyPairGenerator();
            ECKeyGenerationParameters keyParams = new ECKeyGenerationParameters(domainParams, random);
            keyGen.Init(keyParams);
            AsymmetricCipherKeyPair keyPair        = keyGen.GenerateKeyPair();
            ECPublicKeyParameters   publicKeyPara  = keyPair.Public as ECPublicKeyParameters;
            ECPrivateKeyParameters  privateKeyPara = keyPair.Private as ECPrivateKeyParameters;


            ECPoint q   = publicKeyPara.Q;
            FpPoint fp  = new FpPoint(ec.Curve, q.AffineXCoord, q.AffineYCoord);
            byte[]  enc = fp.GetEncoded(true);
            string  compressedPubKey = BitConverter.ToString(enc).Replace("-", "");
            //HexStr으로 표현한 값. 이 publicKey로도 서명이 증명가능.


            SHA256 mySHA256         = SHA256Managed.Create();
            byte[] hashPublicKey    = mySHA256.ComputeHash(HexStringTobytes(compressedPubKey));
            string hexHashPublicKey = bytesToHexString(hashPublicKey);
            sendJsonBody = " \"Body\" : { \"Transaction\" : { \"Type\" : 0, \"UserAddress\" : \""
                           + hexHashPublicKey + "\" } }";
            JsonData transaction = new JsonData();
            body["Transaction"]        = transaction;
            transaction["Type"]        = 0;
            transaction["UserAddress"] = hexHashPublicKey;


            //publicKey를 헥사String으로 변환 후 바이트형식으로 인코딩한걸 해쉬
            ECDsaSigner privSigner = new ECDsaSigner();
            privSigner.Init(true, privateKeyPara);
            BigInteger[] signature = privSigner.GenerateSignature(Encoding.ASCII.GetBytes(packet["Body"].ToJson()));
            BigInteger   r         = signature[0];
            BigInteger   s         = signature[1];
            sendJsonHeader = " \"Header\" : { \"Type\" : \"WalletRegist\", \"PublicKey\" : \"" + compressedPubKey +
                             "\", \"EncryptR\" : \"" + bytesToHexString(r.ToByteArray()) + "\", \"EncryptS\" : \"" +
                             bytesToHexString(s.ToByteArray()) + "\" }";
            header["Type"]      = "WalletRegist";
            header["PublicKey"] = compressedPubKey;
            header["EncryptR"]  = bytesToHexString(r.ToByteArray());
            header["EncryptS"]  = bytesToHexString(s.ToByteArray());

            sendJson = "{ " + sendJsonHeader + ", " + sendJsonBody + " }";

            byte[] walletRegistOutput = Encoding.ASCII.GetBytes(packet.ToJson());
            //Json형식  Str를 byte Array로 해서 보낸다.

            /*
             * // 대칭키 인증서 인증이 맞는지 테스트.
             * BigInteger biPublicKey = new BigInteger(HexStringTobytes(compressedPubKey));
             * ECPoint q2 = domainParams.Curve.DecodePoint(biPublicKey.ToByteArray());
             * publicKeyPara = new ECPublicKeyParameters(q2, domainParams);
             *
             * ECDsaSigner pubSigner = new ECDsaSigner();
             * pubSigner.Init(false, publicKeyPara);
             * Debug.Log(pubSigner.VerifySignature(Encoding.ASCII.GetBytes(packet["Body"].ToJson()), r, s));
             */

            Debug.Log(packet.ToJson());

            TcpClient client = new TcpClient(nodeIP, nodePort);
            //TcpClient client = new TcpClient("13.209.78.154", 51166);
            NetworkStream stream = client.GetStream();
            stream.Write(walletRegistOutput, 0, walletRegistOutput.Length);
            System.Array.Clear(buffer, 0, buffer.Length);
            stream.Read(buffer, 0, buffer.Length);

            JsonData registResponse = JsonMapper.ToObject(Encoding.ASCII.GetString(buffer));
            Debug.Log(Encoding.ASCII.GetString(buffer));
            if (registResponse["Body"]["Response"].GetNatural() == 1)
            {
                // 만약 등록되면
                PlayerPrefs.SetString("PublicKey", compressedPubKey);
                PlayerPrefs.SetString("PrivateKey", bytesToHexString(privateKeyPara.D.ToByteArray()));
                PlayerPrefs.SetString("UserAddress", hexHashPublicKey);

                //지갑이 유효하면 while문을 벗어난다.
                isVerify = true;
            }
            client.Close();
            //우선 소켓을 닫는다.
        }
        changeState();
        OnClickHomeButton();
    }
Esempio n. 6
0
        public static byte[] recoverPubBytesFromSignature(int recId,
                                                          ECDSASignature sig,
                                                          byte[] messageHash)
        {
            check(recId >= 0, "recId must be positive");
            check(sig.r.SignValue >= 0, "r must be positive");
            check(sig.s.SignValue >= 0, "s must be positive");
            check(messageHash != null, "messageHash must not be null");
            // 1.0 For j from 0 to h   (h == recId here and the loop is outside
            // this function)
            //   1.1 Let x = r + jn
            BigInteger n = ECKey.Curve.N;              // Curve order.
            BigInteger i = BigInteger.ValueOf((long)recId / 2);
            BigInteger x = sig.r.Add(i.Multiply(n));

            //   1.2. Convert the integer x to an octet string X of length mlen
            // using the conversion routine
            //        specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or
            // mlen = ⌈m/8⌉.
            //   1.3. Convert the octet string (16 set binary digits)||X to an
            // elliptic curve point R using the
            //        conversion routine specified in Section 2.3.4. If this
            // conversion routine outputs “invalid”, then
            //        do another iteration of Step 1.
            //
            // More concisely, what these points mean is to use X as a compressed
            // public key.
            Org.BouncyCastle.Math.EC.FpCurve curve = (Org.BouncyCastle.Math.EC.FpCurve)ECKey.Curve.Curve;
            BigInteger prime = curve.Q;              // Bouncy Castle is not consistent

            // about the letter it uses for the prime.
            if (x.CompareTo(prime) >= 0)
            {
                // Cannot have point co-ordinates larger than this as everything
                // takes place modulo Q.
                return(null);
            }
            // Compressed allKeys require you to know an extra bit of data about the
            // y-coord as there are two possibilities.
            // So it's encoded in the recId.
            ECPoint R = decompressKey(x, (recId & 1) == 1);

            //   1.4. If nR != point at infinity, then do another iteration of
            // Step 1 (callers responsibility).
            if (!R.Multiply(n).IsInfinity)
            {
                return(null);
            }
            //   1.5. Compute e from M using Steps 2 and 3 of ECDSA signature
            // verification.
            BigInteger e = new BigInteger(1, messageHash);
            //   1.6. For k from 1 to 2 do the following.   (loop is outside this
            // function via iterating recId)
            //   1.6.1. Compute a candidate public key as:
            //               Q = mi(r) * (sR - eG)
            //
            // Where mi(x) is the modular multiplicative inverse. We transform
            // this into the following:
            //               Q = (mi(r) * s ** R) + (mi(r) * -e ** G)
            // Where -e is the modular additive inverse of e, that is z such that
            // z + e = 0 (mod n). In the above equation
            // ** is point multiplication and + is point addition (the EC group
            // operator).
            //
            // We can find the additive inverse by subtracting e from zero then
            // taking the mod. For example the additive
            // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod
            // 11 = 8.
            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);
            FpPoint    q        = (FpPoint)ECAlgorithms.SumOfTwoMultiplies(ECKey.Params.G, eInvrInv, R, srInv);

            return(q.GetEncoded(/* compressed */ false));
        }