Ejemplo n.º 1
0
        /**
         * Goes through all points on an elliptic curve and checks, if adding a
         * point <code>k</code>-times is the same as multiplying the point by
         * <code>k</code>, for all <code>k</code>. Should be called for points
         * on very small elliptic curves only.
         *
         * @param p
         *            The base point on the elliptic curve.
         * @param infinity
         *            The point at infinity on the elliptic curve.
         */
        private void implTestAllPoints(ECPoint p, ECPoint infinity)
        {
            ECPoint adder      = infinity;
            ECPoint multiplier = infinity;
            int     i          = 1;

            do
            {
                adder      = adder.Add(p);
                multiplier = p.Multiply(new BigInteger(i.ToString()));
                Assert.AreEqual(adder, multiplier,
                                "Results of add() and multiply() are inconsistent " + i);
                i++;
            }while (!(adder.Equals(infinity)));
        }
Ejemplo n.º 2
0
        void PointCompressTest(int bits, ECGroup group, ECPoint p, int repeats, string name)
        {
            int bytes = (bits >> 3) + ((bits & 7) == 0 ? 0 : 1) + 1;

            for (int i = 0; i < repeats; i++)
            {
                byte[] tmp = p.ToByteArray(true);
                Assert.IsTrue(tmp.Length == bytes, name + " #1");
                ECPoint x  = new ECPoint(group, tmp).Export();
                ECPoint p2 = p.Export();
                Assert.IsTrue(x.X.CompareTo(p2.X) == 0, name + " #2");
                Assert.IsTrue(x.Y.CompareTo(p2.Y) == 0, name + " #3");
                p = p.Multiply(Number.CreateRandomElement(group.P));
            }
        }
Ejemplo n.º 3
0
        private void ComputePublicKey()
        {
            var     ps    = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1");
            ECPoint point = ps.G;

            Org.BouncyCastle.Math.BigInteger Db = new Org.BouncyCastle.Math.BigInteger(1, privKey);
            ECPoint dd = point.Multiply(Db);

            pubaddr = new byte[65];
            byte[] Y = dd.Y.ToBigInteger().ToByteArray();
            Array.Copy(Y, 0, pubaddr, 64 - Y.Length + 1, Y.Length);
            byte[] X = dd.X.ToBigInteger().ToByteArray();
            Array.Copy(X, 0, pubaddr, 32 - X.Length + 1, X.Length);
            pubaddr[0] = 4;
        }
Ejemplo n.º 4
0
        /**
         * Goes through all points on an elliptic curve and checks, if adding a
         * point <code>k</code>-times is the same as multiplying the point by
         * <code>k</code>, for all <code>k</code>. Should be called for points
         * on very small elliptic curves only.
         *
         * @param p
         *            The base point on the elliptic curve.
         * @param infinity
         *            The point at infinity on the elliptic curve.
         */
        private void ImplTestAllPoints(ECPoint p, ECPoint infinity)
        {
            ECPoint adder      = infinity;
            ECPoint multiplier = infinity;

            BigInteger i = BigInteger.One;

            do
            {
                adder      = adder.Add(p);
                multiplier = p.Multiply(i);
                AssertPointsEqual("Results of Add() and Multiply() are inconsistent " + i, adder, multiplier);
                i = i.Add(BigInteger.One);
            }while (!(adder.Equals(infinity)));
        }
Ejemplo n.º 5
0
        // Section 7.2.6 ECVP-NR, pg 35

        /**
         * return true if the value r and s represent a signature for the
         * message passed in. Generally, the order of the curve should be at
         * least as long as the hash of the message of interest, and with
         * ECNR, it *must* be at least as long.  But just in case the signer
         * applied mod(n) to the longer digest, this implementation will
         * apply mod(n) during verification.
         *
         * @param digest  the digest to be verified.
         * @param r       the r value of the signature.
         * @param s       the s value of the signature.
         * @exception DataLengthException if the digest is longer than the key allows
         */
        public bool VerifySignature(
            byte[]          message,
            BigInteger r,
            BigInteger s)
        {
            if (this.forSigning)
            {
                // not properly initilaized... deal with it
                throw new InvalidOperationException("not initialised for verifying");
            }

            ECPublicKeyParameters pubKey = (ECPublicKeyParameters)key;
            BigInteger            n      = pubKey.Parameters.N;
            int nBitLength = n.BitLength;

            BigInteger e          = new BigInteger(1, message);
            int        eBitLength = e.BitLength;

            if (eBitLength > nBitLength)
            {
                throw new DataLengthException("input too large for ECNR key.");
            }

            // r in the range [1,n-1]
            if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
            {
                return(false);
            }

            // TODO So why is this different from the spec?
            // s in the range [0,n-1]           NB: ECNR spec says 0
            if (s.CompareTo(BigInteger.Zero) < 0 || s.CompareTo(n) >= 0)
            {
                return(false);
            }

            // compute P = sG + rW

            ECPoint G = pubKey.Parameters.G;
            ECPoint W = pubKey.Q;
            // calculate P using Bouncy math
            ECPoint P = G.Multiply(s).Add(W.Multiply(r));

            BigInteger x = P.X.ToBigInteger();
            BigInteger t = r.Subtract(x).Mod(n);

            return(t.Equals(e));
        }
