예제 #1
0
        public void Sign(IPacket packet, object args = null)
        {
            if (!(packet is UtxoSignedPacketBase packetBase))
            {
                throw new ArgumentOutOfRangeException(nameof(packet), string.Format(Resources.ERR_WRONG_PACKET_BASE_TYPE, nameof(UtxoSigningService), typeof(UtxoSignedPacketBase).FullName));
            }

            UtxoSignatureInput signatureInput = args as UtxoSignatureInput;

            byte[][] publicKeys = signatureInput.PublicKeys;
            int      index      = signatureInput.KeyPosition;

            byte[] otsk = ConfidentialAssetsHelper.GetOTSK(signatureInput.SourceTransactionKey, _secretViewKey, _secretSpendKey);

            byte[] keyImage = ConfidentialAssetsHelper.GenerateKeyImage(otsk);
            packetBase.KeyImage = _identityKeyProvider.GetKey(keyImage);

            byte[] msg = new byte[packet.BodyBytes.Length + keyImage.Length];

            Array.Copy(packet.BodyBytes.ToArray(), 0, msg, 0, packet.BodyBytes.Length);
            Array.Copy(keyImage, 0, msg, packet.BodyBytes.Length, keyImage.Length);

            RingSignature[] ringSignatures = ConfidentialAssetsHelper.GenerateRingSignature(msg, keyImage, publicKeys, otsk, index);

            packetBase.PublicKeys = signatureInput.PublicKeys.Select(p => _identityKeyProvider.GetKey(p)).ToArray();
            packetBase.Signatures = ringSignatures;
        }
예제 #2
0
        private void ProcessTransferAssetsToUtxo(TransferAssetToUtxoBlock block, ulong registryCombinedBlockHeight)
        {
            if (_clientState.IsConfidential())
            {
                bool isToMe = ConfidentialAssetsHelper.IsDestinationKeyMine(block.DestinationKey, block.TransactionPublicKey, _clientState.GetSecretViewKey(), _clientState.GetPublicSpendKey());

                if (isToMe)
                {
                    byte[] otsk    = ConfidentialAssetsHelper.GetOTSK(block.TransactionPublicKey, _clientState.GetSecretViewKey(), _clientState.GetSecretSpendKey());
                    byte[] assetId = ConfidentialAssetsHelper.GetAssetIdFromEcdhTupleCA(block.EcdhTuple, block.TransactionPublicKey, _clientState.GetSecretViewKey());
                    _dataAccessService.StoreUtxoUnspentOutputs(block.SyncBlockHeight, registryCombinedBlockHeight, block.BlockType,
                                                               block.RawData.Span, block.TransactionPublicKey, ConfidentialAssetsHelper.GenerateKeyImage(otsk), block.TagId, block.AssetCommitment, block.DestinationKey, 1, assetId);
                }
                else
                {
                    _dataAccessService.StoreUtxoOutput(block.TagId, block.AssetCommitment, block.DestinationKey);
                }
            }
        }
