示例#1
0
        //Returns enumerator of shares by calculating (x, y) pair points for a given amount of shares
        public IEnumerable <Share> GetShares(int totalShares)
        {
            for (int i = 1; i <= totalShares; ++i)
            {
                FFPolynom x = new FFPolynom(_irreduciblePolynom, new BigInteger(i));
                FFPolynom y = FFPolynom.HornerEvaluateAt(_allCoefficients, i);

                yield return(new Share(new FFPoint(x, y)));
            }
        }
示例#2
0
        //Returns whether two finite fields polynoms are equal
        public override bool Equals(object obj)
        {
            FFPolynom fpp = obj as FFPolynom;

            if (fpp == null)
            {
                return(base.Equals(obj));
            }

            bool res = (PrimePolynom == fpp.PrimePolynom) && (PolyValue.Equals(fpp.PolyValue));

            return(res);
        }
示例#3
0
        //Adjusts the finite field points by removing the high term monomial
        private static FFPoint AdjustPoint(int total, FFPoint point)
        {
            FFPolynom corrector  = new FFPolynom(point.Y.PrimePolynom, BigInteger.One);
            FFPolynom corrFactor = point.X;

            for (int i = 1; i <= total; i++)
            {
                corrector = corrector * corrFactor;
            }

            FFPolynom newY     = point.Y + corrector;
            FFPoint   newPoint = new FFPoint(point.X, newY);

            return(newPoint);
        }
示例#4
0
        //Checks for matching with Regex and proccess the , and returns FiniteFieldPoint if success; otherwise null.
        internal static bool TryParse(Match matchedShare, out FFPoint res)
        {
            if (!matchedShare.Success)
            {
                res = null;
                return(false);
            }
            try
            {
                //Parse the share string: x - number by order, y - the string after '.' sign
                //Gets the string matched by the particular expression. Change to lowcase and apply casing invariant
                string xStr = matchedShare.Groups["x"].Value.ToLowerInvariant();
                string yStr = matchedShare.Groups["y"].Value.ToLowerInvariant();

                //Remove initial 0s to compare with ordinal = 4
                while (xStr.StartsWith("0", StringComparison.Ordinal))
                {
                    xStr = xStr.Substring(1);
                }

                // 1hexChar = 4 bits, so degree in bits = degree * 4
                int polynomialDegree = yStr.Length * 4;

                IrreduciblePolynom irp = new IrreduciblePolynom(polynomialDegree);

                FFPolynom x = new FFPolynom(irp, BigInteger.Parse(xStr));

                // Create an array of bites (big endian) with the length in bytes as initial phrase, initialize to 0
                byte[] yArr = new byte[yStr.Length / 2];

                for (int i = 0; i < yStr.Length; i += 2)
                {
                    //Convert a hex-string to byte representation (1hex = 4 bits).. that's why i/2
                    yArr[i / 2] = Byte.Parse(yStr.Substring(i, 2), NumberStyles.HexNumber);
                }

                //Convert yArr to BigInteger and create a finite field polynom
                FFPolynom y = new FFPolynom(irp, yArr.FromBigEndUnsignedBytesToBigInt());

                res = new FFPoint(x, y);
                return(true);
            }
            catch (Exception e)
            {
                res = null;
                return(false);
            }
        }
示例#5
0
        //Combine shares to recover the secret by applying Lagrange Interpolation for all FFPoints
        private RecoveredSecret RecoverImpl(IEnumerable <Share> shares)
        {
            Share[] allShares = shares.ToArray();

            //Create a collection of finite field points out from generated shares
            IEnumerable <FFPoint> collection = allShares.Select(s => s.Point);

            //Recover the secret phrase using the points -> f(0)
            FFPolynom secretCoeff = LagrangeInterpolation.LagrInterpolate(collection);

            byte[] secret = secretCoeff.PolyValue.ToUnsignedBigEnd();

            RecoveredSecret newRecSecret = new RecoveredSecret(secret);

            return(newRecSecret);
        }