Ejemplo n.º 6
0
        private SimpleTestResult Test431()
        {
            SecureRandom random = FixedSecureRandom.From(Hex.Decode("0000C4224DBBD800988DBAA39DE838294C345CDA5F5929D1174AA8D9340A5E79D10ACADE6B53CF873E7301A3871C2073AD75AB530457"));

            byte[] hash = Hex.Decode("0137187EA862117EF1484289470ECAC802C5A651FDA8");
            Array.Reverse(hash);


            BigInteger r = new BigInteger("1911fefb1f494bebcf8dffdf5276946ff9c9f662192ee18c718db47310a439c784fe07577b16e1edbe16179876e0792a634f1c9c3a2e", 16);
            BigInteger s = new BigInteger("3852170ee801c2083c52f1ea77b987a5432acecd9c654f064e87bf179e0a397151edbca430082e43bd38a67b55424b5bbc7f2713f620", 16);

            F2mCurve   curve = new F2mCurve(431, 1, 3, 5, BigInteger.One, new BigInteger("3CE10490F6A708FC26DFE8C3D27C4F94E690134D5BFF988D8D28AAEAEDE975936C66BAC536B18AE2DC312CA493117DAA469C640CAF3", 16));
            ECPoint    P     = curve.CreatePoint(new BigInteger("9548BCDF314CEEEAF099C780FFEFBF93F9FE5B5F55547603C9C8FC1A2774170882B3BE35E892C6D4296B8DEA282EC30FB344272791", 16), new BigInteger("4C6CBD7C62A8EEEFDE17A8B5E196E49A22CE6DE128ABD9FBD81FA4411AD5A38E2A810BEDE09A7C6226BCDCB4A4A5DA37B4725E00AA74", 16));
            BigInteger n     = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA3175458009A8C0A724F02F81AA8A1FCBAF80D90C7A95110504CF", 16);

            BigInteger d = new BigInteger("D0F97354E314191FD773E2404F478C8AEE0FF5109F39E6F37D1FEEC8B2ED1691D84C9882CC729E716A71CC013F66CAC60E29E22C", 16);
            ECPoint    Q = P.Multiply(d).Negate();

            ECDomainParameters    domain  = new ECDomainParameters(curve, P, n);
            ICipherParameters     privKey = new ParametersWithRandom(new ECPrivateKeyParameters(d, domain), random);
            ECPublicKeyParameters pubKey  = new ECPublicKeyParameters(Q, domain);



            Dstu4145Signer dstuSigner = new Dstu4145Signer();

            dstuSigner.Init(true, privKey);
            BigInteger[] rs = dstuSigner.GenerateSignature(hash);

            if (rs[0].CompareTo(r) != 0)
            {
                return(new SimpleTestResult(false, Name + " test 431: expected r: " + r.ToString(16) + " got r:" + rs[0].ToString(16)));
            }

            if (rs[1].CompareTo(s) != 0)
            {
                return(new SimpleTestResult(false, Name + " test 431: expected s: " + s.ToString(16) + " got s:" + rs[1].ToString(16)));
            }

            dstuSigner.Init(false, pubKey);
            if (!dstuSigner.VerifySignature(hash, r, s))
            {
                return(new SimpleTestResult(false, Name + " test 431: verification failed"));
            }

            return(new SimpleTestResult(true, Name + ": Okay"));
        }
Ejemplo n.º 7
0
        private SimpleTestResult Test163()
        {
            SecureRandom random = FixedSecureRandom.From(Hex.Decode("01025e40bd97db012b7a1d79de8e12932d247f61c6"));

            byte[] hash = Hex.Decode("09c9c44277910c9aaee486883a2eb95b7180166ddf73532eeb76edaef52247ff");
            Array.Reverse(hash);


            BigInteger r = new BigInteger("274ea2c0caa014a0d80a424f59ade7a93068d08a7", 16);
            BigInteger s = new BigInteger("2100d86957331832b8e8c230f5bd6a332b3615aca", 16);

            F2mCurve   curve = new F2mCurve(163, 3, 6, 7, BigInteger.One, new BigInteger("5FF6108462A2DC8210AB403925E638A19C1455D21", 16));
            ECPoint    P     = curve.CreatePoint(new BigInteger("72d867f93a93ac27df9ff01affe74885c8c540420", 16), new BigInteger("0224a9c3947852b97c5599d5f4ab81122adc3fd9b", 16));
            BigInteger n     = new BigInteger("400000000000000000002BEC12BE2262D39BCF14D", 16);

            BigInteger d = new BigInteger("183f60fdf7951ff47d67193f8d073790c1c9b5a3e", 16);
            ECPoint    Q = P.Multiply(d).Negate();

            ECDomainParameters    domain  = new ECDomainParameters(curve, P, n);
            ICipherParameters     privKey = new ParametersWithRandom(new ECPrivateKeyParameters(d, domain), random);
            ECPublicKeyParameters pubKey  = new ECPublicKeyParameters(Q, domain);

            Dstu4145Signer dstuSigner = new Dstu4145Signer();

            dstuSigner.Init(true, privKey);
            BigInteger[] rs = dstuSigner.GenerateSignature(hash);

            if (rs[0].CompareTo(r) != 0)
            {
                return(new SimpleTestResult(false, Name + " test 163: expected r: " + r.ToString(16) + " got r:" + rs[0].ToString(16)));
            }

            if (rs[1].CompareTo(s) != 0)
            {
                return(new SimpleTestResult(false, Name + " test 163: expected s: " + s.ToString(16) + " got s:" + rs[1].ToString(16)));
            }

            dstuSigner.Init(false, pubKey);
            if (!dstuSigner.VerifySignature(hash, r, s))
            {
                return(new SimpleTestResult(false, Name + " test 163: verification failed"));
            }

            return(new SimpleTestResult(true, Name + ": Okay"));
        }
Ejemplo n.º 8
0
        private SimpleTestResult Test173()
        {
            SecureRandom random = FixedSecureRandom.From(Hex.Decode("0000137449348C1249971759D99C252FFE1E14D8B31F"));

            byte[] hash = Hex.Decode("0137187EA862117EF1484289470ECAC802C5A651FDA8");
            Array.Reverse(hash);


            BigInteger r = new BigInteger("13ae89746386709cdbd237cc5ec20ca30004a82ead8", 16);
            BigInteger s = new BigInteger("3597912cdd093b3e711ccb74a79d3c4ab4c7cccdc60", 16);

            F2mCurve   curve = new F2mCurve(173, 1, 2, 10, BigInteger.Zero, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16));
            ECPoint    P     = curve.CreatePoint(new BigInteger("BE6628EC3E67A91A4E470894FBA72B52C515F8AEE9", 16), new BigInteger("D9DEEDF655CF5412313C11CA566CDC71F4DA57DB45C", 16));
            BigInteger n     = new BigInteger("800000000000000000000189B4E67606E3825BB2831", 16);

            BigInteger d = new BigInteger("955CD7E344303D1034E66933DC21C8044D42ADB8", 16);
            ECPoint    Q = P.Multiply(d).Negate();

            ECDomainParameters    domain  = new ECDomainParameters(curve, P, n);
            ICipherParameters     privKey = new ParametersWithRandom(new ECPrivateKeyParameters(d, domain), random);
            ECPublicKeyParameters pubKey  = new ECPublicKeyParameters(Q, domain);

            Dstu4145Signer dstuSigner = new Dstu4145Signer();

            dstuSigner.Init(true, privKey);
            BigInteger[] rs = dstuSigner.GenerateSignature(hash);

            if (rs[0].CompareTo(r) != 0)
            {
                return(new SimpleTestResult(false, Name + " test 173: expected r: " + r.ToString(16) + " got r:" + rs[0].ToString(16)));
            }

            if (rs[1].CompareTo(s) != 0)
            {
                return(new SimpleTestResult(false, Name + " test 173: expected s: " + s.ToString(16) + " got s:" + rs[1].ToString(16)));
            }

            dstuSigner.Init(false, pubKey);
            if (!dstuSigner.VerifySignature(hash, r, s))
            {
                return(new SimpleTestResult(false, Name + " test 173: verification failed"));
            }

            return(new SimpleTestResult(true, Name + ": Okay"));
        }
