예제 #1
0
 private void ProcessNonQuantitativeTransitionAssetTransfer(NonQuantitativeTransitionAssetTransferBlock block, ulong registryCombinedBlockHeight)
 {
     if (!_clientState.IsConfidential() && _clientState.GetPublicKeyHash().Equals32(block.DestinationKey))
     {
         _dataAccessService.StoreIncomingTransitionUtxoTransactionBlock(block.SyncBlockHeight, registryCombinedBlockHeight, block.BlockType, block.TagId, block.RawData.Span,
                                                                        block.KeyImage.Value.Span, block.AssetCommitment, block.DestinationKey);
     }
 }
예제 #2
0
        private BlockBase CreateNonQuantitativeTransitionAssetTransferBlock(Account receiver, byte[] assetId, byte[] prevTransactionKey, byte[] prevCommitment, byte[] prevDestinationKey, int ringSize, ulong tagId, out byte[] otsk, out int pos)
        {
            if (!_clientState.IsConfidential())
            {
                otsk = null;
                pos  = -1;
                return(null);
            }

            byte[] otskAsset = ConfidentialAssetsHelper.GetOTSK(prevTransactionKey, _clientState.GetSecretViewKey(), _clientState.GetSecretSpendKey());
            otsk = otskAsset;
            byte[] keyImage        = ConfidentialAssetsHelper.GenerateKeyImage(otskAsset);
            byte[] secretKey       = ConfidentialAssetsHelper.GetRandomSeed();
            byte[] transactionKey  = ConfidentialAssetsHelper.GetTrancationKey(secretKey);
            byte[] destinationKey  = _hashCalculation.CalculateHash(receiver.PublicKey);
            byte[] blindingFactor  = ConfidentialAssetsHelper.GetRandomSeed();
            byte[] assetCommitment = ConfidentialAssetsHelper.GetAssetCommitment(assetId, blindingFactor);

            byte[] msg = ConfidentialAssetsHelper.FastHash256(BitConverter.GetBytes(tagId), keyImage, destinationKey, transactionKey, assetCommitment);

            Random random = new Random(BitConverter.ToInt32(secretKey, 0));

            GetCommitmentAndProofs(prevCommitment, prevDestinationKey, ringSize, tagId, random, out int actualAssetPos, out byte[][] assetCommitments, out byte[][] assetPubs);
            pos = actualAssetPos;

            UtxoUnspentBlock idCardBlock = _dataAccessService.GetUtxoUnspentBlocksByTagId(_idCardTagId).First();

            byte[] otskAffiliation            = ConfidentialAssetsHelper.GetOTSK(idCardBlock.TransactionKey, _clientState.GetSecretViewKey(), _clientState.GetSecretSpendKey());
            byte[] affiliationBlindingFactor  = ConfidentialAssetsHelper.GetRandomSeed();
            byte[] affiliationAssetCommitment = ConfidentialAssetsHelper.GetAssetCommitment(idCardBlock.AssetId, affiliationBlindingFactor);
            GetCommitmentAndProofs(idCardBlock.Output.Commitment, idCardBlock.Output.DestinationKey, ringSize, _idCardTagId, random, out int actualAffiliationPos, out byte[][] affiliationCommitments, out byte[][] affiliationPubs);

            BorromeanRingSignature borromeanRingSignature = ConfidentialAssetsHelper.GenerateBorromeanRingSignature(msg, affiliationPubs, actualAffiliationPos, otskAffiliation);

            SurjectionProof assetSurjectionProof       = ConfidentialAssetsHelper.CreateAssetRangeProof(assetCommitment, assetCommitments, actualAssetPos, blindingFactor);
            SurjectionProof affilaitionSurjectionProof = ConfidentialAssetsHelper.CreateAssetRangeProof(affiliationAssetCommitment, affiliationCommitments, actualAffiliationPos, affiliationBlindingFactor);

            List <TransactionalIncomingBlock> incomingBlocks    = _dataAccessService.GetIncomingBlocksByBlockType(BlockTypes.Transaction_IssueAssets);
            List <IssueAssetsBlock>           issueAssetsBlocks = incomingBlocks.Where(b => b.TagId == _idCardTagId).ToList().Select(b =>
            {
                return((IssueAssetsBlock)_blockParsersRepositoriesRepository.GetBlockParsersRepository(PacketType.Transactional).GetInstance(b.BlockType).Parse(b.Content));
            }).ToList();

            List <byte[]> rawIdCardAssetIds = issueAssetsBlocks.SelectMany(b => b.IssuedAssetIds).ToList();

            SurjectionProof affiliationEvidenceSurjectionProof = ConfidentialAssetsHelper.CreateNewIssuanceSurjectionProof(affiliationAssetCommitment, rawIdCardAssetIds.ToArray(), rawIdCardAssetIds.FindIndex(b => b.Equals32(idCardBlock.AssetId)), affiliationBlindingFactor);

            NonQuantitativeTransitionAssetTransferBlock block = new NonQuantitativeTransitionAssetTransferBlock
            {
                TagId                              = tagId,
                KeyImage                           = _identityKeyProvider.GetKey(keyImage),
                DestinationKey                     = destinationKey,
                TransactionPublicKey               = transactionKey,
                AssetCommitment                    = assetCommitment,
                SurjectionProof                    = assetSurjectionProof,
                AffiliationCommitment              = affiliationAssetCommitment,
                AffiliationPseudoKeys              = affiliationPubs,
                AffiliationSurjectionProof         = affilaitionSurjectionProof,
                AffiliationBorromeanSignature      = borromeanRingSignature,
                AffiliationEvidenceSurjectionProof = affiliationEvidenceSurjectionProof,
                EcdhTuple                          = ConfidentialAssetsHelper.CreateEcdhTupleCA(blindingFactor, assetId, secretKey, receiver.PublicKey),
                PublicKeys                         = assetPubs.Select(p => _identityKeyProvider.GetKey(p)).ToArray(),
                Signatures                         = ConfidentialAssetsHelper.GenerateRingSignature(msg, keyImage, assetPubs, otskAsset, actualAssetPos)
            };

            FillSyncData(block);
            FillRawData(block);

            return(block);
        }
