/** * return true if the value r and s represent a GOST3410 signature for * the passed in message (for standard GOST3410 the message should be * a GOST3411 hash of the real message to be verified). */ public bool VerifySignature( byte[] message, IBigInteger r, IBigInteger s) { byte[] mRev = new byte[message.Length]; // conversion is little-endian for (int i = 0; i != mRev.Length; i++) { mRev[i] = message[mRev.Length - 1 - i]; } IBigInteger e = new BigInteger(1, mRev); IBigInteger n = key.Parameters.N; // r in the range [1,n-1] if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) { return(false); } // s in the range [1,n-1] if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0) { return(false); } IBigInteger v = e.ModInverse(n); IBigInteger z1 = s.Multiply(v).Mod(n); IBigInteger z2 = (n.Subtract(r)).Multiply(v).Mod(n); ECPoint G = key.Parameters.G; // P ECPoint Q = ((ECPublicKeyParameters)key).Q; ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2); IBigInteger R = point.X.ToBigInteger().Mod(n); return(R.Equals(r)); }
/** * Approximate division by <code>n</code>. For an integer * <code>k</code>, the value <code>λ = s k / n</code> is * computed to <code>c</code> bits of accuracy. * @param k The parameter <code>k</code>. * @param s The curve parameter <code>s<sub>0</sub></code> or * <code>s<sub>1</sub></code>. * @param vm The Lucas Sequence element <code>V<sub>m</sub></code>. * @param a The parameter <code>a</code> of the elliptic curve. * @param m The bit length of the finite field * <code><b>F</b><sub>m</sub></code>. * @param c The number of bits of accuracy, i.e. the scale of the returned * <code>SimpleBigDecimal</code>. * @return The value <code>λ = s k / n</code> computed to * <code>c</code> bits of accuracy. */ public static SimpleBigDecimal ApproximateDivisionByN(IBigInteger k, IBigInteger s, IBigInteger vm, sbyte a, int m, int c) { int _k = (m + 5) / 2 + c; IBigInteger ns = k.ShiftRight(m - _k - 2 + a); IBigInteger gs = s.Multiply(ns); IBigInteger hs = gs.ShiftRight(m); IBigInteger js = vm.Multiply(hs); IBigInteger gsPlusJs = gs.Add(js); IBigInteger ls = gsPlusJs.ShiftRight(_k - c); if (gsPlusJs.TestBit(_k - c - 1)) { // round up ls = ls.Add(BigInteger.One); } return(new SimpleBigDecimal(ls, c)); }
public void TestPow() { Assert.AreEqual(one, zero.Pow(0)); Assert.AreEqual(zero, zero.Pow(123)); Assert.AreEqual(one, one.Pow(0)); Assert.AreEqual(one, one.Pow(123)); IBigInteger n = new BigInteger("1234567890987654321"); IBigInteger result = one; for (int i = 0; i < 10; ++i) { try { val(i).Pow(-1); Assert.Fail("expected ArithmeticException"); } catch (ArithmeticException) {} Assert.AreEqual(result, n.Pow(i)); result = result.Multiply(n); } }
/** * return true if the value r and s represent a Gost3410 signature for * the passed in message for standard Gost3410 the message should be a * Gost3411 hash of the real message to be verified. */ public bool VerifySignature( byte[] message, IBigInteger r, IBigInteger s) { byte[] mRev = new byte[message.Length]; // conversion is little-endian for (int i = 0; i != mRev.Length; i++) { mRev[i] = message[mRev.Length - 1 - i]; } IBigInteger m = new BigInteger(1, mRev); Gost3410Parameters parameters = key.Parameters; if (r.SignValue < 0 || parameters.Q.CompareTo(r) <= 0) { return(false); } if (s.SignValue < 0 || parameters.Q.CompareTo(s) <= 0) { return(false); } IBigInteger v = m.ModPow(parameters.Q.Subtract(BigInteger.Two), parameters.Q); IBigInteger z1 = s.Multiply(v).Mod(parameters.Q); IBigInteger z2 = (parameters.Q.Subtract(r)).Multiply(v).Mod(parameters.Q); z1 = parameters.A.ModPow(z1, parameters.P); z2 = ((Gost3410PublicKeyParameters)key).Y.ModPow(z2, parameters.P); IBigInteger u = z1.Multiply(z2).Mod(parameters.P).Mod(parameters.Q); return(u.Equals(r)); }
/** * Approximate division by <code>n</code>. For an integer * <code>k</code>, the value <code>λ = s k / n</code> is * computed to <code>c</code> bits of accuracy. * @param k The parameter <code>k</code>. * @param s The curve parameter <code>s<sub>0</sub></code> or * <code>s<sub>1</sub></code>. * @param vm The Lucas Sequence element <code>V<sub>m</sub></code>. * @param a The parameter <code>a</code> of the elliptic curve. * @param m The bit length of the finite field * <code><b>F</b><sub>m</sub></code>. * @param c The number of bits of accuracy, i.e. the scale of the returned * <code>SimpleBigDecimal</code>. * @return The value <code>λ = s k / n</code> computed to * <code>c</code> bits of accuracy. */ public static SimpleBigDecimal ApproximateDivisionByN(IBigInteger k, IBigInteger s, IBigInteger vm, sbyte a, int m, int c) { int _k = (m + 5)/2 + c; IBigInteger ns = k.ShiftRight(m - _k - 2 + a); IBigInteger gs = s.Multiply(ns); IBigInteger hs = gs.ShiftRight(m); IBigInteger js = vm.Multiply(hs); IBigInteger gsPlusJs = gs.Add(js); IBigInteger ls = gsPlusJs.ShiftRight(_k - c); if (gsPlusJs.TestBit(_k-c-1)) { // round up ls = ls.Add(BigInteger.One); } return new SimpleBigDecimal(ls, c); }
public SimpleBigDecimal Multiply(SimpleBigDecimal b) { CheckScale(b); return(new SimpleBigDecimal(bigInt.Multiply(b.bigInt), scale + scale)); }
/* * Blind message with the blind factor. */ private IBigInteger BlindMessage( IBigInteger msg) { IBigInteger blindMsg = blindingFactor; blindMsg = msg.Multiply(blindMsg.ModPow(key.Exponent, key.Modulus)); blindMsg = blindMsg.Mod(key.Modulus); return blindMsg; }
//Procedure B' private void procedure_Bb(long x0, long c, IBigInteger[] pq) { //Verify and perform condition: 0<x<2^32; 0<c<2^32; c - odd. while (x0 < 0 || x0 > 4294967296L) { x0 = init_random.NextInt() * 2; } while ((c < 0 || c > 4294967296L) || (c / 2 == 0)) { c = init_random.NextInt() * 2 + 1; } IBigInteger [] qp = new BigInteger[2]; IBigInteger q = null, Q = null, p = null; IBigInteger C = BigInteger.ValueOf(c); IBigInteger constA32 = BigInteger.ValueOf(97781173); //step1 x0 = procedure_Aa(x0, c, qp, 256); q = qp[0]; //step2 x0 = procedure_Aa(x0, c, qp, 512); Q = qp[0]; IBigInteger[] y = new IBigInteger[33]; y[0] = BigInteger.ValueOf(x0); const int tp = 1024; IBigInteger qQ = q.Multiply(Q); step3: for (;;) { //step 3 for (int j = 0; j < 32; j++) { y[j + 1] = (y[j].Multiply(constA32).Add(C)).Mod(BigInteger.Two.Pow(32)); } //step 4 IBigInteger Y = BigInteger.Zero; for (int j = 0; j < 32; j++) { Y = Y.Add(y[j].ShiftLeft(32 * j)); } y[0] = y[32]; //step 5 //step 6 IBigInteger N = BigInteger.One.ShiftLeft(tp - 1).Divide(qQ).Add( Y.ShiftLeft(tp - 1).Divide(qQ.ShiftLeft(1024))); if (N.TestBit(0)) { N = N.Add(BigInteger.One); } //step 7 for (;;) { //step 11 IBigInteger qQN = qQ.Multiply(N); if (qQN.BitLength > tp) { goto step3; //step 9 } p = qQN.Add(BigInteger.One); //step10 if (BigInteger.Two.ModPow(qQN, p).CompareTo(BigInteger.One) == 0 && BigInteger.Two.ModPow(q.Multiply(N), p).CompareTo(BigInteger.One) != 0) { pq[0] = p; pq[1] = q; return; } N = N.Add(BigInteger.Two); } } }
//Procedure A private int procedure_A(int x0, int c, IBigInteger[] pq, int size) { //Verify and perform condition: 0<x<2^16; 0<c<2^16; c - odd. while (x0 < 0 || x0 > 65536) { x0 = init_random.NextInt() / 32768; } while ((c < 0 || c > 65536) || (c / 2 == 0)) { c = init_random.NextInt() / 32768 + 1; } IBigInteger C = BigInteger.ValueOf(c); IBigInteger constA16 = BigInteger.ValueOf(19381); //step1 IBigInteger[] y = new IBigInteger[1]; // begin length = 1 y[0] = BigInteger.ValueOf(x0); //step 2 int[] t = new int[1]; // t - orders; begin length = 1 t[0] = size; int s = 0; for (int i = 0; t[i] >= 17; i++) { // extension array t int[] tmp_t = new int[t.Length + 1]; /////////////// Array.Copy(t, 0, tmp_t, 0, t.Length); // extension t = new int[tmp_t.Length]; // array t Array.Copy(tmp_t, 0, t, 0, tmp_t.Length); /////////////// t[i + 1] = t[i] / 2; s = i + 1; } //step3 IBigInteger[] p = new IBigInteger[s + 1]; p[s] = new BigInteger("8003", 16); //set min prime number length 16 bit int m = s - 1; //step4 for (int i = 0; i < s; i++) { int rm = t[m] / 16; //step5 step6 : for (;;) { //step 6 IBigInteger[] tmp_y = new BigInteger[y.Length]; //////////////// Array.Copy(y, 0, tmp_y, 0, y.Length); // extension y = new BigInteger[rm + 1]; // array y Array.Copy(tmp_y, 0, y, 0, tmp_y.Length); //////////////// for (int j = 0; j < rm; j++) { y[j + 1] = (y[j].Multiply(constA16).Add(C)).Mod(BigInteger.Two.Pow(16)); } //step 7 IBigInteger Ym = BigInteger.Zero; for (int j = 0; j < rm; j++) { Ym = Ym.Add(y[j].ShiftLeft(16 * j)); } y[0] = y[rm]; //step 8 //step 9 IBigInteger N = BigInteger.One.ShiftLeft(t[m] - 1).Divide(p[m + 1]).Add( Ym.ShiftLeft(t[m] - 1).Divide(p[m + 1].ShiftLeft(16 * rm))); if (N.TestBit(0)) { N = N.Add(BigInteger.One); } //step 10 for (;;) { //step 11 IBigInteger NByLastP = N.Multiply(p[m + 1]); if (NByLastP.BitLength > t[m]) { goto step6; //step 12 } p[m] = NByLastP.Add(BigInteger.One); //step13 if (BigInteger.Two.ModPow(NByLastP, p[m]).CompareTo(BigInteger.One) == 0 && BigInteger.Two.ModPow(N, p[m]).CompareTo(BigInteger.One) != 0) { break; } N = N.Add(BigInteger.Two); } if (--m < 0) { pq[0] = p[0]; pq[1] = p[1]; return(y[0].IntValue); //return for procedure B step 2 } break; //step 14 } } return(y[0].IntValue); }
private static IBigInteger[] FastLucasSequence(IBigInteger p, IBigInteger P, IBigInteger Q, IBigInteger k) { // TODO Research and apply "common-multiplicand multiplication here" var n = k.BitLength; var s = k.GetLowestSetBit(); Debug.Assert(k.TestBit(s)); var uh = BigInteger.One; var vl = BigInteger.Two; var vh = P; var ql = BigInteger.One; var qh = BigInteger.One; for (var j = n - 1; j >= s + 1; --j) { ql = ql.Multiply(qh).Mod(p); if (k.TestBit(j)) { qh = ql.Multiply(Q).Mod(p); uh = uh.Multiply(vh).Mod(p); vl = vh.Multiply(vl).Subtract(P.Multiply(ql)).Mod(p); vh = vh.Multiply(vh).Subtract(qh.ShiftLeft(1)).Mod(p); } else { qh = ql; uh = uh.Multiply(vl).Subtract(ql).Mod(p); vh = vh.Multiply(vl).Subtract(P.Multiply(ql)).Mod(p); vl = vl.Multiply(vl).Subtract(ql.ShiftLeft(1)).Mod(p); } } ql = ql.Multiply(qh).Mod(p); qh = ql.Multiply(Q).Mod(p); uh = uh.Multiply(vl).Subtract(ql).Mod(p); vl = vh.Multiply(vl).Subtract(P.Multiply(ql)).Mod(p); ql = ql.Multiply(qh).Mod(p); for (var j = 1; j <= s; ++j) { uh = uh.Multiply(vl).Mod(p); vl = vl.Multiply(vl).Subtract(ql.ShiftLeft(1)).Mod(p); ql = ql.Multiply(ql).Mod(p); } return new[] { uh, vl }; }
/** * return true if the value r and s represent a Gost3410 signature for * the passed in message for standard Gost3410 the message should be a * Gost3411 hash of the real message to be verified. */ public bool VerifySignature( byte[] message, IBigInteger r, IBigInteger s) { byte[] mRev = new byte[message.Length]; // conversion is little-endian for (int i = 0; i != mRev.Length; i++) { mRev[i] = message[mRev.Length - 1 - i]; } IBigInteger m = new BigInteger(1, mRev); Gost3410Parameters parameters = key.Parameters; if (r.SignValue < 0 || parameters.Q.CompareTo(r) <= 0) { return false; } if (s.SignValue < 0 || parameters.Q.CompareTo(s) <= 0) { return false; } IBigInteger v = m.ModPow(parameters.Q.Subtract(BigInteger.Two), parameters.Q); IBigInteger z1 = s.Multiply(v).Mod(parameters.Q); IBigInteger z2 = (parameters.Q.Subtract(r)).Multiply(v).Mod(parameters.Q); z1 = parameters.A.ModPow(z1, parameters.P); z2 = ((Gost3410PublicKeyParameters)key).Y.ModPow(z2, parameters.P); IBigInteger u = z1.Multiply(z2).Mod(parameters.P).Mod(parameters.Q); return u.Equals(r); }
/* * (non-Javadoc) * * @see org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator#generateKeyPair() */ public IAsymmetricCipherKeyPair GenerateKeyPair() { int strength = param.Strength; ISecureRandom rand = param.Random; int certainty = param.Certainty; bool debug = param.IsDebug; #if !NETFX_CORE if (debug) { Console.WriteLine("Fetching first " + param.CountSmallPrimes + " primes."); } #endif IList smallPrimes = findFirstPrimes(param.CountSmallPrimes); smallPrimes = PermuteList(smallPrimes, rand); IBigInteger u = BigInteger.One; IBigInteger v = BigInteger.One; for (int i = 0; i < smallPrimes.Count / 2; i++) { u = u.Multiply((BigInteger)smallPrimes[i]); } for (int i = smallPrimes.Count / 2; i < smallPrimes.Count; i++) { v = v.Multiply((BigInteger)smallPrimes[i]); } IBigInteger sigma = u.Multiply(v); // n = (2 a u _p + 1 ) ( 2 b v _q + 1) // -> |n| = strength // |2| = 1 in bits // -> |a| * |b| = |n| - |u| - |v| - |_p| - |_q| - |2| -|2| // remainingStrength = strength - sigma.bitLength() - _p.bitLength() - // _q.bitLength() - 1 -1 int remainingStrength = strength - sigma.BitLength - 48; IBigInteger a = GeneratePrime(remainingStrength / 2 + 1, certainty, rand); IBigInteger b = GeneratePrime(remainingStrength / 2 + 1, certainty, rand); IBigInteger _p; IBigInteger _q; IBigInteger p; IBigInteger q; long tries = 0; #if !NETFX_CORE if (debug) { Console.WriteLine("generating p and q"); } #endif IBigInteger _2au = a.Multiply(u).ShiftLeft(1); IBigInteger _2bv = b.Multiply(v).ShiftLeft(1); for (; ;) { tries++; _p = GeneratePrime(24, certainty, rand); p = _p.Multiply(_2au).Add(BigInteger.One); if (!p.IsProbablePrime(certainty)) { continue; } for (; ;) { _q = GeneratePrime(24, certainty, rand); if (_p.Equals(_q)) { continue; } q = _q.Multiply(_2bv).Add(BigInteger.One); if (q.IsProbablePrime(certainty)) { break; } } if (!sigma.Gcd(_p.Multiply(_q)).Equals(BigInteger.One)) { #if !NETFX_CORE Console.WriteLine("sigma.gcd(_p.mult(_q)) != 1!\n _p: " + _p + "\n _q: " + _q); #endif continue; } if (p.Multiply(q).BitLength < strength) { #if !NETFX_CORE if (debug) { Console.WriteLine("key size too small. Should be " + strength + " but is actually " + p.Multiply(q).BitLength); } #endif continue; } break; } #if !NETFX_CORE if (debug) { Console.WriteLine("needed " + tries + " tries to generate p and q."); } #endif IBigInteger n = p.Multiply(q); IBigInteger phi_n = p.Subtract(BigInteger.One).Multiply(q.Subtract(BigInteger.One)); IBigInteger g; tries = 0; #if !NETFX_CORE if (debug) { Console.WriteLine("generating g"); } #endif for (; ;) { // TODO After the first loop, just regenerate one randomly-selected gPart each time? IList gParts = Platform.CreateArrayList(); for (int ind = 0; ind != smallPrimes.Count; ind++) { IBigInteger i = (BigInteger)smallPrimes[ind]; IBigInteger e = phi_n.Divide(i); for (; ;) { tries++; g = GeneratePrime(strength, certainty, rand); if (!g.ModPow(e, n).Equals(BigInteger.One)) { gParts.Add(g); break; } } } g = BigInteger.One; for (int i = 0; i < smallPrimes.Count; i++) { IBigInteger gPart = (BigInteger)gParts[i]; IBigInteger smallPrime = (BigInteger)smallPrimes[i]; g = g.Multiply(gPart.ModPow(sigma.Divide(smallPrime), n)).Mod(n); } // make sure that g is not divisible by p_i or q_i bool divisible = false; for (int i = 0; i < smallPrimes.Count; i++) { if (g.ModPow(phi_n.Divide((BigInteger)smallPrimes[i]), n).Equals(BigInteger.One)) { #if !NETFX_CORE if (debug) { Console.WriteLine("g has order phi(n)/" + smallPrimes[i] + "\n g: " + g); } #endif divisible = true; break; } } if (divisible) { continue; } // make sure that g has order > phi_n/4 //if (g.ModPow(phi_n.Divide(BigInteger.ValueOf(4)), n).Equals(BigInteger.One)) if (g.ModPow(phi_n.ShiftRight(2), n).Equals(BigInteger.One)) { #if !NETFX_CORE if (debug) { Console.WriteLine("g has order phi(n)/4\n g:" + g); } #endif continue; } if (g.ModPow(phi_n.Divide(_p), n).Equals(BigInteger.One)) { #if !NETFX_CORE if (debug) { Console.WriteLine("g has order phi(n)/p'\n g: " + g); } #endif continue; } if (g.ModPow(phi_n.Divide(_q), n).Equals(BigInteger.One)) { #if !NETFX_CORE if (debug) { Console.WriteLine("g has order phi(n)/q'\n g: " + g); } #endif continue; } if (g.ModPow(phi_n.Divide(a), n).Equals(BigInteger.One)) { #if !NETFX_CORE if (debug) { Console.WriteLine("g has order phi(n)/a\n g: " + g); } #endif continue; } if (g.ModPow(phi_n.Divide(b), n).Equals(BigInteger.One)) { #if !NETFX_CORE if (debug) { Console.WriteLine("g has order phi(n)/b\n g: " + g); } #endif continue; } break; } #if !NETFX_CORE if (debug) { Console.WriteLine("needed " + tries + " tries to generate g"); Console.WriteLine(); Console.WriteLine("found new NaccacheStern cipher variables:"); Console.WriteLine("smallPrimes: " + CollectionUtilities.ToString(smallPrimes)); Console.WriteLine("sigma:...... " + sigma + " (" + sigma.BitLength + " bits)"); Console.WriteLine("a:.......... " + a); Console.WriteLine("b:.......... " + b); Console.WriteLine("p':......... " + _p); Console.WriteLine("q':......... " + _q); Console.WriteLine("p:.......... " + p); Console.WriteLine("q:.......... " + q); Console.WriteLine("n:.......... " + n); Console.WriteLine("phi(n):..... " + phi_n); Console.WriteLine("g:.......... " + g); Console.WriteLine(); } #endif return(new AsymmetricCipherKeyPair(new NaccacheSternKeyParameters(false, g, n, sigma.BitLength), new NaccacheSternPrivateKeyParameters(g, n, sigma.BitLength, smallPrimes, phi_n))); }
/** * Computes the <code>[τ]</code>-adic window NAF of an element * <code>λ</code> of <code><b>Z</b>[τ]</code>. * @param mu The parameter μ of the elliptic curve. * @param lambda The element <code>λ</code> of * <code><b>Z</b>[τ]</code> of which to compute the * <code>[τ]</code>-adic NAF. * @param width The window width of the resulting WNAF. * @param pow2w 2<sup>width</sup>. * @param tw The auxiliary value <code>t<sub>w</sub></code>. * @param alpha The <code>α<sub>u</sub></code>'s for the window width. * @return The <code>[τ]</code>-adic window NAF of * <code>λ</code>. */ public static sbyte[] TauAdicWNaf(sbyte mu, ZTauElement lambda, sbyte width, IBigInteger pow2w, IBigInteger tw, ZTauElement[] alpha) { if (!((mu == 1) || (mu == -1))) { throw new ArgumentException("mu must be 1 or -1"); } IBigInteger norm = Norm(mu, lambda); // Ceiling of log2 of the norm int log2Norm = norm.BitLength; // If length(TNAF) > 30, then length(TNAF) < log2Norm + 3.52 int maxLength = log2Norm > 30 ? log2Norm + 4 + width : 34 + width; // The array holding the TNAF sbyte[] u = new sbyte[maxLength]; // 2^(width - 1) IBigInteger pow2wMin1 = pow2w.ShiftRight(1); // Split lambda into two BigIntegers to simplify calculations IBigInteger r0 = lambda.u; IBigInteger r1 = lambda.v; int i = 0; // while lambda <> (0, 0) while (!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero)))) { // if r0 is odd if (r0.TestBit(0)) { // uUnMod = r0 + r1*tw Mod 2^width IBigInteger uUnMod = r0.Add(r1.Multiply(tw)).Mod(pow2w); sbyte uLocal; // if uUnMod >= 2^(width - 1) if (uUnMod.CompareTo(pow2wMin1) >= 0) { uLocal = (sbyte)uUnMod.Subtract(pow2w).IntValue; } else { uLocal = (sbyte)uUnMod.IntValue; } // uLocal is now in [-2^(width-1), 2^(width-1)-1] u[i] = uLocal; bool s = true; if (uLocal < 0) { s = false; uLocal = (sbyte)-uLocal; } // uLocal is now >= 0 if (s) { r0 = r0.Subtract(alpha[uLocal].u); r1 = r1.Subtract(alpha[uLocal].v); } else { r0 = r0.Add(alpha[uLocal].u); r1 = r1.Add(alpha[uLocal].v); } } else { u[i] = 0; } IBigInteger t = r0; if (mu == 1) { r0 = r1.Add(r0.ShiftRight(1)); } else { // mu == -1 r0 = r1.Subtract(r0.ShiftRight(1)); } r1 = t.ShiftRight(1).Negate(); i++; } return(u); }
/** * 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, IBigInteger r, IBigInteger s) { var parameters = _key.Parameters; var q = parameters.Q; var m = CalculateE(q, message); if (r.SignValue <= 0 || q.CompareTo(r) <= 0) { return false; } if (s.SignValue <= 0 || q.CompareTo(s) <= 0) { return false; } var w = s.ModInverse(q); var u1 = m.Multiply(w).Mod(q); var u2 = r.Multiply(w).Mod(q); var p = parameters.P; u1 = parameters.G.ModPow(u1, p); u2 = ((DsaPublicKeyParameters)_key).Y.ModPow(u2, p); var v = u1.Multiply(u2).Mod(p).Mod(q); return v.Equals(r); }
//Procedure B private void procedure_B(int x0, int c, IBigInteger[] pq) { //Verify and perform condition: 0<x<2^16; 0<c<2^16; c - odd. while (x0 < 0 || x0 > 65536) { x0 = init_random.NextInt() / 32768; } while ((c < 0 || c > 65536) || (c / 2 == 0)) { c = init_random.NextInt() / 32768 + 1; } IBigInteger [] qp = new BigInteger[2]; IBigInteger q = null, Q = null, p = null; IBigInteger C = BigInteger.ValueOf(c); IBigInteger constA16 = BigInteger.ValueOf(19381); //step1 x0 = procedure_A(x0, c, qp, 256); q = qp[0]; //step2 x0 = procedure_A(x0, c, qp, 512); Q = qp[0]; IBigInteger[] y = new IBigInteger[65]; y[0] = BigInteger.ValueOf(x0); const int tp = 1024; IBigInteger qQ = q.Multiply(Q); step3: for (;;) { //step 3 for (int j = 0; j < 64; j++) { y[j + 1] = (y[j].Multiply(constA16).Add(C)).Mod(BigInteger.Two.Pow(16)); } //step 4 IBigInteger Y = BigInteger.Zero; for (int j = 0; j < 64; j++) { Y = Y.Add(y[j].ShiftLeft(16 * j)); } y[0] = y[64]; //step 5 //step 6 IBigInteger N = BigInteger.One.ShiftLeft(tp - 1).Divide(qQ).Add( Y.ShiftLeft(tp - 1).Divide(qQ.ShiftLeft(1024))); if (N.TestBit(0)) { N = N.Add(BigInteger.One); } //step 7 for (;;) { //step 11 IBigInteger qQN = qQ.Multiply(N); if (qQN.BitLength > tp) { goto step3; //step 9 } p = qQN.Add(BigInteger.One); //step10 if (BigInteger.Two.ModPow(qQN, p).CompareTo(BigInteger.One) == 0 && BigInteger.Two.ModPow(q.Multiply(N), p).CompareTo(BigInteger.One) != 0) { pq[0] = p; pq[1] = q; return; } N = N.Add(BigInteger.Two); } } }
// 5.4 pg 29 /** * 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, IBigInteger r, IBigInteger s) { var n = _key.Parameters.N; // r and s should both in the range [1,n-1] if (r.SignValue < 1 || s.SignValue < 1 || r.CompareTo(n) >= 0 || s.CompareTo(n) >= 0) { return false; } var e = CalculateE(n, message); var c = s.ModInverse(n); var u1 = e.Multiply(c).Mod(n); var u2 = r.Multiply(c).Mod(n); var g = _key.Parameters.G; var q = ((ECPublicKeyParameters)_key).Q; var point = ECAlgorithms.SumOfTwoMultiplies(g, u1, q, u2); var v = point.X.ToBigInteger().Mod(n); return v.Equals(r); }
/** * return true if the value r and s represent a GOST3410 signature for * the passed in message (for standard GOST3410 the message should be * a GOST3411 hash of the real message to be verified). */ public bool VerifySignature( byte[] message, IBigInteger r, IBigInteger s) { byte[] mRev = new byte[message.Length]; // conversion is little-endian for (int i = 0; i != mRev.Length; i++) { mRev[i] = message[mRev.Length - 1 - i]; } IBigInteger e = new BigInteger(1, mRev); IBigInteger n = key.Parameters.N; // r in the range [1,n-1] if (r.CompareTo(BigInteger.One) < 0 || r.CompareTo(n) >= 0) { return false; } // s in the range [1,n-1] if (s.CompareTo(BigInteger.One) < 0 || s.CompareTo(n) >= 0) { return false; } IBigInteger v = e.ModInverse(n); IBigInteger z1 = s.Multiply(v).Mod(n); IBigInteger z2 = (n.Subtract(r)).Multiply(v).Mod(n); ECPoint G = key.Parameters.G; // P ECPoint Q = ((ECPublicKeyParameters)key).Q; ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, z1, Q, z2); IBigInteger R = point.X.ToBigInteger().Mod(n); return R.Equals(r); }