Ejemplo n.º 9
0
        private SimpleTestResult Test283()
        {
            SecureRandom random = FixedSecureRandom.From(Hex.Decode("00000000245383CB3AD41BF30F5F7E8FBA858509B2D5558C92D539A6D994BFA98BC6940E"));

            byte[] hash = Hex.Decode("0137187EA862117EF1484289470ECAC802C5A651FDA8");
            Array.Reverse(hash);


            BigInteger r = new BigInteger("12a5edcc38d92208ff23036d75b000c7e4bc0f9af2d40b35f15d6fd15e01234e67781a8", 16);
            BigInteger s = new BigInteger("2de0775577f75b643cf5afc80d4fe10b21100690f17e2cab7bdc9b50ec87c5727aeb515", 16);

            F2mCurve   curve = new F2mCurve(283, 5, 7, 12, BigInteger.One, new BigInteger("27B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", 16));
            ECPoint    P     = curve.CreatePoint(new BigInteger("4D95820ACE761110824CE425C8089129487389B7F0E0A9D043DDC0BB0A4CC9EB25", 16), new BigInteger("954C9C4029B2C62DE35C2B9C2A164984BF1101951E3A68ED03DF234DDE5BB2013152F2", 16));
            BigInteger n     = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", 16);

            BigInteger d = new BigInteger("B844EEAF15213E4BAD4FB84796D68F2448DB8EB7B4621EC0D51929874892C43E", 16);
            ECPoint    Q = P.Multiply(d).Negate();

            ECDomainParameters    domain  = new ECDomainParameters(curve, P, n);
            ICipherParameters     privKey = new ParametersWithRandom(new ECPrivateKeyParameters(d, domain), random);
            ECPublicKeyParameters pubKey  = new ECPublicKeyParameters(Q, domain);

            Dstu4145Signer dstuSigner = new Dstu4145Signer();

            dstuSigner.Init(true, privKey);
            BigInteger[] rs = dstuSigner.GenerateSignature(hash);

            if (rs[0].CompareTo(r) != 0)
            {
                return(new SimpleTestResult(false, Name + " test 283: expected r: " + r.ToString(16) + " got r:" + rs[0].ToString(16)));
            }

            if (rs[1].CompareTo(s) != 0)
            {
                return(new SimpleTestResult(false, Name + " test 283: expected s: " + s.ToString(16) + " got s:" + rs[1].ToString(16)));
            }

            dstuSigner.Init(false, pubKey);
            if (!dstuSigner.VerifySignature(hash, r, s))
            {
                return(new SimpleTestResult(false, Name + " test 283: verification failed"));
            }

            return(new SimpleTestResult(true, Name + ": Okay"));
        }
Ejemplo n.º 10
0
        private SimpleTestResult TestTruncation()
        {
            SecureRandom random = FixedSecureRandom.From(Hex.Decode("0000C4224DBBD800988DBAA39DE838294C345CDA5F5929D1174AA8D9340A5E79D10ACADE6B53CF873E7301A3871C2073AD75AB530457"));

            // use extra long "hash" with set bits ...
            byte[] hash = Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");


            BigInteger r = new BigInteger("6bb5c0cb82e5067485458ebfe81025f03b687c63a27", 16);
            BigInteger s = new BigInteger("34d6b1868969b86ecf934167c8fe352c63d1074bd", 16);

            F2mCurve   curve = new F2mCurve(173, 1, 2, 10, BigInteger.Zero, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16));
            ECPoint    P     = curve.CreatePoint(new BigInteger("BE6628EC3E67A91A4E470894FBA72B52C515F8AEE9", 16), new BigInteger("D9DEEDF655CF5412313C11CA566CDC71F4DA57DB45C", 16));
            BigInteger n     = new BigInteger("800000000000000000000189B4E67606E3825BB2831", 16);

            BigInteger d = new BigInteger("955CD7E344303D1034E66933DC21C8044D42ADB8", 16);
            ECPoint    Q = P.Multiply(d).Negate();

            ECDomainParameters    domain  = new ECDomainParameters(curve, P, n);
            ICipherParameters     privKey = new ParametersWithRandom(new ECPrivateKeyParameters(d, domain), random);
            ECPublicKeyParameters pubKey  = new ECPublicKeyParameters(Q, domain);

            Dstu4145Signer dstuSigner = new Dstu4145Signer();

            dstuSigner.Init(true, privKey);
            BigInteger[] rs = dstuSigner.GenerateSignature(hash);

            if (rs[0].CompareTo(r) != 0)
            {
                return(new SimpleTestResult(false, Name + " test truncation: expected r: " + r.ToString(16) + " got r:" + rs[0].ToString(16)));
            }

            if (rs[1].CompareTo(s) != 0)
            {
                return(new SimpleTestResult(false, Name + " test truncation: expected s: " + s.ToString(16) + " got s:" + rs[1].ToString(16)));
            }

            dstuSigner.Init(false, pubKey);
            if (!dstuSigner.VerifySignature(hash, r, s))
            {
                return(new SimpleTestResult(false, Name + " test truncation: verification failed"));
            }

            return(new SimpleTestResult(true, Name + ": Okay"));
        }
