/// <summary> /// Get "float window" and parametrs /// </summary> /// <param name="value">Mul value</param> /// <param name="lastIndex">Last index in mul value</param> /// <param name="mulValue">How many doubling</param> /// <param name="addValue">How much add after</param> /// <returns>New index</returns> private static int GetWindow(IntBig value, int lastIndex, out int mulValue, out int addValue) { mulValue = 0; addValue = 0; if (lastIndex < 0) { return(lastIndex); } while (true) { mulValue++; addValue *= 2; if (value.GetBit(lastIndex)) { addValue += 1; } lastIndex--; if (addValue >= 8) { break; } if (lastIndex < 0) { break; } } return(lastIndex); }
/// <summary> /// Initializes a new instance of the MIntBig value using string representation /// </summary> /// <param name="value">Value in x mod y view</param> /// <param name="littleEndian">true if value represents as little-Endian</param> public static MIntBig Parse(string value, bool littleEndian) { string[] items = value.Split(new string[] { "mod", "MOD" }, StringSplitOptions.RemoveEmptyEntries); if (items == null || items.Length < 2) { throw new Exception("Unknown format. Please change format to x mod y view."); } return(new MIntBig(IntBig.Parse(items[0], littleEndian), IntBig.Parse(items[1], littleEndian))); }
/// <summary> /// Умножить точку на число на эллиптической кривой /// </summary> /// <param name="value1">Точка на эллиптической кривой</param> /// <param name="value2">Множитель к точке</param> /// <returns></returns> public IEllipticCurvePoint Multiply(IntBig value2) { EllipticCurvePointB tempPoint = null; // Массив значений для этапа "предвычислений" // !!!!!!!!!!!!!!Занимательная задачка: надо подумать над графом вычислений, ибо почти стопроцентная уверенность, что не все значения массива понадобятся... Налицо оптимизация EllipticCurvePointB[] points = new EllipticCurvePointB[16]; points[0] = GetInfinity() as EllipticCurvePointB; points[1] = this; points[2] = points[1].Doubling() as EllipticCurvePointB; points[3] = points[1].Addition(points[2]) as EllipticCurvePointB; points[4] = points[2].Doubling() as EllipticCurvePointB; points[5] = points[1].Addition(points[4]) as EllipticCurvePointB; points[6] = points[3].Doubling() as EllipticCurvePointB; points[7] = points[1].Addition(points[6]) as EllipticCurvePointB; points[8] = points[4].Doubling() as EllipticCurvePointB; points[9] = points[1].Addition(points[8]) as EllipticCurvePointB; points[10] = points[5].Doubling() as EllipticCurvePointB; points[11] = points[1].Addition(points[10]) as EllipticCurvePointB; points[12] = points[6].Doubling() as EllipticCurvePointB; points[13] = points[1].Addition(points[12]) as EllipticCurvePointB; points[14] = points[7].Doubling() as EllipticCurvePointB; points[15] = points[1].Addition(points[14]) as EllipticCurvePointB; // Начальный индекс множителя, от него начинается движение по двоичному представлению большого числа int index = BigHelper.MaxNonZeroBitIndex(value2.m_Value); int howManyDouble = 0; int howMuchAdd = 0; //if (index < 0) // break; index = GetWindow(value2, index, out howManyDouble, out howMuchAdd); tempPoint = points[howMuchAdd]; while (true) { if (index < 0) { break; } index = GetWindow(value2, index, out howManyDouble, out howMuchAdd); if (howManyDouble > 0) { for (int t = 0; t < howManyDouble; ++t) { tempPoint = tempPoint.Doubling() as EllipticCurvePointB; } } if (howMuchAdd > 0) { tempPoint = tempPoint.Addition(points[howMuchAdd]) as EllipticCurvePointB; } } return(tempPoint); }
/// <summary> /// Parse the curve and points parameters /// </summary> /// <param name="x">The X value in affine coordinate</param> /// <param name="y">The Y value in affine coordinate</param> /// <param name="a1">The a1 elliptic curve parameter in the Weierstrass equation</param> /// <param name="a2">The a2 elliptic curve parameter in the Weierstrass equation</param> /// <param name="a3">The a3 elliptic curve parameter in the Weierstrass equation</param> /// <param name="a4">The a4 elliptic curve parameter in the Weierstrass equation</param> /// <param name="a6">The a6 elliptic curve parameter in the Weierstrass equation</param> /// <param name="modulo">The modulo for finite field operations</param> internal EllipticCurvePoint(IntBig x, IntBig y, IntBig a1, IntBig a2, IntBig a3, IntBig a4, IntBig a6, IntBig modulo) { // Set resolver for different types of elliptic curve if (a1 == null && a2 == null && a3 == null && a4 != null && a6 != null) { m_Resolver = new EllipticCurvePointB(x, y, a4, a6, modulo); } else { throw new Exception("Unknown type of elliptic curve."); } }
public static bool IsValid(IntBig x, IntBig y, IntBig a4, IntBig a6, IntBig modulo) { MIntBig my = new MIntBig(y, modulo); MIntBig mx = new MIntBig(x, modulo); MIntBig ma4 = new MIntBig(a4, modulo); MIntBig ma6 = new MIntBig(a6, modulo); MIntBig my2 = my * my; MIntBig mx2 = mx * mx * mx + ma4 * mx + ma6; return(my2 == mx2); }
/// <summary> /// Multiplies the this value at IntBig value /// </summary> /// <param name="value">IntBig multiplier</param> /// <returns>Result of operation</returns> public IEllipticCurvePoint Multiply(IntBig value2) { EllipticCurvePointC tempPoint = null; EllipticCurvePointC[] points = new EllipticCurvePointC[16]; points[0] = GetInfinity() as EllipticCurvePointC; points[1] = this; points[2] = points[1].Doubling() as EllipticCurvePointC; points[3] = points[1].Addition(points[2]) as EllipticCurvePointC; points[4] = points[2].Doubling() as EllipticCurvePointC; points[5] = points[1].Addition(points[4]) as EllipticCurvePointC; points[6] = points[3].Doubling() as EllipticCurvePointC; points[7] = points[1].Addition(points[6]) as EllipticCurvePointC; points[8] = points[4].Doubling() as EllipticCurvePointC; points[9] = points[1].Addition(points[8]) as EllipticCurvePointC; points[10] = points[5].Doubling() as EllipticCurvePointC; points[11] = points[1].Addition(points[10]) as EllipticCurvePointC; points[12] = points[6].Doubling() as EllipticCurvePointC; points[13] = points[1].Addition(points[12]) as EllipticCurvePointC; points[14] = points[7].Doubling() as EllipticCurvePointC; points[15] = points[1].Addition(points[14]) as EllipticCurvePointC; // First index int index = BigHelper.MaxNonZeroBitIndex(value2.m_Value); int howManyDouble = 0; int howMuchAdd = 0; //if (index < 0) // break; index = GetWindow(value2, index, out howManyDouble, out howMuchAdd); tempPoint = points[howMuchAdd]; while (true) { if (index < 0) { break; } index = GetWindow(value2, index, out howManyDouble, out howMuchAdd); if (howManyDouble > 0) { for (int t = 0; t < howManyDouble; ++t) { tempPoint = tempPoint.Doubling() as EllipticCurvePointC; } } if (howMuchAdd > 0) { tempPoint = tempPoint.Addition(points[howMuchAdd]) as EllipticCurvePointC; } } return(tempPoint); }
internal EllipticCurvePointC(uint[] x, uint[] y, uint[] z, EllipticCurvePointC point) { m_Modulo = point.m_Modulo; m_a4 = point.m_a4; m_a6 = point.m_a6; m_X = new IntBig(x) % m_Modulo; m_Y = new IntBig(y) % m_Modulo; m_Z = new IntBig(z) % m_Modulo; if (!IsValid(m_X, m_Y, m_Z, m_a4, m_a6, m_Modulo)) { throw new Exception("Point is not from elliptic curve"); } }
internal EllipticCurvePointC(IntBig x, IntBig y, IntBig z, EllipticCurvePointC point) { m_Modulo = point.m_Modulo; m_a4 = point.m_a4; m_a6 = point.m_a6; m_X = x % m_Modulo; m_Y = y % m_Modulo; m_Z = z % m_Modulo; if (!IsValid(m_X, m_Y, m_Z, m_a4, m_a6, m_Modulo)) { throw new Exception("Point is not from elliptic curve"); } }
/// <summary> /// Indicates whether the current value is equal to another IntBig value /// </summary> /// <param name="other">A value to compare with this value</param> /// <returns>true if the current value is equal to the other value; otherwise, false</returns> public bool Equals(IntBig obj) { if (obj as object == null) { return(false); } if (obj as object == m_Value as object) { return(true); } IntBig temp = obj % m_Modulo; return(m_Value.Equals(temp)); }
/// <summary> /// Compares the current value with another IntBig value /// </summary> /// <param name="obj">An object to compare with this value</param> /// <returns> /// Zero if this value is equal to other value. /// 1 if value is greater than other value. /// -1 if the value is less than the other value/ /// </returns> public int CompareTo(IntBig other) { if (other as object == null) { throw new ArgumentNullException("other"); } if (other as object == m_Value as object) { return(0); } IntBig temp = other % m_Modulo; return(m_Value.CompareTo(temp)); }
public EllipticCurvePointC(IntBig x, IntBig y, IntBig a4, IntBig a6, IntBig modulo) { m_x = x; m_y = y; m_Modulo = modulo; m_a4 = a4; m_a6 = a6; m_X = new IntBig(x.m_Value) % m_Modulo; m_Y = new IntBig(y.m_Value) % m_Modulo; m_Z = new IntBig(1); if (!IsValid(m_X, m_Y, m_Z, m_a4, m_a6, m_Modulo)) { throw new Exception("Point is not from elliptic curve"); } }
public EllipticCurvePointB(IntBig x, IntBig y, EllipticCurvePointB point) { m_x = x; m_y = y; m_Modulo = point.m_Modulo; m_a4 = point.m_a4; m_a6 = point.m_a6; if (!IsValid(m_x, m_y, m_a4, m_a6, m_Modulo)) { throw new Exception("Point is not from elliptic curve"); } m_X = new IntBig(x.m_Value) % m_Modulo; m_Y = new IntBig(y.m_Value) % m_Modulo; m_Z = new IntBig(1); }
/// <summary> /// Initializes a new instance of the value using the ulong value and the modulo in a uint array /// </summary> /// <param name="value">The value</param> /// <param name="modulo">An array of uint values in little-endian order</param> internal MIntBig(ulong value, uint[] modulo) { m_Value = new IntBig(value); IntBig moduloTemp = new IntBig(modulo); IntBig temp; if (m_Modules.TryGetValue(moduloTemp, out temp)) { m_Modulo = temp; } else { m_Modules.Add(moduloTemp, moduloTemp); m_Modulo = moduloTemp; } m_MaxModuloBitIndex = m_Modulo.Length - 1; }
public static bool IsValid(IntBig x, IntBig y, IntBig z, IntBig a4, IntBig a6, IntBig modulo) { MIntBig my = new MIntBig(y, modulo); MIntBig mx = new MIntBig(x, modulo); MIntBig mz = new MIntBig(z, modulo); MIntBig ma4 = new MIntBig(a4, modulo); MIntBig ma6 = new MIntBig(a6, modulo); MIntBig mz2 = mz * mz; MIntBig mz4 = mz2 * mz2; MIntBig mz6 = mz4 * mz2; MIntBig my2 = my * my; MIntBig mx2 = mx * mx * mx + ma4 * mx * mz4 + ma6 * mz6; return(my2 == mx2); }
/// <summary> /// Initializes a new instance of the value using the values in a uint arrays /// </summary> /// <param name="value">An array of uint values in little-endian order</param> /// <param name="modulo">An array of uint values in little-endian order</param> internal MIntBig(uint[] value, uint[] modulo) { int length = (value.Length > modulo.Length) ? value.Length : modulo.Length; length *= 32; m_Value = new IntBig(value); IntBig moduloTemp = new IntBig(modulo); IntBig temp; if (m_Modules.TryGetValue(moduloTemp, out temp)) { m_Modulo = temp; } else { m_Modules.Add(moduloTemp, moduloTemp); m_Modulo = moduloTemp; } m_MaxModuloBitIndex = m_Modulo.Length - 1; }
/// <summary> /// Initializes a new instance of the value using the IntBig values /// </summary> /// <param name="value">The value</param> /// <param name="modulo">The modulo</param> internal MIntBig(IntBig value, IntBig modulo) { if (value < modulo) { m_Value = value; } else { m_Value = value % modulo; } IntBig temp; if (m_Modules.TryGetValue(modulo, out temp)) { m_Modulo = temp; } else { m_Modules.Add(modulo, modulo); m_Modulo = modulo; } m_MaxModuloBitIndex = m_Modulo.Length - 1; }
internal EllipticCurvePoint(IntBig x, IntBig y, IntBig z, IEllipticCurvePoint resolver) { m_Resolver = new EllipticCurvePointB(x, y, z, resolver as EllipticCurvePointB); }
/// <summary> /// Multiplies the value at IntBig value /// </summary> /// <param name="value1">Elliptic curve point</param> /// <param name="value2">IntBig multiplier</param> /// <returns>Result</returns> public static EllipticCurvePointC Multiply(EllipticCurvePointC value1, IntBig value2) { return(value1.Multiply(value2) as EllipticCurvePointC); }
/// <summary> /// Parse the byte array /// </summary> /// <param name="value">Value array</param> /// <param name="modulo">Modulo value</param> public static MIntBig Parse(byte[] value, IntBig modulo) { IntBig value1 = IntBig.Parse(value, true); return(new MIntBig(value1, modulo)); }
/// <summary> /// Initializes a new instance of the MIntBig value using IntBig value /// </summary> /// <param name="value">IntBig value</param> /// <param name="modulo">Modulo of value</param> public static MIntBig Parse(IntBig value, IntBig modulo) { return(new MIntBig(value, modulo)); }
/// <summary> /// Compares the current value with another object. /// </summary> /// <param name="obj">An object to compare with this value</param> /// <returns> /// Zero if this value is equal to other value. /// 1 if value is greater than other value. /// -1 if the value is less than the other value/ /// </returns> public int CompareTo(object obj) { IntBig obj1 = obj as IntBig; return(CompareTo(obj1)); }
/// <summary> /// Parse the curve from another point and new points parameters x,y /// </summary> /// <param name="x">The X value in affine coordinate</param> /// <param name="y">The Y value in affine coordinate</param> /// <param name="point">Another point</param> public static EllipticCurvePoint Parse(IntBig x, IntBig y, EllipticCurvePoint point) { return(new EllipticCurvePoint(x, y, point.m_Resolver)); }
/// <summary> /// Умножить точку на число на эллиптической кривой /// </summary> /// <param name="value1">Точка на эллиптической кривой</param> /// <param name="value2">Множитель к точке</param> /// <returns></returns> public static EllipticCurvePoint Multiply(EllipticCurvePoint value1, IntBig value2) { return(new EllipticCurvePoint(value1.m_Resolver.Multiply(value2))); }
/// <summary> /// Initializes a new instance of the MIntBig value using value and modulo strings /// </summary> /// <param name="value">Value</param> /// <param name="modulo">Modulo</param> /// <param name="littleEndian">true if value represents as little-Endian</param> public static MIntBig Parse(string value, string modulo, bool littleEndian) { return(new MIntBig(IntBig.Parse(value, littleEndian), IntBig.Parse(modulo, littleEndian))); }
/// <summary> /// Parse the curve and points parameters /// </summary> /// <param name="x">The X value in affine coordinate</param> /// <param name="y">The Y value in affine coordinate</param> /// <param name="a1">The a1 elliptic curve parameter in the Weierstrass equation</param> /// <param name="a2">The a2 elliptic curve parameter in the Weierstrass equation</param> /// <param name="a3">The a3 elliptic curve parameter in the Weierstrass equation</param> /// <param name="a4">The a4 elliptic curve parameter in the Weierstrass equation</param> /// <param name="a6">The a6 elliptic curve parameter in the Weierstrass equation</param> /// <param name="modulo">The modulo for finite field operations</param> public static EllipticCurvePoint Parse(IntBig x, IntBig y, IntBig a1, IntBig a2, IntBig a3, IntBig a4, IntBig a6, IntBig modulo) { return(new EllipticCurvePoint(x, y, a1, a2, a3, a4, a6, modulo)); }
/// <summary> /// Initializes a new instance of the MIntBig value using ulong value /// </summary> /// <param name="value">ulong value</param> /// <param name="modulo">Modulo of value</param> public static MIntBig Parse(ulong value, IntBig modulo) { return(new MIntBig(value, modulo.m_Value)); }