public FfcVerificationResult Verify(FfcDomainParameters domainParameters, FfcKeyPair keyPair, BitString message, FfcSignature signature, bool skipHash = false) { // 1 if (signature.R < 0 || signature.R > domainParameters.Q) { return(new FfcVerificationResult("Invalid r provided")); } if (signature.S < 0 || signature.S > domainParameters.Q) { return(new FfcVerificationResult("Invalid s provided")); } // 2 var w = signature.S.ModularInverse(domainParameters.Q); var zLen = System.Math.Min(Sha.HashFunction.OutputLen, new BitString(domainParameters.Q).BitLength); var z = BitString.MSBSubstring(Sha.HashMessage(message).Digest, 0, zLen).ToPositiveBigInteger(); var u1 = (z * w) % domainParameters.Q; var u2 = (signature.R * w) % domainParameters.Q; // (g^u1 * y^u2) mod p == [(g^u1 mod p) * (y^u2 mod p)] mod p var v = ((BigInteger.ModPow(domainParameters.G, u1, domainParameters.P) * BigInteger.ModPow(keyPair.PublicKeyY, u2, domainParameters.P)) % domainParameters.P) % domainParameters.Q; // 3 if (v != signature.R) { return(new FfcVerificationResult("Invalid v, does not match provided r")); } return(new FfcVerificationResult()); }
public void Setup() { _sha = new Mock <ISha>(); _shaFactory = new Mock <IShaFactory>(); _dsa = new Mock <IDsaFfc>(); _dsaFactory = new Mock <IDsaFfcFactory>(); _kdfFactory = new Mock <IKdfOneStepFactory>(); _keyConfirmationFactory = new Mock <IKeyConfirmationFactory>(); _noKeyConfirmationFactory = new Mock <INoKeyConfirmationFactory>(); _otherInfoFactory = new Mock <IOtherInfoFactory>(); _entropyProvider = new Mock <IEntropyProvider>(); _diffieHellmanFfc = new Mock <IDiffieHellman <FfcDomainParameters, FfcKeyPair> >(); _mqv = new Mock <IMqv <FfcDomainParameters, FfcKeyPair> >(); _subject = new SchemeBuilderFfc( _dsaFactory.Object, _kdfFactory.Object, _keyConfirmationFactory.Object, _noKeyConfirmationFactory.Object, _otherInfoFactory.Object, _entropyProvider.Object, _diffieHellmanFfc.Object, _mqv.Object ); _mockDomainParameters = new FfcDomainParameters(1, 2, 3); _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 <FfcDomainParametersGenerateRequest>())) .Returns( new FfcDomainParametersGenerateResult( _mockDomainParameters, new DomainSeed(0, 1, 2), new Counter(0) ) ); _dsa .Setup(s => s.GenerateKeyPair(It.IsAny <FfcDomainParameters>())) .Returns(new FfcKeyPairGenerateResult(new FfcKeyPair(1, 2))); _dsaFactory .Setup(s => s.GetInstance(It.IsAny <HashFunction>(), It.IsAny <EntropyProviderTypes>())) .Returns(_dsa.Object); }
public FfcKeyPairValidateResult ValidateKeyPair(FfcDomainParameters domainParameters, FfcKeyPair keyPair) { if (keyPair.PrivateKeyX <= 0 || keyPair.PrivateKeyX >= domainParameters.Q) { return(new FfcKeyPairValidateResult("Invalid key pair, x must satisfy 0 < x < q")); } if (keyPair.PublicKeyY == BigInteger.ModPow(domainParameters.G, keyPair.PrivateKeyX, domainParameters.P)) { return(new FfcKeyPairValidateResult()); } else { return(new FfcKeyPairValidateResult("Invalid key pair, y != g^x mod p")); } }
/// <summary> /// B.1.1 from FIPS 186-4. This is equivalent to B.1.2, the other KeyGeneration method. /// </summary> /// <param name="domainParameters"></param> /// <returns></returns> public FfcKeyPairGenerateResult GenerateKeyPair(FfcDomainParameters domainParameters) { var L = new BitString(domainParameters.P).BitLength; var N = new BitString(domainParameters.Q).BitLength; // Shouldn't really be necessary but just in case if (!DSAHelper.VerifyLenPair(L, N)) { return(new FfcKeyPairGenerateResult("Invalid L, N pair")); } var rand = new Random800_90(); var c = rand.GetRandomBitString(N + 64).ToPositiveBigInteger(); var x = (c % (domainParameters.Q - 1)) + 1; var y = BigInteger.ModPow(domainParameters.G, x, domainParameters.P); return(new FfcKeyPairGenerateResult(new FfcKeyPair(x, y))); }
public FfcSignatureResult Sign(FfcDomainParameters domainParameters, FfcKeyPair keyPair, BitString message, bool skipHash = false) { BigInteger r, s; do { var k = _entropyProvider.GetEntropy(1, domainParameters.Q - 1); var kInv = k.ModularInverse(domainParameters.Q); r = BigInteger.ModPow(domainParameters.G, k, domainParameters.P) % domainParameters.Q; var zLen = System.Math.Min(Sha.HashFunction.OutputLen, new BitString(domainParameters.Q).BitLength); var z = BitString.MSBSubstring(Sha.HashMessage(message).Digest, 0, zLen).ToPositiveBigInteger(); s = (kInv * (z + keyPair.PrivateKeyX * r)) % domainParameters.Q; } while (r == 0 || s == 0); return(new FfcSignatureResult(new FfcSignature(r, s))); }
public void ShouldCalculateCorrectSharedSecret( string label, BigInteger xPrivateKeyPartyA, BigInteger yPublicKeyPartyB, BigInteger p, BigInteger expectedSharedZ ) { FfcDomainParameters domainParameters = new FfcDomainParameters(p, 0, 0); var result = _subject.GenerateSharedSecretZ( domainParameters, new FfcKeyPair(xPrivateKeyPartyA, 0), new FfcKeyPair(yPublicKeyPartyB) ); Assert.That(result.Success, $"{nameof(result)} should have been successful"); Assert.AreEqual(expectedSharedZ, result.SharedSecretZ.ToPositiveBigInteger(), nameof(expectedSharedZ)); }
public void ShouldUseOverriddenImplementationOfDependencies() { FfcDomainParameters newDomainParameters = new FfcDomainParameters(42, 43, 44); _dsa .Setup(s => s.Sha) .Returns(_sha.Object); _dsa .Setup(s => s.GenerateDomainParameters(It.IsAny <FfcDomainParametersGenerateRequest>())) .Returns( new FfcDomainParametersGenerateResult( newDomainParameters, new DomainSeed(0, 1, 2), new Counter(0) ) ); _dsa .Setup(s => s.GenerateKeyPair(It.IsAny <FfcDomainParameters>())) .Returns(new FfcKeyPairGenerateResult(new FfcKeyPair(1, 2))); var scheme = _subject .WithHashFunction(new HashFunction(ModeValues.SHA2, DigestSizes.d256)) .BuildScheme( new SchemeParametersFfc( new KasDsaAlgoAttributesFfc(FfcScheme.DhEphem, FfcParameterSet.Fb), KeyAgreementRole.InitiatorPartyU, KasMode.NoKdfNoKc, KeyConfirmationRole.None, KeyConfirmationDirection.None, KasAssurance.None, new BitString(1) ), null, null ); var result = scheme.ReturnPublicInfoThisParty(); Assert.AreEqual(newDomainParameters.P, result.DomainParameters.P, nameof(newDomainParameters.P)); Assert.AreEqual(newDomainParameters.Q, result.DomainParameters.Q, nameof(newDomainParameters.Q)); Assert.AreEqual(newDomainParameters.G, result.DomainParameters.G, nameof(newDomainParameters.G)); }
public FfcDomainParametersGenerateResult GenerateDomainParameters(FfcDomainParametersGenerateRequest generateRequest) { // Generate p and q var pqGenerator = _pqGeneratorFactory.GetGeneratorValidator(generateRequest.PrimeGen, Sha); var pqResult = pqGenerator.Generate(generateRequest.PLength, generateRequest.QLength, generateRequest.SeedLength); if (!pqResult.Success) { return(new FfcDomainParametersGenerateResult($"Failed to generate p and q with error: {pqResult.ErrorMessage}")); } // Generate g var gGenerator = _gGeneratorFactory.GetGeneratorValidator(generateRequest.GeneratorGen, Sha); var gResult = gGenerator.Generate(pqResult.P, pqResult.Q, pqResult.Seed, generateRequest.Index); if (!gResult.Success) { return(new FfcDomainParametersGenerateResult($"Failed to generate g with error: {gResult.ErrorMessage}")); } var domainParameters = new FfcDomainParameters(pqResult.P, pqResult.Q, gResult.G); return(new FfcDomainParametersGenerateResult(domainParameters, pqResult.Seed, pqResult.Count)); }
public FfcDomainParametersGenerateResult(FfcDomainParameters pqgDomainParameters, DomainSeed seed, Counter count) { PqgDomainParameters = pqgDomainParameters; Seed = seed; Count = count; }