Ejemplo n.º 11
0
        public bool Check(string passphrase, BitcoinAddress expectedAddress)
        {
            //Derive passfactor using scrypt with ownerentropy and the user's passphrase and use it to recompute passpoint
            byte[] passfactor = BitcoinEncryptedSecretEC.CalculatePassFactor(passphrase, LotSequence, OwnerEntropy);
            //Derive decryption key for pointb using scrypt with passpoint, addresshash, and ownerentropy
            byte[] passpoint = BitcoinEncryptedSecretEC.CalculatePassPoint(passfactor);
            byte[] derived   = BitcoinEncryptedSecretEC.CalculateDecryptionKey(passpoint, AddressHash, OwnerEntropy);

            //Decrypt encryptedpointb to yield pointb
            var pointbprefix = EncryptedPointB[0];

            pointbprefix = (byte)(pointbprefix ^ (byte)(derived[63] & (byte)0x01));

            //Optional since ArithmeticException will catch it, but it saves some times
            if (pointbprefix != 0x02 && pointbprefix != 0x03)
            {
                return(false);
            }
            var pointb = BitcoinEncryptedSecret.DecryptKey(EncryptedPointB.Skip(1).ToArray(), derived);

            pointb = new byte[] { pointbprefix }.Concat(pointb).ToArray();

            //4.ECMultiply pointb by passfactor. Use the resulting EC point as a public key
            var     curve    = ECKey.CreateCurve();
            ECPoint pointbec = null;

            try
            {
                pointbec = curve.Curve.DecodePoint(pointb);
            }
            catch (ArithmeticException)
            {
                return(false);
            }
            PubKey pubkey = new PubKey(pointbec.Multiply(new BigInteger(1, passfactor)).GetEncoded());

            //and hash it into address using either compressed or uncompressed public key methodology as specifid in flagbyte.
            pubkey = IsCompressed ? pubkey.Compress() : pubkey.Decompress();

            var actualhash   = BitcoinEncryptedSecretEC.HashAddress(pubkey.GetAddress(Network));
            var expectedhash = BitcoinEncryptedSecretEC.HashAddress(expectedAddress);

            return(Utils.ArrayEqual(actualhash, expectedhash));
        }
Ejemplo n.º 12
0
        /**
         * Recover the public key from signature and message.
         * @param recId recovery id which 0 or 1.
         * @param sig {@link ECDSASignature} a signature object
         * @param message message bytes array.
         * @return public key represented by {@link BigInteger}
         */
        public static BigInteger RecoverFromSignature(int recId, ECDSASignature sig, byte[] message)
        {
            if (!(recId == 0 || recId == 1))
            {
                throw new ArgumentOutOfRangeException(nameof(recId), "recId must be 0 or 1");
            }
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message), "message cannot be null");
            }


            BigInteger n = ECKeyPair.Curve.N; // Curve order.
            BigInteger i = BigInteger.ValueOf((long)recId / 2);
            BigInteger x = sig.R.Add(i.Multiply(n));

            // TODO SecP256K1Curve
            //BigInteger prime = SecP256K1Curve.q;
            //if (x.CompareTo(prime) >= 0)
            //{
            //    return null;
            //}

            ECPoint R = DecompressKey(x, (recId & 1) == 1);

            if (!R.Multiply(n).IsInfinity)
            {
                return(null);
            }

            BigInteger e = new BigInteger(1, message);

            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    q        = ECAlgorithms.SumOfTwoMultiplies(ECKeyPair.Curve.G, eInvrInv, R, srInv);

            byte[] qBytes = q.GetEncoded(false);
            // We remove the prefix
            return(new BigInteger(1, Arrays.CopyOfRange(qBytes, 1, qBytes.Length)));
        }
Ejemplo n.º 13
0
        byte[] PerformKeyAgreement(ECPoint other, int keyDataLength)
        {
            // Diffie-Hellman Primitives
            if (_params.D == null)
            {
                _params.CreateNewPrivateKey();
            }
            Number sharedSecretField = other.Multiply(_params.D).Export().X;

            byte[] sharedSecretValue = new byte[(_params.Domain.Bits >> 3) + ((_params.Domain.Bits & 7) == 0 ? 0 : 1)];
            sharedSecretField.CopyToBigEndian(sharedSecretValue, 0, sharedSecretValue.Length);

            // KDF
            if (_kdf == null)
            {
                return(sharedSecretValue);
            }
            _kdf.SharedInfo = _sharedInfo;
            return(_kdf.Calculate(sharedSecretValue, keyDataLength));
        }
Ejemplo n.º 14
0
        public virtual ECPoint Init_enc(SM2 sm2, ECPoint userKey)
        {
            BigInteger k  = null;
            ECPoint    c1 = null;


            AsymmetricCipherKeyPair key    = sm2.ecc_key_pair_generator.GenerateKeyPair();
            ECPrivateKeyParameters  ecpriv = (ECPrivateKeyParameters)key.Private;
            ECPublicKeyParameters   ecpub  = (ECPublicKeyParameters)key.Public;

            k  = ecpriv.D;
            c1 = ecpub.Q;


            p2 = userKey.Multiply(k);
            Reset();


            return(c1);
        }
Ejemplo n.º 15
0
        public byte[] PerformKeyAgreement(byte[] otherPublicKey1, byte[] otherPublicKey2, int keyDataLength)
        {
            ECPoint      otherQ1 = new ECPoint(_params.Domain.Group, otherPublicKey1);
            ECPoint      otherQ2 = new ECPoint(_params.Domain.Group, otherPublicKey2);
            IFiniteField ff      = _params.Domain.FieldN;

            // MQV Primitives
            if (_params.KeyPair1.D == null)
            {
                _params.KeyPair1.CreateNewPrivateKey();
            }
            if (_params.KeyPair2.D == null)
            {
                _params.KeyPair2.CreateNewPrivateKey();
            }
            if (_params.KeyPair2.Q == null)
            {
                _params.KeyPair2.CreatePublicKeyFromPrivateKey();
            }
            int logBits = _params.Domain.N.BitCount();

            logBits = (logBits >> 1) + ((logBits & 1) == 0 ? 0 : 1);
            Number  mod  = Number.One << logBits;
            Number  mask = mod - Number.One;
            Number  q2u  = (_params.KeyPair2.Q.Export().X & mask) + mod;
            Number  s    = ff.Add(_params.KeyPair2.D, ff.Multiply(q2u, _params.KeyPair1.D));
            Number  q2v  = (otherQ2.Export().X & mask) + mod;
            ECPoint P    = otherQ2.Add(otherQ1.Multiply(q2v)).Multiply(s * new Number(new uint[] { _params.Domain.H }));

            if (P.IsInifinity())
            {
                throw new CryptographicException();
            }
            int keyBytes = (int)((_params.Domain.Bits >> 3) + ((_params.Domain.Bits & 7) == 0 ? 0 : 1));

            byte[] sharedSecretValue = P.Export().X.ToByteArray(keyBytes, false);

            // KDF
            _kdf.SharedInfo = _sharedInfo;
            return(_kdf.Calculate(sharedSecretValue, keyDataLength));
        }