예제 #3
0
        public void TransitionAssetProofSerializerTest()
        {
            ulong syncBlockHeight = 1;
            uint  nonce           = 4;

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

            byte[] body;
            byte[] transactionPublicKey = ConfidentialAssetsHelper.GetRandomSeed();
            byte[] destinationKey       = ConfidentialAssetsHelper.GetRandomSeed();
            byte[] destinationKey2      = ConfidentialAssetsHelper.GetRandomSeed();
            byte[] keyImage             = BinaryHelper.GetRandomPublicKey();
            byte[] assetCommitment      = ConfidentialAssetsHelper.GetRandomSeed();

            byte[] mask        = ConfidentialAssetsHelper.GetRandomSeed();
            byte[] assetId     = ConfidentialAssetsHelper.GetRandomSeed();
            byte[] assetIssuer = ConfidentialAssetsHelper.GetRandomSeed();
            byte[] payload     = ConfidentialAssetsHelper.GetRandomSeed();

            ushort pubKeysCount = 10;

            byte[][] ownershipAssetCommitments = new byte[pubKeysCount][];
            byte[][] pubKeys = new byte[pubKeysCount][];

            byte[] secretKey      = null;
            ushort secretKeyIndex = 5;

            byte[]   e = ConfidentialAssetsHelper.GetRandomSeed();
            byte[][] s = new byte[pubKeysCount][];


            ushort eligibilityCommitmentsCount = 7;

            byte[][] eligibilityCommitments = new byte[eligibilityCommitmentsCount][];
            byte[]   eligibilityE           = ConfidentialAssetsHelper.GetRandomSeed();
            byte[][] eligibilityS           = new byte[eligibilityCommitmentsCount][];


            for (int i = 0; i < pubKeysCount; i++)
            {
                if (i == secretKeyIndex)
                {
                    secretKey  = ConfidentialAssetsHelper.GetOTSK(transactionPublicKey, _privateViewKey, _privateKey);
                    pubKeys[i] = ConfidentialAssetsHelper.GetPublicKey(secretKey);
                    keyImage   = ConfidentialAssetsHelper.GenerateKeyImage(secretKey);
                }
                else
                {
                    pubKeys[i] = BinaryHelper.GetRandomPublicKey(out byte[] secretKeyTemp);
                }

                ownershipAssetCommitments[i] = ConfidentialAssetsHelper.GetRandomSeed();
                s[i] = ConfidentialAssetsHelper.GetRandomSeed();
            }

            for (int i = 0; i < eligibilityCommitmentsCount; i++)
            {
                eligibilityCommitments[i] = ConfidentialAssetsHelper.GetRandomSeed();
                eligibilityS[i]           = ConfidentialAssetsHelper.GetRandomSeed();
            }

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

                    bw.Write(mask);
                    bw.Write(assetId);
                    bw.Write(assetIssuer);
                    bw.Write(payload);

                    bw.Write(pubKeysCount);
                    for (int i = 0; i < pubKeysCount; i++)
                    {
                        bw.Write(ownershipAssetCommitments[i]);
                    }
                    bw.Write(e);
                    for (int i = 0; i < pubKeysCount; i++)
                    {
                        bw.Write(s[i]);
                    }

                    bw.Write(eligibilityCommitmentsCount);
                    for (int i = 0; i < eligibilityCommitmentsCount; i++)
                    {
                        bw.Write(eligibilityCommitments[i]);
                    }
                    bw.Write(eligibilityE);
                    for (int i = 0; i < eligibilityCommitmentsCount; i++)
                    {
                        bw.Write(eligibilityS[i]);
                    }
                }

                body = ms.ToArray();
            }

            byte[] expectedPacket = BinaryHelper.GetUtxoConfidentialPacket(PacketType.UtxoConfidential, syncBlockHeight, nonce, powHash, version,
                                                                           BlockTypes.UtxoConfidential_TransitionOnboardingDisclosingProofs, keyImage, destinationKey, destinationKey2, transactionPublicKey, body, pubKeys, secretKey, secretKeyIndex,
                                                                           out RingSignature[] ringSignatures);

            TransitionOnboardingDisclosingProofs block = new TransitionOnboardingDisclosingProofs
            {
                SyncBlockHeight      = syncBlockHeight,
                Nonce                = nonce,
                PowHash              = powHash,
                DestinationKey       = destinationKey,
                DestinationKey2      = destinationKey2,
                KeyImage             = new Key32(keyImage),
                TransactionPublicKey = transactionPublicKey,
                AssetCommitment      = assetCommitment,
                EcdhTuple            = new EcdhTupleProofs
                {
                    Mask        = mask,
                    AssetId     = assetId,
                    AssetIssuer = assetIssuer,
                    Payload     = payload
                },
                OwnershipProof = new SurjectionProof
                {
                    AssetCommitments = ownershipAssetCommitments,
                    Rs = new BorromeanRingSignature
                    {
                        E = e,
                        S = s
                    }
                },
                EligibilityProof = new SurjectionProof
                {
                    AssetCommitments = eligibilityCommitments,
                    Rs = new BorromeanRingSignature
                    {
                        E = eligibilityE,
                        S = eligibilityS
                    }
                }
            };

            TransitionOnboardingDisclosingProofsSerializer serializer = new TransitionOnboardingDisclosingProofsSerializer();

            serializer.Initialize(block);
            serializer.SerializeBody();
            _utxoSigningService.Sign(block, new UtxoSignatureInput(transactionPublicKey, pubKeys, secretKeyIndex));

            byte[] actualPacket = serializer.GetBytes();

            Span <byte> expectedSpan = new Span <byte>(expectedPacket);
            Span <byte> actualSpan   = new Span <byte>(actualPacket);

            Assert.Equal(expectedSpan.Slice(0, expectedPacket.Length - pubKeysCount * 64).ToArray(), actualSpan.Slice(0, actualPacket.Length - pubKeysCount * 64).ToArray());
        }
예제 #4
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);
        }