/// <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());
        }
示例#2
0
        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);
        }
示例#3
0
        /// 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())));
        }
示例#4
0
        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);
        }
示例#5
0
        /// <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);
        }
示例#6
0
        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);
        }
示例#8
0
        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);
        }
示例#9
0
        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);
        }
示例#10
0
        /// <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);
        }
示例#12
0
        /// <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);
        }
示例#13
0
        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);
        }
示例#14
0
        /// <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);
                }
            }
        }