public void Should_ProveTheProofOfSuccess_For_SpecifiedListOfParameters() { var phe = new PheCrypto(); var skS = phe.DecodeSecretKey(Bytes.FromString("I4ETKFzr3QmUu+Olhp1L2KvRgjfseO530R/A+aQ80Go=", StringEncoding.BASE64)); var c0 = Bytes.FromString("BKAH5Rww+a9+8lzO3oYE8zfz2Oxp3+Xrv2jp9EFGRlS7bWU5iYoWQHZqrkM+UYq2TYON3Gz8w3mzLSy3yS0XlJw=", StringEncoding.BASE64); var c1 = Bytes.FromString("BOkgpxdavc+CYqmeKboBPhEjgXCEKbb5HxFeJ1+rVoOm006Jbu5a/Ol4rK5bVbkhzGAT+gUZaodUsnEuucfIbJc=", StringEncoding.BASE64); var proof = new ProofOfSuccess { Term1 = Bytes.FromString("BJkkIassffljoINliNRNcR7J/PmYcAl9PPUBeIT2I6oBy6wKb5gZsIOchWEN5pNfLVPH1V0BuhhlTi7MZeBlPOY=", StringEncoding.BASE64), Term2 = Bytes.FromString("BIiZfmmzuffwmJmibNnpws9D5SkgkPMBYxbgaWS1274kbJKC7WakUp1Mzk9BWvah0kDomJhqzyV7/8ZBX1rGX9I=", StringEncoding.BASE64), Term3 = Bytes.FromString("BCBcx9GsjQcoKI0pW4t49WWS/Z1bmg62KlCjAzB1IsKVDYQAT4213UuIMBthNnxSOVUUHikZCUw01mX5XKGQD5A=", StringEncoding.BASE64), BlindX = Bytes.FromString("KFiLnVVliWdm3fdYcuFK1sTiw1hvbKSesy4sGlYO8Rs=", StringEncoding.BASE64) }; var skC = phe.DecodeSecretKey(Bytes.FromString("gPdKsQRz9Vmc/DnbfxCHUioU6omEa0Sg7pncSHOhA7I=", StringEncoding.BASE64)); var nS = Bytes.FromString("POKVRG0nmZc9062v41TNFngibsgMKzt/BY6lZ/5pcZg=", StringEncoding.BASE64); var pkS = phe.ExtractPublicKey(skS); var isValid = phe.ValidateProofOfSuccess(proof, pkS, nS, c0, c1); Assert.True(isValid); }
/// <summary> /// Validates the proof of success. /// </summary> internal bool ValidateProofOfSuccess(ProofOfSuccess proof, PublicKey pkS, byte[] nS, byte[] c0, byte[] c1) { Validation.NotNull(proof); Validation.NotNull(pkS); Validation.NotNullOrEmptyByteArray(nS); Validation.NotNullOrEmptyByteArray(c0); Validation.NotNullOrEmptyByteArray(c1); var term1 = proof.Term1.ToByteArray(); var term2 = proof.Term2.ToByteArray(); var term3 = proof.Term3.ToByteArray(); var trm1Point = this.Curve.DecodePoint(term1); var trm2Point = this.Curve.DecodePoint(term2); var trm3Point = this.Curve.DecodePoint(term3); var blindXInt = new BigInteger(1, proof.BlindX.ToByteArray()); var c0Point = this.Curve.DecodePoint(c0); var c1Point = this.Curve.DecodePoint(c1); var hs0Point = this.HashToPoint(Domains.Dhs0, nS); var hs1Point = this.HashToPoint(Domains.Dhs1, nS); var challenge = this.HashZ( Domains.ProofOK, pkS.Encode(), this.CurveG.GetEncoded(), c0, c1, term1, term2, term3); var t1Point = trm1Point.Add(c0Point.Multiply(challenge)); var t2Point = hs0Point.Multiply(blindXInt); if (!t1Point.Equals(t2Point)) { return(false); } t1Point = trm2Point.Add(c1Point.Multiply(challenge)); t2Point = hs1Point.Multiply(blindXInt); if (!t1Point.Equals(t2Point)) { return(false); } t1Point = trm3Point.Add(pkS.Point.Multiply(challenge)); t2Point = this.curveParams.G.Multiply(blindXInt); if (!t1Point.Equals(t2Point)) { return(false); } return(true); }
private void ValidateProofOfSuccess(ProofOfSuccess proofOfSuccess, byte[] ns, byte[] c0, byte[] c1) { if (proofOfSuccess == null) { throw new ProofNotProvidedException(); } var isValid = this.Crypto.ValidateProofOfSuccess( proofOfSuccess, this.ServicePublicKey, ns, c0, c1); if (!isValid) { throw new ProofOfSuccessNotValidException(); } }
/// <summary> /// Verifies a <see cref="PasswordRecord"/> by specified password. /// </summary> public async Task <VerificationResult> VerifyAsync(PasswordRecord pwdRecord, string password) { var pwdBytes = Bytes.FromString(password); var skC = this.ctx.GetClientSecretKeyForVersion(pwdRecord.Version); var pkS = this.ctx.GetServerPublicKeyForVersion(pwdRecord.Version); var c0 = this.ctx.Crypto.ComputeC0(skC, pwdBytes, pwdRecord.ClientNonce, pwdRecord.RecordT0); var parameters = new VerificationRequestModel { AppId = this.ctx.AppId, Version = pwdRecord.Version, Verification = new VerificationModel { C0 = c0, Ns = pwdRecord.ServerNonce } }; byte[] m = null; var serverResult = await this.ctx.Client.VerifyAsync(parameters).ConfigureAwait(false); if (serverResult.IsSuccess) { var proofModel = serverResult.ProofOfSuccess ?? throw new ProofNotProvidedException(); var proof = new ProofOfSuccess { Term1 = proofModel.Term1, Term2 = proofModel.Term2, Term3 = proofModel.Term3, BlindX = proofModel.BlindX, }; var isValid = this.ctx.Crypto.ValidateProofOfSuccess(proof, pkS, pwdRecord.ServerNonce, c0, serverResult.C1); if (!isValid) { throw new ProofOfSuccessNotValidException(); } m = this.ctx.Crypto.DecryptM(skC, pwdBytes, pwdRecord.ClientNonce, pwdRecord.RecordT1, serverResult.C1); } else { var proofModel = serverResult.ProofOfFail ?? throw new ProofNotProvidedException(); var proof = new ProofOfFail { Term1 = proofModel.Term1, Term2 = proofModel.Term2, Term3 = proofModel.Term3, Term4 = proofModel.Term4, BlindA = proofModel.BlindA, BlindB = proofModel.BlindB, }; var isValid = this.ctx.Crypto.ValidateProofOfFail(proof, pkS, pwdRecord.ServerNonce, c0, serverResult.C1); if (!isValid) { throw new ProofOfFailNotValidException(); } } var result = new VerificationResult { IsSuccess = serverResult.IsSuccess, Key = m }; return(result); }