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 static byte[] GetUtxoConfidentialPacket(PacketType packetType, ulong syncBlockHeight, uint nonce, byte[] powHash, ushort version, ushort blockType, ulong tagId, byte[] keyImage, byte[] destinationKey, byte[] transactionPublicKey, byte[] body, byte[][] pubKeys, byte[] secretKey, int secIndex, out RingSignature[] ringSignatures) { byte[] bodyBytes = null; byte[] result = null; using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter bw = new BinaryWriter(ms)) { bw.Write(version); bw.Write(blockType); bw.Write(tagId); bw.Write(keyImage); bw.Write(destinationKey); bw.Write(transactionPublicKey); bw.Write(body); } bodyBytes = ms.ToArray(); } ringSignatures = ConfidentialAssetsHelper.GenerateRingSignature(bodyBytes, keyImage, pubKeys, secretKey, secIndex); using (MemoryStream ms = new MemoryStream()) { using (BinaryWriter bw = new BinaryWriter(ms)) { bw.Write((ushort)packetType); bw.Write(syncBlockHeight); bw.Write(nonce); bw.Write(powHash); bw.Write(bodyBytes); bw.Write((ushort)ringSignatures.Length); for (int i = 0; i < pubKeys.Length; i++) { bw.Write(pubKeys[i]); } for (int i = 0; i < pubKeys.Length; i++) { bw.Write(ringSignatures[i].C); bw.Write(ringSignatures[i].R); } } result = ms.ToArray(); } return(result); }
public BlockBase CreateUtxoRegisterBlock(UtxoConfidentialBase confidentialBase, byte[] otsk, int actualAssetPos) { byte[] msg = ConfidentialAssetsHelper.FastHash256(confidentialBase.RawData.ToArray()); RegistryRegisterUtxoConfidentialBlock registryRegisterUtxoConfidentialBlock = new RegistryRegisterUtxoConfidentialBlock { SyncBlockHeight = confidentialBase.SyncBlockHeight, Nonce = confidentialBase.Nonce, PowHash = confidentialBase.PowHash, ReferencedPacketType = confidentialBase.PacketType, ReferencedBlockType = confidentialBase.BlockType, DestinationKey = confidentialBase.DestinationKey, KeyImage = confidentialBase.KeyImage, ReferencedBodyHash = _hashCalculation.CalculateHash(confidentialBase.RawData), TransactionPublicKey = confidentialBase.TransactionPublicKey, TagId = confidentialBase.TagId, PublicKeys = confidentialBase.PublicKeys, Signatures = ConfidentialAssetsHelper.GenerateRingSignature(msg, confidentialBase.KeyImage.Value.ToArray(), confidentialBase.PublicKeys.Select(p => p.Value.ToArray()).ToArray(), otsk, actualAssetPos) }; return(registryRegisterUtxoConfidentialBlock); }
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); }