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; }
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()); }
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); } } }
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); }