/// <summary> /// Computes the public key from the private key. /// </summary> protected override byte[] ComputePublicKey() { var ps = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256k1"); Org.BouncyCastle.Math.EC.ECPoint point = ps.G; Org.BouncyCastle.Math.BigInteger Db = new Org.BouncyCastle.Math.BigInteger(1, _privKey); Org.BouncyCastle.Math.EC.ECPoint dd = point.Multiply(Db); if (IsCompressedPoint) { dd = ps.Curve.CreatePoint(dd.X.ToBigInteger(), dd.Y.ToBigInteger(), true); return(dd.GetEncoded()); } else { byte[] pubaddr = new byte[65]; byte[] Y = dd.Y.ToBigInteger().ToByteArray(); Array.Copy(Y, 0, pubaddr, 64 - Y.Length + 1, Y.Length); byte[] X = dd.X.ToBigInteger().ToByteArray(); Array.Copy(X, 0, pubaddr, 32 - X.Length + 1, X.Length); pubaddr[0] = 4; return(pubaddr); } }
public static byte GetRecoveryId(byte[] sigR, byte[] sigS, byte[] message, byte[] publicKey) { //ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1"); X9ECParameters spec = ECNamedCurveTable.GetByName("secp256k1"); BigInteger pointN = spec.N; for (int recoveryId = 0; recoveryId < 2; recoveryId++) { try { BigInteger pointX = new BigInteger(1, sigR); byte[] compEnc = X9IntegerConverter.IntegerToBytes(pointX, 1 + X9IntegerConverter.GetByteLength(spec.Curve)); compEnc[0] = (byte)((recoveryId & 1) == 1 ? 0x03 : 0x02); ECPoint pointR = spec.Curve.DecodePoint(compEnc); if (!pointR.Multiply(pointN).IsInfinity) { continue; } BigInteger pointE = new BigInteger(1, message); BigInteger pointEInv = BigInteger.Zero.Subtract(pointE).Mod(pointN); BigInteger pointRInv = new BigInteger(1, sigR).ModInverse(pointN); BigInteger srInv = pointRInv.Multiply(new BigInteger(1, sigS)).Mod(pointN); BigInteger pointEInvRInv = pointRInv.Multiply(pointEInv).Mod(pointN); ECPoint pointQ = ECAlgorithms.SumOfTwoMultiplies(spec.G, pointEInvRInv, pointR, srInv); byte[] pointQBytes = pointQ.GetEncoded(false); bool matchedKeys = true; for (int j = 0; j < publicKey.Length; j++) { if (pointQBytes[j] != publicKey[j]) { matchedKeys = false; break; } } if (!matchedKeys) { continue; } return((byte)(0xFF & recoveryId)); } catch (Exception e) { continue; Console.WriteLine(" Failed: GET recoveryID"); } } return((byte)0xFF); }
public static string PrivHexToPubHex(string PrivHex, ECPoint point) { byte[] hex = ValidateAndGetHexPrivateKey(0x00, PrivHex, 33); if (hex == null) { throw new ApplicationException("Invalid private hex key"); } Org.BouncyCastle.Math.BigInteger Db = new Org.BouncyCastle.Math.BigInteger(hex); ECPoint dd = point.Multiply(Db); byte[] pubaddr = PubKeyToByteArray(dd); return(ByteArrayToString(pubaddr)); }
public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b) { ECCurve cp = P.Curve; Q = ImportPoint(cp, Q); // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick if (cp is F2mCurve) { F2mCurve f2mCurve = (F2mCurve) cp; if (f2mCurve.IsKoblitz) { return P.Multiply(a).Add(Q.Multiply(b)); } } return ImplShamirsTrickWNaf(P, a, Q, b); }
public static ECPoint SumOfTwoMultiplies(ECPoint p, IBigInteger a, ECPoint q, IBigInteger b) { var c = p.Curve; if (!c.Equals(q.Curve)) throw new ArgumentException("P and Q must be on same curve"); // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick var f2MCurve = c as F2MCurve; if (f2MCurve != null) { if (f2MCurve.IsKoblitz) { return p.Multiply(a).Add(q.Multiply(b)); } } return ImplShamirsTrick(p, a, q, b); }
public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b) { ECCurve cp = P.Curve; Q = ImportPoint(cp, Q); // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick if (cp is F2mCurve) { F2mCurve f2mCurve = (F2mCurve)cp; if (f2mCurve.IsKoblitz) { return(P.Multiply(a).Add(Q.Multiply(b))); } } return(ImplShamirsTrickWNaf(P, a, Q, b)); }
public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b) { ECCurve c = P.Curve; if (!c.Equals(Q.Curve)) throw new ArgumentException("P and Q must be on same curve"); // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick if (c is F2mCurve) { F2mCurve f2mCurve = (F2mCurve) c; if (f2mCurve.IsKoblitz) { return P.Multiply(a).Add(Q.Multiply(b)); } } return ImplShamirsTrick(P, a, Q, b); }
private ECPoint CalculatePoint(ECPublicKeyParameters pubKeyParams) { ECDomainParameters dp = KeyParam.Parameters; if (!dp.Equals(pubKeyParams.Parameters)) { throw new InvalidOperationException( "ECDH public key has wrong domain parameters" ); } BigInteger d = KeyParam.D; ECPoint q = dp.Curve.DecodePoint(pubKeyParams.Q.GetEncoded(true)); if (q.IsInfinity) { throw new InvalidOperationException( "Infinity is not a valid public key for ECDH" ); } BigInteger h = dp.H; if (!h.Equals(BigInteger.One)) { d = dp.H.ModInverse(dp.N).Multiply(d).Mod(dp.N); q = ECAlgorithms.ReferenceMultiply(q, h); } ECPoint p = q.Multiply(d).Normalize(); if (p.IsInfinity) { throw new InvalidOperationException( "Infinity is not a valid agreement value for ECDH" ); } return(p); }
public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b) { ECCurve c = P.Curve; Q = ImportPoint(c, Q); AbstractF2mCurve curve2 = c as AbstractF2mCurve; if ((curve2 != null) && curve2.IsKoblitz) { return(ValidatePoint(P.Multiply(a).Add(Q.Multiply(b)))); } GlvEndomorphism glvEndomorphism = c.GetEndomorphism() as GlvEndomorphism; if (glvEndomorphism != null) { ECPoint[] ps = new ECPoint[] { P, Q }; BigInteger[] ks = new BigInteger[] { a, b }; return(ValidatePoint(ImplSumOfMultipliesGlv(ps, ks, glvEndomorphism))); } return(ValidatePoint(ImplShamirsTrickWNaf(P, a, Q, b))); }
public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b) { ECCurve c = P.Curve; if (!c.Equals(Q.Curve)) { throw new ArgumentException("P and Q must be on same curve"); } // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick if (c is F2mCurve) { F2mCurve f2mCurve = (F2mCurve)c; if (f2mCurve.IsKoblitz) { return(P.Multiply(a).Add(Q.Multiply(b))); } } return(ImplShamirsTrick(P, a, Q, b)); }
/// <summary> /// Used by the token service. Signs the point submitted by the initiator in order to create a token, and outputs a proof of validity. /// </summary> /// <param name="k">The private key for the token scheme</param> /// <param name="K">The public key for the token scheme</param> /// <param name="ecParameters">Curve parameters</param> /// <param name="P">Point submitted by the app</param> /// <returns>A signed point Q and a Chaum-Pedersen proof (c,z) proving that the point is signed correctly</returns> public (ECPoint Q, BigInteger c, BigInteger z) GenerateToken( BigInteger k, ECPoint K, X9ECParameters ecParameters, ECPoint P) { ECCurve?curve = ecParameters.Curve; // Check that P is a valid point on the currect curve if (ECPointVerifier.PointIsValid(P, curve) == false) { throw new AnonymousTokensException("P is not a valid point on the curve"); } // Compute Q = k*P ECPoint?Q = P.Multiply(k); // Chaum-Pedersen proof of correct signature var(c, z) = CreateProof(ecParameters, k, K, P, Q); return(Q, c, z); }
public static ECPoint SumOfTwoMultiplies(ECPoint p, IBigInteger a, ECPoint q, IBigInteger b) { var c = p.Curve; if (!c.Equals(q.Curve)) { throw new ArgumentException("P and Q must be on same curve"); } // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick var f2MCurve = c as F2MCurve; if (f2MCurve != null) { if (f2MCurve.IsKoblitz) { return(p.Multiply(a).Add(q.Multiply(b))); } } return(ImplShamirsTrick(p, a, q, b)); }
public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b) { ECCurve cp = P.Curve; Q = ImportPoint(cp, Q); // Point multiplication for Koblitz curves (using WTNAF) beats Shamir's trick if (cp is F2mCurve) { F2mCurve f2mCurve = (F2mCurve) cp; if (f2mCurve.IsKoblitz) { return P.Multiply(a).Add(Q.Multiply(b)); } } GlvEndomorphism glvEndomorphism = cp.GetEndomorphism() as GlvEndomorphism; if (glvEndomorphism != null) { return ImplSumOfMultipliesGlv(new ECPoint[] { P, Q }, new BigInteger[] { a, b }, glvEndomorphism); } return ImplShamirsTrickWNaf(P, a, Q, b); }
/// <summary> /// Used by the token service. Creates a full transcript of a Chaum-Pedersen protocol instance, using the strong Fiat-Shamir transform. /// The Chaum-Pedersen proof proves that the same secret key k is used to compute K = k*G and Q = k*P, without revealing k. /// </summary> /// <param name="ecParameters">Curve parameters</param> /// <param name="k">The private key of the token scheme</param> /// <param name="K">The public key of the token scheme</param> /// <param name="P">Point submitted by the initiator</param> /// <param name="Q">Point signed using the secret key</param> /// <returns></returns> private (BigInteger c, BigInteger z) CreateProof( X9ECParameters ecParameters, BigInteger k, ECPoint K, ECPoint P, ECPoint Q) { // Sample a random integer 0 < r < N BigInteger r = ECCurveRandomNumberGenerator.GenerateRandomNumber(ecParameters.Curve, _random); // Computes X = r*G ECPoint X = ecParameters.G.Multiply(r); // Computes Y = r*P ECPoint Y = P.Multiply(r); BigInteger c = CPChallengeGenerator.CreateChallenge(ecParameters.G, P, K, Q, X, Y); // Compute proof z = r - ck mod N BigInteger z = r.Subtract(c.Multiply(k)).Mod(ecParameters.Curve.Order); return(c, z); }
public static ECPoint SumOfTwoMultiplies(ECPoint P, BigInteger a, ECPoint Q, BigInteger b) { ECCurve curve = P.Curve; Q = ImportPoint(curve, Q); AbstractF2mCurve abstractF2mCurve = curve as AbstractF2mCurve; if (abstractF2mCurve != null && abstractF2mCurve.IsKoblitz) { return(ValidatePoint(P.Multiply(a).Add(Q.Multiply(b)))); } GlvEndomorphism glvEndomorphism = curve.GetEndomorphism() as GlvEndomorphism; if (glvEndomorphism != null) { return(ValidatePoint(ImplSumOfMultipliesGlv(new ECPoint[2] { P, Q }, new BigInteger[2] { a, b }, glvEndomorphism))); } return(ValidatePoint(ImplShamirsTrickWNaf(P, a, Q, b))); }
/** * Recover the public key that corresponds to the private key, which signed this message. */ public static byte[] RecoverPublicKey(byte[] sigR, byte[] sigS, byte[] sigV, byte[] message) { //ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("secp256k1"); X9ECParameters spec = ECNamedCurveTable.GetByName("secp256k1"); BigInteger pointN = spec.N; try { BigInteger pointX = new BigInteger(1, sigR); byte[] compEnc = X9IntegerConverter.IntegerToBytes(pointX, 1 + X9IntegerConverter.GetByteLength(spec.Curve)); compEnc[0] = (byte)((sigV[0] & 1) == 1 ? 0x03 : 0x02); ECPoint pointR = spec.Curve.DecodePoint(compEnc); if (!pointR.Multiply(pointN).IsInfinity) { return(new byte[0]); } BigInteger pointE = new BigInteger(1, message); BigInteger pointEInv = BigInteger.Zero.Subtract(pointE).Mod(pointN); BigInteger pointRInv = new BigInteger(1, sigR).ModInverse(pointN); BigInteger srInv = pointRInv.Multiply(new BigInteger(1, sigS)).Mod(pointN); BigInteger pointEInvRInv = pointRInv.Multiply(pointEInv).Mod(pointN); ECPoint pointQ = ECAlgorithms.SumOfTwoMultiplies(spec.G, pointEInvRInv, pointR, srInv); byte[] pointQBytes = pointQ.GetEncoded(false); return(pointQBytes); } catch (Exception e) { } return(new byte[0]); }
/** * Checks, if the point multiplication algorithm of the given point yields * the same result as point multiplication done by the reference * implementation given in <code>multiply()</code>. This method tests * multiplication of <code>p</code> by every number of bitlength * <code>numBits</code> or less. * * @param p * The point to be multiplied. * @param numBits * Try every multiplier up to this bitlength */ private void ImplTestMultiplyAll(ECPoint p, int numBits) { BigInteger bound = BigInteger.One.ShiftLeft(numBits); BigInteger k = BigInteger.Zero; do { ECPoint reff = Multiply(p, k); ECPoint q = p.Multiply(k); AssertPointsEqual("ECPoint.Multiply is incorrect", reff, q); k = k.Add(BigInteger.One); } while (k.CompareTo(bound) < 0); }
/** * Checks, if the point multiplication algorithm of the given point yields * the same result as point multiplication done by the reference * implementation given in <code>multiply()</code>. This method chooses a * random number by which the given point <code>p</code> is multiplied. * * @param p * The point to be multiplied. * @param numBits * The bitlength of the random number by which <code>p</code> * is multiplied. */ private void ImplTestMultiply(ECPoint p, int numBits) { BigInteger k = new BigInteger(numBits, secRand); ECPoint reff = Multiply(p, k); ECPoint q = p.Multiply(k); AssertPointsEqual("ECPoint.Multiply is incorrect", reff, q); }
/** * Goes through all points on an elliptic curve and checks, if adding a * point <code>k</code>-times is the same as multiplying the point by * <code>k</code>, for all <code>k</code>. Should be called for points * on very small elliptic curves only. * * @param p * The base point on the elliptic curve. * @param infinity * The point at infinity on the elliptic curve. */ private void ImplTestAllPoints(ECPoint p, ECPoint infinity) { ECPoint adder = infinity; ECPoint multiplier = infinity; BigInteger i = BigInteger.One; do { adder = adder.Add(p); multiplier = p.Multiply(i); AssertPointsEqual("Results of Add() and Multiply() are inconsistent " + i, adder, multiplier); i = i.Add(BigInteger.One); } while (!(adder.Equals(infinity))); }
internal static BigInteger CalculateAgreement (ECPoint q, BigInteger d) { ECPoint p = q.Multiply (d); // if ( p.IsInfinity ) throw new Exception("d*Q == infinity"); return p.X.ToBigInteger(); }
private double RandMult(SecureRandom random, ECPoint g, BigInteger n) { BigInteger[] ks = new BigInteger[128]; for (int i = 0; i < ks.Length; ++i) { ks[i] = new BigInteger(n.BitLength - 1, random); } int ki = 0; ECPoint p = g; for (int i = 1; i <= PRE_ROUNDS; i++) { BigInteger k = ks[ki]; p = g.Multiply(k); if (++ki == ks.Length) { ki = 0; g = p; } } long startTime = DateTimeUtilities.CurrentUnixMs(); for (int i = 1; i <= NUM_ROUNDS; i++) { BigInteger k = ks[ki]; p = g.Multiply(k); if (++ki == ks.Length) { ki = 0; g = p; } } long endTime = DateTimeUtilities.CurrentUnixMs(); return (double)(endTime - startTime) / NUM_ROUNDS; }
private BigInteger ExtractUsersPrivateKey( ECPoint G, BigInteger N, string message1, string message2, BigInteger r1, BigInteger s1, BigInteger r2, BigInteger s2, BigInteger attackersPrivate, ECPoint attackersPublic, ECPoint usersPublic) { var m1 = new BigInteger(1, Hash(Encoding.UTF8.GetBytes(message1))); // hash of m1 var m2 = new BigInteger(1, Hash(Encoding.UTF8.GetBytes(message2))); // hash of m2 //calculate the result of verifying signature 1 var w = s1.ModInverse(N); var u1 = m1.Multiply(w).Mod(N); var u2 = r1.Multiply(w).Mod(N); var verifyPoint = ECAlgorithms.SumOfTwoMultiplies(G, u1, usersPublic, u2).Normalize(); //reinit K calculator to reproduce a,b,h,e var kCalc = new RandomDsaKCalculator(); kCalc.Init(N, new SecureRandom(new SeededGenerator(Hash(Encoding.UTF8.GetBytes(message2))))); var a = kCalc.NextK(); var b = kCalc.NextK(); var h = kCalc.NextK(); var e = kCalc.NextK(); var Z1 = verifyPoint.Multiply(a).Add(verifyPoint.Multiply(attackersPrivate).Multiply(b)); //cycle through all possible j & u for (int i = 0; i < 2; i++) for (int l = 0; l < 2; l++) { var j = new BigInteger(i.ToString()); var u = new BigInteger(l.ToString()); var Z2 = Z1.Add(G.Multiply(j).Multiply(h)).Add(attackersPublic.Multiply(u).Multiply(e)).Normalize(); var zX = Z2.AffineXCoord.ToBigInteger().ToByteArray(); var hash = Hash(zX); var kCandidate = new BigInteger(1, hash); var verifyPointCandidate = G.Multiply(kCandidate).Normalize(); var rCandidate = verifyPointCandidate.AffineXCoord.ToBigInteger().Mod(N); if (rCandidate.Equals(r2)) // Gotcha! { return s2.Multiply(kCandidate).Subtract(m2).Multiply(r2.ModInverse(N)).Mod(N); } } return null; }
private double RandMult(SecureRandom random, ECPoint g, BigInteger n) { BigInteger[] ks = new BigInteger[128]; for (int i = 0; i < ks.Length; ++i) { ks[i] = new BigInteger(n.BitLength - 1, random); } int ki = 0; ECPoint p = g; { long startTime = DateTimeUtilities.CurrentUnixMs(); long goalTime = startTime + MILLIS_WARMUP; do { BigInteger k = ks[ki]; p = g.Multiply(k); if ((ki & 1) != 0) { g = p; } if (++ki == ks.Length) { ki = 0; } } while (DateTimeUtilities.CurrentUnixMs() < goalTime); } double minRate = Double.MaxValue, maxRate = Double.MinValue, totalRate = 0.0; for (int i = 1; i <= NUM_ROUNDS; i++) { long startTime = DateTimeUtilities.CurrentUnixMs(); long goalTime = startTime + MILLIS_PER_ROUND; long count = 0, endTime; do { ++count; for (int j = 0; j < MULTS_PER_CHECK; ++j) { BigInteger k = ks[ki]; p = g.Multiply(k); if ((ki & 1) != 0) { g = p; } if (++ki == ks.Length) { ki = 0; } } endTime = DateTimeUtilities.CurrentUnixMs(); } while (endTime < goalTime); double roundElapsed = (double)(endTime - startTime); double roundRate = count * MULTS_PER_CHECK * 1000L / roundElapsed; minRate = System.Math.Min(minRate, roundRate); maxRate = System.Math.Max(maxRate, roundRate); totalRate += roundRate; } return (totalRate - minRate - maxRate) / (NUM_ROUNDS - 2); }
/** * Goes through all points on an elliptic curve and checks, if adding a * point <code>k</code>-times is the same as multiplying the point by * <code>k</code>, for all <code>k</code>. Should be called for points * on very small elliptic curves only. * * @param p * The base point on the elliptic curve. * @param infinity * The point at infinity on the elliptic curve. */ private void implTestAllPoints(ECPoint p, ECPoint infinity) { ECPoint adder = infinity; ECPoint multiplier = infinity; int i = 1; do { adder = adder.Add(p); multiplier = p.Multiply(new BigInteger(i.ToString())); Assert.AreEqual(adder, multiplier, "Results of add() and multiply() are inconsistent " + i); i++; } while (!(adder.Equals(infinity))); }
/** * Checks, if the point multiplication algorithm of the given point yields * the same result as point multiplication done by the reference * implementation given in <code>multiply()</code>. This method chooses a * random number by which the given point <code>p</code> is multiplied. * * @param p * The point to be multiplied. * @param numBits * The bitlength of the random number by which <code>p</code> * is multiplied. */ private void implTestMultiply(ECPoint p, int numBits) { BigInteger k = new BigInteger(numBits, secRand); ECPoint reff = multiply(p, k); ECPoint q = p.Multiply(k); Assert.AreEqual(reff, q, "ECPoint.multiply is incorrect"); }
private double RandMult(SecureRandom random, ECPoint g, BigInteger n) { BigInteger[] ks = new BigInteger[128]; for (int i = 0; i < ks.Length; ++i) { ks[i] = new BigInteger(n.BitLength - 1, random); } int ki = 0; ECPoint p = g; for (int i = 1; i <= PRE_ROUNDS; i++) { for (int j = 0; j < MULTS_PER_ROUND; ++j) { BigInteger k = ks[ki]; p = g.Multiply(k); if ((ki & 1) != 0) { g = p; } if (++ki == ks.Length) { ki = 0; } } } double minElapsed = Double.MaxValue, maxElapsed = Double.MinValue, totalElapsed = 0.0; for (int i = 1; i <= NUM_ROUNDS; i++) { long startTime = DateTimeUtilities.CurrentUnixMs(); for (int j = 0; j < MULTS_PER_ROUND; ++j) { BigInteger k = ks[ki]; p = g.Multiply(k); if ((ki & 1) != 0) { g = p; } if (++ki == ks.Length) { ki = 0; } } long endTime = DateTimeUtilities.CurrentUnixMs(); double roundElapsed = (double)(endTime - startTime); minElapsed = System.Math.Min(minElapsed, roundElapsed); maxElapsed = System.Math.Max(maxElapsed, roundElapsed); totalElapsed += roundElapsed; } return (totalElapsed - minElapsed - maxElapsed) / (NUM_ROUNDS - 2) / MULTS_PER_ROUND; }
public static string PrivHexToPubHex(string PrivHex, ECPoint point) { byte[] hex = ValidateAndGetHexPrivateKey(0x00, PrivHex, 33); if (hex == null) throw new ApplicationException("Invalid private hex key"); Org.BouncyCastle.Math.BigInteger Db = new Org.BouncyCastle.Math.BigInteger(hex); ECPoint dd = point.Multiply(Db); byte[] pubaddr = PubKeyToByteArray(dd); return ByteArrayToString(pubaddr); }
/** * Checks, if the point multiplication algorithm of the given point yields * the same result as point multiplication done by the reference * implementation given in <code>multiply()</code>. This method tests * multiplication of <code>p</code> by every number of bitlength * <code>numBits</code> or less. * * @param p * The point to be multiplied. * @param numBits * Try every multiplier up to this bitlength */ private void implTestMultiplyAll(ECPoint p, int numBits) { BigInteger bound = BigInteger.Two.Pow(numBits); BigInteger k = BigInteger.Zero; do { ECPoint reff = multiply(p, k); ECPoint q = p.Multiply(k); Assert.AreEqual(reff, q, "ECPoint.multiply is incorrect"); k = k.Add(BigInteger.One); } while (k.CompareTo(bound) < 0); }