예제 #3
0
        protected override Memory <byte> ParseUtxoConfidential(ushort version, Memory <byte> spanBody, out UtxoConfidentialBase utxoConfidentialBase)
        {
            UtxoConfidentialBase block = null;

            if (version == 1)
            {
                int readBytes = 0;

                ReadCommitmentAndProof(ref spanBody, ref readBytes, out byte[] assetCommitment, out SurjectionProof surjectionProof);
                ReadCommitmentAndProof(ref spanBody, ref readBytes, out byte[] affiliationAssetCommitment, out SurjectionProof affiliationSurjectionProof);

                ushort affiliationPseudoKeysCount = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Span.Slice(readBytes));
                readBytes += 2;

                byte[][] affiliationPseudoKeys = new byte[affiliationPseudoKeysCount][];
                for (int i = 0; i < affiliationPseudoKeysCount; i++)
                {
                    affiliationPseudoKeys[i] = spanBody.Slice(readBytes, 32).ToArray();
                    readBytes += 32;
                }

                byte[] e = spanBody.Slice(readBytes, 32).ToArray();
                readBytes += 32;

                ushort sCount = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Span.Slice(readBytes));
                readBytes += 2;

                byte[][] s = new byte[sCount][];
                for (int i = 0; i < sCount; i++)
                {
                    s[i]       = spanBody.Slice(readBytes, 32).ToArray();
                    readBytes += 32;
                }

                BorromeanRingSignature borromeanRingSignature = new BorromeanRingSignature {
                    E = e, S = s
                };

                SurjectionProof surjectionEvidenceProof = GetSurhectionProof(ref spanBody, ref readBytes);

                ReadEcdhTupleCA(ref spanBody, ref readBytes, out byte[] mask, out byte[] assetId);

                block = new NonQuantitativeTransitionAssetTransferBlock
                {
                    AssetCommitment                    = assetCommitment,
                    SurjectionProof                    = surjectionProof,
                    AffiliationCommitment              = affiliationAssetCommitment,
                    AffiliationSurjectionProof         = affiliationSurjectionProof,
                    AffiliationPseudoKeys              = affiliationPseudoKeys,
                    AffiliationBorromeanSignature      = borromeanRingSignature,
                    AffiliationEvidenceSurjectionProof = surjectionEvidenceProof,
                    EcdhTuple = new EcdhTupleCA
                    {
                        Mask    = mask,
                        AssetId = assetId
                    }
                };

                utxoConfidentialBase = block;

                return(spanBody.Slice(readBytes));
            }

            throw new BlockVersionNotSupportedException(version, BlockType);
        }