예제 #1
0
        public EccPoint Add(EccPoint pointA, EccPoint pointB)
        {
            // Any point added to infinity is itself
            if (pointA.Infinity)
            {
                return(pointB);
            }

            // Any point added to infinity is itself
            if (pointB.Infinity)
            {
                return(pointA);
            }

            // Any point added to its inverse is infinity
            if (pointA.Equals(Negate(pointB)))
            {
                return(new EccPoint("infinity"));
            }

            // Cannot add two identical points, use Double instead
            if (pointA.Equals(pointB))
            {
                return(Double(pointA));
            }

            var numerator   = _operator.Subtract(pointB.Y, pointA.Y);
            var denominator = _operator.Subtract(pointB.X, pointA.X);
            var lambda      = _operator.Divide(numerator, denominator);

            var x = _operator.Subtract(_operator.Subtract(_operator.Multiply(lambda, lambda), pointA.X), pointB.X);
            var y = _operator.Subtract(_operator.Multiply(_operator.Subtract(pointA.X, x), lambda), pointA.Y);

            return(new EccPoint(x, y));
        }
예제 #2
0
        /// <summary>
        /// Based on the Fixed-base comb method (Algorithm 17 from https://link.springer.com/content/pdf/10.1007/3-540-44499-8_1.pdf)
        /// </summary>
        /// <param name="scalar"></param>
        /// <returns></returns>
        private EccPoint FastMultiply(BigInteger scalar)
        {
            var width      = 4;
            var degree     = FieldSizeQ.ExactBitLength();
            var d          = degree.CeilingDivide(width);
            var scalarBits = new BitString(scalar, degree).Bits;
            var point      = new EccPoint("infinity");

            for (var i = d - 1; i >= 0; i--)
            {
                point = Double(point);

                var index = 0;
                for (var j = width - 1; j >= 0; j--)
                {
                    index *= 2;
                    if (i + d * j >= degree)
                    {
                        continue;
                    }
                    if (scalarBits[i + d * j])
                    {
                        index++;
                    }
                }

                if (index != 0)
                {
                    point = Add(point, _precomputedMultiplication[index]);
                }
            }

            return(point);
        }
예제 #3
0
        public bool PointExistsOnCurve(EccPoint point)
        {
            if (point.Infinity)
            {
                return(true);
            }

            // Point is out of bounds
            if (!PointExistsInField(point))
            {
                return(false);
            }

            var ySquared = _operator.Multiply(point.Y, point.Y);
            var xTimesY  = _operator.Multiply(point.X, point.Y);
            var lhs      = _operator.Add(ySquared, xTimesY);

            var xCubed         = _operator.Multiply(_operator.Multiply(point.X, point.X), point.X);
            var xSquared       = _operator.Multiply(point.X, point.X);
            var aTimesXSquares = _operator.Multiply(CoefficientA, xSquared);
            var rhs            = _operator.Add(_operator.Add(xCubed, aTimesXSquares), CoefficientB);

            // y^2 + xy = x^3 + ax^2 + b
            return(lhs == rhs);
        }
예제 #4
0
        public static bool PerformEccPublicKeyValidation(IEccCurve curve, EccPoint publicKey, bool shouldThrow = false)
        {
            if (!curve.PointExistsOnCurve(publicKey))
            {
                if (shouldThrow)
                {
                    throw new Exception("public key does not exist on curve");
                }

                return(false);
            }

            var n  = curve.OrderN;
            var nQ = curve.Multiply(publicKey, n);

            if (!nQ.Infinity)
            {
                if (shouldThrow)
                {
                    throw new Exception("public key validation error");
                }

                return(false);
            }

            return(true);
        }
예제 #5
0
        public EccPoint Negate(EccPoint point)
        {
            if (point.Infinity)
            {
                return(point);
            }

            return(new EccPoint(point.X, _operator.Add(point.X, point.Y)));
        }
예제 #6
0
        public EccPoint Subtract(EccPoint pointA, EccPoint pointB)
        {
            if (pointA.Infinity || pointB.Infinity)
            {
                return(pointA);
            }

            return(Add(pointA, Negate(pointB)));
        }
예제 #7
0
        public EccPoint Negate(EccPoint point)
        {
            if (point.Infinity)
            {
                return(point);
            }

            // Negate the point, - (x, y) == (x, -y), but -1 * y (mod q) == q - y
            return(new EccPoint(point.X, _operator.Negate(point.Y)));
        }
