public static EllipticCurvePoint AffineCoords(EllipticCurvePoint p) { p.X = BigInteger.Remainder(p.X * Additional.Inverse(p.Z, p.P), p.P); p.Y = BigInteger.Remainder(p.Y * Additional.Inverse(p.Z, p.P), p.P); p.Z = 1; return(p); } // Приведение к афинным координатам
public static Shifr[] encrypt(byte[][] message, EllipticCurvePoint publicB, EllipticCurvePoint _pointG) { Shifr[] sh = new Shifr[message.GetLength(0)]; RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); byte[] key = new byte[15]; rng.GetBytes(key); BigInteger k = new BigInteger(key); if (k < 0) { k = -k; } ; ParallelEncoding pe = new ParallelEncoding(k, message, publicB, _pointG); Task t1 = new Task(pe.Func0); Task t2 = new Task(pe.Func1); Task t3 = new Task(pe.Func2); t1.Start(); t2.Start(); t3.Start(); pe.Func3(); Task.WaitAll(t1, t2, t3); return(pe.Shifr); }
public void FuncNoParallel() { for (int i = 0; i < lengthmess; i++) { int correct = 0; BigInteger bigtext = new BigInteger(Message[i]); EllipticCurvePoint pointtext = PointG.SearchPoint(bigtext, out correct); EllipticCurvePoint point2 = EllipticCurvePoint.AffineCoords(EllipticCurvePoint.AddPoint(pointtext, kPublicB)); Shifr[i] = new Shifr(kP, point2, correct); } }
public static Shifr[] InShifr(string _str, EllipticCurvePoint g) { StringBuilder str = new StringBuilder(_str); int _countSh = Convert.ToInt32(str.ToString(0, 24), 2); Shifr[] sh = new Shifr[_countSh]; int count = Convert.ToInt32(str.ToString(24, 8), 2); List <byte> pkP = new List <byte>(); for (int i = 0; i < count; i++) { byte temp = Convert.ToByte(str.ToString(32 + i * 8, 8), 2); pkP.Add(temp); } str = str.Remove(0, count * 8 + 32); byte[] pointkP = pkP.ToArray(); string point1 = BitConverter.ToString(pointkP, 0).Replace("-", ""); // сжатая точка kP EllipticCurvePoint kP = EllipticCurvePoint.UnCompressPoint(point1, g); string[] strshifr = new string[_countSh]; var tasks = new List <Task>(); int currentchar = 0; for (int i = 0; i < _countSh; i++) { int lenstrcadr = Convert.ToInt32(str.ToString(currentchar, 16), 2); strshifr[i] = str.ToString(currentchar + 16, lenstrcadr); currentchar += lenstrcadr + 16; var i1 = i; tasks.Add(Task.Factory.StartNew(delegate() { int correct = 0; // корректировка correct = Convert.ToInt32(strshifr[i1].Substring(0, 5), 2); int countSecondPoint = Convert.ToInt32(strshifr[i1].Substring(5, 8), 2); var secondPoint = new List <byte>(); for (int j = 0; j < countSecondPoint; j++) { byte temp = Convert.ToByte(strshifr[i1].Substring(13 + 8 * j, 8), 2); secondPoint.Add(temp); } string _second = BitConverter.ToString(secondPoint.ToArray(), 0).Replace("-", ""); // сжатая точка var second = EllipticCurvePoint.UnCompressPoint(_second, g); sh[i1] = new Shifr(kP, second, correct); })); } Task.WaitAll(tasks.ToArray()); return(sh.ToArray()); }
public ParallelEncoding(BigInteger key, byte[][] mess, EllipticCurvePoint _publicB, EllipticCurvePoint g) { Key = key; Message = mess; PublicB = _publicB; PointG = g; lengthmess = mess.GetLength(0); Shifr = new Shifr[lengthmess]; // вычисление общей части шифрограммы kP = EllipticCurvePoint.Multiply(key, PointG); kP = EllipticCurvePoint.AffineCoords(kP); //Вычисление общего ключа kPublicB = EllipticCurvePoint.Multiply(Key, PublicB); }
public ParallelDecoding(BigInteger key, Shifr[] shifr) { Key = key; Sh = shifr; lengtshifr = shifr.Count(); Message = new byte[lengtshifr][]; // Вычисляем точку Key*K*pointG KeyPara1 = EllipticCurvePoint.Multiply(Key, shifr[0].PointA); // привод к аффиным координатам и смена знака координаты Y(Для вычитания) KeyPara1 = EllipticCurvePoint.AffineCoords(KeyPara1); KeyPara1.Y = -KeyPara1.Y; // конец }
public void Func3() { for (int i = 3; i < lengtshifr; i += 4) { Shifr _sh = Sh[i]; EllipticCurvePoint para2 = _sh.PointB; EllipticCurvePoint t = EllipticCurvePoint.AddPoint(para2, KeyPara1); BigInteger q = t.X * Additional.Inverse(t.Z, t.P); q = BigInteger.Remainder(q, t.P); if (_sh.Correct != 0) { q += _sh.Correct; } Message[i] = q.ToByteArray(); } }
} // Сжатие точки public static EllipticCurvePoint UnCompressPoint(string compressP, EllipticCurvePoint g) { BigInteger X, Y = new BigInteger(); EllipticCurvePoint point; byte[] compressPointX = new byte[compressP.Count() / 2 - 1]; StringBuilder s = new StringBuilder(); s.Append(compressP[0]); s.Append(compressP[1]); compressP = compressP.Remove(0, 2); byte y = Convert.ToByte(s.ToString(), 16); //байт четности X = BigInteger.Parse(compressP, System.Globalization.NumberStyles.HexNumber); BigInteger xcord = BigInteger.Remainder((X * X * X + g.A * X + g.B), g.P); Y = BigInteger.ModPow(xcord, ((g.P + 1) / 4), g.P); if (y == 2) { if (BigInteger.Remainder(Y, 2) == 0) { point = new EllipticCurvePoint(g.P, g.A, g.B, g.N, X, Y, 1, g.BlockSize); return(point); } else { point = new EllipticCurvePoint(g.P, g.A, g.B, g.N, X, g.P - Y, 1, g.BlockSize); return(point); } } else { if (BigInteger.Remainder(Y, 2) != 0) { point = new EllipticCurvePoint(g.P, g.A, g.B, g.N, X, Y, 1, g.BlockSize); return(point); } else { point = new EllipticCurvePoint(g.P, g.A, g.B, g.N, X, g.P - Y, 1, g.BlockSize); return(point); } } }
} // Возвращает точку на кривой в которой размещено сообщение public static string CompressPoint(EllipticCurvePoint point) { string compress = ""; BigInteger X = point.X; byte[] temp = X.ToByteArray(); byte[] tochka = new byte[temp.Count() + 1]; if (BigInteger.Remainder(point.Y, 2) == 0) { tochka[0] = 2; } else { tochka[0] = 3; } for (int i = 1; i < temp.Count() + 1; i++) { tochka[i] = temp[i - 1]; } Array.Reverse(tochka, 1, tochka.Count() - 1); compress = BitConverter.ToString(tochka, 0).Replace("-", ""); return(compress); } // Сжатие точки
public static EllipticCurvePoint Multiply(BigInteger k, EllipticCurvePoint point) { EllipticCurvePoint temp = point; k--; while (k != 0) { if (BigInteger.Remainder(k, 2) != 0) { if ((temp.X == point.X) && (temp.Y == point.Y)) { temp = X2(temp); } else { temp = AddPoint(temp, point); } k--; } k = k / 2; point = X2(point); } return(temp); }
public Shifr(EllipticCurvePoint para1, EllipticCurvePoint para2, int correct) { PointA = para1; PointB = para2; Correct = correct; }
public Encryption(string pathPublicKey) { #region открытие ключа StringBuilder sb = new StringBuilder(); byte[] inputfile = File.ReadAllBytes(pathPublicKey); byte rem = inputfile[0]; for (int i = 1; i < inputfile.Count() - 1; i++) { sb.Append(Convert.ToString(Convert.ToByte(inputfile[i]), 2).FillWithZero(8)); } sb.Append(Convert.ToString(Convert.ToByte(inputfile[inputfile.Count() - 1]), 2).FillWithZero(rem)); #endregion if (sb.ToString(0, 1).Equals("1")) // если кривая заданна в программе { EllipticCurvePoint g = new EllipticCurvePoint(192); if (sb.ToString(1, 2).Equals("00")) { // g = new EllipticCurvePoint(192); } else if (sb.ToString(1, 2).Equals("01")) { g = new EllipticCurvePoint(256); } else if (sb.ToString(1, 2).Equals("10")) { g = new EllipticCurvePoint(384); } else if (sb.ToString(1, 2).Equals("11")) { g = new EllipticCurvePoint(521); } else { throw new Exception("Файл поврежден. Невозможно определить тип кривой."); } int count = Convert.ToInt32(sb.ToString(3, 8), 2); List <byte> point = new List <byte>(); for (int j = 0; j < count; j++) { byte temp = Convert.ToByte(sb.ToString(11 + 8 * j, 8), 2); point.Add(temp); } sb = sb.Remove(0, 8 * count + 11); string _second = BitConverter.ToString(point.ToArray(), 0).Replace("-", ""); // сжатая точка openKey = EllipticCurvePoint.UnCompressPoint(_second, g); count = Convert.ToInt32(sb.ToString(0, 8), 2); point = new List <byte>(); for (int j = 0; j < count; j++) { byte temp = Convert.ToByte(sb.ToString(8 + 8 * j, 8), 2); point.Add(temp); } _second = BitConverter.ToString(point.ToArray(), 0).Replace("-", ""); // сжатая точка Point = EllipticCurvePoint.UnCompressPoint(_second, g); } else { throw new Exception("Файл поврежден"); } }
private static EllipticCurvePoint X2(EllipticCurvePoint point) { BigInteger A = 3 * point.X * point.X + point.A * point.Z * point.Z; A = BigInteger.Remainder(A, point.P); if (A < 0) { while (A < 0) { A += point.P; } } BigInteger B = 2 * point.Y * point.Z; B = BigInteger.Remainder(B, point.P); if (B < 0) { while (B < 0) { B += point.P; } } BigInteger X = B * (A * A - 4 * point.X * point.Y * B); X = BigInteger.Remainder(X, point.P); if (X < 0) { while (X < 0) { X += point.P; } } BigInteger Y = A * (6 * point.Y * point.X * B - A * A) - 2 * point.Y * point.Y * B * B; Y = BigInteger.Remainder(Y, point.P); if (Y < 0) { while (Y < 0) { Y += point.P; } } BigInteger Z = B * B * B; Z = BigInteger.Remainder(Z, point.P); if (Z < 0) { while (Z < 0) { Z += point.P; } } return(new EllipticCurvePoint(point.P, point.A, point.B, point.N, X, Y, Z, point.BlockSize)); }
public static EllipticCurvePoint AddPoint(EllipticCurvePoint pointA, EllipticCurvePoint pointB) { if ((pointA.X == pointA.Z) && (pointA.X == 0)) { return(pointB); } if ((pointB.X == pointB.Z) && (pointB.X == 0)) { return(pointA); } BigInteger A = pointB.Y * pointA.Z - pointA.Y * pointB.Z; A = BigInteger.Remainder(A, pointA.P); if (A < 0) { while (A < 0) { A += pointA.P; } } BigInteger B = pointB.X * pointA.Z - pointA.X * pointB.Z; B = BigInteger.Remainder(B, pointA.P); if (B < 0) { while (B < 0) { B += pointA.P; } } BigInteger C = pointB.X * pointA.Z + pointA.X * pointB.Z; C = BigInteger.Remainder(C, pointA.P); if (C < 0) { while (C < 0) { C += pointA.P; } } BigInteger D = pointB.X * pointA.Z + 2 * pointA.X * pointB.Z; D = BigInteger.Remainder(D, pointA.P); if (D < 0) { while (D < 0) { D += pointA.P; } } BigInteger E = pointB.Z * pointA.Z; E = BigInteger.Remainder(E, pointA.P); if (E < 0) { while (E < 0) { E += pointA.P; } } BigInteger X = B * (E * A * A - C * B * B); X = BigInteger.Remainder(X, pointA.P); if (X < 0) { while (X < 0) { X += pointA.P; } } BigInteger Y = A * (B * B * D - A * A * E) - pointA.Y * pointB.Z * B * B * B; Y = BigInteger.Remainder(Y, pointA.P); if (Y < 0) { while (Y < 0) { Y += pointA.P; } } BigInteger Z = B * B * B * E; Z = BigInteger.Remainder(Z, pointA.P); if (Z < 0) { while (Z < 0) { Z += pointA.P; } } if (X == 0 && Z == 0) { return(new EllipticCurvePoint(pointA.P, pointA.A, pointA.B, pointA.N, 0, 1, 0, pointA.BlockSize)); } return(new EllipticCurvePoint(pointA.P, pointA.A, pointA.B, pointA.N, X, Y, Z, pointA.BlockSize)); }
public static void createKey(string path, int typePoint) { EllipticCurvePoint g = new EllipticCurvePoint(typePoint); RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); byte[] _key = new byte[g.BlockSize]; rng.GetBytes(_key); BigInteger key = new BigInteger(_key); // секрет if (key < 0) { key = -key; } ; rng.GetBytes(_key); BigInteger t = new BigInteger(_key); //Случайное число, для нахождения случайной точки if (t < 0) { t = -t; } ; int b; EllipticCurvePoint point = g.SearchPoint(t, out b); EllipticCurvePoint publicPoint = EllipticCurvePoint.Multiply(key, point); // публичная точка #region openkey StringBuilder openkey = new StringBuilder(); // определение типа кривой openkey.Append('1'); if (typePoint == 192) { openkey.Append("00"); } else if (typePoint == 256) { openkey.Append("01"); } else if (typePoint == 384) { openkey.Append("10"); } else if (typePoint == 521) { openkey.Append("11"); } // cохранение publicPoint publicPoint = EllipticCurvePoint.AffineCoords(publicPoint); string pointstr = EllipticCurvePoint.CompressPoint(publicPoint); openkey.Append(Convert.ToString(Convert.ToByte(pointstr.Count() / 2), 2).FillWithZero(8)); // кол-во байт в сжатой точке openkey.Append(Additional.FromByteStrToBitStr(pointstr)); // Сохранение point pointstr = EllipticCurvePoint.CompressPoint(point); openkey.Append(Convert.ToString(Convert.ToByte(pointstr.Count() / 2), 2).FillWithZero(8)); // кол-во байт в сжатой точке openkey.Append(Additional.FromByteStrToBitStr(pointstr)); // Вывод piblicKey List <byte> q = new List <byte>(); string s = openkey.ToString(); q.Add((byte)(s.Count() % 8)); q.AddRange(s.ToByteList()); File.WriteAllBytes(path + "\\" + Environment.MachineName + "_" + typePoint.ToString() + ".publickey", q.ToArray()); #endregion #region closekey StringBuilder closekey = new StringBuilder(); // определение типа кривой closekey.Append('1'); if (typePoint == 192) { closekey.Append("00"); } else if (typePoint == 256) { closekey.Append("01"); } else if (typePoint == 384) { closekey.Append("10"); } else if (typePoint == 521) { closekey.Append("11"); } // сохранение ключа closekey.Append(Convert.ToString(Convert.ToByte(key.ToByteArray().Count()), 2).FillWithZero(8)); // кол-во байт в в ключе closekey.Append(Additional.FromByteStrToBitStr(key.ToByteArray())); // Сохранение point pointstr = EllipticCurvePoint.CompressPoint(point); closekey.Append(Convert.ToString(Convert.ToByte(pointstr.Count() / 2), 2).FillWithZero(8)); // кол-во байт в сжатой точке closekey.Append(Additional.FromByteStrToBitStr(pointstr)); // Вывод piblicKey q = new List <byte>(); s = closekey.ToString(); q.Add((byte)(s.Count() % 8)); q.AddRange(s.ToByteList()); File.WriteAllBytes(path + "\\" + Environment.MachineName + "_" + typePoint.ToString() + ".privatekey", q.ToArray()); #endregion }