public async Task WrongSignatureTest() { var sign = await ECDSAProvider.VerifyMessage(FakeDataGenerator.DefaultDto.BasicMessage, FakeDataGenerator.DefaultDto.AliceBasicMessageWrongSignature, FakeDataGenerator.DefaultDto.AliceSecret.PubKey); Assert.False(sign.Item1); }
/* * public static async Task<(bool,(OwnershipVerificationCodeDto,byte[]))> GetQRCode(string txid, EncryptionKey key) * { * var signature = await GetCode(txid, key); * if (signature.Item1) * { * var dto = new OwnershipVerificationCodeDto(); * dto.TxId = txid; * dto.Signature = signature.Item2; * var dtos = JsonConvert.SerializeObject(dto); * if (dtos != null) * { * QRCodeData qrCodeData = qrGenerator.CreateQrCode(dtos, QRCodeGenerator.ECCLevel.Q); * var qrCode = new BitmapByteQRCode(qrCodeData); * var g = qrCode.GetGraphic(20); * return (true, (dto, g)); * } * } * return (false, (null, null)); * } */ public static async Task <OwnershipVerificationResult> VerifyOwner(OwnershipVerificationCodeDto dto) { var msg = CreateMessage(dto.TxId); var res = await NFTHelpers.GetNFTWithOwner(dto.TxId); if (res.Item1) { //var ownerpubkey = await NFTHelpers.GetPubKeyFromProfileNFTTx(res.Item2.Owner); /*var ownerpubkey = await NFTHelpers.GetPubKeyFromLastFoundTx(res.Item2.Owner); * if (!ownerpubkey.Item1) * return new OwnershipVerificationResult() * { * Owner = res.Item2.Owner, * Sender = res.Item2.Sender, * NFT = res.Item2.NFT, * Message = msg, * VerifyResult = "Cannot get owner pubkey. He probably did not allow this function." * };*/ var r = await ECDSAProvider.VerifyMessage(msg, dto.Signature, res.Item2.Owner); if (r.Item1) { return(new OwnershipVerificationResult() { Owner = res.Item2.Owner, Sender = res.Item2.Sender, NFT = res.Item2.NFT, Message = msg, VerifyResult = "Verified. This is owner. Signature is valid." }); } else { if (r.Item2 != null) { return new OwnershipVerificationResult() { Owner = res.Item2.Owner, Sender = res.Item2.Sender, NFT = res.Item2.NFT, Message = msg, VerifyResult = "Not Owner of NFT or provided signature is no longer valid." } } ; } } return(new OwnershipVerificationResult() { VerifyResult = "Not Valid input." }); }
public async Task CorrectSignatureTest() { var alicever = await ECDSAProvider.VerifyMessage(FakeDataGenerator.DefaultDto.BasicMessage, FakeDataGenerator.DefaultDto.AliceBasicMessageSignature, FakeDataGenerator.DefaultDto.AliceSecret.PubKey); Assert.True(alicever.Item1); var bobver = await ECDSAProvider.VerifyMessage(FakeDataGenerator.DefaultDto.BasicMessage, FakeDataGenerator.DefaultDto.BobBasicMessageSignature, FakeDataGenerator.DefaultDto.BobSecret.PubKey); Assert.True(bobver.Item1); }
/// <summary> /// Function will check if the requested action exists and if the signature match /// </summary> /// <param name="admin"></param> /// <param name="signature"></param> /// <param name="message"></param> /// <returns></returns> /// <exception cref="Exception"></exception> public static async Task <IAdminAction> VerifyAdminAction(string admin, string signature, string message) { if (string.IsNullOrEmpty(admin) || string.IsNullOrEmpty(signature)) { throw new Exception("You must fill the admin address and signature for this action."); } if (VEDLDataContext.AdminAddresses.Contains(admin)) { if (VEDLDataContext.Accounts.TryGetValue(admin, out var acc)) { if (VEDLDataContext.AdminActionsRequests.TryRemove(message, out var areq)) { var res = await ECDSAProvider.VerifyMessage(message, signature, acc.Secret.PubKey); if (res.Item1) { return(areq); } } } } return(null); }
public static async Task <VerifyNFTTicketDto> LoadNFTTicketToVerify(OwnershipVerificationCodeDto dto, string eventId, List <string> allowedMintingAddresses) { if (string.IsNullOrEmpty(dto.TxId)) { throw new Exception("Utxo id must be provided."); } if (string.IsNullOrEmpty(dto.Signature)) { throw new Exception("Signature id must be provided."); } if (string.IsNullOrEmpty(eventId)) { throw new Exception("Event Id must be provided."); } if (allowedMintingAddresses == null || allowedMintingAddresses.Count == 0) { throw new Exception("You must provide list of allowed minting addresses."); } var msg = CreateMessage(dto.TxId); // create verification message ASAP because of time relation var txi = await NeblioTransactionHelpers.GetTransactionInfo(dto.TxId); var Time = TimeHelpers.UnixTimestampToDateTime((double)txi.Blocktime); bool isYesterdayOrOlder = DateTime.Today - Time.Date >= TimeSpan.FromDays(1); if (isYesterdayOrOlder) { throw new Exception("This ticket was used earlier than today. Or it is not used at all."); } var metadata = await NeblioTransactionHelpers.GetTransactionMetadata(NFTHelpers.TokenId, dto.TxId); if (metadata.TryGetValue("NFT", out var isnft)) { if (isnft != "true") { throw new Exception("This is not NFT"); } } if (metadata.TryGetValue("Type", out var type)) { if (type != "NFT Ticket") { throw new Exception("This is not NFT Ticket"); } } if (metadata.TryGetValue("EventId", out var nfteventId)) { if (nfteventId != eventId) { throw new Exception("Event Id on the ticket does not match the requested."); } } if (metadata.TryGetValue("Used", out var used)) { if (used != "true") { throw new Exception("This NFT Ticket is not used."); } } else { throw new Exception("This NFT Ticket is not used."); } var tx = Transaction.Parse(txi.Hex, NeblioTransactionHelpers.Network); var outDto = new VerifyNFTTicketDto(); if (tx != null && tx.Outputs.Count > 0 && tx.Inputs.Count > 0) { var outp = tx.Outputs[0]; var inpt = tx.Inputs[0]; if (outp != null && inpt != null) { var scr = outp.ScriptPubKey; var add = scr.GetDestinationAddress(NeblioTransactionHelpers.Network); var addi = inpt.ScriptSig.GetSignerAddress(NeblioTransactionHelpers.Network); if (add != addi) { throw new Exception("This ticket was not used on this address."); } var pubkey = inpt.ScriptSig.GetAllPubKeys().FirstOrDefault(); if (pubkey == null) { throw new Exception("Cannot Load the owner Public Key."); } // verify of the signature of the NFT var verres = await ECDSAProvider.VerifyMessage(msg, dto.Signature, pubkey); //var vmsg = await ECDSAProvider.VerifyMessage(msg, dto.Signature, pubkey); if (!verres.Item1) { throw new Exception("Signature of the NFT is not valid."); } // check if the NFT is still as utxo on the address var utxos = await NeblioTransactionHelpers.GetAddressUtxosObjects(add.ToString()); if (utxos.FirstOrDefault(u => (u.Txid == dto.TxId && u.Value == 10000 && u.Tokens.Count > 0 && u.Tokens.FirstOrDefault()?.Amount == 1)) == null) { throw new Exception("This ticket is not available on the address as spendable."); } // check if in previous transaction the ticket was unused var prevmeta = await NeblioTransactionHelpers.GetTransactionMetadata(NFTHelpers.TokenId, inpt.PrevOut.Hash.ToString()); if (prevmeta.TryGetValue("NFT", out var isprevnft)) { if (isprevnft != "true") { throw new Exception("This is not NFT"); } } if (prevmeta.TryGetValue("Type", out var prevtype)) { if (prevtype != "NFT Ticket") { throw new Exception("This is not NFT Ticket"); } } if (prevmeta.TryGetValue("EventId", out var prevnfteventId)) { if (prevnfteventId != eventId) { throw new Exception("Event Id on the ticket does not match the requested."); } } if (prevmeta.TryGetValue("Used", out var prevused)) { if (prevused == "true") { throw new Exception("This NFT Ticket was already used in previous transaction."); } } // todo track origin for check minting address var res = await VerifyNFTTicketOrigin(inpt.PrevOut.Hash.ToString(), eventId, allowedMintingAddresses); if (!res.Item1) { throw new Exception($"Ticket was not minted on allowed address. The origin is from: {res.Item2.Item2}"); } outDto.IsMintedByAllowedAddress = true; outDto.MintAddress = res.Item2.Item2; var nft = new TicketNFT(""); await nft.LoadLastData(metadata); // fill with already loaded the newest NFT metadata nft.Time = Time; outDto.IsSignatureValid = true; outDto.NFT = nft; outDto.OwnerAddress = add.ToString(); outDto.IsUsedOnSameAddress = true; outDto.OwnerPubKey = pubkey; outDto.TxId = dto.TxId; } } return(outDto); }