/// <summary> /// /// </summary> /// <param name="transaction"></param> /// <returns></returns> public async Task <VerifyResult> VerifyTransaction(Transaction transaction) { Guard.Argument(transaction, nameof(transaction)).NotNull(); if (transaction.Validate().Any()) { return(VerifyResult.UnableToVerify); } var verifySum = VerifyCommitSum(transaction); if (verifySum == VerifyResult.UnableToVerify) { return(verifySum); } var verifyBulletProof = VerifyBulletProof(transaction); if (verifyBulletProof == VerifyResult.UnableToVerify) { return(verifyBulletProof); } var transactionTypeArray = transaction.Vout.Select(x => x.T.ToString()).ToArray(); if (transactionTypeArray.Contains(CoinType.Fee.ToString()) && transactionTypeArray.Contains(CoinType.Coin.ToString())) { var verifyVOutCommits = await VerifyOutputCommitments(transaction); if (verifyVOutCommits == VerifyResult.UnableToVerify) { return(verifyVOutCommits); } } var verifyKImage = await VerifyKeyImage(transaction); if (verifyKImage == VerifyResult.UnableToVerify) { return(verifyKImage); } using var mlsag = new MLSAG(); for (var i = 0; i < transaction.Vin.Length; i++) { var m = Makemlsag(transaction.Rct[i].M, transaction.Vout, transaction.Vin[i].Key.Offsets, transaction.Mix, 2); var verifymlsag = mlsag.Verify(transaction.Rct[i].I, transaction.Mix, 2, m, transaction.Vin[i].Key.Image, transaction.Rct[i].P, transaction.Rct[i].S); if (verifymlsag) { continue; } _logger.Here() .Fatal("Unable to verify the Multilayered Linkable Spontaneous Anonymous Group transaction"); return(VerifyResult.UnableToVerify); } return(VerifyResult.Succeed); }
/// <summary> /// </summary> /// <param name="m"></param> /// <param name="outputs"></param> /// <param name="keyOffset"></param> /// <param name="cols"></param> /// <param name="rows"></param> /// <returns></returns> private byte[] Makemlsag(byte[] m, Vout[] outputs, byte[] keyOffset, int cols, int rows) { Guard.Argument(m, nameof(m)).NotNull(); Guard.Argument(outputs, nameof(outputs)).NotNull(); Guard.Argument(keyOffset, nameof(keyOffset)).NotNull(); Guard.Argument(cols, nameof(cols)).NotZero().NotNegative(); Guard.Argument(rows, nameof(rows)).NotZero().NotNegative(); var pcmOut = new Span <byte[]>(new[] { outputs[0].C, outputs[1].C, outputs[2].C }); var kOffsets = keyOffset.Split(33).Select(x => x).ToList(); var pcmIn = kOffsets.Where((value, index) => index % 2 == 0).ToArray().AsSpan(); using var mlsag = new MLSAG(); var preparemlsag = mlsag.Prepare(m, null, pcmOut.Length, pcmOut.Length, cols, rows, pcmIn, pcmOut, null); if (preparemlsag) { return(m); } _logger.Here().Fatal("Unable to verify the Multilayered Linkable Spontaneous Anonymous Group membership"); return(null); }