private async Task VerifyProofToAssociatedAttributeKnowledge(RootIssuer rootIssuer, string schemeName) { AttributeProofs attr = rootIssuer.IssuersAttributes?.FirstOrDefault(a => a.Issuer.Equals(rootIssuer.Issuer))?.Attributes.FirstOrDefault(a => a.SchemeName == schemeName); if (attr == null) { throw new AssociatedAttrProofsAreMissingException(schemeName); } if (attr.CommitmentProof.SurjectionProof.AssetCommitments.Length != attr.BindingProof.AssetCommitments.Length) { throw new AssociatedAttrProofsMalformedException(schemeName); } if (!ConfidentialAssetsHelper.VerifySurjectionProof(attr.CommitmentProof.SurjectionProof, attr.Commitment.ArraySegment.Array)) { throw new AssociatedAttrProofToValueKnowledgeIncorrectException(schemeName); } IKey commitmentKey = rootIssuer.IssuersAttributes.FirstOrDefault(a => a.Issuer.Equals(rootIssuer.Issuer))?.RootAttribute.Commitment; byte[] commitment = ConfidentialAssetsHelper.SumCommitments(commitmentKey.Value.Span, attr.Commitment.Value.Span); if (!ConfidentialAssetsHelper.VerifySurjectionProof(attr.BindingProof, commitment)) { throw new AssociatedAttrProofToBindingIncorrectException(schemeName); } (Memory <byte> issuanceCommitment, Memory <byte> commitmentToRoot)[] attrs = new (Memory <byte>, Memory <byte>)[attr.BindingProof.AssetCommitments.Length];
private async Task ProcessUniversalTransport(UniversalTransport universalTransport) { TaskCompletionSource <UniversalProofs> universalProofsTask = _universalProofsPool.Extract(universalTransport.KeyImage); try { UniversalProofs universalProofs = await universalProofsTask.Task.ConfigureAwait(false); var mainIssuer = universalProofs.RootIssuers.Find(i => i.Issuer.Equals(universalProofs.MainIssuer)); IKey commitmentKey = mainIssuer.IssuersAttributes.FirstOrDefault(a => a.Issuer.Equals(mainIssuer.Issuer))?.RootAttribute.Commitment; SurjectionProof eligibilityProof = mainIssuer.IssuersAttributes.FirstOrDefault(a => a.Issuer.Equals(mainIssuer.Issuer))?.RootAttribute.BindingProof; bool isEligibilityCorrect = await CheckEligibilityProofs(commitmentKey.Value, eligibilityProof, mainIssuer.Issuer.Value).ConfigureAwait(false); if (!isEligibilityCorrect && !string.IsNullOrEmpty(universalProofs.SessionKey)) { await _idenitiesHubContext.Clients.Group(universalProofs.SessionKey).SendAsync("EligibilityCheckFailed").ConfigureAwait(false); return; } try { RootIssuer rootIssuer = universalProofs.RootIssuers .Find( i => i.IssuersAttributes.Any( a => a.Attributes.Any( a1 => a1.SchemeName == AttributesSchemes.ATTR_SCHEME_NAME_PASSWORD))); await VerifyProofToAssociatedAttributeKnowledge(rootIssuer, AttributesSchemes.ATTR_SCHEME_NAME_PASSWORD).ConfigureAwait(false); } catch (Exception ex) { string msg = ex.Message; if (ex is AggregateException aex) { if (aex.InnerException is FlurlHttpException fex) { _logger.Error($"[{_accountId}]: Failed request '{fex.Call.Request.RequestUri}' with body '{fex.Call.RequestBody}'"); } msg = aex.InnerException.Message; _logger.Error($"[{_accountId}]: Failure at {nameof(ProcessUniversalTransport)}", aex.InnerException); } else { _logger.Error($"[{_accountId}]: Failure at {nameof(ProcessUniversalTransport)}", ex); } await _idenitiesHubContext.Clients.Group(universalProofs.SessionKey).SendAsync("ProtectionCheckFailed", msg).ConfigureAwait(false); return; } switch (universalProofs.Mission) { case UniversalProofsMission.Authentication: await ProcessUniversalProofsAuthentication( universalProofs.RootIssuers.Find(i => i.Issuer.Equals(universalProofs.MainIssuer)), universalProofs.SessionKey, universalProofs.KeyImage).ConfigureAwait(false); break; case UniversalProofsMission.Vote: ProcessVote(universalProofs); break; default: break; } } catch (TimeoutException) { _logger.Error($"[{_accountId}]: Timeout during obtaining {nameof(UniversalProofs)} for key image {universalTransport.KeyImage}"); } }