예제 #8
0
        public PrimeCurve(Curve curveName, BigInteger p, BigInteger b, EccPoint g, BigInteger n)
        {
            CurveName = curveName;

            FieldSizeQ   = p;
            CoefficientB = b;
            BasePointG   = g;
            OrderN       = n;

            _operator = new PrimeFieldOperator(p);
        }
예제 #9
0
파일: Sample-Ecc.cs 프로젝트: rgl/TSS.MSR
        void EcdhSample(Tpm2 tpm, TestContext testCtx)
        {
            //
            // Peer A (e.g. local machine):
            //

            // Template for an ECC key with the ECDH scheme:
            var inPub = new TpmPublic(TpmAlgId.Sha256,
                                      ObjectAttr.Decrypt | ObjectAttr.UserWithAuth | ObjectAttr.SensitiveDataOrigin,
                                      null,
                                      new EccParms(new SymDefObject(), new SchemeEcdh(TpmAlgId.Sha256),
                                                   EccCurve.NistP256, new NullKdfScheme()),
                                      new EccPoint());

            // Boilerplate stuff
            var          pcrSel = new PcrSelection[0];
            CreationData crData;

            byte[]     crHash;
            TkCreation crTk;

            // Create a key for ECDH
            TpmPublic pubA;
            TpmHandle hKeyA = tpm.CreatePrimary(TpmRh.Owner, new SensitiveCreate(), inPub, null, new PcrSelection[0],
                                                out pubA, out crData, out crHash, out crTk);

            //
            // Peer B (e.g. remote machine):
            //

            // Receives 'pubA' from peer A

            // Load public key
            TpmHandle hPubKeyA = tpm.LoadExternal(null, pubA, TpmRh.Owner);

            // Create shared secret 'zB', and a public ECC point for exchange
            EccPoint ephPubPt;
            EccPoint zB = tpm.EcdhKeyGen(hPubKeyA, out ephPubPt);

            tpm.FlushContext(hPubKeyA);

            //
            // Peer A again:
            //

            // Receives 'ephPubPt' from peer B

            // A full key is required here
            EccPoint zA = tpm.EcdhZGen(hKeyA, ephPubPt);

            testCtx.AssertEqual("SharedSecret", zA, zB);

            tpm.FlushContext(hKeyA);
        } // EcdhSample
예제 #10
0
        public bool PointExistsInField(EccPoint point)
        {
            var m = FieldSizeQ.ExactBitLength();

            if (point.X.ExactBitLength() == m || point.Y.ExactBitLength() == m)
            {
                return(false);
            }

            return(true);
        }
예제 #11
0
        public BinaryCurve(Curve curveName, BigInteger f, BigInteger a, BigInteger b, EccPoint basis, BigInteger n, int h, List <EccPoint> points = null)
        {
            CurveName = curveName;

            FieldSizeQ   = f;
            CoefficientA = a;
            CoefficientB = b;
            BasePointG   = basis;
            OrderN       = n;
            CofactorH    = h;

            _operator = new GaloisFieldOperator(f);
            _precomputedMultiplication = points ?? new List <EccPoint>();
        }
예제 #12
0
        public bool PointExistsInField(EccPoint point)
        {
            if (point.X < 0 || point.X > FieldSizeQ - 1)
            {
                return(false);
            }

            if (point.Y < 0 || point.Y > FieldSizeQ - 1)
            {
                return(false);
            }

            return(true);
        }
예제 #13
0
        public EccPoint Multiply(EccPoint startPoint, BigInteger scalar)
        {
            // Intentional normal modulo, this is what CAVS does
            scalar %= OrderN;

            if (startPoint.Equals(BasePointG) && HasPrecomputedValues)
            {
                return(FastMultiply(scalar));
            }
            else
            {
                return(Multiply(startPoint, new NonAdjacentBitString(scalar)));
            }
        }
예제 #14
0
        public EccPoint Double(EccPoint point)
        {
            if (point.X == 0 || point.Infinity)
            {
                return(point);
            }

            var numerator   = point.Y;
            var denominator = point.X;
            var lambda      = _operator.Add(_operator.Multiply(numerator, _operator.Inverse(denominator)), point.X);

            var x = _operator.Add(_operator.Add(_operator.Multiply(lambda, lambda), lambda), CoefficientA);
            var y = _operator.Add(_operator.Multiply(_operator.Add(lambda, 1), x), _operator.Multiply(point.X, point.X));

            return(new EccPoint(x, y));
        }
