/** * 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); }
/* * 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); }
public static IBigInteger ValidatePublicValue(IBigInteger N, IBigInteger val) { val = val.Mod(N); // Check that val % N != 0 if (val.Equals(BigInteger.Zero)) throw new CryptoException("Invalid public value: 0"); return val; }
public static IBigInteger ValidatePublicValue(IBigInteger N, IBigInteger val) { val = val.Mod(N); // Check that val % N != 0 if (val.Equals(BigInteger.Zero)) { throw new CryptoException("Invalid public value: 0"); } return(val); }
/* * Unblind the message blinded with the blind factor. */ private IBigInteger UnblindMessage( IBigInteger blindedMsg) { IBigInteger m = key.Modulus; IBigInteger msg = blindedMsg; IBigInteger blindFactorInverse = blindingFactor.ModInverse(m); msg = msg.Multiply(blindFactorInverse); msg = msg.Mod(m); return(msg); }
/** * Adds the contents of two encrypted blocks mod sigma * * @param block1 * the first encrypted block * @param block2 * the second encrypted block * @return encrypt((block1 + block2) mod sigma) * @throws InvalidCipherTextException */ public byte[] AddCryptedBlocks( byte[] block1, byte[] block2) { // check for correct blocksize if (forEncryption) { if ((block1.Length > GetOutputBlockSize()) || (block2.Length > GetOutputBlockSize())) { throw new InvalidCipherTextException( "BlockLength too large for simple addition.\n"); } } else { if ((block1.Length > GetInputBlockSize()) || (block2.Length > GetInputBlockSize())) { throw new InvalidCipherTextException( "BlockLength too large for simple addition.\n"); } } // calculate resulting block IBigInteger m1Crypt = new BigInteger(1, block1); IBigInteger m2Crypt = new BigInteger(1, block2); IBigInteger m1m2Crypt = m1Crypt.Multiply(m2Crypt); m1m2Crypt = m1m2Crypt.Mod(key.Modulus); #if !NETFX_CORE if (debug) { Console.WriteLine("c(m1) as BigInteger:....... " + m1Crypt); Console.WriteLine("c(m2) as BigInteger:....... " + m2Crypt); Console.WriteLine("c(m1)*c(m2)%n = c(m1+m2)%n: " + m1m2Crypt); } #endif //byte[] output = key.Modulus.ToByteArray(); //Array.Clear(output, 0, output.Length); byte[] output = new byte[key.Modulus.BitLength / 8 + 1]; byte[] m1m2CryptBytes = m1m2Crypt.ToByteArray(); Array.Copy(m1m2CryptBytes, 0, output, output.Length - m1m2CryptBytes.Length, m1m2CryptBytes.Length); return(output); }
public void TestMod() { // TODO Basic tests for (int rep = 0; rep < 100; ++rep) { int diff = _random.Next(25); IBigInteger a = new BigInteger(100 - diff, 0, _random); IBigInteger b = new BigInteger(100 + diff, 0, _random); IBigInteger c = new BigInteger(10 + diff, 0, _random); IBigInteger d = a.Multiply(b).Add(c); IBigInteger e = d.Mod(a); Assert.AreEqual(c, e); IBigInteger pow2 = one.ShiftLeft(_random.Next(128)); Assert.AreEqual(b.And(pow2.Subtract(one)), b.Mod(pow2)); } }
/** * 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)); }
/** * generate a signature for the given message using the key we were * initialised with. For conventional GOST3410 the message should be a GOST3411 * hash of the message of interest. * * @param message the message that will be verified later. */ public IBigInteger[] GenerateSignature( byte[] message) { 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; IBigInteger r = null; IBigInteger s = null; do // generate s { IBigInteger k = null; do // generate r { do { k = new BigInteger(n.BitLength, random); }while (k.SignValue == 0); ECPoint p = key.Parameters.G.Multiply(k); IBigInteger x = p.X.ToBigInteger(); r = x.Mod(n); }while (r.SignValue == 0); IBigInteger d = ((ECPrivateKeyParameters)key).D; s = (k.Multiply(e)).Add(d.Multiply(r)).Mod(n); }while (s.SignValue == 0); return(new IBigInteger[] { r, s }); }
/** * 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; }
/** * 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. } }