Exemplo n.º 1
0
        public void TransferGroupedAssetsToUtxoBlockSerializerTest()
        {
            ulong syncBlockHeight = 1;
            uint  nonce           = 4;

            byte[] powHash     = BinaryHelper.GetPowHash(1234);
            ushort version     = 1;
            ulong  blockHeight = 9;

            byte[] body;

            ulong uptodateFunds = 10001;

            byte[] transactionPublicKey = ConfidentialAssetsHelper.GetRandomSeed();
            byte[] destinationKey       = ConfidentialAssetsHelper.GetRandomSeed();
            byte[] assetId                  = ConfidentialAssetsHelper.GetRandomSeed();
            byte[] assetCommitment          = ConfidentialAssetsHelper.GetRandomSeed();
            ushort blindedAssetsGroupsCount = 2;
            ushort assetsCount              = 10;

            uint[]     groupIds = new uint[blindedAssetsGroupsCount];
            byte[][][] ownedAssetCommitments     = new byte[blindedAssetsGroupsCount][][];
            byte[][]   surjectionAssetCommitment = new byte[blindedAssetsGroupsCount * assetsCount + 1][];
            byte[][]   e    = new byte[blindedAssetsGroupsCount * assetsCount + 1][];
            byte[][][] s    = new byte[blindedAssetsGroupsCount * assetsCount + 1][][];
            byte[]     mask = ConfidentialAssetsHelper.GetRandomSeed();

            Random random = new Random();

            for (int i = 0; i < blindedAssetsGroupsCount; i++)
            {
                groupIds[i] = (uint)i;
                ownedAssetCommitments[i] = new byte[assetsCount][];
                for (int j = 0; j < assetsCount; j++)
                {
                    ownedAssetCommitments[i][j] = ConfidentialAssetsHelper.GetRandomSeed();
                }
            }

            for (int i = 0; i < blindedAssetsGroupsCount * assetsCount + 1; i++)
            {
                surjectionAssetCommitment[i] = ConfidentialAssetsHelper.GetRandomSeed();
                e[i] = ConfidentialAssetsHelper.GetRandomSeed();
                s[i] = new byte[blindedAssetsGroupsCount * assetsCount + 1][];
                for (int j = 0; j < blindedAssetsGroupsCount * assetsCount + 1; j++)
                {
                    s[i][j] = ConfidentialAssetsHelper.GetRandomSeed();
                }
            }

            using (MemoryStream ms = new MemoryStream())
            {
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    bw.Write(uptodateFunds);

                    bw.Write(destinationKey);
                    bw.Write(transactionPublicKey);

                    // TransferredAsset
                    // ==============================
                    bw.Write(assetCommitment);
                    bw.Write(assetId);
                    bw.Write(mask);
                    // ==============================

                    bw.Write(blindedAssetsGroupsCount);
                    for (int i = 0; i < blindedAssetsGroupsCount; i++)
                    {
                        bw.Write(groupIds[i]);
                        bw.Write(assetsCount);
                        for (int j = 0; j < assetsCount; j++)
                        {
                            bw.Write(ownedAssetCommitments[i][j]);
                        }
                    }

                    for (int i = 0; i < blindedAssetsGroupsCount * assetsCount + 1; i++)
                    {
                        bw.Write(surjectionAssetCommitment[i]);
                        bw.Write(e[i]);
                        bw.Write((ushort)(blindedAssetsGroupsCount * assetsCount + 1));

                        for (int j = 0; j < blindedAssetsGroupsCount * assetsCount + 1; j++)
                        {
                            bw.Write(s[i][j]);
                        }
                    }
                }

                body = ms.ToArray();
            }

            byte[] expectedPacket = BinaryHelper.GetSignedPacket(PacketType.Transactional, syncBlockHeight, nonce, powHash, version,
                                                                 BlockTypes.Transaction_TransferGroupedAssetsToUtxo, blockHeight, null, body, _privateKey, out byte[] expectedSignature);

            EncryptedAsset transferredAsset = new EncryptedAsset
            {
                AssetCommitment = assetCommitment,
                EcdhTuple       = new EcdhTupleCA
                {
                    AssetId = assetId,
                    Mask    = mask
                }
            };

            BlindedAssetsGroup[] blindedAssetsGroups = new BlindedAssetsGroup[blindedAssetsGroupsCount];
            for (int i = 0; i < blindedAssetsGroupsCount; i++)
            {
                blindedAssetsGroups[i] = new BlindedAssetsGroup
                {
                    GroupId          = groupIds[i],
                    AssetCommitments = ownedAssetCommitments[i]
                };
            }

            InversedSurjectionProof[] inversedSurjectionProofs = new InversedSurjectionProof[blindedAssetsGroupsCount * assetsCount + 1];
            for (int i = 0; i < blindedAssetsGroupsCount * assetsCount + 1; i++)
            {
                inversedSurjectionProofs[i] = new InversedSurjectionProof
                {
                    AssetCommitment = surjectionAssetCommitment[i],
                    Rs = new BorromeanRingSignature
                    {
                        E = e[i],
                        S = s[i]
                    }
                };
            }

            TransferGroupedAssetToUtxo block = new TransferGroupedAssetToUtxo
            {
                SyncBlockHeight          = syncBlockHeight,
                Nonce                    = nonce,
                PowHash                  = powHash,
                BlockHeight              = blockHeight,
                UptodateFunds            = uptodateFunds,
                DestinationKey           = destinationKey,
                TransactionPublicKey     = transactionPublicKey,
                TransferredAsset         = transferredAsset,
                BlindedAssetsGroups      = blindedAssetsGroups,
                InversedSurjectionProofs = inversedSurjectionProofs
            };

            TransferGroupedAssetsToUtxoSerializer serializer = new TransferGroupedAssetsToUtxoSerializer();

            serializer.Initialize(block);
            serializer.SerializeBody();
            _signingService.Sign(block);

            byte[] actualPacket = serializer.GetBytes();

            Assert.Equal(expectedPacket, actualPacket);
        }