示例#6
0
        //Shares the secret respectfully to number of shares and threshold
        protected virtual SharedSecret ShareImpl(byte[] secret, int threshold, int numberOfShares)
        {
            //Define irred polynom for a secret
            IrreduciblePolynom irreduciblePolynom = IrreduciblePolynom.GiveFromBytes(secret.Length);

            BigInteger rawSecret   = secret.FromBigEndUnsignedBytesToBigInt();
            FFPolynom  secretCoeff = new FFPolynom(irreduciblePolynom, rawSecret);

            //Generate random polynom with corresponding irred. polynom and given threshold
            IEnumerable <FFPolynom> randPolynom = GenerateRandomPolynom(irreduciblePolynom, threshold - 1);

            //Construct an array of all coefficients represented as finite field polynoms
            FFPolynom[] consTerm = new[] { secretCoeff };

            //Concatenate previously created random coefficients converting them as an array
            FFPolynom[] allCoefficients = consTerm.Concat(randPolynom).ToArray();

            return(new SharedSecret(threshold, irreduciblePolynom, allCoefficients));
        }
示例#7
0
        //Evaluate polynom of coefficients for certain x using Horner's method http//en.wikipedia.org/wiki/Horner_scheme
        public static FFPolynom HornerEvaluateAt(FFPolynom[] coefficients, long x)
        {
            FFPolynom xPoly = coefficients[0].ReturnValueInField(x);

            //The coefficient for the highest mono-polynom = 1
            FFPolynom resValue = xPoly.DeepCopy();

            //For all the coeffs, go thru them and add lowest first coeff, further multiolying by x-polyn
            //Start backwards
            for (int i = coefficients.Length - 1; i > 0; i--)
            {
                resValue = resValue + coefficients[i];
                resValue = resValue * xPoly;
            }

            resValue = resValue + coefficients[0];

            return(resValue);
        }
示例#8
0
        /// <summary>
        /// /Calculate f(0) in a finite field
        /// </summary>
        /// <param name="points"></param>
        /// <returns></returns>
        public static FFPolynom LagrInterpolate(IEnumerable <FFPoint> points)
        {
            FFPoint[] originalPoints = points.ToArray();

            if (originalPoints.Length == 0)
            {
                throw new ArgumentOutOfRangeException();
            }

            int threshold = originalPoints.Length;

            //"Correct" these points by removing the high term monomial
            FFPoint[] adjustedPoints = originalPoints.Select(p => AdjustPoint(threshold, p)).ToArray();

            //Use Lagrange interpolating polynomials ( http//en.wikipedia.org/wiki/Lagrange_polynomial )
            //to solve:

            //        (x-x2)(x-x3)...(x-xn)         (x-x1)(x-x3)...(x-xn)
            //P(x) = ------------------------ y1 + -------------------------- y2 + ... +
            //        (x1-x2)(x1-x3)...(x1-xn)      (x2-x1)(x2-x3)...(x2-xn-1)

            //Simplifying things is that x is 0 since we want to find the constant term

            //Polynomial that belongs to the GF[2] and represents the initially constructed polynom
            FFPolynom originalPolynom = originalPoints[0].Y;

            FFPolynom total = originalPolynom.ReturnValueInField(0);

            for (int iPoint = 0; iPoint < threshold; iPoint++)// where iPoint is currently processing point
            {
                FFPolynom processingNumerator   = originalPolynom.ReturnValueInField(1);
                FFPolynom processingDenominator = originalPolynom.ReturnValueInField(1);
                FFPoint   processingPoint       = adjustedPoints[iPoint];

                for (int tempPoint = 0; tempPoint < threshold; tempPoint++)
                {
                    //Skip if both are the same
                    if (iPoint == tempPoint)
                    {
                        continue;
                    }

                    //numerator needs multiplied by
                    //(0-x_i) = -x_i = x_i
                    //subtraction and addition are the same in GF[2]
                    processingNumerator   *= adjustedPoints[tempPoint].X;
                    processingDenominator *= (processingPoint.X + adjustedPoints[tempPoint].X);
                }

                //Dividing is just multiplying by the inverse
                FFPolynom denomInv = processingDenominator.GetInverse();

                FFPolynom fraction = processingNumerator * denomInv;

                //Multiply the fraction by the corresponding y_i
                FFPolynom currentTermValue = fraction * processingPoint.Y;
                total += currentTermValue;
            }

            return(total);
        }
示例#9
0
 //Constructs the point using two polynoms for x and y dimension respectfully
 public FFPoint(FFPolynom x, FFPolynom y)
 {
     X = x; Y = y;
 }