public AsymmetricCipherKeyPair GenerateKeyPair() { BigInteger p, q, n, d, e, pSub1, qSub1, phi; // // p and q values should have a length of half the strength in bits // int strength = param.Strength; int pbitlength = (strength + 1) / 2; int qbitlength = (strength - pbitlength); int mindiffbits = strength / 3; e = param.PublicExponent; // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes) // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm") // // Generate p, prime and (p-1) relatively prime to e // for (;;) { p = new BigInteger(pbitlength, 1, param.Random); if (p.Mod(e).Equals(BigInteger.One)) continue; if (!p.IsProbablePrime(param.Certainty)) continue; if (e.Gcd(p.Subtract(BigInteger.One)).Equals(BigInteger.One)) break; } // // Generate a modulus of the required length // for (;;) { // Generate q, prime and (q-1) relatively prime to e, // and not equal to p // for (;;) { q = new BigInteger(qbitlength, 1, param.Random); if (q.Subtract(p).Abs().BitLength < mindiffbits) continue; if (q.Mod(e).Equals(BigInteger.One)) continue; if (!q.IsProbablePrime(param.Certainty)) continue; if (e.Gcd(q.Subtract(BigInteger.One)).Equals(BigInteger.One)) break; } // // calculate the modulus // n = p.Multiply(q); if (n.BitLength == param.Strength) break; // // if we Get here our primes aren't big enough, make the largest // of the two p and try again // p = p.Max(q); } if (p.CompareTo(q) < 0) { phi = p; p = q; q = phi; } pSub1 = p.Subtract(BigInteger.One); qSub1 = q.Subtract(BigInteger.One); phi = pSub1.Multiply(qSub1); // // calculate the private exponent // d = e.ModInverse(phi); // // calculate the CRT factors // BigInteger dP, dQ, qInv; dP = d.Remainder(pSub1); dQ = d.Remainder(qSub1); qInv = q.ModInverse(p); return new AsymmetricCipherKeyPair( new RsaKeyParameters(false, n, e), new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv)); }
/** * 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 BigInteger[] 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]; } BigInteger m = new BigInteger(1, mRev); Gost3410Parameters parameters = key.Parameters; BigInteger k; do { k = new BigInteger(parameters.Q.BitLength, random); } while (k.CompareTo(parameters.Q) >= 0); BigInteger r = parameters.A.ModPow(k, parameters.P).Mod(parameters.Q); BigInteger s = k.Multiply(m). Add(((Gost3410PrivateKeyParameters)key).X.Multiply(r)). Mod(parameters.Q); return new BigInteger[]{ r, s }; }
public RSA(int bits) { p = Helper.GenerateBigIntegerPrimes(bits); //p = new Org.BouncyCastle.Math.BigInteger("3557"); q = Helper.GenerateBigIntegerPrimes(bits); //q = new Org.BouncyCastle.Math.BigInteger("2579"); Console.WriteLine("p generated " + p); Console.WriteLine("q generated " + q); n = p.Multiply(q); Console.WriteLine("n = " + n); BigInteger p1 = p.Subtract(new BigInteger("1")); BigInteger q1 = q.Subtract(new BigInteger("1")); fn = p1.Multiply(q1); Console.WriteLine("Функция Эйлера = " + fn); int[] er = new[] { 17, 257, 65537 }; Random rand = new Random((int)System.DateTime.Now.Ticks); e = new BigInteger(er[rand.Next(0, er.Length)].ToString()); Console.WriteLine("e = " + e); d = e.ModInverse(fn); Console.WriteLine("d = " + d); Console.WriteLine("Public Key: " + e + ", " + n); Console.WriteLine("Private Key: " + d + ", " + n); }
public void MonoBug81857() { BigInteger b = new BigInteger("18446744073709551616"); BigInteger exp = BigInteger.Two; BigInteger mod = new BigInteger("48112959837082048697"); BigInteger expected = new BigInteger("4970597831480284165"); BigInteger manual = b.Multiply(b).Mod(mod); Assert.AreEqual(expected, manual, "b * b % mod"); }
public MHKey() { generator gen = new generator(8); Org.BouncyCastle.Math.BigInteger w = gen.w; e = new List <Org.BouncyCastle.Math.BigInteger>(); for (int i = 0; i < gen.a.Count; i++) { e.Add((w.Multiply(gen.a.ElementAt(i))).Mod(gen.n)); // w*a Mod n .. } Org.BouncyCastle.Math.BigInteger w1 = Org.BouncyCastle.Math.BigInteger.ValueOf(1); Org.BouncyCastle.Math.BigInteger one = Org.BouncyCastle.Math.BigInteger.ValueOf(2); while (one.IntValue != 1) { w1 = w1.Add(Org.BouncyCastle.Math.BigInteger.ValueOf(1)).Mod(gen.n); one = w.Multiply(w1).Mod(gen.n); } privateKey = new MHPrivateKey(gen.a, w.ModInverse(gen.n), gen.n); }
public static ECPoint ECDSA_SIG_recover_key_GFp(BigInteger[] sig, byte[] hash, int recid, bool check) { X9ECParameters ecParams = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1"); int i = recid / 2; Console.WriteLine("r: "+ToHex(sig[0].ToByteArrayUnsigned())); Console.WriteLine("s: "+ToHex(sig[1].ToByteArrayUnsigned())); BigInteger order = ecParams.N; BigInteger field = (ecParams.Curve as FpCurve).Q; BigInteger x = order.Multiply(new BigInteger(i.ToString())).Add(sig[0]); if (x.CompareTo(field) >= 0) throw new Exception("X too large"); Console.WriteLine("Order: "+ToHex(order.ToByteArrayUnsigned())); Console.WriteLine("Field: "+ToHex(field.ToByteArrayUnsigned())); byte[] compressedPoint = new Byte[x.ToByteArrayUnsigned().Length+1]; compressedPoint[0] = (byte) (0x02+(recid%2)); Buffer.BlockCopy(x.ToByteArrayUnsigned(), 0, compressedPoint, 1, compressedPoint.Length-1); ECPoint R = ecParams.Curve.DecodePoint(compressedPoint); Console.WriteLine("R: "+ToHex(R.GetEncoded())); if (check) { ECPoint O = R.Multiply(order); if (!O.IsInfinity) throw new Exception("Check failed"); } int n = (ecParams.Curve as FpCurve).Q.ToByteArrayUnsigned().Length*8; BigInteger e = new BigInteger(1, hash); if (8*hash.Length > n) { e = e.ShiftRight(8-(n & 7)); } e = BigInteger.Zero.Subtract(e).Mod(order); BigInteger rr = sig[0].ModInverse(order); BigInteger sor = sig[1].Multiply(rr).Mod(order); BigInteger eor = e.Multiply(rr).Mod(order); ECPoint Q = ecParams.G.Multiply(eor).Add(R.Multiply(sor)); Console.WriteLine("n: "+n); Console.WriteLine("e: "+ToHex(e.ToByteArrayUnsigned())); Console.WriteLine("rr: "+ToHex(rr.ToByteArrayUnsigned())); Console.WriteLine("sor: "+ToHex(sor.ToByteArrayUnsigned())); Console.WriteLine("eor: "+ToHex(eor.ToByteArrayUnsigned())); Console.WriteLine("Q: "+ToHex(Q.GetEncoded())); return Q; }
/** * 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 string GetSign(byte[] msg) { //Org.BouncyCastle.Math.BigInteger d = new Org.BouncyCastle.Math.BigInteger(Convert.FromBase64String(privKey)); byte[] prvB = StringToByteArray(prv); byte[] pubB = StringToByteArray(pub); //byte[] prvB = StringToByteArray(prvTmp); //byte[] pubB = StringToByteArray(pubTmp); Org.BouncyCastle.Math.BigInteger sk = new Org.BouncyCastle.Math.BigInteger(+1, prvB); Org.BouncyCastle.Math.EC.ECPoint q = domain.G.Multiply(sk); byte[] pubKeyX = q.Normalize().AffineXCoord.GetEncoded(); byte[] pubKeyY = q.Normalize().AffineYCoord.GetEncoded(); BigInteger k = GenerateRandom(); //BigInteger k = new BigInteger(+1,StringToByteArray("015B931D9C7BF3A7A70E57868BF29712377E74355FC59032CD7547C80E179010")); //Debug.Log("kv:" + BitConverter.ToString(kv.ToByteArray()).Replace("-", "")); Debug.Log("K:" + BitConverter.ToString(k.ToByteArray()).Replace("-", "")); ECPoint Q = domain.G.Multiply(k); Org.BouncyCastle.Crypto.Digests.Sha256Digest digester = new Org.BouncyCastle.Crypto.Digests.Sha256Digest(); byte[] h = new byte[digester.GetDigestSize()]; digester.BlockUpdate(Q.GetEncoded(true), 0, Q.GetEncoded(true).Length); digester.BlockUpdate(pubB, 0, pubB.Length); digester.BlockUpdate(msg, 0, msg.Length); digester.DoFinal(h, 0); Org.BouncyCastle.Math.BigInteger r = new Org.BouncyCastle.Math.BigInteger(+1, h); BigInteger s = r.Multiply(sk); s = k.Subtract(s); s = s.Mod(domain.n); string rt = BitConverter.ToString(r.ToByteArray()).Replace("-", ""); if (rt.Length > 32) { rt = rt.Remove(0, 2); } string st = BitConverter.ToString(s.ToByteArray()).Replace("-", ""); return(rt + st); }
/** * 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 BigInteger[] 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]; } BigInteger e = new BigInteger(1, mRev); BigInteger n = key.Parameters.N; BigInteger r = null; BigInteger s = null; do // generate s { BigInteger k = null; do // generate r { do { k = new BigInteger(n.BitLength, random); } while (k.SignValue == 0); ECPoint p = key.Parameters.G.Multiply(k); BigInteger x = p.X.ToBigInteger(); r = x.Mod(n); } while (r.SignValue == 0); BigInteger d = ((ECPrivateKeyParameters)key).D; s = (k.Multiply(e)).Add(d.Multiply(r)).Mod(n); } while (s.SignValue == 0); return new BigInteger[]{ r, s }; }
/// <summary> /// Calculate a zero knowledge proof of x using Schnorr's signature. /// The returned array has two elements {g^v, r = v-x*h} for x. /// </summary> public static BigInteger[] CalculateZeroKnowledgeProof(BigInteger p, BigInteger q, BigInteger g, BigInteger gx, BigInteger x, string participantId, IDigest digest, SecureRandom random) { /* Generate a random v, and compute g^v */ BigInteger vMin = Zero; BigInteger vMax = q.Subtract(One); BigInteger v = BigIntegers.CreateRandomInRange(vMin, vMax, random); BigInteger gv = g.ModPow(v, p); BigInteger h = CalculateHashForZeroKnowledgeProof(g, gv, gx, participantId, digest); // h return new BigInteger[] { gv, v.Subtract(x.Multiply(h)).Mod(q) // r = v-x*h }; }
/** * Process a single block using the basic ElGamal algorithm. * * @param in the input array. * @param inOff the offset into the input buffer where the data starts. * @param length the length of the data to be processed. * @return the result of the ElGamal process. * @exception DataLengthException the input block is too large. */ public virtual byte[] ProcessBlock( byte[] input, int inOff, int length) { if (key == null) throw new InvalidOperationException("ElGamal engine not initialised"); int maxLength = forEncryption ? (bitSize - 1 + 7) / 8 : GetInputBlockSize(); if (length > maxLength) throw new DataLengthException("input too large for ElGamal cipher.\n"); BigInteger p = key.Parameters.P; byte[] output; if (key is ElGamalPrivateKeyParameters) // decryption { int halfLength = length / 2; BigInteger gamma = new BigInteger(1, input, inOff, halfLength); BigInteger phi = new BigInteger(1, input, inOff + halfLength, halfLength); ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters) key; // a shortcut, which generally relies on p being prime amongst other things. // if a problem with this shows up, check the p and g values! BigInteger m = gamma.ModPow(p.Subtract(BigInteger.One).Subtract(priv.X), p).Multiply(phi).Mod(p); output = m.ToByteArrayUnsigned(); } else // encryption { BigInteger tmp = new BigInteger(1, input, inOff, length); if (tmp.BitLength >= p.BitLength) throw new DataLengthException("input too large for ElGamal cipher.\n"); ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters) key; BigInteger pSub2 = p.Subtract(BigInteger.Two); // TODO In theory, a series of 'k', 'g.ModPow(k, p)' and 'y.ModPow(k, p)' can be pre-calculated BigInteger k; do { k = new BigInteger(p.BitLength, random); } while (k.SignValue == 0 || k.CompareTo(pSub2) > 0); BigInteger g = key.Parameters.G; BigInteger gamma = g.ModPow(k, p); BigInteger phi = tmp.Multiply(pub.Y.ModPow(k, p)).Mod(p); output = new byte[this.GetOutputBlockSize()]; // TODO Add methods to allow writing BigInteger to existing byte array? byte[] out1 = gamma.ToByteArrayUnsigned(); byte[] out2 = phi.ToByteArrayUnsigned(); out1.CopyTo(output, output.Length / 2 - out1.Length); out2.CopyTo(output, output.Length - out2.Length); } return output; }
//Following code from https://bitcointalk.org/index.php?topic=25141.0 public static byte[] Base58ToByteArray(string base58) { Org.BouncyCastle.Math.BigInteger bi2 = new Org.BouncyCastle.Math.BigInteger("0"); string b58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; bool IgnoreChecksum = false; foreach (char c in base58) { if (b58.IndexOf(c) != -1) { bi2 = bi2.Multiply(new Org.BouncyCastle.Math.BigInteger("58")); bi2 = bi2.Add(new Org.BouncyCastle.Math.BigInteger(b58.IndexOf(c).ToString())); } else if (c == '?') { IgnoreChecksum = true; } else { return(null); } } byte[] bb = bi2.ToByteArrayUnsigned(); // interpret leading '1's as leading zero bytes foreach (char c in base58) { if (c != '1') { break; } byte[] bbb = new byte[bb.Length + 1]; Array.Copy(bb, 0, bbb, 1, bb.Length); bb = bbb; } if (bb.Length < 4) { return(null); } if (IgnoreChecksum == false) { SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider(); byte[] checksum = sha256.ComputeHash(bb, 0, bb.Length - 4); checksum = sha256.ComputeHash(checksum); for (int i = 0; i < 4; i++) { if (checksum[i] != bb[bb.Length - 4 + i]) { return(null); } } } byte[] rv = new byte[bb.Length - 4]; Array.Copy(bb, 0, rv, 0, bb.Length - 4); return(rv); }
public void TestMod() { // TODO Basic tests for (int rep = 0; rep < 100; ++rep) { int diff = random.Next(25); BigInteger a = new BigInteger(100 - diff, 0, random); BigInteger b = new BigInteger(100 + diff, 0, random); BigInteger c = new BigInteger(10 + diff, 0, random); BigInteger d = a.Multiply(b).Add(c); BigInteger e = d.Mod(a); Assert.AreEqual(c, e); BigInteger pow2 = one.ShiftLeft(random.Next(128)); Assert.AreEqual(b.And(pow2.Subtract(one)), b.Mod(pow2)); } }
// 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 virtual bool VerifySignature(byte[] message, BigInteger r, BigInteger s) { BigInteger 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; } BigInteger e = CalculateE(n, message); BigInteger c = s.ModInverse(n); BigInteger u1 = e.Multiply(c).Mod(n); BigInteger u2 = r.Multiply(c).Mod(n); ECPoint G = key.Parameters.G; ECPoint Q = ((ECPublicKeyParameters) key).Q; ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2); if (point.IsInfinity) return false; /* * If possible, avoid normalizing the point (to save a modular inversion in the curve field). * * There are ~cofactor elements of the curve field that reduce (modulo the group order) to 'r'. * If the cofactor is known and small, we generate those possible field values and project each * of them to the same "denominator" (depending on the particular projective coordinates in use) * as the calculated point.X. If any of the projected values matches point.X, then we have: * (point.X / Denominator mod p) mod n == r * as required, and verification succeeds. * * Based on an original idea by Gregory Maxwell (https://github.com/gmaxwell), as implemented in * the libsecp256k1 project (https://github.com/bitcoin/secp256k1). */ ECCurve curve = point.Curve; if (curve != null) { BigInteger cofactor = curve.Cofactor; if (cofactor != null && cofactor.CompareTo(Eight) <= 0) { ECFieldElement D = GetDenominator(curve.CoordinateSystem, point); if (D != null && !D.IsZero) { ECFieldElement X = point.XCoord; while (curve.IsValidFieldElement(r)) { ECFieldElement R = curve.FromBigInteger(r).Multiply(D); if (R.Equals(X)) { return true; } r = r.Add(n); } return false; } } } BigInteger v = point.Normalize().AffineXCoord.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, BigInteger r, BigInteger 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]; } BigInteger 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; } BigInteger v = m.ModPow(parameters.Q.Subtract(BigInteger.Two), parameters.Q); BigInteger z1 = s.Multiply(v).Mod(parameters.Q); BigInteger 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); BigInteger u = z1.Multiply(z2).Mod(parameters.P).Mod(parameters.Q); return u.Equals(r); }
/* * Blind message with the blind factor. */ private BigInteger BlindMessage( BigInteger msg) { BigInteger blindMsg = blindingFactor; blindMsg = msg.Multiply(blindMsg.ModPow(key.Exponent, key.Modulus)); blindMsg = blindMsg.Mod(key.Modulus); return blindMsg; }
/** * 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 virtual 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 BigInteger m1Crypt = new BigInteger(1, block1); BigInteger m2Crypt = new BigInteger(1, block2); BigInteger m1m2Crypt = m1Crypt.Multiply(m2Crypt); m1m2Crypt = m1m2Crypt.Mod(key.Modulus); //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; }
/** * 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 virtual bool VerifySignature( byte[] message, BigInteger r, BigInteger 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]; } BigInteger e = new BigInteger(1, mRev); BigInteger 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; } BigInteger v = e.ModInverse(n); BigInteger z1 = s.Multiply(v).Mod(n); BigInteger 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).Normalize(); if (point.IsInfinity) return false; BigInteger R = point.AffineXCoord.ToBigInteger().Mod(n); return R.Equals(r); }
/** * 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 virtual BigInteger[] 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]; } BigInteger e = new BigInteger(1, mRev); ECDomainParameters ec = key.Parameters; BigInteger n = ec.N; BigInteger d = ((ECPrivateKeyParameters)key).D; BigInteger r, s = null; ECMultiplier basePointMultiplier = CreateBasePointMultiplier(); do // generate s { BigInteger k; do // generate r { do { k = new BigInteger(n.BitLength, random); } while (k.SignValue == 0); ECPoint p = basePointMultiplier.Multiply(ec.G, k).Normalize(); r = p.AffineXCoord.ToBigInteger().Mod(n); } while (r.SignValue == 0); s = (k.Multiply(e)).Add(d.Multiply(r)).Mod(n); } while (s.SignValue == 0); return new BigInteger[]{ r, s }; }
public void TestRemainder() { // TODO Basic tests for (int rep = 0; rep < 10; ++rep) { BigInteger a = new BigInteger(100 - rep, 0, random); BigInteger b = new BigInteger(100 + rep, 0, random); BigInteger c = new BigInteger(10 + rep, 0, random); BigInteger d = a.Multiply(b).Add(c); BigInteger e = d.Remainder(a); Assert.AreEqual(c, e); } }
public void TestMultiply() { BigInteger 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); BigInteger a = new BigInteger(aLen, random).SetBit(aLen); BigInteger b = new BigInteger(bLen, random).SetBit(bLen); BigInteger c = new BigInteger(32, random); BigInteger ab = a.Multiply(b); BigInteger 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); BigInteger a = one.ShiftLeft(shift); BigInteger b = new BigInteger(64 + random.Next(64), random); BigInteger 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 TestModInverse() { for (int i = 0; i < 10; ++i) { BigInteger p = BigInteger.ProbablePrime(64, random); BigInteger q = new BigInteger(63, random).Add(one); BigInteger inv = q.ModInverse(p); BigInteger inv2 = inv.ModInverse(p); Assert.AreEqual(q, inv2); Assert.AreEqual(one, q.Multiply(inv).Mod(p)); } }
private void btnCombine_Click(object sender, EventArgs e) { // What is input #1? string input1 = txtInput1.Text; string input2 = txtInput2.Text; PublicKey pub1 = null, pub2 = null; KeyPair kp1 = null, kp2 = null; if (KeyPair.IsValidPrivateKey(input1)) { pub1 = kp1 = new KeyPair(input1); } else if (PublicKey.IsValidPublicKey(input1)) { pub1 = new PublicKey(input1); } else { MessageBox.Show("Input key #1 is not a valid Public Key or Private Key Hex", "Can't combine", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (KeyPair.IsValidPrivateKey(input2)) { pub2 = kp2 = new KeyPair(input2); } else if (PublicKey.IsValidPublicKey(input2)) { pub2 = new PublicKey(input2); } else { MessageBox.Show("Input key #2 is not a valid Public Key or Private Key Hex", "Can't combine", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (kp1 == null && kp2 == null && rdoAdd.Checked == false) { MessageBox.Show("Can't multiply two public keys. At least one of the keys must be a private key.", "Can't combine", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (pub1.IsCompressedPoint != pub2.IsCompressedPoint) { MessageBox.Show("Can't combine a compressed key with an uncompressed key.", "Can't combine", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (pub1.AddressBase58 == pub2.AddressBase58) { if (MessageBox.Show("Both of the key inputs have the same public key hash. You can continue, but " + "the results are probably going to be wrong. You might have provided the wrong " + "information, such as two parts from the same side of the transaction, instead " + "of one part from each side. Continue anyway?", "Duplicate Key Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) != DialogResult.OK) { return; } } var ps = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1"); // Combining two private keys? if (kp1 != null && kp2 != null) { BigInteger e1 = new BigInteger(1, kp1.PrivateKeyBytes); BigInteger e2 = new BigInteger(1, kp2.PrivateKeyBytes); BigInteger ecombined = (rdoAdd.Checked ? e1.Add(e2) : e1.Multiply(e2)).Mod(ps.N); System.Diagnostics.Debug.WriteLine(kp1.PublicKeyHex); System.Diagnostics.Debug.WriteLine(kp2.PublicKeyHex); KeyPair kpcombined = new KeyPair(Util.Force32Bytes(ecombined.ToByteArrayUnsigned()), compressed: kp1.IsCompressedPoint); txtOutputAddress.Text = kpcombined.AddressBase58; txtOutputPubkey.Text = kpcombined.PublicKeyHex.Replace(" ", ""); txtOutputPriv.Text = kpcombined.PrivateKeyBase58; } else if (kp1 != null || kp2 != null) { // Combining one public and one private KeyPair priv = (kp1 == null) ? kp2 : kp1; PublicKey pub = (kp1 == null) ? pub1 : pub2; ECPoint point = pub.GetECPoint(); ECPoint combined = rdoAdd.Checked ? point.Add(priv.GetECPoint()) : point.Multiply(new BigInteger(1, priv.PrivateKeyBytes)); ECPoint combinedc = ps.Curve.CreatePoint(combined.X.ToBigInteger(), combined.Y.ToBigInteger(), priv.IsCompressedPoint); PublicKey pkcombined = new PublicKey(combinedc.GetEncoded()); txtOutputAddress.Text = pkcombined.AddressBase58; txtOutputPubkey.Text = pkcombined.PublicKeyHex.Replace(" ", ""); txtOutputPriv.Text = "Only available when combining two private keys"; } else { // Adding two public keys ECPoint combined = pub1.GetECPoint().Add(pub2.GetECPoint()); ECPoint combinedc = ps.Curve.CreatePoint(combined.X.ToBigInteger(), combined.Y.ToBigInteger(), pub1.IsCompressedPoint); PublicKey pkcombined = new PublicKey(combinedc.GetEncoded()); txtOutputAddress.Text = pkcombined.AddressBase58; txtOutputPubkey.Text = pkcombined.PublicKeyHex.Replace(" ", ""); txtOutputPriv.Text = "Only available when combining two private keys"; } }
public void TestDivideAndRemainder() { // TODO More basic tests BigInteger n = new BigInteger(48, random); BigInteger[] qr = n.DivideAndRemainder(one); Assert.AreEqual(n, qr[0]); Assert.AreEqual(zero, qr[1]); for (int rep = 0; rep < 10; ++rep) { BigInteger a = new BigInteger(100 - rep, 0, random); BigInteger b = new BigInteger(100 + rep, 0, random); BigInteger c = new BigInteger(10 + rep, 0, random); BigInteger d = a.Multiply(b).Add(c); BigInteger[] es = d.DivideAndRemainder(a); Assert.AreEqual(b, es[0]); Assert.AreEqual(c, es[1]); } // Special tests for power of two since uses different code path internally for (int i = 0; i < 100; ++i) { int shift = random.Next(64); BigInteger a = one.ShiftLeft(shift); BigInteger b = new BigInteger(64 + random.Next(64), random); BigInteger bShift = b.ShiftRight(shift); BigInteger bMod = b.And(a.Subtract(one)); string data = "shift=" + shift +", b=" + b.ToString(16); qr = b.DivideAndRemainder(a); Assert.AreEqual(bShift, qr[0], data); Assert.AreEqual(bMod, qr[1], data); qr = b.DivideAndRemainder(a.Negate()); Assert.AreEqual(bShift.Negate(), qr[0], data); Assert.AreEqual(bMod, qr[1], data); qr = b.Negate().DivideAndRemainder(a); Assert.AreEqual(bShift.Negate(), qr[0], data); Assert.AreEqual(bMod.Negate(), qr[1], data); qr = b.Negate().DivideAndRemainder(a.Negate()); Assert.AreEqual(bShift, qr[0], data); Assert.AreEqual(bMod.Negate(), qr[1], data); } }
/** * 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, BigInteger r, BigInteger s) { DsaParameters parameters = key.Parameters; BigInteger q = parameters.Q; BigInteger m = calculateE(q, message); if (r.SignValue <= 0 || q.CompareTo(r) <= 0) { return false; } if (s.SignValue <= 0 || q.CompareTo(s) <= 0) { return false; } BigInteger w = s.ModInverse(q); BigInteger u1 = m.Multiply(w).Mod(q); BigInteger u2 = r.Multiply(w).Mod(q); BigInteger p = parameters.P; u1 = parameters.G.ModPow(u1, p); u2 = ((DsaPublicKeyParameters)key).Y.ModPow(u2, p); BigInteger v = u1.Multiply(u2).Mod(p).Mod(q); return v.Equals(r); }
public void TestDivide() { for (int i = -5; i <= 5; ++i) { try { val(i).Divide(zero); Assert.Fail("expected ArithmeticException"); } catch (ArithmeticException) {} } int product = 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9; int productPlus = product + 1; BigInteger bigProduct = val(product); BigInteger bigProductPlus = val(productPlus); for (int divisor = 1; divisor < 10; ++divisor) { // Exact division BigInteger expected = val(product / divisor); Assert.AreEqual(expected, bigProduct.Divide(val(divisor))); Assert.AreEqual(expected.Negate(), bigProduct.Negate().Divide(val(divisor))); Assert.AreEqual(expected.Negate(), bigProduct.Divide(val(divisor).Negate())); Assert.AreEqual(expected, bigProduct.Negate().Divide(val(divisor).Negate())); expected = val((product + 1)/divisor); Assert.AreEqual(expected, bigProductPlus.Divide(val(divisor))); Assert.AreEqual(expected.Negate(), bigProductPlus.Negate().Divide(val(divisor))); Assert.AreEqual(expected.Negate(), bigProductPlus.Divide(val(divisor).Negate())); Assert.AreEqual(expected, bigProductPlus.Negate().Divide(val(divisor).Negate())); } for (int rep = 0; rep < 10; ++rep) { BigInteger a = new BigInteger(100 - rep, 0, random); BigInteger b = new BigInteger(100 + rep, 0, random); BigInteger c = new BigInteger(10 + rep, 0, random); BigInteger d = a.Multiply(b).Add(c); BigInteger e = d.Divide(a); Assert.AreEqual(b, e); } // Special tests for power of two since uses different code path internally for (int i = 0; i < 100; ++i) { int shift = random.Next(64); BigInteger a = one.ShiftLeft(shift); BigInteger b = new BigInteger(64 + random.Next(64), random); BigInteger bShift = b.ShiftRight(shift); string data = "shift=" + shift +", b=" + b.ToString(16); Assert.AreEqual(bShift, b.Divide(a), data); Assert.AreEqual(bShift.Negate(), b.Divide(a.Negate()), data); Assert.AreEqual(bShift.Negate(), b.Negate().Divide(a), data); Assert.AreEqual(bShift, b.Negate().Divide(a.Negate()), data); } // Regression { int shift = 63; BigInteger a = one.ShiftLeft(shift); BigInteger b = new BigInteger(1, Hex.Decode("2504b470dc188499")); BigInteger bShift = b.ShiftRight(shift); string data = "shift=" + shift +", b=" + b.ToString(16); Assert.AreEqual(bShift, b.Divide(a), data); Assert.AreEqual(bShift.Negate(), b.Divide(a.Negate()), data); // Assert.AreEqual(bShift.Negate(), b.Negate().Divide(a), data); Assert.AreEqual(bShift, b.Negate().Divide(a.Negate()), data); } }
// 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, BigInteger r, BigInteger s) { BigInteger 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; } BigInteger e = calculateE(n, message); BigInteger c = s.ModInverse(n); BigInteger u1 = e.Multiply(c).Mod(n); BigInteger u2 = r.Multiply(c).Mod(n); ECPoint G = key.Parameters.G; ECPoint Q = ((ECPublicKeyParameters) key).Q; ECPoint point = ECAlgorithms.SumOfTwoMultiplies(G, u1, Q, u2); if (point.IsInfinity) return false; BigInteger v = point.X.ToBigInteger().Mod(n); return v.Equals(r); }
/// <summary> /// Calculates the keying material, which can be done after round 2 has completed. /// A session key must be derived from this key material using a secure key derivation function (KDF). /// The KDF used to derive the key is handled externally (i.e. not by JPAKEParticipant). /// /// KeyingMaterial = (B/g^{x2*x4*s})^x2 /// </summary> public static BigInteger CalculateKeyingMaterial(BigInteger p, BigInteger q, BigInteger gx4, BigInteger x2, BigInteger s, BigInteger B) { return gx4.ModPow(x2.Multiply(s).Negate().Mod(q), p).Multiply(B).ModPow(x2, p); }
public BigInteger SolveRight(BigInteger[] pcs) { BigInteger accum = new BigInteger("0"); foreach (coefficient c in rightside) { BigInteger scratch = new BigInteger(pcs[c.vindex].ToString()); scratch = scratch.Multiply(new BigInteger(c.multiplier.ToString())); accum = accum.Add(scratch); } return accum.Subtract(subtractor).Divide(new BigInteger(divisor.ToString())); ; }
/// <summary> /// Calculate ga as done in round 2. /// </summary> public static BigInteger CalculateGA(BigInteger p, BigInteger gx1, BigInteger gx3, BigInteger gx4) { // ga = g^(x1+x3+x4) = g^x1 * g^x3 * g^x4 return gx1.Multiply(gx3).Multiply(gx4).Mod(p); }
/// <summary> /// millerov agoritam /// </summary> /// <param name="a">točka</param> /// <param name="b">točka</param> /// <param name="m">red grupe</param> /// <param name="p">red polja, prim</param> /// <returns></returns> private static BigInteger Miller(FpPoint P, FpPoint Q, BigInteger m, BigInteger prim) { // Millerov algoritam string mBin = m.ToString(2); BigInteger t1 = new BigInteger("1", 10); BigInteger t2 = new BigInteger("1", 10); FpPoint V = P; for (int i = 0; i < m.BitLength; i++) { V = (FpPoint)V.Twice(); t1 = t1.ModPow(new BigInteger("2", 10), prim).Multiply(MLF(V, V, Q)); if (mBin[i] == '1') { t1 = t1.Multiply(MLF(V, P, Q)); V = (FpPoint)V.Add(P); } } return t1; }
/// <summary> /// Calculate x2 * s as done in round 2. /// </summary> public static BigInteger CalculateX2s(BigInteger q, BigInteger x2, BigInteger s) { return x2.Multiply(s).Mod(q); }
private void btnDecrypt_Click(object sender, EventArgs e) { // Remove any spaces or dashes from the encrypted key (in case they were typed) txtEncrypted.Text = txtEncrypted.Text.Replace("-", "").Replace(" ", ""); if (txtEncrypted.Text == "" || txtPassphrase.Text == "") { MessageBox.Show("Enter an encrypted key and its passphrase.", "Entries Required", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } // What were we given as encrypted text? object encrypted = StringInterpreter.Interpret(txtEncrypted.Text); if (encrypted == null) { if (txtEncrypted.Text.StartsWith("cfrm38")) { var r = MessageBox.Show("This is not a private key. This looks like a confirmation code. " + "Do you want to open the Confirmation Code Validator?", "Invalid private key", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); if (r == DialogResult.Yes) { Program.ShowConfValidator(); } return; } string containsL = ""; if (txtEncrypted.Text.Contains("l")) { containsL = " Your entry contains the lowercase letter l. Private keys are far " + "more likely to contain the digit 1, and not the lowercase letter l."; } MessageBox.Show("The private key entry (top box) was invalid. " + "Please verify the private key was properly typed." + containsL, "Invalid private key", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } if (encrypted is PassphraseKeyPair) { PassphraseKeyPair pkp = encrypted as PassphraseKeyPair; if (pkp.DecryptWithPassphrase(txtPassphrase.Text) == false) { MessageBox.Show("The passphrase is incorrect.", "Could not decrypt", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } MessageBox.Show("Decryption successful.", "Decryption", MessageBoxButtons.OK, MessageBoxIcon.Information); Program.ShowAddressUtility(); Program.AddressUtility.DisplayKeyCollectionItem(new KeyCollectionItem(pkp.GetUnencryptedPrivateKey())); return; } else if (encrypted is KeyPair) { // it's unencrypted - perhaps we're doing an EC multiply and the passphrase is a private key. object encrypted2 = StringInterpreter.Interpret(txtPassphrase.Text); if (encrypted2 == null) { var r = MessageBox.Show("Does the key you entered belong to the following address?: " + (encrypted as KeyPair).AddressBase58, "Key appears unencrypted", MessageBoxButtons.YesNo); if (r == DialogResult.Yes) { r = MessageBox.Show("Then this key is already unencrypted and you don't need to decrypt it. " + "Would you like to open it in the Address Utility screen to see its various forms?", "Key is not encrypted", MessageBoxButtons.YesNo, MessageBoxIcon.Information); if (r == DialogResult.Yes) { Program.ShowAddressUtility(); Program.AddressUtility.DisplayKeyCollectionItem(new KeyCollectionItem(encrypted as KeyPair)); } } else { MessageBox.Show("The passphrase or secondary key is incorrect. Please verify it was properly typed.", "Second entry is not a valid private key", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } return; } BigInteger n1 = new BigInteger(1, (encrypted as KeyPair).PrivateKeyBytes); BigInteger n2 = new BigInteger(1, (encrypted2 as KeyPair).PrivateKeyBytes); var ps = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1"); BigInteger privatekey = n1.Multiply(n2).Mod(ps.N); MessageBox.Show("Keys successfully combined using EC multiplication.", "EC multiplication successful", MessageBoxButtons.OK, MessageBoxIcon.Information); if (n1.Equals(n2)) { MessageBox.Show("The two key entries have the same public hash. The results you see might be wrong.", "Duplicate key hash", MessageBoxButtons.OK, MessageBoxIcon.Information); } // use private key KeyPair kp = new KeyPair(privatekey); Program.ShowAddressUtility(); Program.AddressUtility.DisplayKeyCollectionItem(new KeyCollectionItem(kp)); } else if (encrypted is AddressBase) { MessageBox.Show("This is not a private key. It looks like an address or a public key. Private keys usually start with 5, 6, or S.", "Not a private key", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } else { MessageBox.Show("This is not a private key that this program can decrypt.", "Not a recognized private key", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } }
public void TestGcd() { for (int i = 0; i < 10; ++i) { BigInteger fac = new BigInteger(32, random).Add(two); BigInteger p1 = BigInteger.ProbablePrime(63, random); BigInteger p2 = BigInteger.ProbablePrime(64, random); BigInteger gcd = fac.Multiply(p1).Gcd(fac.Multiply(p2)); Assert.AreEqual(fac, gcd); } }