//проверка цифровой подписи. public bool VerifDs(byte[] h, string sign, EcPoint q) { string rvector = sign.Substring(0, sign.Length / 2); string svector = sign.Substring(sign.Length / 2, sign.Length / 2); var r = new BigInteger(rvector, 16); var s = new BigInteger(svector, 16); if ((r < 1) || (r > (_n - 1)) || (s < 1) || (s > (_n - 1))) { return(false); } var a = new BigInteger(h); BigInteger e = a % _n; if (e == 0) { e = 1; } BigInteger v = e.modInverse(_n); BigInteger z1 = (s * v) % _n; BigInteger z2 = _n + ((-(r * v)) % _n); _g = GDecompression(); EcPoint A = EcPoint.Multiply(_g, z1); EcPoint b = EcPoint.Multiply(q, z2); EcPoint c = A + b; BigInteger R = c.X % _n; return(R == r); }
public static byte[] CreateSignature(byte[] p_data, ElGamalKeyStruct p_key_struct) { BigInteger x_pminusone = p_key_struct.P - 1; // create K, which is the random number BigInteger K; do { K = new BigInteger(); K.genRandomBits(p_key_struct.P.bitCount() - 1, new Random()); } while (K.gcd(x_pminusone) != 1); BigInteger A = p_key_struct.G.modPow(K, p_key_struct.P); BigInteger B = mod(mod(K.modInverse(x_pminusone) * (new BigInteger(p_data) - (p_key_struct.X * (A))), (x_pminusone)), (x_pminusone)); byte[] x_a_bytes = A.getBytes(); byte[] x_b_bytes = B.getBytes(); // define the result size int x_result_size = (((p_key_struct.P.bitCount() + 7) / 8) * 2); // create an array to contain the ciphertext byte[] x_result = new byte[x_result_size]; // populate the arrays Array.Copy(x_a_bytes, 0, x_result, x_result_size / 2 - x_a_bytes.Length, x_a_bytes.Length); Array.Copy(x_b_bytes, 0, x_result, x_result_size - x_b_bytes.Length, x_b_bytes.Length); // return the result array .. return(x_result); }
/** * return true if the value r and s represent a DSA signature for * the passed in message for standard DSA the message should be a * SHA-1 hash of the real message to be verified. */ public bool verifySignature( byte[] message, BigInteger r, BigInteger s) { BigInteger m = new BigInteger(1, message); DSAParameters parameters = key.getParameters(); BigInteger zero = BigInteger.valueOf(0); if (zero.compareTo(r) >= 0 || parameters.getQ().compareTo(r) <= 0) { return(false); } if (zero.compareTo(s) >= 0 || parameters.getQ().compareTo(s) <= 0) { return(false); } BigInteger w = s.modInverse(parameters.getQ()); BigInteger u1 = m.multiply(w).mod(parameters.getQ()); BigInteger u2 = r.multiply(w).mod(parameters.getQ()); u1 = parameters.getG().modPow(u1, parameters.getP()); u2 = ((DSAPublicKeyParameters)key).getY().modPow(u2, parameters.getP()); BigInteger v = u1.multiply(u2).mod(parameters.getP()).mod(parameters.getQ()); return(v.Equals(r)); }
protected internal bool VerifySignature(byte[] msg, BigInteger r, BigInteger s) { // Create a SHA1 hash of the message SHA1Digest h = new SHA1Digest(); h.update(msg, 0, msg.Length); byte[] data = new byte[h.getDigestSize()]; h.doFinal(data, 0); BigInteger m = new BigInteger(1, data); m = m.mod(q); if (BigInteger.valueOf(0).compareTo(r) >= 0 || q.compareTo(r) <= 0) { return(false); } if (BigInteger.valueOf(0).compareTo(s) >= 0 || q.compareTo(s) <= 0) { return(false); } BigInteger w = s.modInverse(q); BigInteger u1 = m.multiply(w).mod(q); BigInteger u2 = r.multiply(w).mod(q); BigInteger v = g.modPow(u1, p).multiply(y.modPow(u2, p)).mod(p).mod(q); return(v.compareTo(r) == 0); }
//сложение точки P c собой же public static ECPoint Double(ECPoint p) { ECPoint p2 = new ECPoint(); p2.a = p.a; p2.b = p.b; p2.FieldChar = p.FieldChar; BigInteger dy = 3 * p.x * p.x + p.a; BigInteger dx = 2 * p.y; if (dx < 0) { dx += p.FieldChar; } if (dy < 0) { dy += p.FieldChar; } BigInteger m = (dy * dx.modInverse(p.FieldChar)) % p.FieldChar; p2.x = (m * m - p.x - p.x) % p.FieldChar; p2.y = (m * (p.x - p2.x) - p.y) % p.FieldChar; if (p2.x < 0) { p2.x += p.FieldChar; } if (p2.y < 0) { p2.y += p.FieldChar; } return(p2); }
public static string GetPrivateKeyExponent(string p, string q) { BigInteger e = new BigInteger(Convert.ToInt64(17)); BigInteger d = e.modInverse((new BigInteger(p, _RADIX) - 1) * (new BigInteger(q, _RADIX) - 1)); return(d.ToString(_RADIX)); }
public static string GetPrivateKeyExponent(string p, string q) { BigInteger e = new BigInteger(Convert.ToInt64(17)); BigInteger d = e.modInverse((new BigInteger(p, _RADIX) - 1) * (new BigInteger(q, _RADIX) - 1)); return d.ToString(_RADIX); }
//проверяем подпись public bool SingVer(byte[] H, string sing, ECPoint Q) { string Rvector = sing.Substring(0, n.bitCount() / 4); string Svector = sing.Substring(n.bitCount() / 4, n.bitCount() / 4); BigInteger r = new BigInteger(Rvector, 16); BigInteger s = new BigInteger(Svector, 16); if ((r < 1) || (r > (n - 1)) || (s < 1) || (s > (n - 1))) { return(false); } BigInteger alpha = new BigInteger(H); BigInteger e = alpha % n; if (e == 0) { e = 1; } BigInteger v = e.modInverse(n); BigInteger z1 = (s * v) % n; BigInteger z2 = n + ((-(r * v)) % n); ECPoint A = ECPoint.multiply(z1, G); ECPoint B = ECPoint.multiply(z2, Q); ECPoint C = A + B; BigInteger R = C.x % n; if (R == r) { return(true); } else { return(false); } }
/** * generate a signature for the given message using the key we were * initialised with. For conventional DSA the message should be a SHA-1 * hash of the message of interest. * * @param message the message that will be verified later. */ public BigInteger[] generateSignature( byte[] message) { BigInteger m = new BigInteger(1, message); DSAParameters parameters = key.getParameters(); BigInteger k; do { k = new BigInteger(parameters.getQ().bitLength(), random); }while (k.compareTo(parameters.getQ()) >= 0); BigInteger r = parameters.getG().modPow(k, parameters.getP()).mod(parameters.getQ()); k = k.modInverse(parameters.getQ()).multiply( m.add(((DSAPrivateKeyParameters)key).getX().multiply(r))); BigInteger s = k.mod(parameters.getQ()); BigInteger[] res = new BigInteger[2]; res[0] = r; res[1] = s; return(res); }
//функция вычисления квадратоного корня по модулю простого числа q public BigInteger ModSqrt(BigInteger a, BigInteger q) { BigInteger b = new BigInteger(); do { b.genRandomBits(255, new Random()); } while (Legendre(b, q) == 1); BigInteger s = 0; BigInteger t = q - 1; while ((t & 1) != 1) { s++; t = t >> 1; } BigInteger InvA = a.modInverse(q); BigInteger c = b.modPow(t, q); BigInteger r = a.modPow(((t + 1) / 2), q); BigInteger d = new BigInteger(); for (int i = 1; i < s; i++) { BigInteger temp = 2; temp = temp.modPow((s - i - 1), q); d = (r.modPow(2, q) * InvA).modPow(temp, q); if (d == (q - 1)) r = (r * c) % q; c = c.modPow(2, q); } return r; }
//функция вычисления квадратоного корня по модулю простого числа q public BigInteger ModSqrt(BigInteger a, BigInteger q) { BigInteger b = new BigInteger(); do { b.genRandomBits(255, new Random()); } while (Legendre(b, q) == 1); BigInteger s = 0; BigInteger t = q - 1; while ((t & 1) != 1) { s++; t = t >> 1; } BigInteger InvA = a.modInverse(q); BigInteger c = b.modPow(t, q); BigInteger r = a.modPow(((t + 1) / 2), q); BigInteger d = new BigInteger(); for (int i = 1; i < s; i++) { BigInteger temp = 2; temp = temp.modPow((s - i - 1), q); d = (r.modPow(2, q) * InvA).modPow(temp, q); if (d == (q - 1)) { r = (r * c) % q; } c = c.modPow(2, q); } return(r); }
public static byte[] CreateSignature(byte[] p_data, ElGamalKeyStruct p_key_struct) { BigInteger x_pminusone = p_key_struct.P - 1; BigInteger K; do { K = new BigInteger(); K.genRandomBits(p_key_struct.P.bitCount() - 1, new Random()); } while (K.gcd(x_pminusone) != 1); BigInteger A = p_key_struct.G.modPow(K, p_key_struct.P); BigInteger B = mod(mod(K.modInverse(x_pminusone) * (new BigInteger(p_data) - (p_key_struct.X * (A))), (x_pminusone)), (x_pminusone)); byte[] x_a_bytes = A.getBytes(); byte[] x_b_bytes = B.getBytes(); int x_result_size = (((p_key_struct.P.bitCount() + 7) / 8) * 2); byte[] x_result = new byte[x_result_size]; Array.Copy(x_a_bytes, 0, x_result, x_result_size / 2 - x_a_bytes.Length, x_a_bytes.Length); Array.Copy(x_b_bytes, 0, x_result, x_result_size - x_b_bytes.Length, x_b_bytes.Length); return(x_result); }
public void init(int keysize = 512) { Random rand = new Random(); m_e = m_pq.genCoPrime(keysize, rand); m_d = m_e.modInverse(m_pq); }
private BigInteger GenerateS(BigInteger r, byte[] data) { SHA1 sha1 = SHA1.Create(); BigInteger hash = new BigInteger(sha1.ComputeHash(data)); return(k.modInverse(q) * (hash + x * r) % q); }
internal RSAKeyPair(BigInteger modulus, BigInteger e, BigInteger d, BigInteger p, BigInteger q) { _publickey = new RSAPublicKey(e, modulus); _d = d; _p = p; _q = q; _u = p.modInverse(q); }
public long ReconstructData(SharedData[] shares) { BigInteger[] nominators = new BigInteger[numNecessaryParts]; for (int i = 0; i < numNecessaryParts; i++) { nominators[i] = 1; for (int j = 0; j < numNecessaryParts; j++) { if (i != j) { BigInteger inv = new BigInteger(shares[i].xi) - new BigInteger(shares[j].xi); inv = inv % modP; if (inv < 0) { while (inv <= 0) { inv += modP; } inv = inv.modInverse(modP); } else if (inv != 1) { inv = inv.modInverse(modP); } nominators[i] = (nominators[i] * (new BigInteger(shares[j].xi) * inv)) % modP; } } } for (int i = 0; i < numNecessaryParts; i++) { nominators[i] = (nominators[i] * new BigInteger(shares[i].yi)) % modP; } BigInteger nominator = new BigInteger(0); for (int i = 0; i < numNecessaryParts; i++) { nominator = (nominator + nominators[i]) % modP; } return(nominator.LongValue()); }
private BigInteger CalcolaD(BigInteger _e, BigInteger _b) { BigInteger _d = 0; _d = _e.modInverse(_b); return(_d); }
public long ReconstructData(SharedData[] shares) { BigInteger[] nominators = new BigInteger[numNecessaryParts]; for (int i = 0; i < numNecessaryParts; i++) { nominators[i] = 1; for (int j = 0; j < numNecessaryParts; j++) { if (i != j) { BigInteger inv = new BigInteger(shares[i].xi) - new BigInteger(shares[j].xi); inv = inv % modP; if (inv < 0) { while (inv <= 0) inv += modP; inv = inv.modInverse(modP); } else if (inv != 1) { inv = inv.modInverse(modP); } nominators[i] = (nominators[i] * (new BigInteger(shares[j].xi) * inv)) % modP; } } } for (int i = 0; i < numNecessaryParts; i++) { nominators[i] = (nominators[i] * new BigInteger(shares[i].yi)) % modP; } BigInteger nominator = new BigInteger(0); for (int i = 0; i < numNecessaryParts; i++) { nominator = (nominator + nominators[i]) % modP; } return nominator.LongValue(); }
private BigInteger genrecshare(BigInteger Ri, BigInteger x) { BigInteger inverseX = x.modInverse(q); BigInteger Si = new BigInteger(Ri.modPow(inverseX, p)); //to be reviewed //Console.WriteLine("\nSi: " + Si); return(Si); }
private BigInteger GenerateD(BigInteger e, BigInteger totient) { BigInteger d = e.modInverse(totient); if (d < 0) { d += totient; } return(d); }
public void GeneratePair(int B, BigInteger _E) { E = _E; int Qs = B >> 1; while (true) { while (true) { P = BigInteger.genPseudoPrime(B - Qs, 1, new Random()); if ((P - 1).gcd(E) == 1 && P.isProbablePrime(10)) { break; } } while (true) { Q = BigInteger.genPseudoPrime(Qs, 1, new Random()); if ((Q - 1).gcd(E) == 1 && P.isProbablePrime(10)) { break; } } if (P < Q) { BigInteger t = P; P = Q; Q = t; } BigInteger phi = (P - 1) * (Q - 1); if (phi.gcd(E) == 1) { N = P * Q; D = E.modInverse(phi); Dmp1 = D % (P - 1); Dmq1 = D % (Q - 1); Coeff = Q.modInverse(P); break; } } CanEncrypt = N != 0 && E != 0; CanDecrypt = CanEncrypt && D != 0; Console.WriteLine(N.ToString(16)); Console.WriteLine(D.ToString(16)); }
/** * Performs modulo inverse * */ private int modInverse(int num, int prime) { if (num == -1) { return(prime - 1); } BigInteger n = new BigInteger(num); BigInteger p = new BigInteger(prime); BigInteger result = n.modInverse(p); return(result.IntValue()); }
public byte[] Sign(byte[] data) { BigInteger r = _publickey._g.modPow(_x, _publickey._p) % _publickey._q; BigInteger s = (_x.modInverse(_publickey._q) * (new BigInteger(data) + _x * r)) % _publickey._q; byte[] result = new byte[data.Length * 2]; byte[] br = r.getBytes(); byte[] bs = s.getBytes(); Array.Copy(br, 0, result, data.Length - br.Length, br.Length); Array.Copy(bs, 0, result, data.Length * 2 - bs.Length, bs.Length); return(result); }
public static void GetE(string sp, string sdp) { sp = ConvertTool.RemoveSpace(sp); sdp = ConvertTool.RemoveSpace(sdp); BigInteger e, p, dp; p = new BigInteger(sp, 16); dp = new BigInteger(sdp, 16); e = dp.modInverse(p - 1); //e = temp % (p - 1); RSA_E = e.ToHexString(); }
public void TestModInverse() { var a = new BigInteger("470782681346529800216759025446747092045188631141622615445464429840250748896490263346676188477401449398784352124574498378830506322639352584202116605974693692194824763263949618703029846313252400361025245824301828641617858127932941468016666971398736792667282916657805322080902778987073711188483372360907612588995664533157503380846449774089269965646418521613225981431666593065726252482995754339317299670566915780168", 10); var b = a.modInverse(new BigInteger(1000000007)); Assert.AreEqual(736445995, b.LongValue()); b = a.modInverse(new BigInteger(1999)); Assert.AreEqual(1814, b.LongValue()); var isExceptionRaised = false; try { b = a.modInverse(new BigInteger(9999998)); } catch (ArithmeticException) { isExceptionRaised = true; } Assert.IsTrue(isExceptionRaised); }
//проверяем подпись // H - хэш-сумма // sing - подпись // Q - ключ проверки подписи public bool SingVer(byte[] H, string sing, ECPoint Q) { // Шаг 1: вычисляем целые числа r и s по полученной подписи string Rvector = sing.Substring(0, q.bitCount() / 4); string Svector = sing.Substring(q.bitCount() / 4, q.bitCount() / 4); BigInteger r = new BigInteger(Rvector, 16); BigInteger s = new BigInteger(Svector, 16); if ((r < 1) || (r > (q - 1)) || (s < 1) || (s > (q - 1))) { return(false); } // Шаг 3 BigInteger alpha = new BigInteger(H); BigInteger e = alpha % q; if (e == 0) { e = 1; } // Шаг 4 BigInteger v = e.modInverse(q); // Шаг 5 BigInteger z1 = (s * v) % q; BigInteger z2 = q + ((-(r * v)) % q); // восст. y по x this.Q = QDecompression(); // Шаг 6: найти C = z1 P + z2 Q ECPoint A = ECPoint.multiply(z1, this.Q); ECPoint B = ECPoint.multiply(z2, Q); ECPoint C = A + B; // R = xc (mod q) BigInteger R = C.x % q; //Шаг 7 if (R == r) { return(true); } else { return(false); } }
private void button1_Click(object sender, EventArgs e) { //Пример 2 из стандарта BigInteger p = new BigInteger("3623986102229003635907788753683874306021320925534678605086546150450856166624002482588482022271496854025090823603058735163734263822371964987228582907372403", 10); BigInteger x = new BigInteger("1928356944067022849399309401243137598997786635459507974357075491307766592685835441065557681003184874819658004903212332884252335830250729527632383493573274", 10); BigInteger y = new BigInteger("2288728693371972859970012155529478416353562327329506180314497425931102860301572814141997072271708807066593850650334152381857347798885864807605098724013854", 10); BigInteger a = new BigInteger(7); BigInteger b = new BigInteger("1518655069210828534508950034714043154928747527740206436194018823352809982443793732829756914785974674866041605397883677596626326413990136959047435811826396", 10); BigInteger k = new BigInteger("175516356025850499540628279921125280333451031747737791650208144243182057075034446102986750962508909227235866126872473516807810541747529710309879958632945", 10); ECPoint P1 = new ECPoint(); P1.a = a; P1.b = b; P1.FieldChar = p; P1.x = x; P1.y = y; ECPoint P3 = ECPoint.multiply(k, P1); BigInteger r = P3.x % p; /////// DS forming BigInteger q = new BigInteger("3623986102229003635907788753683874306021320925534678605086546150450856166623969164898305032863068499961404079437936585455865192212970734808812618120619743", 10); BigInteger d = new BigInteger("610081804136373098219538153239847583006845519069531562982388135354890606301782255383608393423372379057665527595116827307025046458837440766121180466875860", 10); BigInteger E = new BigInteger("2897963881682868575562827278553865049173745197871825199562947419041388950970536661109553499954248733088719748844538964641281654463513296973827706272045964", 10); BigInteger s = ((r * d) + (k * E)) % q; //////// DS verification BigInteger v = E.modInverse(q); BigInteger z = (s * v) % q; BigInteger z2 = q + ((-(r * v)) % q); BigInteger x1 = new BigInteger("909546853002536596556690768669830310006929272546556281596372965370312498563182320436892870052842808608262832456858223580713780290717986855863433431150561", 10); BigInteger y1 = new BigInteger(" 2921457203374425620632449734248415455640700823559488705164895837509539134297327397380287741428246088626609329139441895016863758984106326600572476822372076", 10); ECPoint Q = new ECPoint(); Q.a = a; Q.b = b; Q.x = x1; Q.y = y1; Q.FieldChar = p; ECPoint A = ECPoint.multiply(z, P1); ECPoint B = ECPoint.multiply(z2, Q); ECPoint C = A + B; BigInteger R = C.x % q; }
public void Verify(byte[] data, byte[] expecteddata) { byte[] first = new byte[data.Length / 2]; byte[] second = new byte[data.Length / 2]; Array.Copy(data, 0, first, 0, first.Length); Array.Copy(data, first.Length, second, 0, second.Length); BigInteger r = new BigInteger(first); BigInteger s = new BigInteger(second); BigInteger w = s.modInverse(_q); BigInteger u1 = (new BigInteger(expecteddata) * w) % _q; BigInteger u2 = (r * w) % _q; BigInteger v = ((_g.modPow(u1, _p) * _y.modPow(u2, _p)) % _p) % _q; if (v != r) { throw new VerifyException("Failed to verify"); } }
//сложение пары точек. public static EcPoint operator +(EcPoint p1, EcPoint p2) { var res = new EcPoint { A = p1.A, B = p1.B, FieldChar = p1.FieldChar }; BigInteger dx = p2.X - p1.X; BigInteger dy = p2.Y - p1.Y; if (dx < 0) { dx += p1.FieldChar; } if (dy < 0) { dy += p1.FieldChar; } BigInteger t = (dy * dx.modInverse(p1.FieldChar)) % p1.FieldChar; if (t < 0) { t += p1.FieldChar; } res.X = (t * t - p1.X - p2.X) % p1.FieldChar; res.Y = (t * (p1.X - res.X) - p1.Y) % p1.FieldChar; if (res.X < 0) { res.X += p1.FieldChar; } if (res.Y < 0) { res.Y += p1.FieldChar; } return(res); }
public bool Verify(byte[] data, BigInteger r, BigInteger s) { if (r <= 0 || r >= q) { return(false); } if (s <= 0 || s >= q) { return(false); } SHA1 sha1 = SHA1.Create(); BigInteger hash = new BigInteger(sha1.ComputeHash(data)); BigInteger w = s.modInverse(q); BigInteger u1 = (hash * w) % q; BigInteger u2 = (r * w) % q; BigInteger v = ((g.modPow(u1, p) * y.modPow(u2, p)) % p) % q; return(v == r); }
//сложение пары точек. public static CECPoint operator +(CECPoint p1, CECPoint p2) { CECPoint res = new CECPoint(); res.a = p1.a; res.b = p1.b; res.fieldChar = p1.fieldChar; BigInteger dx = p2.x - p1.x; BigInteger dy = p2.y - p1.y; if (dx < 0) { dx += p1.fieldChar; } if (dy < 0) { dy += p1.fieldChar; } BigInteger t = (dy * dx.modInverse(p1.fieldChar)) % p1.fieldChar; if (t < 0) { t += p1.fieldChar; } res.x = (t * t - p1.x - p2.x) % p1.fieldChar; res.y = (t * (p1.x - res.x) - p1.y) % p1.fieldChar; if (res.x < 0) { res.x += p1.fieldChar; } if (res.y < 0) { res.y += p1.fieldChar; } return(res); }
public rsa() { Random rn = new Random(); p = BigInteger.genPseudoPrime(520, 100, rn); q = BigInteger.genPseudoPrime(520, 100, rn); n = new BigInteger(p * q); BigInteger o = new BigInteger((p - 1) * (q - 1)); int eb = 0; do { //eb = rn.Next(2, o.bitCount()); //e = BigInteger.genPseudoPrime(eb, 100, rn); e = new BigInteger(65537); }while (e > o || e.gcd(o) != new BigInteger(1)); d = new BigInteger(e.modInverse(o)); }
public rsa() { Random rn = new Random(); p = BigInteger.genPseudoPrime(521, 100, rn); q = BigInteger.genPseudoPrime(521, 100, rn); n = new BigInteger(p * q); BigInteger o = new BigInteger((p - 1) * (q - 1)); int eb=0; do { //eb = rn.Next(2, o.bitCount()); //e = BigInteger.genPseudoPrime(eb, 100, rn); e = new BigInteger(65537); } while (e > o || e.gcd(o) != new BigInteger(1)); d = new BigInteger(e.modInverse(o)); }
//проверка цифровой подписи. public bool verifyDS(byte[] H, string sign, CECPoint Q) { string Rvector = sign.Substring(0, n.bitCount() / 4); string Svector = sign.Substring(n.bitCount() / 4, n.bitCount() / 4); BigInteger r = new BigInteger(Rvector, 16); BigInteger s = new BigInteger(Svector, 16); if ((r < 1) || (r > (n - 1)) || (s < 1) || (s > (n - 1))) { return(false); } BigInteger a = new BigInteger(H); BigInteger e = a % n; if (e == 0) { e = 1; } BigInteger v = e.modInverse(n); BigInteger z1 = (s * v) % n; BigInteger z2 = n + ((-(r * v)) % n); this.G = gDecompression(); CECPoint A = CECPoint.multiply(G, z1); CECPoint B = CECPoint.multiply(Q, z2); CECPoint C = A + B; BigInteger R = C.x % n; if (R == r) { return(true); } else { return(false); } }
private BigInteger genrecshare(BigInteger Ri, BigInteger x) { BigInteger inverseX = x.modInverse(q); BigInteger Si = new BigInteger(Ri.modPow(inverseX, p)); //to be reviewed //Console.WriteLine("\nSi: " + Si); return Si; }
private static BigInteger modInverse(BigInteger a, BigInteger mod) { return a.modInverse(mod); }
public void Verify(byte[] data, byte[] expecteddata) { byte[] first = new byte[data.Length/2]; byte[] second = new byte[data.Length/2]; Array.Copy(data, 0, first, 0, first.Length); Array.Copy(data, first.Length, second, 0, second.Length); BigInteger r = new BigInteger(first); BigInteger s = new BigInteger(second); BigInteger w = s.modInverse(_q); BigInteger u1 = (new BigInteger(expecteddata) * w) % _q; BigInteger u2 = (r * w) % _q; BigInteger v = ((_g.modPow(u1, _p) * _y.modPow(u2, _p)) % _p) % _q; //Debug.WriteLine(DebugUtil.DumpByteArray(v.GetBytes())); //Debug.WriteLine(DebugUtil.DumpByteArray(r.GetBytes())); if(v!=r) throw new VerifyException("Failed to verify"); }