public EccKeyPairValidateResult ValidateKeyPair(EccDomainParameters domainParameters, EccKeyPair keyPair) { // If Q == O, invalid if (keyPair.PublicQ.Infinity) { return(new EccKeyPairValidateResult("Q cannot be infinity")); } // If Q is not a valid point (x, y are within the field), invalid if (!domainParameters.CurveE.PointExistsInField(keyPair.PublicQ)) { return(new EccKeyPairValidateResult("Q is out of range of the field")); } // If Q is not a valid point on the specific curve, invalid if (!domainParameters.CurveE.PointExistsOnCurve(keyPair.PublicQ)) { return(new EccKeyPairValidateResult("Q does not lie on the curve")); } // If n * Q == 0, valid // This is fast because the scalar (n) is taken modulo n... so it's 0 if (domainParameters.CurveE.Multiply(keyPair.PublicQ, domainParameters.CurveE.OrderN).Infinity) { return(new EccKeyPairValidateResult()); } // Otherwise invalid return(new EccKeyPairValidateResult("n * Q must equal infinity")); }
public void ShouldVerifyRandomlyGeneratedSignatures(ModeValues mode, DigestSizes digest, Curve curveEnum) { var nonces = new List <BigInteger>(); var hashFunction = new HashFunction(mode, digest); var shaFactory = new NativeShaFactory(); var sha = shaFactory.GetShaInstance(hashFunction); var hmacFactory = new HmacFactory(shaFactory); var hmac = hmacFactory.GetHmacInstance(hashFunction); var subject = new EccDsa(sha, new DeterministicNonceProvider(hmac), EntropyProviderTypes.Random); var curveFactory = new EccCurveFactory(); var curve = curveFactory.GetCurve(curveEnum); var domainParams = new EccDomainParameters(curve); var key = subject.GenerateKeyPair(domainParams).KeyPair; var rand = new Random800_90(); for (var i = 0; i < 100; i++) { var message = rand.GetRandomBitString(1024); var signature = subject.Sign(domainParams, key, message).Signature; var verify = subject.Verify(domainParams, key, message, signature); nonces.Add(signature.R); Assert.IsTrue(verify.Success, verify.ErrorMessage); } // Check nonces for uniqueness Assert.AreEqual(nonces.Count, nonces.Distinct().Count(), "Repeated nonce detected"); }
public EccSignatureResult Sign(EccDomainParameters domainParameters, EccKeyPair keyPair, BitString message, bool skipHash = false) { var bitsOfDigestNeeded = System.Math.Min(domainParameters.CurveE.OrderN.ExactBitLength(), Sha.HashFunction.OutputLen); // Determine whether to hash or skip the hash step for component test var hashDigest = skipHash ? message : Sha.HashMessage(message).Digest; var e = hashDigest.MSBSubstring(0, bitsOfDigestNeeded).ToPositiveBigInteger(); // Generate random number k [1, n-1] var k = _nonceProvider.GetNonce(keyPair.PrivateD, e, domainParameters.CurveE.OrderN); //var k = _entropyProvider.GetEntropy(1, domainParameters.CurveE.OrderN - 1); // Compute point (x, y) = k * G var point = domainParameters.CurveE.Multiply(domainParameters.CurveE.BasePointG, k); // Represent x as an integer j var j = point.X; // Compute r = j mod n var r = j % domainParameters.CurveE.OrderN; // Compute s = k^-1 (e + d*r) mod n, where e = H(m) as an integer var kInverse = k.ModularInverse(domainParameters.CurveE.OrderN); var s = (kInverse * (e + keyPair.PrivateD * r)).PosMod(domainParameters.CurveE.OrderN); // Return pair (r, s) return(new EccSignatureResult(new EccSignature(r, s))); }
public void ShouldDemonstrateCurvePaddingIssue(Curve curve, bool hasIssue) { var shaFactory = new NativeShaFactory(); var hmacFactory = new HmacFactory(shaFactory); var nonceProviderFactory = new EccNonceProviderFactory(); var entropyFactory = new EntropyProviderFactory(); var dsaFactory = new DsaEccFactory(shaFactory, hmacFactory, nonceProviderFactory, entropyFactory); var dsa = dsaFactory.GetInstanceForKeys(entropyFactory.GetEntropyProvider(EntropyProviderTypes.Random)); var domainParameters = new EccDomainParameters(new EccCurveFactory().GetCurve(curve)); var key1 = dsa.GenerateKeyPair(domainParameters).KeyPair; var key2 = dsa.GenerateKeyPair(domainParameters).KeyPair; var calculationOldZ = new BadPaddingDiffieHellmanEcc().GenerateSharedSecretZ(domainParameters, key1, key2); var calculationNewZ = new DiffieHellmanEcc().GenerateSharedSecretZ(domainParameters, key1, key2); if (hasIssue) { Assert.AreNotEqual(calculationOldZ.SharedSecretZ.ToHex(), calculationNewZ.SharedSecretZ.ToHex()); } else { Assert.AreEqual(calculationOldZ.SharedSecretZ.ToHex(), calculationNewZ.SharedSecretZ.ToHex()); } }
public void ShouldComputeCorrectZ( string label, Curve curveEnum, EccKeyPair sPartyA, EccKeyPair ePartyA, EccKeyPair sPartyB, EccKeyPair ePartyB, BitString expectedZ) { var curve = _curveFactory.GetCurve(curveEnum); EccDomainParameters dp = new EccDomainParameters(curve); var result = _subject.GenerateSharedSecretZ( dp, sPartyA, sPartyB, ePartyA, ePartyA, ePartyB ); Assert.That(result.Success); Assert.AreEqual(expectedZ, result.SharedSecretZ); }
/// <inheritdoc /> protected override void GenerateDomainParameters() { DomainParameters = new EccDomainParameters( EccCurveFactory.GetCurve( SchemeParameters.KasAlgoAttributes.CurveName ) ); }
public EccKeyPairGenerateResult GenerateKeyPair(EccDomainParameters domainParameters) { // Generate random number d [1, n - 2] var d = _entropyProvider.GetEntropy(1, domainParameters.CurveE.OrderN - 1); // Compute Q such that Q = d * G var Q = domainParameters.CurveE.Multiply(domainParameters.CurveE.BasePointG, d); // Return key pair (Q, d) return(new EccKeyPairGenerateResult(new EccKeyPair(Q, d))); }
public void Setup() { _sha = new Mock <ISha>(); _shaFactory = new Mock <IShaFactory>(); _dsa = new Mock <IDsaEcc>(); _dsaFactory = new Mock <IDsaEccFactory>(); _kdfFactory = new Mock <IKdfOneStepFactory>(); _keyConfirmationFactory = new Mock <IKeyConfirmationFactory>(); _noKeyConfirmationFactory = new Mock <INoKeyConfirmationFactory>(); _otherInfoFactory = new Mock <IOtherInfoFactory>(); _entropyProvider = new Mock <IEntropyProvider>(); _diffieHellmanEcc = new Mock <IDiffieHellman <EccDomainParameters, EccKeyPair> >(); _mqv = new Mock <IMqv <EccDomainParameters, EccKeyPair> >(); _subject = new SchemeBuilderEcc( _dsaFactory.Object, _curveFactory, _kdfFactory.Object, _keyConfirmationFactory.Object, _noKeyConfirmationFactory.Object, _otherInfoFactory.Object, _entropyProvider.Object, _diffieHellmanEcc.Object, _mqv.Object ); _curve = Curve.B163; _mockDomainParameters = new EccDomainParameters(_curveFactory.GetCurve(_curve)); _sha .Setup(s => s.HashFunction) .Returns(new HashFunction(ModeValues.SHA2, DigestSizes.d224)); _sha .Setup(s => s.HashMessage(It.IsAny <BitString>(), It.IsAny <int>())) .Returns(new HashResult(new BitString(1))); _shaFactory .Setup(s => s.GetShaInstance(It.IsAny <HashFunction>())) .Returns(_sha.Object); _dsa .Setup(s => s.Sha) .Returns(_sha.Object); _dsa .Setup(s => s.GenerateDomainParameters(It.IsAny <EccDomainParametersGenerateRequest>())) .Returns( new EccDomainParametersGenerateResult() ); _dsa .Setup(s => s.GenerateKeyPair(It.IsAny <EccDomainParameters>())) .Returns(new EccKeyPairGenerateResult(new EccKeyPair(new EccPoint(1, 2), 2))); _dsaFactory .Setup(s => s.GetInstance(It.IsAny <HashFunction>(), It.IsAny <EntropyProviderTypes>())) .Returns(_dsa.Object); }
public EccVerificationResult Verify(EccDomainParameters domainParameters, EccKeyPair keyPair, BitString message, EccSignature signature, bool skipHash = false) { // Check r and s to be within the interval [1, n-1] if (signature.R < 1 || signature.R > domainParameters.CurveE.OrderN - 1 || signature.S < 1 || signature.S > domainParameters.CurveE.OrderN) { return(new EccVerificationResult("signature values not within the necessary interval")); } // Hash message e = H(m) var bitsOfDigestNeeded = System.Math.Min(domainParameters.CurveE.OrderN.ExactBitLength(), Sha.HashFunction.OutputLen); // Determine whether to hash or skip the hash step for component test var hashDigest = skipHash ? message : Sha.HashMessage(message).Digest; var e = hashDigest.MSBSubstring(0, bitsOfDigestNeeded).ToPositiveBigInteger(); // Compute u1 = e * s^-1 (mod n) var sInverse = signature.S.ModularInverse(domainParameters.CurveE.OrderN); var u1 = (e * sInverse) % domainParameters.CurveE.OrderN; // Compute u2 = r * s^-1 (mod n) var u2 = (signature.R * sInverse) % domainParameters.CurveE.OrderN; // Compute point R = u1 * G + u2 * Q, if R is infinity, return invalid var u1TimesG = domainParameters.CurveE.Multiply(domainParameters.CurveE.BasePointG, u1); var u2TimesQ = domainParameters.CurveE.Multiply(keyPair.PublicQ, u2); var pointR = domainParameters.CurveE.Add(u1TimesG, u2TimesQ); // Convert xR to an integer j var j = pointR.X; // Compute v = j (mod n) var v = j % domainParameters.CurveE.OrderN; // If v == r, return valid, otherwise invalid if (v == signature.R) { return(new EccVerificationResult()); } else { return(new EccVerificationResult("v did not match r, signature not valid")); } }
public SharedSecretResponse GenerateSharedSecret(EccDomainParameters domainParameters, EccKeyPair privateKeyPartyA, EccKeyPair publicKeyPartyB) { return(_diffieHellman.GenerateSharedSecretZ(domainParameters, privateKeyPartyA, publicKeyPartyB)); }