/** * Computes the Window NAF (non-adjacent Form) of an integer. * @param width The width <code>w</code> of the Window NAF. The width is * defined as the minimal number <code>w</code>, such that for any * <code>w</code> consecutive digits in the resulting representation, at * most one is non-zero. * @param k The integer of which the Window NAF is computed. * @return The Window NAF of the given width, such that the following holds: * <code>k = −<sub>i=0</sub><sup>l-1</sup> k<sub>i</sub>2<sup>i</sup> * </code>, where the <code>k<sub>i</sub></code> denote the elements of the * returned <code>sbyte[]</code>. */ public sbyte[] WindowNaf(sbyte width, IBigInteger k) { // The window NAF is at most 1 element longer than the binary // representation of the integer k. sbyte can be used instead of short or // int unless the window width is larger than 8. For larger width use // short or int. However, a width of more than 8 is not efficient for // m = log2(q) smaller than 2305 Bits. Note: Values for m larger than // 1000 Bits are currently not used in practice. sbyte[] wnaf = new sbyte[k.BitLength + 1]; // 2^width as short and BigInteger short pow2wB = (short)(1 << width); IBigInteger pow2wBI = BigInteger.ValueOf(pow2wB); int i = 0; // The actual length of the WNAF int length = 0; // while k >= 1 while (k.SignValue > 0) { // if k is odd if (k.TestBit(0)) { // k Mod 2^width IBigInteger remainder = k.Mod(pow2wBI); // if remainder > 2^(width - 1) - 1 if (remainder.TestBit(width - 1)) { wnaf[i] = (sbyte)(remainder.IntValue - pow2wB); } else { wnaf[i] = (sbyte)remainder.IntValue; } // wnaf[i] is now in [-2^(width-1), 2^(width-1)-1] k = k.Subtract(BigInteger.ValueOf(wnaf[i])); length = i; } else { wnaf[i] = 0; } // k = k/2 k = k.ShiftRight(1); i++; } length++; // Reduce the WNAF array to its actual length sbyte[] wnafShort = new sbyte[length]; Array.Copy(wnaf, 0, wnafShort, 0, length); return(wnafShort); }
public void TestSetBit() { Assert.AreEqual(one, zero.SetBit(0)); Assert.AreEqual(one, one.SetBit(0)); Assert.AreEqual(three, two.SetBit(0)); Assert.AreEqual(two, zero.SetBit(1)); Assert.AreEqual(three, one.SetBit(1)); Assert.AreEqual(two, two.SetBit(1)); // TODO Tests for setting bits in negative numbers // TODO Tests for setting extended bits for (int i = 0; i < 10; ++i) { IBigInteger n = new BigInteger(128, _random); for (int j = 0; j < 10; ++j) { int pos = _random.Next(128); IBigInteger m = n.SetBit(pos); bool test = m.ShiftRight(pos).Remainder(two).Equals(one); Assert.IsTrue(test); } } for (int i = 0; i < 100; ++i) { IBigInteger pow2 = one.ShiftLeft(i); IBigInteger minusPow2 = pow2.Negate(); Assert.AreEqual(pow2, pow2.SetBit(i)); Assert.AreEqual(minusPow2, minusPow2.SetBit(i)); IBigInteger bigI = BigInteger.ValueOf(i); IBigInteger negI = bigI.Negate(); for (int j = 0; j < 10; ++j) { string data = "i=" + i + ", j=" + j; Assert.AreEqual(bigI.Or(one.ShiftLeft(j)), bigI.SetBit(j), data); Assert.AreEqual(negI.Or(one.ShiftLeft(j)), negI.SetBit(j), data); } } }
/** * 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)); }
/// <summary> /// D.1.4 91 /// return a sqrt root - the routine verifies that the calculation /// returns the right value - if none exists it returns null. /// </summary> /// <returns></returns> public override ECFieldElement Sqrt() { if (!_q.TestBit(0)) { throw Platform.CreateNotImplementedException("even value of q"); } // p mod 4 == 3 if (_q.TestBit(1)) { // TODO Can this be optimised (inline the Square?) // z = g^(u+1) + p, p = 4u + 3 var z = new FPFieldElement(_q, _x.ModPow(_q.ShiftRight(2).Add(BigInteger.One), _q)); return(z.Square().Equals(this) ? z : null); } // p mod 4 == 1 var qMinusOne = _q.Subtract(BigInteger.One); var legendreExponent = qMinusOne.ShiftRight(1); if (!(_x.ModPow(legendreExponent, _q).Equals(BigInteger.One))) { return(null); } var u = qMinusOne.ShiftRight(2); var k = u.ShiftLeft(1).Add(BigInteger.One); var Q = _x; var fourQ = Q.ShiftLeft(2).Mod(_q); IBigInteger U; IBigInteger V; do { IRandom rand = new Random(); IBigInteger P; do { P = new BigInteger(_q.BitLength, rand); }while (P.CompareTo(_q) >= 0 || !(P.Multiply(P).Subtract(fourQ).ModPow(legendreExponent, _q).Equals(qMinusOne))); var result = FastLucasSequence(_q, P, Q, k); U = result[0]; V = result[1]; if (!V.Multiply(V).Mod(_q).Equals(fourQ)) { continue; } // Integer division by 2, mod q if (V.TestBit(0)) { V = V.Add(_q); } V = V.ShiftRight(1); Debug.Assert(V.Multiply(V).Mod(_q).Equals(_x)); return(new FPFieldElement(_q, V)); }while (U.Equals(BigInteger.One) || U.Equals(qMinusOne)); return(null); }
/** * 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; }
/** * 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); }
/** * Computes the Window NAF (non-adjacent Form) of an integer. * @param width The width <code>w</code> of the Window NAF. The width is * defined as the minimal number <code>w</code>, such that for any * <code>w</code> consecutive digits in the resulting representation, at * most one is non-zero. * @param k The integer of which the Window NAF is computed. * @return The Window NAF of the given width, such that the following holds: * <code>k = −<sub>i=0</sub><sup>l-1</sup> k<sub>i</sub>2<sup>i</sup> * </code>, where the <code>k<sub>i</sub></code> denote the elements of the * returned <code>sbyte[]</code>. */ public sbyte[] WindowNaf(sbyte width, IBigInteger k) { // The window NAF is at most 1 element longer than the binary // representation of the integer k. sbyte can be used instead of short or // int unless the window width is larger than 8. For larger width use // short or int. However, a width of more than 8 is not efficient for // m = log2(q) smaller than 2305 Bits. Note: Values for m larger than // 1000 Bits are currently not used in practice. sbyte[] wnaf = new sbyte[k.BitLength + 1]; // 2^width as short and BigInteger short pow2wB = (short)(1 << width); IBigInteger pow2wBI = BigInteger.ValueOf(pow2wB); int i = 0; // The actual length of the WNAF int length = 0; // while k >= 1 while (k.SignValue > 0) { // if k is odd if (k.TestBit(0)) { // k Mod 2^width IBigInteger remainder = k.Mod(pow2wBI); // if remainder > 2^(width - 1) - 1 if (remainder.TestBit(width - 1)) { wnaf[i] = (sbyte)(remainder.IntValue - pow2wB); } else { wnaf[i] = (sbyte)remainder.IntValue; } // wnaf[i] is now in [-2^(width-1), 2^(width-1)-1] k = k.Subtract(BigInteger.ValueOf(wnaf[i])); length = i; } else { wnaf[i] = 0; } // k = k/2 k = k.ShiftRight(1); i++; } length++; // Reduce the WNAF array to its actual length sbyte[] wnafShort = new sbyte[length]; Array.Copy(wnaf, 0, wnafShort, 0, length); return wnafShort; }
public IBigInteger Floor() { return(bigInt.ShiftRight(scale)); }
/* * (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); }
/** * 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); }