예제 #15
0
        public bool PointExistsOnCurve(EccPoint point)
        {
            if (point.Infinity)
            {
                return(true);
            }

            // Point is out of bounds
            if (!PointExistsInField(point))
            {
                return(false);
            }

            var lhs = _operator.Multiply(point.Y, point.Y);
            var rhs = _operator.Add(_operator.Add(_operator.Multiply(_operator.Multiply(point.X, point.X), point.X), _operator.Multiply(CoefficientA, point.X)), CoefficientB);

            return(lhs == rhs);
        }
예제 #16
0
        public EccPoint Add(EccPoint pointA, EccPoint pointB)
        {
            // Any point added to infinity is itself
            if (pointA.Infinity)
            {
                return(pointB);
            }

            // Any point added to infinity is itself
            if (pointB.Infinity)
            {
                return(pointA);
            }

            // Any point added to its inverse is infinity
            if (pointA.Equals(Negate(pointB)))
            {
                return(new EccPoint("infinity"));
            }

            // Cannot add two identical points, use Double instead
            if (pointA.Equals(pointB))
            {
                return(Double(pointA));
            }

            var numerator   = _operator.Add(pointA.Y, pointB.Y);
            var denominator = _operator.Add(pointA.X, pointB.X);

            if (denominator == 0)
            {
                return(new EccPoint("infinity"));
            }

            var lambda = _operator.Multiply(numerator, _operator.Inverse(denominator));

            // x = lambda * lambda + lambda + x1 + x2 + a
            var x = _operator.Add(_operator.Add(_operator.Add(_operator.Add(_operator.Multiply(lambda, lambda), lambda), pointA.X), pointB.X), CoefficientA);

            // y = lambda * (x1 + x3) + x + y1
            var y = _operator.Add(_operator.Add(_operator.Multiply(_operator.Add(pointA.X, x), lambda), x), pointA.Y);

            return(new EccPoint(x, y));
        }
예제 #17
0
        public static SchemeEcdaa PrepareEcdaaScheme(Tpm2 tpm, TpmHandle signKey,
                                                     ISigSchemeUnion scheme)
        {
            var schemeEcdaa = scheme as SchemeEcdaa;

            if (schemeEcdaa != null)
            {
                byte[] name, qualName;
                var    keyPub = tpm.ReadPublic(signKey, out name, out qualName);

                ushort   counter = 0;
                EccPoint l, E;
                EccPoint PP = keyPub.unique as EccPoint;

                tpm.Commit(signKey, PP, null, null, out l, out E, out counter);
                schemeEcdaa.count = counter;
            }
            return(schemeEcdaa);
        }
예제 #18
0
        private EccPoint Multiply(EccPoint startPoint, NonAdjacentBitString nafBs)
        {
            var point  = new EccPoint("infinity");
            var naBits = nafBs.Bits;

            for (var i = naBits.Length - 1; i >= 0; i--)
            {
                point = Double(point);
                if (naBits[i] == 1)
                {
                    point = Add(point, startPoint);
                }
                else if (naBits[i] == -1)
                {
                    point = Subtract(point, startPoint);
                }
            }

            return(point);
        }
예제 #19
0
        public EccPoint Double(EccPoint point)
        {
            if ((point.X == 0 && point.Y == 0) || point.Infinity)
            {
                return(point);
            }

            if (point.Y == 0)
            {
                throw new ArgumentException("Cannot double a point with y = 0");
            }

            var numerator   = _operator.Add(_operator.Multiply(_operator.Multiply(3, point.X), point.X), CoefficientA);
            var denominator = _operator.Multiply(2, point.Y);
            var lambda      = _operator.Divide(numerator, denominator);

            var x = _operator.Subtract(_operator.Multiply(lambda, lambda), _operator.Multiply(2, point.X));
            var y = _operator.Subtract(_operator.Multiply(_operator.Subtract(point.X, x), lambda), point.Y);

            return(new EccPoint(x, y));
        }
예제 #20
0
 public EccPoint Multiply(EccPoint startPoint, BigInteger scalar)
 {
     // Find scalar within group and convert to NABS, normal modulo here, not on the field, like CAVS
     return(Multiply(startPoint, new NonAdjacentBitString(scalar % OrderN)));
 }
        public void ShouldReturnExpectedValidationResultEcc(string label, Curve curveEnum, EccPoint publicKey, bool shouldPassValidation)
        {
            var curve = new EccCurveFactory().GetCurve(curveEnum);

            var result = KeyValidationHelper.PerformEccPublicKeyValidation(curve, publicKey, false);

            Assert.AreEqual(shouldPassValidation, result);
        }
예제 #22
0
 public EccPoint Subtract(EccPoint pointA, EccPoint pointB)
 {
     return(Add(pointA, Negate(pointB)));
 }