private void ProcessDocumentSignRequest(DocumentSignRequest packet) { _clientCryptoService.DecodeEcdhTuple(packet.EcdhTuple, packet.TransactionPublicKey, out byte[] groupNameBlindingFactor, out byte[] documentHash, out byte[] issuer, out byte[] payload); string sessionKey = payload.ToHexString(); SpDocument spDocument = _dataAccessService.GetSpDocument(_accountId, documentHash.ToHexString()); if (spDocument == null) { _idenitiesHubContext.Clients.Group(sessionKey).SendAsync("PushDocumentNotFound"); } bool isEligibilityCorrect = CheckEligibilityProofs(packet.AssetCommitment, packet.EligibilityProof, issuer); if (!isEligibilityCorrect) { _idenitiesHubContext.Clients.Group(sessionKey).SendAsync("PushDocumentSignIncorrect", new { Code = 2, Message = "Eligibility proofs were wrong" }).Wait(); return; } if (!ConfidentialAssetsHelper.VerifySurjectionProof(packet.SignerGroupRelationProof, packet.AssetCommitment, documentHash, BitConverter.GetBytes(spDocument.LastChangeRecordHeight))) { _idenitiesHubContext.Clients.Group(sessionKey).SendAsync("PushDocumentSignIncorrect", new { Code = 2, Message = "Signer group relation proofs were wrong" }).Wait(); return; } SurjectionProof signatureGroupProof = null; string groupIssuer = null; foreach (var allowedSigner in spDocument.AllowedSigners) { byte[] groupAssetId = _assetsService.GenerateAssetId(AttributeType.EmployeeGroup, allowedSigner.GroupIssuer + allowedSigner.GroupName); byte[] expectedGroupCommitment = ConfidentialAssetsHelper.GetAssetCommitment(groupAssetId, groupNameBlindingFactor); if (packet.AllowedGroupCommitment.Equals32(expectedGroupCommitment)) { byte[] groupCommitment = _gatewayService.GetEmployeeRecordGroup(allowedSigner.GroupIssuer.HexStringToByteArray(), packet.SignerGroupRelationProof.AssetCommitments[0]); if (groupCommitment != null && ConfidentialAssetsHelper.VerifySurjectionProof(packet.AllowedGroupNameSurjectionProof, packet.AllowedGroupCommitment)) { byte[] diffBF = ConfidentialAssetsHelper.GetDifferentialBlindingFactor(groupNameBlindingFactor, allowedSigner.BlindingFactor.HexStringToByteArray()); byte[][] commitments = spDocument.AllowedSigners.Select(s => s.GroupCommitment.HexStringToByteArray()).ToArray(); byte[] allowedGroupCommitment = allowedSigner.GroupCommitment.HexStringToByteArray(); int index = 0; for (; index < commitments.Length; index++) { if (commitments[index].Equals32(allowedGroupCommitment)) { break; } } signatureGroupProof = ConfidentialAssetsHelper.CreateSurjectionProof(packet.AllowedGroupCommitment, commitments, index, diffBF); groupIssuer = allowedSigner.GroupIssuer; break; } } } if (signatureGroupProof == null) { _idenitiesHubContext.Clients.Group(sessionKey).SendAsync("PushDocumentSignIncorrect", new { Code = 2, Message = "Signer group relation proofs were wrong" }).Wait(); return; } _transactionsService.IssueDocumentSignRecord(documentHash, spDocument.LastChangeRecordHeight, packet.AssetCommitment, packet.SignerGroupRelationProof, packet.AllowedGroupCommitment, groupIssuer.HexStringToByteArray(), packet.AllowedGroupNameSurjectionProof, signatureGroupProof, out ulong signatureRecordHeight); ulong signatureId = _dataAccessService.AddSpDocumentSignature(_accountId, spDocument.SpDocumentId, spDocument.LastChangeRecordHeight, signatureRecordHeight); _idenitiesHubContext.Clients.Group(_accountId.ToString(CultureInfo.InvariantCulture)) .SendAsync("PushDocumentSignature", new DocumentSignatureDto { DocumentId = spDocument.SpDocumentId, DocumentHash = spDocument.Hash, DocumentRecordHeight = spDocument.LastChangeRecordHeight, SignatureRecordHeight = signatureRecordHeight }); _idenitiesHubContext.Clients.Group(sessionKey) .SendAsync("PushDocumentSignature", new DocumentSignatureDto { DocumentId = spDocument.SpDocumentId, DocumentHash = spDocument.Hash, DocumentRecordHeight = spDocument.LastChangeRecordHeight, SignatureRecordHeight = signatureRecordHeight }); }