//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); }
//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); } }
public static bool TryParse(string s, out Share share) { //Check format for string of future share Match match = RegParser.Match(s); FFPoint point; if (!FFPoint.TryParse(match, out point) || !match.Success) { share = null; return(false); } share = new Share(point); share.ParsedVal = s; return(true); }
/// <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); }
//Helper, tryies to parse the string representation of share. Returns true if success private static bool TryParse(string s, out FFPoint result) { Match m = Regex.Match(s, RegFormat); return(TryParse(m, out result)); }
public Share(FFPoint point) { Point = point; }