/** * Computes the norm of an element <code>λ</code> of * <code><b>Z</b>[τ]</code>. * @param mu The parameter <code>μ</code> of the elliptic curve. * @param lambda The element <code>λ</code> of * <code><b>Z</b>[τ]</code>. * @return The norm of <code>λ</code>. */ public static IBigInteger Norm(sbyte mu, ZTauElement lambda) { IBigInteger norm; // s1 = u^2 IBigInteger s1 = lambda.u.Multiply(lambda.u); // s2 = u * v IBigInteger s2 = lambda.u.Multiply(lambda.v); // s3 = 2 * v^2 IBigInteger s3 = lambda.v.Multiply(lambda.v).ShiftLeft(1); if (mu == 1) { norm = s1.Add(s2).Add(s3); } else if (mu == -1) { norm = s1.Subtract(s2).Add(s3); } else { throw new ArgumentException("mu must be 1 or -1"); } return(norm); }
private static IBigInteger allocateSerialNumber() { IBigInteger _tmp = serialNumber; serialNumber = serialNumber.Add(BigInteger.One); return(_tmp); }
/** * Initializes this algorithm. Must be called before all other Functions. * * @see org.bouncycastle.crypto.AsymmetricBlockCipher#init(bool, * org.bouncycastle.crypto.CipherParameters) */ public void Init( bool forEncryption, ICipherParameters parameters) { this.forEncryption = forEncryption; if (parameters is ParametersWithRandom) { parameters = ((ParametersWithRandom)parameters).Parameters; } key = (NaccacheSternKeyParameters)parameters; // construct lookup table for faster decryption if necessary if (!this.forEncryption) { #if !NETFX_CORE if (debug) { Console.WriteLine("Constructing lookup Array"); } #endif NaccacheSternPrivateKeyParameters priv = (NaccacheSternPrivateKeyParameters)key; IList primes = priv.SmallPrimesList; lookup = new IList[primes.Count]; for (int i = 0; i < primes.Count; i++) { IBigInteger actualPrime = (BigInteger)primes[i]; int actualPrimeValue = actualPrime.IntValue; lookup[i] = Platform.CreateArrayList(actualPrimeValue); lookup[i].Add(BigInteger.One); #if !NETFX_CORE if (debug) { Console.WriteLine("Constructing lookup ArrayList for " + actualPrimeValue); } #endif IBigInteger accJ = BigInteger.Zero; for (int j = 1; j < actualPrimeValue; j++) { // IBigInteger bigJ = BigInteger.ValueOf(j); // accJ = priv.PhiN.Multiply(bigJ); accJ = accJ.Add(priv.PhiN); IBigInteger comp = accJ.Divide(actualPrime); lookup[i].Add(priv.G.ModPow(comp, priv.Modulus)); } } } }
// Section 7.2.5 ECSP-NR, pg 34 /** * generate a signature for the given message using the key we were * initialised with. Generally, the order of the curve should be at * least as long as the hash of the message of interest, and with * ECNR it *must* be at least as long. * * @param digest the digest to be signed. * @exception DataLengthException if the digest is longer than the key allows */ public IBigInteger[] GenerateSignature( byte[] message) { if (!this._forSigning) { // not properly initilaized... deal with it throw new InvalidOperationException("not initialised for signing"); } IBigInteger n = ((ECPrivateKeyParameters)this._key).Parameters.N; int nBitLength = n.BitLength; IBigInteger e = new BigInteger(1, message); int eBitLength = e.BitLength; ECPrivateKeyParameters privKey = (ECPrivateKeyParameters)_key; if (eBitLength > nBitLength) { throw new DataLengthException("input too large for ECNR key."); } IBigInteger r = null; IBigInteger s = null; IAsymmetricCipherKeyPair tempPair; do // generate r { // generate another, but very temporary, key pair using // the same EC parameters ECKeyPairGenerator keyGen = new ECKeyPairGenerator(); keyGen.Init(new ECKeyGenerationParameters(privKey.Parameters, _random)); tempPair = keyGen.GenerateKeyPair(); // IBigInteger Vx = tempPair.getPublic().getW().getAffineX(); ECPublicKeyParameters V = (ECPublicKeyParameters)tempPair.Public; // get temp's public key IBigInteger Vx = V.Q.X.ToBigInteger(); // get the point's x coordinate r = Vx.Add(e).Mod(n); }while (r.SignValue == 0); // generate s IBigInteger x = privKey.D; // private key value IBigInteger u = ((ECPrivateKeyParameters)tempPair.Private).D; // temp's private key value s = u.Subtract(r.Multiply(x)).Mod(n); return(new IBigInteger[] { r, s }); }
public void TestNextProbablePrime() { IBigInteger firstPrime = BigInteger.ProbablePrime(32, _random); IBigInteger nextPrime = firstPrime.NextProbablePrime(); Assert.IsTrue(firstPrime.IsProbablePrime(10)); Assert.IsTrue(nextPrime.IsProbablePrime(10)); IBigInteger check = firstPrime.Add(one); while (check.CompareTo(nextPrime) < 0) { Assert.IsFalse(check.IsProbablePrime(10)); check = check.Add(one); } }
public override string ToString() { if (scale == 0) { return(bigInt.ToString()); } IBigInteger floorBigInt = Floor(); IBigInteger fract = bigInt.Subtract(floorBigInt.ShiftLeft(scale)); if (bigInt.SignValue < 0) { fract = BigInteger.One.ShiftLeft(scale).Subtract(fract); } if ((floorBigInt.SignValue == -1) && (!(fract.Equals(BigInteger.Zero)))) { floorBigInt = floorBigInt.Add(BigInteger.One); } string leftOfPoint = floorBigInt.ToString(); char[] fractCharArr = new char[scale]; string fractStr = fract.ToString(2); int fractLen = fractStr.Length; int zeroes = scale - fractLen; for (int i = 0; i < zeroes; i++) { fractCharArr[i] = '0'; } for (int j = 0; j < fractLen; j++) { fractCharArr[zeroes + j] = fractStr[j]; } string rightOfPoint = new string(fractCharArr); StringBuilder sb = new StringBuilder(leftOfPoint); sb.Append("."); sb.Append(rightOfPoint); return(sb.ToString()); }
public void TestMultiply() { IBigInteger one = BigInteger.One; Assert.AreEqual(one, one.Negate().Multiply(one.Negate())); for (int i = 0; i < 100; ++i) { int aLen = 64 + _random.Next(64); int bLen = 64 + _random.Next(64); IBigInteger a = new BigInteger(aLen, _random).SetBit(aLen); IBigInteger b = new BigInteger(bLen, _random).SetBit(bLen); IBigInteger c = new BigInteger(32, _random); IBigInteger ab = a.Multiply(b); IBigInteger bc = b.Multiply(c); Assert.AreEqual(ab.Add(bc), a.Add(c).Multiply(b)); Assert.AreEqual(ab.Subtract(bc), a.Subtract(c).Multiply(b)); } // Special tests for power of two since uses different code path internally for (int i = 0; i < 100; ++i) { int shift = _random.Next(64); IBigInteger a = one.ShiftLeft(shift); IBigInteger b = new BigInteger(64 + _random.Next(64), _random); IBigInteger bShift = b.ShiftLeft(shift); Assert.AreEqual(bShift, a.Multiply(b)); Assert.AreEqual(bShift.Negate(), a.Multiply(b.Negate())); Assert.AreEqual(bShift.Negate(), a.Negate().Multiply(b)); Assert.AreEqual(bShift, a.Negate().Multiply(b.Negate())); Assert.AreEqual(bShift, b.Multiply(a)); Assert.AreEqual(bShift.Negate(), b.Multiply(a.Negate())); Assert.AreEqual(bShift.Negate(), b.Negate().Multiply(a)); Assert.AreEqual(bShift, b.Negate().Multiply(a.Negate())); } }
/** * Computes the integer x that is expressed through the given primes and the * congruences with the chinese remainder theorem (CRT). * * @param congruences * the congruences c_i * @param primes * the primes p_i * @return an integer x for that x % p_i == c_i */ private static IBigInteger chineseRemainder(IList congruences, IList primes) { IBigInteger retval = BigInteger.Zero; IBigInteger all = BigInteger.One; for (int i = 0; i < primes.Count; i++) { all = all.Multiply((BigInteger)primes[i]); } for (int i = 0; i < primes.Count; i++) { IBigInteger a = (BigInteger)primes[i]; IBigInteger b = all.Divide(a); IBigInteger b2 = b.ModInverse(a); IBigInteger tmp = b.Multiply(b2); tmp = tmp.Multiply((BigInteger)congruences[i]); retval = retval.Add(tmp); } return(retval.Mod(all)); }
/** * 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)); }
//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); } } }
public SimpleBigDecimal Add(SimpleBigDecimal b) { CheckScale(b); return(new SimpleBigDecimal(bigInt.Add(b.bigInt), scale)); }
public IBigInteger And( IBigInteger value) { if (this.SignValue == 0 || value.SignValue == 0) { return Zero; } int[] aMag = this.SignValue > 0 ? this.Magnitude : Add(One).Magnitude; int[] bMag = value.SignValue > 0 ? value.Magnitude : value.Add(One).Magnitude; bool resultNeg = SignValue < 0 && value.SignValue < 0; int resultLength = System.Math.Max(aMag.Length, bMag.Length); var resultMag = new int[resultLength]; int aStart = resultMag.Length - aMag.Length; int bStart = resultMag.Length - bMag.Length; for (int i = 0; i < resultMag.Length; ++i) { int aWord = i >= aStart ? aMag[i - aStart] : 0; int bWord = i >= bStart ? bMag[i - bStart] : 0; if (this.SignValue < 0) { aWord = ~aWord; } if (value.SignValue < 0) { bWord = ~bWord; } resultMag[i] = aWord & bWord; if (resultNeg) { resultMag[i] = ~resultMag[i]; } } IBigInteger result = new BigInteger(1, resultMag, true); // TODO Optimise this case if (resultNeg) { result = result.Not(); } return result; }
/** * Computes the <code>τ</code>-adic NAF (non-adjacent form) of an * element <code>λ</code> of <code><b>Z</b>[τ]</code>. * @param mu The parameter <code>μ</code> of the elliptic curve. * @param lambda The element <code>λ</code> of * <code><b>Z</b>[τ]</code>. * @return The <code>τ</code>-adic NAF of <code>λ</code>. */ public static sbyte[] TauAdicNaf(sbyte mu, ZTauElement lambda) { 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 : 34; // The array holding the TNAF sbyte[] u = new sbyte[maxLength]; int i = 0; // The actual length of the TNAF int length = 0; IBigInteger r0 = lambda.u; IBigInteger r1 = lambda.v; while (!((r0.Equals(BigInteger.Zero)) && (r1.Equals(BigInteger.Zero)))) { // If r0 is odd if (r0.TestBit(0)) { u[i] = (sbyte)BigInteger.Two.Subtract((r0.Subtract(r1.ShiftLeft(1))).Mod(Four)).IntValue; // r0 = r0 - u[i] if (u[i] == 1) { r0 = r0.ClearBit(0); } else { // u[i] == -1 r0 = r0.Add(BigInteger.One); } length = i; } else { u[i] = 0; } IBigInteger t = r0; IBigInteger s = r0.ShiftRight(1); if (mu == 1) { r0 = r1.Add(s); } else { // mu == -1 r0 = r1.Subtract(s); } r1 = t.ShiftRight(1).Negate(); i++; } length++; // Reduce the TNAF array to its actual length sbyte[] tnaf = new sbyte[length]; Array.Copy(u, 0, tnaf, 0, length); return(tnaf); }
/** * Fetches delta CRLs according to RFC 3280 section 5.2.4. * * @param currentDate The date for which the delta CRLs must be valid. * @param paramsPKIX The extended PKIX parameters. * @param completeCRL The complete CRL the delta CRL is for. * @return A <code>Set</code> of <code>X509CRL</code>s with delta CRLs. * @throws Exception if an exception occurs while picking the delta * CRLs. */ internal static ISet GetDeltaCrls( DateTime currentDate, PkixParameters paramsPKIX, X509Crl completeCRL) { X509CrlStoreSelector deltaSelect = new X509CrlStoreSelector(); // 5.2.4 (a) try { IList deltaSelectIssuer = Platform.CreateArrayList(); deltaSelectIssuer.Add(completeCRL.IssuerDN); deltaSelect.Issuers = deltaSelectIssuer; } catch (IOException e) { new Exception("Cannot extract issuer from CRL.", e); } IBigInteger completeCRLNumber = null; try { Asn1Object asn1Object = GetExtensionValue(completeCRL, X509Extensions.CrlNumber); if (asn1Object != null) { completeCRLNumber = CrlNumber.GetInstance(asn1Object).PositiveValue; } } catch (Exception e) { throw new Exception( "CRL number extension could not be extracted from CRL.", e); } // 5.2.4 (b) byte[] idp = null; try { Asn1Object obj = GetExtensionValue(completeCRL, X509Extensions.IssuingDistributionPoint); if (obj != null) { idp = obj.GetDerEncoded(); } } catch (Exception e) { throw new Exception( "Issuing distribution point extension value could not be read.", e); } // 5.2.4 (d) deltaSelect.MinCrlNumber = (completeCRLNumber == null) ? null : completeCRLNumber.Add(BigInteger.One); deltaSelect.IssuingDistributionPoint = idp; deltaSelect.IssuingDistributionPointEnabled = true; // 5.2.4 (c) deltaSelect.MaxBaseCrlNumber = completeCRLNumber; // find delta CRLs ISet temp = CrlUtilities.FindCrls(deltaSelect, paramsPKIX, currentDate); ISet result = new HashSet(); foreach (X509Crl crl in temp) { if (isDeltaCrl(crl)) { result.Add(crl); } } return(result); }
//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); } } }
/** * Rounds an element <code>λ</code> of <code><b>R</b>[τ]</code> * to an element of <code><b>Z</b>[τ]</code>, such that their difference * has minimal norm. <code>λ</code> is given as * <code>λ = λ<sub>0</sub> + λ<sub>1</sub>τ</code>. * @param lambda0 The component <code>λ<sub>0</sub></code>. * @param lambda1 The component <code>λ<sub>1</sub></code>. * @param mu The parameter <code>μ</code> of the elliptic curve. Must * equal 1 or -1. * @return The rounded element of <code><b>Z</b>[τ]</code>. * @throws ArgumentException if <code>lambda0</code> and * <code>lambda1</code> do not have same scale. */ public static ZTauElement Round(SimpleBigDecimal lambda0, SimpleBigDecimal lambda1, sbyte mu) { int scale = lambda0.Scale; if (lambda1.Scale != scale) { throw new ArgumentException("lambda0 and lambda1 do not have same scale"); } if (!((mu == 1) || (mu == -1))) { throw new ArgumentException("mu must be 1 or -1"); } IBigInteger f0 = lambda0.Round(); IBigInteger f1 = lambda1.Round(); SimpleBigDecimal eta0 = lambda0.Subtract(f0); SimpleBigDecimal eta1 = lambda1.Subtract(f1); // eta = 2*eta0 + mu*eta1 SimpleBigDecimal eta = eta0.Add(eta0); if (mu == 1) { eta = eta.Add(eta1); } else { // mu == -1 eta = eta.Subtract(eta1); } // check1 = eta0 - 3*mu*eta1 // check2 = eta0 + 4*mu*eta1 SimpleBigDecimal threeEta1 = eta1.Add(eta1).Add(eta1); SimpleBigDecimal fourEta1 = threeEta1.Add(eta1); SimpleBigDecimal check1; SimpleBigDecimal check2; if (mu == 1) { check1 = eta0.Subtract(threeEta1); check2 = eta0.Add(fourEta1); } else { // mu == -1 check1 = eta0.Add(threeEta1); check2 = eta0.Subtract(fourEta1); } sbyte h0 = 0; sbyte h1 = 0; // if eta >= 1 if (eta.CompareTo(BigInteger.One) >= 0) { if (check1.CompareTo(MinusOne) < 0) { h1 = mu; } else { h0 = 1; } } else { // eta < 1 if (check2.CompareTo(BigInteger.Two) >= 0) { h1 = mu; } } // if eta < -1 if (eta.CompareTo(MinusOne) < 0) { if (check1.CompareTo(BigInteger.One) >= 0) { h1 = (sbyte)-mu; } else { h0 = -1; } } else { // eta >= -1 if (check2.CompareTo(MinusTwo) < 0) { h1 = (sbyte)-mu; } } IBigInteger q0 = f0.Add(BigInteger.ValueOf(h0)); IBigInteger q1 = f1.Add(BigInteger.ValueOf(h1)); return(new ZTauElement(q0, q1)); }
/** * 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); }
//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); }
/** * generate suitable parameters for DSA, in line with * <i>FIPS 186-3 A.1 Generation of the FFC Primes p and q</i>. */ private DsaParameters GenerateParameters_FIPS186_3() { // A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function // FIXME This should be configurable (digest size in bits must be >= N) IDigest d = new Sha256Digest(); int outlen = d.GetDigestSize() * 8; // 1. Check that the (L, N) pair is in the list of acceptable (L, N pairs) (see Section 4.2). If // the pair is not in the list, then return INVALID. // Note: checked at initialisation // 2. If (seedlen < N), then return INVALID. // FIXME This should be configurable (must be >= N) int seedlen = N; byte[] seed = new byte[seedlen / 8]; // 3. n = ceiling(L ⁄ outlen) – 1. int n = (L - 1) / outlen; // 4. b = L – 1 – (n ∗ outlen). int b = (L - 1) % outlen; byte[] output = new byte[d.GetDigestSize()]; for (;;) { // 5. Get an arbitrary sequence of seedlen bits as the domain_parameter_seed. random.NextBytes(seed); // 6. U = Hash (domain_parameter_seed) mod 2^(N–1). Hash(d, seed, output); IBigInteger U = new BigInteger(1, output).Mod(BigInteger.One.ShiftLeft(N - 1)); // 7. q = 2^(N–1) + U + 1 – ( U mod 2). IBigInteger q = BigInteger.One.ShiftLeft(N - 1).Add(U).Add(BigInteger.One).Subtract( U.Mod(BigInteger.Two)); // 8. Test whether or not q is prime as specified in Appendix C.3. // TODO Review C.3 for primality checking if (!q.IsProbablePrime(certainty)) { // 9. If q is not a prime, then go to step 5. continue; } // 10. offset = 1. // Note: 'offset' value managed incrementally byte[] offset = Arrays.Clone(seed); // 11. For counter = 0 to (4L – 1) do int counterLimit = 4 * L; for (int counter = 0; counter < counterLimit; ++counter) { // 11.1 For j = 0 to n do // Vj = Hash ((domain_parameter_seed + offset + j) mod 2^seedlen). // 11.2 W = V0 + (V1 ∗ 2^outlen) + ... + (V^(n–1) ∗ 2^((n–1) ∗ outlen)) + ((Vn mod 2^b) ∗ 2^(n ∗ outlen)). // TODO Assemble w as a byte array IBigInteger W = BigInteger.Zero; for (int j = 0, exp = 0; j <= n; ++j, exp += outlen) { Inc(offset); Hash(d, offset, output); IBigInteger Vj = new BigInteger(1, output); if (j == n) { Vj = Vj.Mod(BigInteger.One.ShiftLeft(b)); } W = W.Add(Vj.ShiftLeft(exp)); } // 11.3 X = W + 2^(L–1). Comment: 0 ≤ W < 2L–1; hence, 2L–1 ≤ X < 2L. IBigInteger X = W.Add(BigInteger.One.ShiftLeft(L - 1)); // 11.4 c = X mod 2q. IBigInteger c = X.Mod(q.ShiftLeft(1)); // 11.5 p = X - (c - 1). Comment: p ≡ 1 (mod 2q). IBigInteger p = X.Subtract(c.Subtract(BigInteger.One)); // 11.6 If (p < 2^(L - 1)), then go to step 11.9 if (p.BitLength != L) { continue; } // 11.7 Test whether or not p is prime as specified in Appendix C.3. // TODO Review C.3 for primality checking if (p.IsProbablePrime(certainty)) { // 11.8 If p is determined to be prime, then return VALID and the values of p, q and // (optionally) the values of domain_parameter_seed and counter. // TODO Make configurable (8-bit unsigned)? // int index = 1; // IBigInteger g = CalculateGenerator_FIPS186_3_Verifiable(d, p, q, seed, index); // if (g != null) // { // // TODO Should 'index' be a part of the validation parameters? // return new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter)); // } IBigInteger g = CalculateGenerator_FIPS186_3_Unverifiable(p, q, random); return(new DsaParameters(p, q, g, new DsaValidationParameters(seed, counter))); } // 11.9 offset = offset + n + 1. Comment: Increment offset; then, as part of // the loop in step 11, increment counter; if // counter < 4L, repeat steps 11.1 through 11.8. // Note: 'offset' value already incremented in inner loop } // 12. Go to step 5. } }