public SimpleBigDecimal AdjustScale(int newScale) { if (newScale < 0) { throw new ArgumentException("scale may not be negative"); } if (newScale == scale) { return(this); } return(new SimpleBigDecimal(bigInt.ShiftLeft(newScale - scale), newScale)); }
public void TestShiftLeft() { for (int i = 0; i < 100; ++i) { int shift = _random.Next(128); IBigInteger a = new BigInteger(128 + i, _random).Add(one); int bits = a.BitCount; // Make sure nBits is set IBigInteger negA = a.Negate(); bits = negA.BitCount; // Make sure nBits is set IBigInteger b = a.ShiftLeft(shift); IBigInteger c = negA.ShiftLeft(shift); Assert.AreEqual(a.BitCount, b.BitCount); Assert.AreEqual(negA.BitCount + shift, c.BitCount); Assert.AreEqual(a.BitLength + shift, b.BitLength); Assert.AreEqual(negA.BitLength + shift, c.BitLength); int j = 0; for (; j < shift; ++j) { Assert.IsFalse(b.TestBit(j)); } for (; j < b.BitLength; ++j) { Assert.AreEqual(a.TestBit(j - shift), b.TestBit(j)); } } }
public void TestClearBit() { Assert.AreEqual(zero, zero.ClearBit(0)); Assert.AreEqual(zero, one.ClearBit(0)); Assert.AreEqual(two, two.ClearBit(0)); Assert.AreEqual(zero, zero.ClearBit(1)); Assert.AreEqual(one, one.ClearBit(1)); Assert.AreEqual(zero, two.ClearBit(1)); // TODO Tests for clearing bits in negative numbers // TODO Tests for clearing 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.ClearBit(pos); bool test = m.ShiftRight(pos).Remainder(two).Equals(one); Assert.IsFalse(test); } } for (int i = 0; i < 100; ++i) { IBigInteger pow2 = one.ShiftLeft(i); IBigInteger minusPow2 = pow2.Negate(); Assert.AreEqual(zero, pow2.ClearBit(i)); Assert.AreEqual(minusPow2.ShiftLeft(1), minusPow2.ClearBit(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.AndNot(one.ShiftLeft(j)), bigI.ClearBit(j), data); Assert.AreEqual(negI.AndNot(one.ShiftLeft(j)), negI.ClearBit(j), data); } } }
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())); } }
public void TestFlipBit() { for (int i = 0; i < 10; ++i) { IBigInteger a = new BigInteger(128, 0, _random); IBigInteger b = a; for (int x = 0; x < 100; ++x) { // Note: Intentionally greater than initial size int pos = _random.Next(256); a = a.FlipBit(pos); b = b.TestBit(pos) ? b.ClearBit(pos) : b.SetBit(pos); } Assert.AreEqual(a, b); } for (int i = 0; i < 100; ++i) { IBigInteger pow2 = one.ShiftLeft(i); IBigInteger minusPow2 = pow2.Negate(); Assert.AreEqual(zero, pow2.FlipBit(i)); Assert.AreEqual(minusPow2.ShiftLeft(1), minusPow2.FlipBit(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.Xor(one.ShiftLeft(j)), bigI.FlipBit(j), data); Assert.AreEqual(negI.Xor(one.ShiftLeft(j)), negI.FlipBit(j), data); } } }
public SimpleBigDecimal Add(IBigInteger b) { return(new SimpleBigDecimal(bigInt.Add(b.ShiftLeft(scale)), scale)); }
/** * Returns a <code>SimpleBigDecimal</code> representing the same numerical * value as <code>value</code>. * @param value The value of the <code>SimpleBigDecimal</code> to be * created. * @param scale The scale of the <code>SimpleBigDecimal</code> to be * created. * @return The such created <code>SimpleBigDecimal</code>. */ public static SimpleBigDecimal GetInstance(IBigInteger val, int scale) { return(new SimpleBigDecimal(val.ShiftLeft(scale), scale)); }
/** * 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); }
/** * Returns a <code>SimpleBigDecimal</code> representing the same numerical * value as <code>value</code>. * @param value The value of the <code>SimpleBigDecimal</code> to be * created. * @param scale The scale of the <code>SimpleBigDecimal</code> to be * created. * @return The such created <code>SimpleBigDecimal</code>. */ public static SimpleBigDecimal GetInstance(IBigInteger val, int scale) { return new SimpleBigDecimal(val.ShiftLeft(scale), scale); }
public int CompareTo(IBigInteger val) { return bigInt.CompareTo(val.ShiftLeft(scale)); }
//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); }
//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 IBigInteger Multiply( IBigInteger val) { if (SignValue == 0 || val.SignValue == 0) return Zero; if (val.QuickPow2Check()) // val is power of two { IBigInteger result = this.ShiftLeft(val.Abs().BitLength - 1); return val.SignValue > 0 ? result : result.Negate(); } if (this.QuickPow2Check()) // this is power of two { IBigInteger result = val.ShiftLeft(this.Abs().BitLength - 1); return this.SignValue > 0 ? result : result.Negate(); } int resLength = (this.BitLength + val.BitLength)/BitsPerInt + 1; var res = new int[resLength]; if (val == this) { Square(res, this.Magnitude); } else { Multiply(res, this.Magnitude, val.Magnitude); } return new BigInteger(SignValue*val.SignValue, res, true); }
//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); } } }
public SimpleBigDecimal Add(IBigInteger b) { return new SimpleBigDecimal(bigInt.Add(b.ShiftLeft(scale)), scale); }
public SimpleBigDecimal Subtract(IBigInteger b) { return(new SimpleBigDecimal(bigInt.Subtract(b.ShiftLeft(scale)), scale)); }
public SimpleBigDecimal Subtract(IBigInteger b) { return new SimpleBigDecimal(bigInt.Subtract(b.ShiftLeft(scale)), scale); }
public int CompareTo(IBigInteger val) { return(bigInt.CompareTo(val.ShiftLeft(scale))); }
private static string MakeOidStringFromBytes(byte[] bytes) { var objId = new StringBuilder(); long value = 0; IBigInteger bigValue = null; var first = true; for (var i = 0; i != bytes.Length; i++) { int b = bytes[i]; if (value < 0x80000000000000L) { value = value * 128 + (b & 0x7f); if ((b & 0x80) == 0) // end of number reached { if (first) { switch ((int)value / 40) { case 0: objId.Append('0'); break; case 1: objId.Append('1'); value -= 40; break; default: objId.Append('2'); value -= 80; break; } first = false; } objId.Append('.'); objId.Append(value); value = 0; } } else { if (bigValue == null) { bigValue = BigInteger.ValueOf(value); } bigValue = bigValue.ShiftLeft(7); bigValue = bigValue.Or(BigInteger.ValueOf(b & 0x7f)); if ((b & 0x80) == 0) { objId.Append('.'); objId.Append(bigValue); bigValue = null; value = 0; } } } return(objId.ToString()); }
/** * 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. } }