Ejemplo n.º 16
0
        private ECPoint CalculatePoint(ECPublicKeyParameters pubKeyParams)
        {
            ECDomainParameters dp = keyParam.Parameters;

            if (!dp.Equals(pubKeyParams.Parameters))
            {
                throw new InvalidOperationException(
                          "ECDH public key has wrong domain parameters"
                          );
            }

            BigInteger d = keyParam.D;

            ECPoint q = dp.Curve.DecodePoint(pubKeyParams.Q.GetEncoded(true));

            if (q.IsInfinity)
            {
                throw new InvalidOperationException(
                          "Infinity is not a valid public key for ECDH"
                          );
            }

            BigInteger h = dp.H;

            if (!h.Equals(BigInteger.One))
            {
                d = dp.H.ModInverse(dp.N).Multiply(d).Mod(dp.N);
                q = ECAlgorithms.ReferenceMultiply(q, h);
            }

            ECPoint p = q.Multiply(d).Normalize();

            if (p.IsInfinity)
            {
                throw new InvalidOperationException(
                          "Infinity is not a valid agreement value for ECDH"
                          );
            }

            return(p);
        }
Ejemplo n.º 17
0
        /// <summary>Calculates a shared secred with ECDH from the client private and server public key.</summary>
        /// <param name="publicKeyPoint">The public key of the server.</param>
        /// <returns>Returns a 32 byte shared secret.</returns>
        private byte[] GetSharedSecret(ECPoint publicKeyPoint)
        {
            ECPoint p = publicKeyPoint.Multiply(Identity.PrivateKey).Normalize();

            byte[] keyArr = p.AffineXCoord.ToBigInteger().ToByteArray();
            if (keyArr.Length == 32)
            {
                return(keyArr);
            }
            var sharedData = new byte[32];

            if (keyArr.Length > 32)
            {
                Array.Copy(keyArr, keyArr.Length - 32, sharedData, 0, 32);
            }
            else             // keyArr.Length < 32
            {
                Array.Copy(keyArr, 0, sharedData, 32 - keyArr.Length, keyArr.Length);
            }
            return(sharedData);
        }
Ejemplo n.º 18
0
        public static bool Verify(byte[] msg, Signature sig, ECPoint publicKey)
        {
            if (sig.R == BigInteger.Zero || sig.S == BigInteger.Zero)
            {
                throw new Exception("Invalid R or S value: cannot be zero.");
            }

            if (sig.R.SignValue == -1 || sig.S.SignValue == -1)
            {
                throw new Exception("Invalid R or S value: cannot be negative.");
            }

            if (publicKey.Curve != (secp256k1.Curve))
            {
                throw new Exception("The public key must be a point on secp256k1.");
            }

            if (!publicKey.IsValid())
            {
                throw new Exception("Invalid public key.");
            }

            ECPoint l = publicKey.Multiply(sig.R);
            ECPoint r = secp256k1.G.Multiply(sig.S);
            ECPoint Q = l.Add(r);

            if (Q.IsInfinity || !Q.IsValid())
            {
                throw new Exception("Invalid intermediate point.");
            }

            BigInteger r1 = Hash(Q, publicKey, msg).Mod(secp256k1.N);

            if (r1 == (BigInteger.Zero))
            {
                throw new Exception("Invalid hash.");
            }

            return(r1.Equals(sig.R));
        }
        /**
         * return true if the value r and s represent a GOST3410 signature for
         * the passed in message (for standard GOST3410 the message should be
         * a GOST3411 hash of the real message to be verified).
         */
        public bool VerifySignature(
            byte[]          message,
            BigInteger r,
            BigInteger s)
        {
            byte[] mRev = new byte[message.Length];             // conversion is little-endian
            for (int i = 0; i != mRev.Length; i++)
            {
                mRev[i] = message[mRev.Length - 1 - i];
            }

            BigInteger e = new BigInteger(1, mRev);
            BigInteger n = key.Parameters.N;

            // r in the range [1,n-1]
            if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0)
            {
                return(false);
            }

            // s in the range [1,n-1]
            if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0)
            {
                return(false);
            }

            BigInteger v = e.ModInverse(n);

            BigInteger z1 = s.Multiply(v).Mod(n);
            BigInteger z2 = (n.Subtract(r)).Multiply(v).Mod(n);

            ECPoint G = key.Parameters.G;             // P
            ECPoint Q = ((ECPublicKeyParameters)key).Q;

            ECPoint point = G.Multiply(z1).Add(Q.Multiply(z2));

            BigInteger R = point.X.ToBigInteger().Mod(n);

            return(R.Equals(r));
        }
Ejemplo n.º 20
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="md">消息</param>
        /// <param name="userKey">公钥</param>
        /// <param name="r">由数字签名得到的大数r</param>
        /// <param name="s">由数字签名得到的大数s</param>
        /// <param name="sm2Ret"></param>
        public virtual void Sm2Verify(byte[] md, ECPoint userKey, BigInteger r, BigInteger s, SM2Result sm2Ret)//客户端验证
        {
            sm2Ret.R = null;

            // e_
            BigInteger e = new BigInteger(1, md); //字节转化大整数e
            // t
            BigInteger t = r.Add(s).Mod(ecc_n);   //大数t=(r+s)%n;

            if (t.Equals(BigInteger.Zero))        //如果t==0,返回上一层
            {
                return;
            }

            // x1y1
            ECPoint x1y1 = ecc_point_g.Multiply(sm2Ret.s); //x1y1=g*s

            x1y1 = x1y1.Add(userKey.Multiply(t));          //x1y1=x1y1+公钥*(t),其中t=(r+s)%n

            // R
            sm2Ret.R = e.Add(x1y1.X.ToBigInteger()).Mod(ecc_n);//r=(x1y1点的X的大数形式+e)%n
        }
