/// <inheritdoc /> public virtual async Task <string> ProcessProofAsync(Wallet wallet, ProofMessage proof) { var(didOrKey, _) = MessageUtils.ParseMessageType(proof.Type); var connectionSearch = await ConnectionService.ListAsync(wallet, new SearchRecordQuery { { TagConstants.MyDid, didOrKey } }); if (!connectionSearch.Any()) { throw new Exception($"Can't find connection record for type {proof.Type}"); } var connection = connectionSearch.First(); var(requestDetails, _) = await MessageSerializer.UnpackSealedAsync <ProofDetails>( proof.Content, wallet, connection.MyVk); var proofJson = requestDetails.ProofJson; var proofRecordSearch = await RecordService.SearchAsync <ProofRecord>(wallet, new SearchRecordQuery { { TagConstants.Nonce, requestDetails.RequestNonce } }, null, 1); if (!proofRecordSearch.Any()) { throw new Exception($"Can't find proof record"); } var proofRecord = proofRecordSearch.Single(); proofRecord.ProofJson = proofJson; await proofRecord.TriggerAsync(ProofTrigger.Accept); await RecordService.UpdateAsync(wallet, proofRecord); return(proofRecord.GetId()); }
public void Test_output_ser_deser() { var keychain = Keychain.From_random_seed(); var keyIdSet = keychain.Derive_key_id(1); var commit = keychain.Commit(5, keyIdSet); var switchCommit = keychain.Switch_commit(keyIdSet); var switchCommitHash = SwitchCommitHash.From_switch_commit(switchCommit); var msg = ProofMessage.Empty(); var proof = keychain.Range_proof(5, keyIdSet, commit, msg); var outp = new Output { Features = OutputFeatures.DefaultOutput, Commit = commit, SwitchCommitHash = switchCommitHash, Proof = proof }; var stream = new MemoryStream(); Ser.Serialize(stream, outp); Console.WriteLine("-------"); Console.WriteLine(stream.ToArray().AsString()); Console.WriteLine("-------"); stream.Position = 0; var dout = Ser.Deserialize(stream, new Output()); Assert.Equal(OutputFeatures.DefaultOutput, dout.Features); Assert.Equal(outp.Commit.Value, dout.Commit.Value); Assert.Equal(outp.Proof.Proof, dout.Proof.Proof); }
/// Adds an output with the provided value and key identifier from the /// keychain. public static Append Output(this Context build, ulong value, Identifier keyId) { var commit = build.Keychain.Commit(value, keyId); var switchCommit = build.Keychain.Switch_commit(keyId); var switchCommitHash = SwitchCommitHash.From_switch_commit(switchCommit); Log.Verbose( "Builder - Pedersen Commit is: {commit}, Switch Commit is: {switch_commit}", commit, switchCommit ); Log.Verbose( "Builder - Switch Commit Hash is: {switch_commit_hash}", switchCommitHash ); var msg = ProofMessage.Empty(); var rproof = build.Keychain.Range_proof(value, keyId, commit, msg); return(new Append( build.Tx.with_output(new Output { Features = OutputFeatures.DefaultOutput, Commit = commit, SwitchCommitHash = switchCommitHash, Proof = rproof }) , build.Sum.add_key_id(keyId.Clone()))); }
public void Test_output_value_recovery() { var keychain = Keychain.From_random_seed(); var keyId = keychain.Derive_key_id(1); var commit = keychain.Commit(1003, keyId); var switchCommit = keychain.Switch_commit(keyId); var switchCommitHash = SwitchCommitHash.From_switch_commit(switchCommit); var msg = ProofMessage.Empty(); var proof = keychain.Range_proof(1003, keyId, commit, msg); var output = new Output { Features = OutputFeatures.DefaultOutput, Commit = commit, SwitchCommitHash = switchCommitHash, Proof = proof }; // check we can successfully recover the value with the original blinding factor var recoveredValue = output.Recover_value(keychain, keyId); Assert.Equal <ulong?>(1003, recoveredValue); // check we cannot recover the value without the original blinding factor var keyId2 = keychain.Derive_key_id(2); var notRecoverable = output.Recover_value(keychain, keyId2); Assert.Null(notRecoverable); }
/// <inheritdoc /> public virtual async Task <(ProofMessage, ProofRecord)> CreateProofAsync(IAgentContext agentContext, string proofRequestId, RequestedCredentials requestedCredentials) { var record = await GetAsync(agentContext, proofRequestId); if (record.State != ProofState.Requested) { throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, $"Proof state was invalid. Expected '{ProofState.Requested}', found '{record.State}'"); } var provisioningRecord = await ProvisioningService.GetProvisioningAsync(agentContext.Wallet); var credentialObjects = new List <CredentialInfo>(); foreach (var credId in requestedCredentials.GetCredentialIdentifiers()) { credentialObjects.Add( JsonConvert.DeserializeObject <CredentialInfo>( await AnonCreds.ProverGetCredentialAsync(agentContext.Wallet, credId))); } var schemas = await BuildSchemasAsync(await agentContext.Pool, credentialObjects .Select(x => x.SchemaId) .Distinct()); var definitions = await BuildCredentialDefinitionsAsync(await agentContext.Pool, credentialObjects .Select(x => x.CredentialDefinitionId) .Distinct()); var revocationStates = await BuildRevocationStatesAsync(await agentContext.Pool, credentialObjects, requestedCredentials); var proofJson = await AnonCreds.ProverCreateProofAsync(agentContext.Wallet, record.RequestJson, requestedCredentials.ToJson(), provisioningRecord.MasterSecretId, schemas, definitions, revocationStates); record.ProofJson = proofJson; await record.TriggerAsync(ProofTrigger.Accept); await RecordService.UpdateAsync(agentContext.Wallet, record); var threadId = record.GetTag(TagConstants.LastThreadId); var proofMsg = new ProofMessage { ProofJson = proofJson }; proofMsg.ThreadFrom(threadId); return(proofMsg, record); }
public static (Output, TxKernel) Reward_output(Keychain keychain, Identifier keyId, ulong fees) { var secp = keychain.Secp; var commit = keychain.Commit(Consensus.Reward(fees), keyId); var switchCommit = keychain.Switch_commit(keyId); var switchCommitHash = SwitchCommitHash.From_switch_commit(switchCommit); Log.Verbose( "Block reward - Pedersen Commit is: {commit}, Switch Commit is: {switch_commit}", commit, switchCommit ); Log.Verbose( "Block reward - Switch Commit Hash is: { switch_commit_hash}", switchCommitHash ); var msg = ProofMessage.Empty(); var rproof = keychain.Range_proof(Consensus.Reward(fees), keyId, commit, msg); var output = new Output { Features = OutputFeatures.CoinbaseOutput, Commit = commit, SwitchCommitHash = switchCommitHash, Proof = rproof }; var overCommit = secp.commit_value(Consensus.Reward(fees)); var outCommit = output.Commit; var excess = secp.commit_sum(new[] { outCommit }, new[] { overCommit }); var msg2 = Message.from_slice(new byte[Constants.MessageSize]); var sig = keychain.Sign(msg2, keyId); var proof = new TxKernel { Features = KernelFeatures.CoinbaseKernel, Excess = excess, ExcessSig = sig.serialize_der(secp), Fee = 0, LockHeight = 0 }; return(output, proof); }
/// <inheritdoc /> public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var item = JObject.Load(reader); var(_, messageType) = MessageUtils.ParseMessageType(item["@type"].ToObject <string>()); IContentMessage message; switch (messageType) { case MessageTypes.ConnectionRequest: message = new ConnectionRequestMessage(); break; case MessageTypes.ConnectionResponse: message = new ConnectionResponseMessage(); break; case MessageTypes.CredentialOffer: message = new CredentialOfferMessage(); break; case MessageTypes.CredentialRequest: message = new CredentialRequestMessage(); break; case MessageTypes.Credential: message = new CredentialMessage(); break; case MessageTypes.ProofRequest: message = new ProofRequestMessage(); break; case MessageTypes.DisclosedProof: message = new ProofMessage(); break; default: throw new TypeLoadException("Unsupported serialization type."); } serializer.Populate(item.CreateReader(), message); return(message); }
public void Test_rewind_range_proof() { var keychain = Keychain.From_random_seed(); var keyId = keychain.Derive_key_id(1); var commit = keychain.Commit(5, keyId); var msg = ProofMessage.Empty(); var proof = keychain.Range_proof(5, keyId, commit, msg); var proofInfo = keychain.Rewind_range_proof(keyId, commit, proof); Assert.True(proofInfo.Success); Assert.Equal <ulong>(5, proofInfo.Value); var pm1 = proofInfo.Message; var pm2 = ProofMessage.from_bytes(new byte[Constants.ProofMsgSize]); // now check the recovered message is "empty" (but not truncated) i.e. all zeroes Assert.Equal(pm1.Value, pm2.Value); var keyId2 = keychain.Derive_key_id(2); // cannot rewind with a different nonce proofInfo = keychain.Rewind_range_proof(keyId2, commit, proof); Assert.False(proofInfo.Success); Assert.Equal <ulong>(0, proofInfo.Value); // cannot rewind with a commitment to the same value using a different key var commit2 = keychain.Commit(5, keyId2); proofInfo = keychain.Rewind_range_proof(keyId, commit2, proof); Assert.False(proofInfo.Success); Assert.Equal <ulong>(0, proofInfo.Value); // cannot rewind with a commitment to a different value var commit3 = keychain.Commit(4, keyId); proofInfo = keychain.Rewind_range_proof(keyId, commit3, proof); Assert.False(proofInfo.Success); Assert.Equal <ulong>(0, proofInfo.Value); }
public void Test_range_proof() { var secp = Secp256K1.WithCaps(ContextFlag.Commit); var blinding = SecretKey.New(secp, RandomNumberGenerator.Create()); var commit = secp.Commit(7, blinding); var msg = ProofMessage.Empty(); var rangeProof = secp.range_proof(0, 7, blinding, commit, msg.Clone()); var proofRange = secp.verify_range_proof(commit, rangeProof); Assert.Equal <ulong>(0, proofRange.Min); var proofInfo = secp.range_proof_info(rangeProof); Assert.True(proofInfo.Success); Assert.Equal <ulong>(0, proofInfo.Min); //// check we get no information back for the value here Assert.Equal <ulong>(0, proofInfo.Value); proofInfo = secp.rewind_range_proof(commit, rangeProof, blinding); Assert.True(proofInfo.Success); Assert.Equal <ulong>(0, proofInfo.Min); Assert.Equal <ulong>(7, proofInfo.Value); //// check we cannot rewind a range proof without the original nonce var badNonce = SecretKey.New(secp, RandomNumberGenerator.Create()); var badInfo = secp.rewind_range_proof(commit, rangeProof, badNonce); Assert.False(badInfo.Success); Assert.Equal <ulong>(0, badInfo.Value); //// check we can construct and verify a range proof on value 0 commit = secp.Commit(0, blinding); rangeProof = secp.range_proof(0, 0, blinding, commit, msg); secp.verify_range_proof(commit, rangeProof); proofInfo = secp.rewind_range_proof(commit, rangeProof, blinding.Clone()); Assert.True(proofInfo.Success); Assert.Equal <ulong>(0, proofInfo.Min); Assert.Equal <ulong>(0, proofInfo.Value); }
/// <summary> /// Metodo per la generazione della ricevuta di avvenuta consegna /// </summary> /// <param name="interoperabilityMessage">Messaggio per cui generare la ricevuta</param> /// <param name="messageId">Id del messaggio ricevuto</param> /// <param name="receiver">Destinatario raggiunto</param> public static void GenerateProof(Interoperability.Domain.InteroperabilityMessage interoperabilityMessage, String messageId, ReceiverInfo receiver, InfoDocumentDelivered documentDelivered) { // Inizializzazione della ricevuta SuccessfullyDeliveredGenerator proof = new SuccessfullyDeliveredGenerator( interoperabilityMessage.Record.Subject, documentDelivered); // Generazione ricevuta ProofMessage message = proof.GenerateProof( interoperabilityMessage.Sender.Code, receiver.Code, messageId); AddProofToDocument( interoperabilityMessage.MainDocument.DocumentNumber, messageId, message.ProofContent, message.ProofDate, message.Receiver); // PEC 4 Modifica Maschera Caratteri InteroperabilitaSemplificataManager.AggiornaStatusMask("ANVAAAN", receiver.AOOCode, receiver.AdministrationCode, interoperabilityMessage.MainDocument.DocumentNumber); }
/// <inheritdoc /> public virtual async Task <(ProofMessage, ConnectionRecord)> CreateProofAsync(IAgentContext agentContext, string proofRequestId, RequestedCredentials requestedCredentials) { var record = await GetAsync(agentContext, proofRequestId); var connection = await ConnectionService.GetAsync(agentContext, record.ConnectionId); if (record.State != ProofState.Requested) { throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, $"Proof state was invalid. Expected '{ProofState.Requested}', found '{record.State}'"); } var proofJson = await CreateProofJsonAsync(agentContext, requestedCredentials, record.RequestJson); if (proofJson.Contains("\"rev_reg_id\":null")) { String[] separator = { "\"rev_reg_id\":null" }; String[] proofJsonList = proofJson.Split(separator, StringSplitOptions.None); proofJson = proofJsonList[0] + "\"rev_reg_id\":null,\"timestamp\":null}]}"; } record.ProofJson = proofJson; await record.TriggerAsync(ProofTrigger.Accept); await RecordService.UpdateAsync(agentContext.Wallet, record); var threadId = record.GetTag(TagConstants.LastThreadId); var proofMsg = new ProofMessage { ProofJson = proofJson }; proofMsg.ThreadFrom(threadId); return(proofMsg, connection); }
/// <inheritdoc /> public virtual async Task <string> ProcessProofAsync(IAgentContext agentContext, ProofMessage proof) { var proofJson = proof.ProofJson; var proofRecordSearch = await RecordService.SearchAsync <ProofRecord>(agentContext.Wallet, SearchQuery.Equal(TagConstants.Nonce, proof.RequestNonce), null, 1); var proofRecord = proofRecordSearch.FirstOrDefault() ?? throw new AgentFrameworkException(ErrorCode.RecordNotFound, "Proof record not found"); if (proofRecord.State != ProofState.Requested) { throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, $"Proof state was invalid. Expected '{ProofState.Requested}', found '{proofRecord.State}'"); } proofRecord.ProofJson = proofJson; await proofRecord.TriggerAsync(ProofTrigger.Accept); await RecordService.UpdateAsync(agentContext.Wallet, proofRecord); EventAggregator.Publish(new ServiceMessageProcessingEvent { RecordId = proofRecord.Id, MessageType = proof.Type, }); return(proofRecord.Id); }
public RangeProof Range_proof(ulong amount, Identifier keyId, Commitment commit, ProofMessage msg) { var skey = Derived_key(keyId); var rangeProof = Secp.range_proof(0, amount, skey, commit, msg); return(rangeProof); }
/// <inheritdoc /> public virtual async Task <string> ProcessProofAsync(IAgentContext agentContext, ProofMessage proof) { var proofJson = proof.ProofJson; var proofRecord = await this.GetByThreadIdAsync(agentContext, proof.GetThreadId()); if (proofRecord.State != ProofState.Requested) { throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, $"Proof state was invalid. Expected '{ProofState.Requested}', found '{proofRecord.State}'"); } proofRecord.ProofJson = proofJson; await proofRecord.TriggerAsync(ProofTrigger.Accept); await RecordService.UpdateAsync(agentContext.Wallet, proofRecord); EventAggregator.Publish(new ServiceMessageProcessingEvent { RecordId = proofRecord.Id, MessageType = proof.Type, ThreadId = proof.GetThreadId() }); return(proofRecord.Id); }
private async Task SelectCredentialsForProofAsync(IAgentContext agentContext, ProofRecord proof, ConnectionRecord connection) { var requestJson = (JObject)JsonConvert.DeserializeObject(proof.RequestJson); JObject _requestedAttributes = (JObject)requestJson["requested_attributes"]; JObject _requestedPredicates = (JObject)requestJson["requested_predicates"]; IList <string> _requestedAttributesKeys = _requestedAttributes?.Properties().Select(p => p.Name).ToList(); IList <string> _requestedPredicatesKeys = _requestedPredicates?.Properties().Select(p => p.Name).ToList(); JToken cred_def_id = null; try { cred_def_id = _requestedAttributes[_requestedAttributesKeys[0]]["restrictions"][0]["cred_def_id"]; } catch (Exception) { cred_def_id = null; } var credentials = new List <CredentialRecord>(); if (cred_def_id != null) { credentials = await RecordService.SearchAsync <CredentialRecord>(agentContext.Wallet, SearchQuery.And(SearchQuery.Equal(nameof(CredentialRecord.State), CredentialState.Issued.ToString("G")), SearchQuery.Equal(nameof(CredentialRecord.CredentialDefinitionId), cred_def_id.ToString())), null, 100); } else { credentials = await RecordService.SearchAsync <CredentialRecord>(agentContext.Wallet, SearchQuery.Equal(nameof(CredentialRecord.State), CredentialState.Issued.ToString("G")), null, 100); } bool credentialFound = false; if (credentials.Count > 0) { Dictionary <string, RequestedAttribute> requestedAttributes = new Dictionary <string, RequestedAttribute>(); Dictionary <string, RequestedAttribute> requestedPredicates = new Dictionary <string, RequestedAttribute>(); foreach (var credential in credentials) { if (!credentialFound) { IEnumerable <CredentialAttribute> Attributes = credential.CredentialAttributesValues .Select(p => new CredentialAttribute() { Name = p.Name, Value = p.Value?.ToString(), Type = "Text" }) .ToList(); foreach (var item in _requestedAttributesKeys) { foreach (var attrib in Attributes) { if (_requestedAttributes[item]["name"].ToString() == attrib.Name) { RequestedAttribute requestedAttribute = new RequestedAttribute(); requestedAttribute.CredentialId = credential.CredentialId; requestedAttribute.Revealed = true; requestedAttribute.Timestamp = ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeMilliseconds(); requestedAttributes.Add(item, requestedAttribute); credentialFound = true; } } if (!credentialFound) { requestedAttributes.Clear(); } } foreach (var item in _requestedPredicatesKeys) { RequestedAttribute requestedAttribute = new RequestedAttribute(); requestedAttribute.CredentialId = credential.CredentialId; requestedAttribute.Timestamp = ((DateTimeOffset)DateTime.UtcNow).ToUnixTimeMilliseconds(); requestedPredicates.Add(item, requestedAttribute); } } } if (credentialFound) { RequestedCredentials requestedCredentials = new RequestedCredentials(); requestedCredentials.RequestedAttributes = requestedAttributes; requestedCredentials.RequestedPredicates = requestedPredicates; var proofJson = await CreateProofJsonAsync(agentContext, requestedCredentials, proof.RequestJson); var threadId = proof.GetTag(TagConstants.LastThreadId); var proofMsg = new ProofMessage { ProofJson = proofJson }; proofMsg.ThreadFrom(threadId); await MessageService.SendAsync(agentContext.Wallet, proofMsg, connection); } } }