Exemplo n.º 2
0
        protected override Memory <byte> ParseTransactionalTransitional(ushort version, Memory <byte> spanBody, out TransactionalTransitionalPacketBase transactionalBlockBase)
        {
            TransferGroupedAssetToUtxo block = null;

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

                byte[] assetCommitment = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                byte[] assetId = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                byte[] mask = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                readBytes += Globals.NODE_PUBLIC_KEY_SIZE;

                EncryptedAsset transferedAsset = new EncryptedAsset
                {
                    AssetCommitment = assetCommitment,
                    EcdhTuple       = new EcdhTupleCA {
                        AssetId = assetId, Mask = mask
                    }
                };

                ushort blindedAssetsGroupsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                readBytes += sizeof(ushort);

                BlindedAssetsGroup[] blindedAssetsGroups = new BlindedAssetsGroup[blindedAssetsGroupsLength];

                ushort totalCommitments = 0;

                for (int i = 0; i < blindedAssetsGroupsLength; i++)
                {
                    uint groupId = BinaryPrimitives.ReadUInt32LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(uint);

                    ushort assetCommitmentsLength = BinaryPrimitives.ReadUInt16LittleEndian(spanBody.Slice(readBytes).Span);
                    readBytes += sizeof(ushort);

                    totalCommitments += assetCommitmentsLength;
                    byte[][] assetCommitments = new byte[assetCommitmentsLength][];

                    for (int j = 0; j < assetCommitmentsLength; j++)
                    {
                        assetCommitments[j] = spanBody.Slice(readBytes, Globals.NODE_PUBLIC_KEY_SIZE).ToArray();
                        readBytes          += Globals.NODE_PUBLIC_KEY_SIZE;
                    }

                    blindedAssetsGroups[i] = new BlindedAssetsGroup
                    {
                        GroupId          = groupId,
                        AssetCommitments = assetCommitments
                    };
                }

                InversedSurjectionProof[] inversedSurjectionProofs = new InversedSurjectionProof[totalCommitments + 1];
                for (int i = 0; i < inversedSurjectionProofs.Length; i++)
                {
                    inversedSurjectionProofs[i] = ReadInversedSurjectionProof(spanBody.Slice(readBytes).Span, out int count);
                    readBytes += count;
                }

                block = new TransferGroupedAssetToUtxo
                {
                    TransferredAsset         = transferedAsset,
                    BlindedAssetsGroups      = blindedAssetsGroups,
                    InversedSurjectionProofs = inversedSurjectionProofs
                };

                transactionalBlockBase = block;
                return(spanBody.Slice(readBytes));
            }

            throw new BlockVersionNotSupportedException(version, BlockType);
        }