Ejemplo n.º 21
0
        public void TestAddSubtractMultiplyTwiceEncoding()
        {
            foreach (string name in SecNamedCurves.Names)
            {
                X9ECParameters x9ECParameters = SecNamedCurves.GetByName(name);

                IBigInteger n = x9ECParameters.N;

                // The generator is multiplied by random b to get random q
                IBigInteger b = new BigInteger(n.BitLength, _secRand);
                ECPoint     g = x9ECParameters.G;
                ECPoint     q = g.Multiply(b);

                // Get point at infinity on the curve
                ECPoint infinity = x9ECParameters.Curve.Infinity;

                implTestAddSubtract(q, infinity);
                ImplTestMultiply(q, n.BitLength);
                ImplTestMultiply(infinity, n.BitLength);
                implTestEncoding(q);
            }
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Recover the public key from signature and message.
        /// </summary>
        /// <param name="i">recovery id which 0 or 1</param>
        /// <param name="sig">a signature object</param>
        /// <param name="message">message bytes array</param>
        /// <returns>public key</returns>
        public static BigInteger RecoverFromSignature(int recId, ECDSASignature sig, byte[] message)
        {
            VerifyPrecondition(recId == 0 || recId == 1, "recId must be 0 or 1");
            VerifyPrecondition(sig.R.SignValue >= 0, "r must be positive");
            VerifyPrecondition(sig.S.SignValue >= 0, "s must be positive");
            VerifyPrecondition(message != null, "message cannot be null");

            var n = ECKeyPair.CURVE.N; // Curve order.
            var i = BigInteger.ValueOf((long)recId / 2);
            var x = sig.R.Add(i.Multiply(n));

            var Prime = new BigInteger(1, Hex.Decode("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"));

            if (x.CompareTo(Prime) >= 0)
            {
                return(null);
            }

            ECPoint R = DecompressKey(x, (recId & 1) == 1);

            if (!R.Multiply(n).IsInfinity)
            {
                return(null);
            }

            var e = new BigInteger(1, message);

            var EInv     = BigInteger.Zero.Subtract(e).Mod(n);
            var RInv     = sig.R.ModInverse(n);
            var SrInv    = RInv.Multiply(sig.S).Mod(n);
            var EInvrInv = RInv.Multiply(EInv).Mod(n);
            var q        = ECAlgorithms.SumOfTwoMultiplies(ECKeyPair.CURVE.G, EInvrInv, R, SrInv);

            var QBytes = q.GetEncoded(false);

            // We remove the prefix
            return(new BigInteger(1, Arrays.CopyOfRange(QBytes, 1, QBytes.Length)));
        }
        public virtual BigInteger CalculateAgreement(
            ICipherParameters pubKey)
        {
            ECPublicKeyParameters pub = (ECPublicKeyParameters)pubKey;
            ECDomainParameters    dp  = privKey.Parameters;

            if (!dp.Equals(pub.Parameters))
            {
                throw new InvalidOperationException("ECDH public key has wrong domain parameters");
            }

            BigInteger d = privKey.D;

            // Always perform calculations on the exact curve specified by our private key's parameters
            ECPoint Q = ECAlgorithms.CleanPoint(dp.Curve, pub.Q);

            if (Q.IsInfinity)
            {
                throw new InvalidOperationException("Infinity is not a valid public key for ECDH");
            }

            BigInteger h = dp.H;

            if (!h.Equals(BigInteger.One))
            {
                d = dp.HInv.Multiply(d).Mod(dp.N);
                Q = ECAlgorithms.ReferenceMultiply(Q, h);
            }

            ECPoint P = Q.Multiply(d).Normalize();

            if (P.IsInfinity)
            {
                throw new InvalidOperationException("Infinity is not a valid agreement value for ECDH");
            }

            return(P.AffineXCoord.ToBigInteger());
        }
Ejemplo n.º 24
0
            public virtual ECPoint Init_enc(SM2 sm2, ECPoint userKey)
            {
                BigInteger k  = null;
                ECPoint    c1 = null;

                if (!sm2.sm2Test)//判断使用哪种方法
                {
                    AsymmetricCipherKeyPair key    = sm2.ecc_key_pair_generator.GenerateKeyPair();
                    ECPrivateKeyParameters  ecpriv = (ECPrivateKeyParameters)key.Private; //生成私钥
                    ECPublicKeyParameters   ecpub  = (ECPublicKeyParameters)key.Public;   //生成公钥
                    k  = ecpriv.D;                                                        //k
                    c1 = ecpub.Q;                                                         //计算椭圆点c1
                }
                else//使用测试参数
                {
                    k  = new BigInteger("4C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F", 16); //指定k
                    c1 = sm2.ecc_point_g.Multiply(k);                                                            //获取公钥
                }

                p2 = userKey.Multiply(k);
                Reset();    //调用密码杂凑Reset方法

                return(c1); //把公钥返回给调用他得式子.
            }
Ejemplo n.º 25
0
        private void DoTestSumOfTwoMultiplies(X9ECParameters x9)
        {
            ECPoint    p = GetRandomPoint(x9);
            BigInteger a = GetRandomScalar(x9);

            for (int i = 0; i < Scale; ++i)
            {
                ECPoint    q = GetRandomPoint(x9);
                BigInteger b = GetRandomScalar(x9);

                ECPoint u = p.Multiply(a).Add(q.Multiply(b));
                ECPoint v = ECAlgorithms.ShamirsTrick(p, a, q, b);
                ECPoint w = ECAlgorithms.SumOfTwoMultiplies(p, a, q, b);

                ECPoint[] results = new ECPoint[] { u, v, w };
                x9.Curve.NormalizeAll(results);

                AssertPointsEqual("ECAlgorithms.ShamirsTrick is incorrect", results[0], results[1]);
                AssertPointsEqual("ECAlgorithms.SumOfTwoMultiplies is incorrect", results[0], results[2]);

                p = q;
                a = b;
            }
        }
Ejemplo n.º 26
0
        public static ECKey RecoverFromSignature(int recId, ECDSASignature sig, uint256 message, bool compressed)
        {
            if (recId < 0)
            {
                throw new ArgumentException("recId should be positive");
            }
#pragma warning disable 618
            if (sig.R.SignValue < 0)
            {
                throw new ArgumentException("r should be positive");
            }
            if (sig.S.SignValue < 0)
            {
                throw new ArgumentException("s should be positive");
            }
#pragma warning restore 618
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }


            var curve = ECKey.Secp256k1;

            // 1.0 For j from 0 to h   (h == recId here and the loop is outside this function)
            //   1.1 Let x = r + jn

            var n = curve.N;
            var i = NBitcoin.BouncyCastle.Math.BigInteger.ValueOf((long)recId / 2);
#pragma warning disable 618
            var x = sig.R.Add(i.Multiply(n));
#pragma warning restore 618

            //   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.
            var prime = ((SecP256K1Curve)curve.Curve).QQ;
            if (x.CompareTo(prime) >= 0)
            {
                return(null);
            }

            // Compressed keys 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.
            var e = new NBitcoin.BouncyCastle.Math.BigInteger(1, message.ToBytes());
            //   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.

            var eInv = NBitcoin.BouncyCastle.Math.BigInteger.Zero.Subtract(e).Mod(n);
#pragma warning disable 618
            var rInv  = sig.R.ModInverse(n);
            var srInv = rInv.Multiply(sig.S).Mod(n);
#pragma warning restore 618
            var     eInvrInv = rInv.Multiply(eInv).Mod(n);
            ECPoint q        = ECAlgorithms.SumOfTwoMultiplies(curve.G, eInvrInv, R, srInv);
            q = q.Normalize();
            if (compressed)
            {
                q = new SecP256K1Point(curve.Curve, q.XCoord, q.YCoord, true);
            }
            return(new ECKey(q.GetEncoded(), false));
        }
        private double RandMult(SecureRandom random, ECPoint g, BigInteger n)
        {
            BigInteger[] ks = new BigInteger[128];
            for (int i = 0; i < ks.Length; ++i)
            {
                ks[i] = new BigInteger(n.BitLength - 1, random);
            }

            int     ki = 0;
            ECPoint p  = g;

            {
                long startTime = DateTimeUtilities.CurrentUnixMs();
                long goalTime  = startTime + MILLIS_WARMUP;

                do
                {
                    BigInteger k = ks[ki];
                    p = g.Multiply(k);
                    if ((ki & 1) != 0)
                    {
                        g = p;
                    }
                    if (++ki == ks.Length)
                    {
                        ki = 0;
                    }
                }while (DateTimeUtilities.CurrentUnixMs() < goalTime);
            }

            double minRate = Double.MaxValue, maxRate = Double.MinValue, totalRate = 0.0;

            for (int i = 1; i <= NUM_ROUNDS; i++)
            {
                long startTime = DateTimeUtilities.CurrentUnixMs();
                long goalTime = startTime + MILLIS_PER_ROUND;
                long count = 0, endTime;

                do
                {
                    ++count;

                    for (int j = 0; j < MULTS_PER_CHECK; ++j)
                    {
                        BigInteger k = ks[ki];
                        p = g.Multiply(k);
                        if ((ki & 1) != 0)
                        {
                            g = p;
                        }
                        if (++ki == ks.Length)
                        {
                            ki = 0;
                        }
                    }

                    endTime = DateTimeUtilities.CurrentUnixMs();
                }while (endTime < goalTime);

                double roundElapsed = (double)(endTime - startTime);
                double roundRate    = count * MULTS_PER_CHECK * 1000L / roundElapsed;

                minRate    = System.Math.Min(minRate, roundRate);
                maxRate    = System.Math.Max(maxRate, roundRate);
                totalRate += roundRate;
            }

            return((totalRate - minRate - maxRate) / (NUM_ROUNDS - 2));
        }
Ejemplo n.º 28
0
        private void btnCombine_Click(object sender, EventArgs e)
        {
            // What is input #1?

            string    input1 = txtInput1.Text;
            string    input2 = txtInput2.Text;
            PublicKey pub1 = null, pub2 = null;
            KeyPair   kp1 = null, kp2 = null;


            if (KeyPair.IsValidPrivateKey(input1))
            {
                pub1 = kp1 = new KeyPair(input1);
            }
            else if (PublicKey.IsValidPublicKey(input1))
            {
                pub1 = new PublicKey(input1);
            }
            else
            {
                MessageBox.Show("Input key #1 is not a valid Public Key or Private Key Hex", "Can't combine", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (KeyPair.IsValidPrivateKey(input2))
            {
                pub2 = kp2 = new KeyPair(input2);
            }
            else if (PublicKey.IsValidPublicKey(input2))
            {
                pub2 = new PublicKey(input2);
            }
            else
            {
                MessageBox.Show("Input key #2 is not a valid Public Key or Private Key Hex", "Can't combine", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (kp1 == null && kp2 == null && rdoAdd.Checked == false)
            {
                MessageBox.Show("Can't multiply two public keys.  At least one of the keys must be a private key.",
                                "Can't combine", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (pub1.IsCompressedPoint != pub2.IsCompressedPoint)
            {
                MessageBox.Show("Can't combine a compressed key with an uncompressed key.", "Can't combine", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (pub1.AddressBase58 == pub2.AddressBase58)
            {
                if (MessageBox.Show("Both of the key inputs have the same public key hash.  You can continue, but " +
                                    "the results are probably going to be wrong.  You might have provided the wrong " +
                                    "information, such as two parts from the same side of the transaction, instead " +
                                    "of one part from each side.  Continue anyway?", "Duplicate Key Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK)
                {
                    return;
                }
            }

            var ps = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1");

            // Combining two private keys?
            if (kp1 != null && kp2 != null)
            {
                BigInteger e1        = new BigInteger(1, kp1.PrivateKeyBytes);
                BigInteger e2        = new BigInteger(1, kp2.PrivateKeyBytes);
                BigInteger ecombined = (rdoAdd.Checked ? e1.Add(e2) : e1.Multiply(e2)).Mod(ps.N);


                System.Diagnostics.Debug.WriteLine(kp1.PublicKeyHex);
                System.Diagnostics.Debug.WriteLine(kp2.PublicKeyHex);
                KeyPair kpcombined = new KeyPair(Util.Force32Bytes(ecombined.ToByteArrayUnsigned()), compressed: kp1.IsCompressedPoint);

                txtOutputAddress.Text = kpcombined.AddressBase58;
                txtOutputPubkey.Text  = kpcombined.PublicKeyHex.Replace(" ", "");
                txtOutputPriv.Text    = kpcombined.PrivateKeyBase58;
            }
            else if (kp1 != null || kp2 != null)
            {
                // Combining one public and one private

                KeyPair   priv = (kp1 == null) ? kp2 : kp1;
                PublicKey pub  = (kp1 == null) ? pub1 : pub2;

                ECPoint point = pub.GetECPoint();

                ECPoint   combined   = rdoAdd.Checked ? point.Add(priv.GetECPoint()) : point.Multiply(new BigInteger(1, priv.PrivateKeyBytes));
                ECPoint   combinedc  = ps.Curve.CreatePoint(combined.X.ToBigInteger(), combined.Y.ToBigInteger(), priv.IsCompressedPoint);
                PublicKey pkcombined = new PublicKey(combinedc.GetEncoded());
                txtOutputAddress.Text = pkcombined.AddressBase58;
                txtOutputPubkey.Text  = pkcombined.PublicKeyHex.Replace(" ", "");
                txtOutputPriv.Text    = "Only available when combining two private keys";
            }
            else
            {
                // Adding two public keys
                ECPoint   combined   = pub1.GetECPoint().Add(pub2.GetECPoint());
                ECPoint   combinedc  = ps.Curve.CreatePoint(combined.X.ToBigInteger(), combined.Y.ToBigInteger(), pub1.IsCompressedPoint);
                PublicKey pkcombined = new PublicKey(combinedc.GetEncoded());
                txtOutputAddress.Text = pkcombined.AddressBase58;
                txtOutputPubkey.Text  = pkcombined.PublicKeyHex.Replace(" ", "");
                txtOutputPriv.Text    = "Only available when combining two private keys";
            }
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Default constructor.  Creates a new matched pair of escrow invitation codes.
        /// </summary>
        public EscrowCodeSet()
        {
            SecureRandom sr = new SecureRandom();

            byte[] x = new byte[32];
            byte[] y = new byte[32];
            sr.NextBytes(x);
            sr.NextBytes(y);

            // Force x to be even
            // Force y to be odd
            x[31] &= 0xFE;
            y[31] |= 0x01;

            KeyPair kx = new KeyPair(x, true);
            KeyPair ky = new KeyPair(y, true);

            BigInteger xi = new BigInteger(1, x);
            BigInteger yi = new BigInteger(1, y);

            ECPoint Gx = kx.GetECPoint();

            byte[]  bytesGx = Gx.GetEncoded();
            ECPoint Gy      = ky.GetECPoint();

            byte[]  bytesGy = Gy.GetEncoded();
            ECPoint Gxy     = Gx.Multiply(yi);

            byte[]       bytesGxy = Gxy.GetEncoded();
            Sha256Digest sha256   = new Sha256Digest();

            byte[] hashGxy = new byte[32];
            sha256.BlockUpdate(bytesGxy, 0, bytesGxy.Length);
            sha256.DoFinal(hashGxy, 0);
            sha256.BlockUpdate(hashGxy, 0, 32);
            sha256.DoFinal(hashGxy, 0);

            int identifier30 = ((hashGxy[0] & 0x3f) << 24) + (hashGxy[1] << 16) + (hashGxy[2] << 8) + hashGxy[3];

            byte[] invitationA = new byte[74];
            byte[] invitationB = new byte[74];

            long headA = headbaseA + (long)identifier30;
            long headB = headbaseB + (long)identifier30;

            // turn headA and headB into bytes
            for (int i = 7; i >= 0; i--)
            {
                invitationA[i] = (byte)(headA & 0xFF);
                invitationB[i] = (byte)(headB & 0xFF);
                headA        >>= 8;
                headB        >>= 8;
            }

            Array.Copy(x, 0, invitationA, 8 + 1, 32);
            Array.Copy(y, 0, invitationB, 8 + 1, 32);
            Array.Copy(bytesGy, 0, invitationA, 8 + 1 + 32, 33);
            Array.Copy(bytesGx, 0, invitationB, 8 + 1 + 32, 33);

            EscrowInvitationCodeA = Util.ByteArrayToBase58Check(invitationA);
            EscrowInvitationCodeB = Util.ByteArrayToBase58Check(invitationB);
        }
Ejemplo n.º 30
0
        public byte[] Decrypt(byte[] value)
        {
            if (_params.Q == null)
            {
                if (_params.D == null)
                {
                    throw new CryptographicException();
                }
                _params.CreatePublicKeyFromPrivateKey();
            }

            int domainLen = (int)((_domain.Bits >> 3) + ((_domain.Bits & 7) == 0 ? 0 : 1));
            int macKeyLen = _mac.HashSize >> 3;

            // Step.1
            if (value[0] != 2 && value[0] != 3 && value[0] != 4)
            {
                throw new CryptographicException();
            }
            byte[] RBytes = new byte[domainLen + 1];
            byte[] EM     = new byte[value.Length - RBytes.Length - macKeyLen];
            byte[] D      = new byte[macKeyLen];
            if (value.Length != RBytes.Length + EM.Length + D.Length)
            {
                throw new CryptographicException();
            }
            Array.Copy(value, 0, RBytes, 0, RBytes.Length);
            Array.Copy(value, RBytes.Length, EM, 0, EM.Length);
            Array.Copy(value, RBytes.Length + EM.Length, D, 0, D.Length);
            int encKeyLen = (_symmetricAlgo == null ? EM.Length : _symmetricAlgo.KeySize >> 3);;

            // Step.2
            ECPoint R = new ECPoint(_domain.Group, RBytes);

            // Step.3
            // TODO: Step.3

            // Step.4 & 5
            // TODO: Cofactor Diffie-Hellmanプリミティブを利用するオプションを追加する
            byte[] Z = R.Multiply(_params.D).Export().X.ToByteArray(domainLen, false);

            // Step.6
            byte[] K = _kdf.Calculate(Z, encKeyLen + macKeyLen);

            // Step.7
            byte[] EK = null;
            if (_symmetricAlgo != null)
            {
                EK = new byte[encKeyLen];
                for (int i = 0; i < EK.Length; i++)
                {
                    EK[i] = K[i];
                }
            }
            byte[] MK = new byte[macKeyLen];
            for (int i = 0; i < MK.Length; i++)
            {
                MK[i] = K[K.Length - MK.Length + i];
            }

            // Step.8
            // TODO: HMAC-SHA1-80への対応
            _mac.Key = MK;
            _mac.Initialize();
            _mac.TransformBlock(EM, 0, EM.Length, null, 0);
            if (_sharedInfo == null)
            {
                _mac.TransformFinalBlock(EM, 0, 0);
            }
            else
            {
                _mac.TransformFinalBlock(_sharedInfo, 0, _sharedInfo.Length);
            }
            byte[] hash = _mac.Hash;
            for (int i = 0; i < hash.Length; i++)
            {
                if (hash[i] != D[i])
                {
                    throw new CryptographicException();
                }
            }

            // Step.9
            byte[] result = new byte[EM.Length];
            if (_symmetricAlgo == null)
            {
                for (int i = 0; i < result.Length; i++)
                {
                    result[i] = (byte)(EM[i] ^ K[i]);
                }
            }
            else
            {
                int blockBytes = _symmetricAlgo.BlockSize >> 3;
                using (ICryptoTransform transform = _symmetricAlgo.CreateDecryptor(EK, new byte[blockBytes])) {
                    int i = 0;
                    for (; i < result.Length - blockBytes; i += blockBytes)
                    {
                        transform.TransformBlock(EM, i, blockBytes, result, i);
                    }
                    byte[] temp = transform.TransformFinalBlock(EM, i, EM.Length - i);
                    Buffer.BlockCopy(temp, 0, result, i, temp.Length);
                    if (temp.Length != blockBytes)
                    {
                        Array.Resize <byte> (ref result, i + temp.Length);
                    }
                }
            }
            return(result);
        }