From 97294f5b41eff8ab2e2fa2946a9632d68e3ef3db Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Thu, 19 Mar 2020 16:28:39 -0500 Subject: [PATCH] schnorr: Rework signing tests. The existing signing and verification tests have several issues: - They are using data that is not easily independently verifiable by other implementations - The known good test data is using a hash function that is, per the comments, "horribly broken" instead of using the real hash function - They are not actually testing anything for the real hash function since they are doing the equivalent of sign(x) == sign(x) - The randomness aspects are not actually all that random since they just involve shuffling the order of the test data instead of actually producing random data each run - They aren't consistent with the way tests are written in the rest of the code Consequently, this reworks the signing and signature verification tests to resolve all of those issues. The following is a high-level overview of the changes: - Create new known good test data that is easily reproducible and has been independently verified with the Sage computer algebra system - The test data includes the original messages so the resulting hashes are independently verifiable and have a known source - The test data includes variations of signing the same data with different keys and nonces, both deterministically generated via RFC6979 and random, and signing different data with the same keys - Add random tests that generate random keys and messages with each run from a new random seed and log that seed in the event of failure - Ensure mutating a random bit in each good signature results in that mutated signature failing to verify the original message - Ensure mutating a random bit in each message hash that was originally signed results in the original good signature failing to verify the new mutated message --- dcrec/secp256k1/schnorr/signature_test.go | 524 ++++++++++++---------- 1 file changed, 298 insertions(+), 226 deletions(-) diff --git a/dcrec/secp256k1/schnorr/signature_test.go b/dcrec/secp256k1/schnorr/signature_test.go index e032f645..494a27a2 100644 --- a/dcrec/secp256k1/schnorr/signature_test.go +++ b/dcrec/secp256k1/schnorr/signature_test.go @@ -6,253 +6,325 @@ package schnorr import ( "bytes" - "encoding/hex" "math/rand" "testing" + "time" "github.com/decred/dcrd/chaincfg/chainhash" "github.com/decred/dcrd/dcrec/secp256k1/v3" ) -type SchnorrSigningTestVectorHex struct { - msg string - nonce string - priv string - sig string -} +// TestSchnorrSignAndVerify ensures the Schnorr signing function produces the +// expected signatures for a selected set of private keys, messages, and nonces +// that have been independently verified with the Sage computer algebra system. +// It also ensures verifying the signature works as expected. +func TestSchnorrSignAndVerify(t *testing.T) { + tests := []struct { + name string // test description + key string // hex encded private key + msg string // hex encoded message to sign before hashing + hash string // hex encoded hash of the message to sign + nonce string // hex encoded nonce to use in the signature calculation + rfc6979 bool // whether or not the nonce is an RFC6979 nonce + expected string // expected signature + }{{ + name: "key 0x1, blake256(0x01020304), rfc6979 nonce", + key: "0000000000000000000000000000000000000000000000000000000000000001", + msg: "01020304", + hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7", + nonce: "4154324ecd4158938f1df8b5b659aeb639c7fbc36005934096e514af7d64bcc2", + rfc6979: true, + expected: "c6c4137b0e5fbfc88ae3f293d7e80c8566c43ae20340075d44f75b009c943d09" + + "fe359056a1f6090fe2599acbe6b315be1e2dc7a675545ec96bb8a12d1a144deb", + }, { + name: "key 0x1, blake256(0x01020304), random nonce", + key: "0000000000000000000000000000000000000000000000000000000000000001", + msg: "01020304", + hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7", + nonce: "a6df66500afeb7711d4c8e2220960855d940a5ed57260d2c98fbf6066cca283e", + rfc6979: false, + expected: "b073759a96a835b09b79e7b93c37fdbe48fb82b000c4a0e1404ba5d1fbc15d0a" + + "299d614b02dec30f8261ae43d09a224b233f3221405c9ffd3d2b00a3d2188fd4", + }, { + name: "key 0x2, blake256(0x01020304), rfc6979 nonce", + key: "0000000000000000000000000000000000000000000000000000000000000002", + msg: "01020304", + hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7", + nonce: "55f96f24cf7531f527edfe3b9222eca12d575367c32a7f593a828dc3651acf49", + rfc6979: true, + expected: "e6f137b52377250760cc702e19b7aee3c63b0e7d95a91939b14ab3b5c4771e59" + + "57341a8bb99ea27ccebee775fe6ea24b560763bb499d03354e739c3cd32d6629", + }, { + name: "key 0x2, blake256(0x01020304), random nonce", + key: "0000000000000000000000000000000000000000000000000000000000000002", + msg: "01020304", + hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7", + nonce: "679a6d36e7fe6c02d7668af86d78186e8f9ccc04371ac1c8c37939d1f5cae07a", + rfc6979: false, + expected: "4a090d82f48ca12d9e7aa24b5dcc187ee0db2920496f671d63e86036aaa7997e" + + "16d33ae10eade4db33dda17873948b4803d6eb9b10781616880a6f66ba2d1b78", + }, { + name: "key 0x1, blake256(0x0102030405), rfc6979 nonce", + key: "0000000000000000000000000000000000000000000000000000000000000001", + msg: "0102030405", + hash: "dc063eba3c8d52a159e725c1a161506f6cb6b53478ad5ef3f08d534efa871d9f", + nonce: "aa87a543c68f2568bb107c9946afa5233bf94fb6a7a063544505282621021629", + rfc6979: true, + expected: "dda8308cdbda2edf51ccf598b42b42b19597e102eb2ed4a04a16dd57084d3b40" + + "5798fd44eba62ca35aa7efb27677414b46b7adfe6c523ccc5b18019314acaa71", + }, { + name: "key 0x1, blake256(0x0102030405), random nonce", + key: "0000000000000000000000000000000000000000000000000000000000000001", + msg: "0102030405", + hash: "dc063eba3c8d52a159e725c1a161506f6cb6b53478ad5ef3f08d534efa871d9f", + nonce: "65f880c892fdb6e7f74f76b18c7c942cfd037ef9cf97c39c36e08bbc36b41616", + rfc6979: false, + expected: "72e5666f4e9d1099447b825cf737ee32112f17a67e2ca7017ae098da31dfbb8b" + + "c19f5a4f815e9737f1b635075c50b3fa28dbbbebfcb98749b9f3c7b0fa748422", + }, { + name: "key 0x2, blake256(0x0102030405), rfc6979 nonce", + key: "0000000000000000000000000000000000000000000000000000000000000002", + msg: "0102030405", + hash: "dc063eba3c8d52a159e725c1a161506f6cb6b53478ad5ef3f08d534efa871d9f", + nonce: "a13d652abd54b6e862548e5d12716df14dc192d93f3fa13536fdf4e56c54f233", + rfc6979: true, + expected: "122663fd29e41a132d3c8329cf05d61ebcca9351074cc277dcd868faba58d87d" + + "e2d0532d74bcff2c8b643d098546590262f42f01826c28b656cf67e89514e655", + }, { + name: "key 0x2, blake256(0x0102030405), random nonce", + key: "0000000000000000000000000000000000000000000000000000000000000002", + msg: "0102030405", + hash: "dc063eba3c8d52a159e725c1a161506f6cb6b53478ad5ef3f08d534efa871d9f", + nonce: "026ece4cfb704733dd5eef7898e44c33bd5a0d749eb043f48705e40fa9e9afa0", + rfc6979: false, + expected: "3c4c5a2f217ea758113fd4e89eb756314dfad101a300f48e5bd764d3b6e0f8bf" + + "c29f43beed7d84348386152f1c43fc606d0887fa5b6f5c0b7875687f53b344f0", + }, { + name: "random key 1, blake256(0x01), rfc6979 nonce", + key: "a1becef2069444a9dc6331c3247e113c3ee142edda683db8643f9cb0af7cbe33", + msg: "01", + hash: "4a6c419a1e25c85327115c4ace586decddfe2990ed8f3d4d801871158338501d", + nonce: "edb3a01063a0c6ccfc0d77295077cbd322cf364bfa64b7eeea3b20305135d444", + rfc6979: true, + expected: "ef392791d87afca8256c4c9c68d981248ee34a09069f50fa8dfc19ae34cd92ce" + + "14f6553176e5ca434831720f02c4c0c6b6228338cfa00aaae4aa6da5b72aae05", + }, { + name: "random key 2, blake256(0x02), rfc6979 nonce", + key: "59930b76d4b15767ec0e8c8e5812aa2e57db30c6af7963e2a6295ba02af5416b", + msg: "02", + hash: "49af37ab5270015fe25276ea5a3bb159d852943df23919522a202205fb7d175c", + nonce: "af2a59085976494567ef0fc2ecede587b2d1d8e9898cc46e72d7f3e33156e057", + rfc6979: true, + expected: "886c9cccb356b3e1deafef2c276a4f8717ab73c1244c3f673cfbff5897de0e06" + + "0ef8e0ed66405379d05cf34934ccb3a38a8d800d35d4f0577b96f3cc316fb09d", + }, { + name: "random key 3, blake256(0x03), rfc6979 nonce", + key: "c5b205c36bb7497d242e96ec19a2a4f086d8daa919135cf490d2b7c0230f0e91", + msg: "03", + hash: "b706d561742ad3671703c247eb927ee8a386369c79644131cdeb2c5c26bf6c5d", + nonce: "82d82b696a386d6d7a111c4cb943bfd39de8e5f6195e7eed9d3edb40fe1419fa", + rfc6979: true, + expected: "6589d5950cec1fe2e7e20593b5ffa3556de20c176720a1796aa77a0cec1ec5a7" + + "194f86c06b44bde164fcaaac03452c55dde0ba51a27c6397363b54cb705d3afa", + }, { + name: "random key 4, blake256(0x04), rfc6979 nonce", + key: "65b46d4eb001c649a86309286aaf94b18386effe62c2e1586d9b1898ccf0099b", + msg: "04", + hash: "4c6eb9e38415034f4c93d3304d10bef38bf0ad420eefd0f72f940f11c5857786", + nonce: "7afd696a9e770961d2b2eaec77ab7c22c734886fa57bc4a50a9f1946168cd06f", + rfc6979: true, + expected: "81db1d6dca08819ad936d3284a359091e57c036648d477b96af9d8326965a7d1" + + "b5f807b7b4b62ff9f946d802c896d3bdf4eccdfc364f983aa29aa99da68df390", + }, { + name: "random key 5, blake256(0x05), rfc6979 nonce", + key: "915cb9ba4675de06a182088b182abcf79fa8ac989328212c6b866fa3ec2338f9", + msg: "05", + hash: "bdd15db13448905791a70b68137445e607cca06cc71c7a58b9b2e84a06c54d08", + nonce: "2a6ae70ea5cf1b932331901d640ece54551f5f33bf9484d5f95c676b5612b527", + rfc6979: true, + expected: "47fd51aecbc743477cb59aa29d18d11d75fb206ae1cdd044216e4f294e33d5b6" + + "58541d8273675ac15d6e2113d56756febdc85c977716422761d4332d508d0ebe", + }, { + name: "random key 6, blake256(0x06), rfc6979 nonce", + key: "93e9d81d818f08ba1f850c6dfb82256b035b42f7d43c1fe090804fb009aca441", + msg: "06", + hash: "19b7506ad9c189a9f8b063d2aee15953d335f5c88480f8515d7d848e7771c4ae", + nonce: "0b847a0ae0cbe84dfca66621f04f04b0f2ec190dce10d43ba8c3915c0fcd90ed", + rfc6979: true, + expected: "c99800bc7ac7ea11afe5d7a264f4c26edd63ae9c7ecd6d0d19992980bcda1d34" + + "02ac38658b8102e6ebb35707f550ab106d27e2ce7f20e7ed14f8227b1ca2c6ba", + }, { + name: "random key 7, blake256(0x07), rfc6979 nonce", + key: "c249bbd5f533672b7dcd514eb1256854783531c2b85fe60bf4ce6ea1f26afc2b", + msg: "07", + hash: "53d661e71e47a0a7e416591200175122d83f8af31be6a70af7417ad6f54d0038", + nonce: "0f8e20694fe766d7b79e5ac141e3542f2f3c3d2cc6d0f60e0ec263a46dbe6d49", + rfc6979: true, + expected: "7a57a5222fb7d615eaa0041193f682262cebfa9b448f9c519d3644d0a3348521" + + "c2d8d91ba147a3f59557f02465f3e4e29adcc0988cbda169ed4a0e6992b258b1", + }, { + name: "random key 8, blake256(0x08), rfc6979 nonce", + key: "ec0be92fcec66cf1f97b5c39f83dfd4ddcad0dad468d3685b5eec556c6290bcc", + msg: "08", + hash: "9bff7982eab6f7883322edf7bdc86a23c87ca1c07906fbb1584f57b197dc6253", + nonce: "ab7df49257d18f5f1b730cc7448f46bd82eb43e6e220f521fa7d23802310e24d", + rfc6979: true, + expected: "64f90b09c8b1763a3eeefd156e5d312f80a98c24017811c0163b1c0b01323668" + + "6f918ac37ead03f06ee7cf0cbe0927a3598874f5cfae087567ff6fd0904609f2", + }, { + name: "random key 9, blake256(0x09), rfc6979 nonce", + key: "6847b071a7cba6a85099b26a9c3e57a964e4990620e1e1c346fecc4472c4d834", + msg: "09", + hash: "4c2231813064f8500edae05b40195416bd543fd3e76c16d6efb10c816d92e8b6", + nonce: "48ea6c907e1cda596048d812439ccf416eece9a7de400c8a0e40bd48eb7e613a", + rfc6979: true, + expected: "81fc600775d3cdcaa14f8629537299b8226a0c8bfce9320ce64a8d14e3f95bae" + + "faf7d1cdc07134f72fde4f0e306ed09543344a8c9834a5f134226fb2a12971e5", + }, { + name: "random key 10, blake256(0x0a), rfc6979 nonce", + key: "b7548540f52fe20c161a0d623097f827608c56023f50442cc00cc50ad674f6b5", + msg: "0a", + hash: "e81db4f0d76e02805155441f50c861a8f86374f3ae34c7a3ff4111d3a634ecb1", + nonce: "95c07e315cd5457e84270ca01019563c8eeaffb18ab4f23e88a44a0ff01c5f6f", + rfc6979: true, + expected: "0d4cbf2da84f7448b083fce9b9c4e1834b5e2e98defcec7ec87e87c739f5fe78" + + "032b07372963fb913d86e7c911f69aa96a7821191b15210e99b8ce33c2b205a3", + }} -// schnorrSigningTestVectors were produced using the testing functions -// implemented in libsecp256k1. -// https://github.com/bitcoin/secp256k1/blob/258720851e24e23c1036b4802a185850e258a105/src/modules/schnorr/tests_impl.h -var schnorrSigningTestVectors = []SchnorrSigningTestVectorHex{ - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "D1C4C30F60582323A609B56B92270181EB05C3E5AB3E19AE1F768C65C6D09A29", "714D90C991E5D26CBF5771D8A84D087200AAA3197C3217A702ED8D69EA714CAB", "0A3E13BFD0B64C120AA25D27E3CD87678154A4461CE0AD471273927A6459F0C6" + "B9A36629C110ECEEEBBD52E7A5D491BB10AF59C3C73285B9427D1254F28DC460"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "86D9A69D76C1435EDC35347B50B4F944D30EDF8B5CB8E897E95F2C1F1B72D3C3", "60A30BC3BC7CDED4F13C9E3F20F69B8F7B4AB70E60825AE053FC88A2E7046C1F", "D60EFA079B194592A5200C60438A3617691FDE1B5FBCF788D0943A4BB69592F1" + "66D469F48267AA71DAF4BA996BA2BF3A99858C4BF854E2CDFC8AB7E6571D6A8C"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "499FE87D281A8EDEC40D7C29202CA93F9E612760C689543897255CC3B543F2E9", "0C23A2A854DD57AC4773533E84039BA165CA1F79BE8019BDF9EA3173741C67E9", "3C3483E5CDAAF894261071A948B1E21906CEF0293D10A3D20325EA84CC129B32" + "FF07618FAD7BE485A5A1C15DD6EE5485058D03514259714E724879AABCD70C5D"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "258E4C1130CACA9D1CF5DDB589551374DC06491BED02A72CBB8FC7D211E1ED20", "D4045E55A0FED015E1E90934C092C146680090F5538752152F35DAD6ECE70A45", "5EC936DC757F57473A84383F11511B78DB25ABEC5D0DEAE76ECFB30B7A006D9E" + "073D1EFC0C026F41BFBAF9E98FCA42CC6E1946123BD30B5BD27039FFF2D5FC48"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "8E4E9709D63F40167327325CDB6595AD806CABA520FC678993EA872151F6F520", "FD986300F2EB2F3F004D878B8E05C0E8D423DD4B7F112E1396406A0180F14956", "6025A47D8E92D32C417AF55414E6DB6FDEA98D64271C98C5C7FE4C4A6AF75727" + "4106736F0AC7C8782223BCFCDDB2D9396EF5169AE74E81EBE66F1EF3B5982A77"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "F6945B4B5A036BD85915F617054066E16B95392002CE7E7A4B1CD8C2190191A2", "80B060ACE5CB0D9971FB6A8E9A1342D88D144B56FE21A24B9183ED4DACADD30B", "7CF3258EEFE3B837916C21D7E13E0A9363FF6F82444D849D2607DB805B19BF68" + "1B78E1E9C509076E1361A0CE3CE46F4E155EC269D19EDCA9685788728EDD9269"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "1A25DEBF234C081CBFA24EF6A61F59ABE76EA58A91B5D749C31B5FBDFA7D80E9", "AF32FAC33D85C1BFE52C29CE47A9E62CF9E4B7EB66E94DACEDBB61AE0733F826", "31D285DA09369C500E4ADA47D868720852176B813AB25A998E7518855780FF08" + "2C04CE5E1BB33A951496475B594A3B42E740DAC3A0EBED07766CE79FA53DFB56"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "1C158A9FFB6CA28F2C2B4DE2680CCFD166D7FE24ED4E46125FDA392B1B547B24", "DEB515BB6074FBDD04EF7F17F055C82C2BE78C21639AED5F80663A0E89C4C9FE", "77383212DABB1F13B23EEE672C3D2D0CA84A58A148CAD023BC7D27F4C2A1BBD0" + "E3A2DB11E8DDC5D8DA1C55C14214FCA9C876EA0635DC260EDD47C8EE6C4B0F11"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "A11FBCD2EFB92CD714C088A5DAA8BEEE5645B7B70A253EB49F6A08E8E64B2F6F", "C57B3F9CB4E72C757BF477BCC5C6CBFEE8F9BFF35FCDE781F647648955F89D70", "180997C4BC9C6BDA81580330CDC4826B15A6A0B591023F84E5A5CCD8503D0E0D" + "172EA8B127F3BEAE03FBB6E3E20A8324A270905854B4EC4F6734C10A0A87DEE3"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "98BFCC52C846EB49CD728C566F58A62FF2D046D7B4A61CBDE8A2A3607AF5484D", "9A77F52ECFCF560FD9DE0B353CDE562FB1674B5ADD569832808C7015197F2600", "B9CD85998407F3E190BE5144BDF15ADDA8178C1F38C5168A2567C7895698DA40" + "E86BA74E0ACB2C7B9045826921265DAAF31FA05DAE8B83A6F3354B6CB493E52F"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "48DEFD73566CCAC57B1CB1FE7143767646B045A57D84C6C43B68958EDEED0439", "18F462C1C3EC3492613BA5E6C2D12C7A271948DB943A6A7081C8F9E58C308BB2", "EFC76E59819889BAEC540F5D89D28A4404B7EB98D34F941A7CA1D8C525256876" + "679BA0F14E5B2C1F69E1010D1B4FD0265AF34A583059805D5A3D13BBD4C8C83E"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "54415DD3EA817C1338D3AFDBBB142A25C2658B7A0E002BEA64E8DB88F5D62AC0", "56469DE2D40B2D7F0012042EFC7647D265D62254500B3D2864D9830D06C0536C", "DAD150AD11E5814E5DA4451A5D6EEE409779BD47D57C4AE7A788536E7E9426A3" + "DE5F61C9E54CE432BAB0FB8A4D6AF3D81A54062108DC2D23B397B7566AAB3A7A"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "7AC0AD497AD4F45285970132B2F15F48A61D2102EE60630A0345D20577070995", "2B72777C7784D50D538810A30AE3BF430A8A9C15E8658ACAED4D41207BA804D1", "827560F2F92A0905097E381BD0E962421A9E43E105585F9CFC3FB2D321369293" + "E16F37244D106FB0FFF2CF4A239F65C2A01D8C3FAAD187E39509AB0B16C7B72F"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "D7B06ED329566E59C551D71C52E9878DC49A2955159C30C5F373B29858A7CB89", "E76806E6BFDDC81B642A0A880313F8A552F448035B82CB2A91DD6175A497147C", "B772E3BFADC01A5088B9637E2E3D7D3269531091B79FC48ABCEE5A887BD3A11B" + "8BFA61100172D404D4938E097EEFFB0508320657BFE54699CD7490F5DC939333"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "23154117CD21BD4FCCB706F32D0945C7C835C632F02C6AC350B4E6BFDAA7F5BC", "96B0E0189F88AB41C486A65957CE6DEEEEBF2382F5393F9DAD1E8C65ADABEF25", "4D46A811696D6ADFCEDB303C4CA5474912502278D17BDB991C90C7EF54943B14" + "B2AF61F481E885C0B73033730AA78C3E59E7BB01B976D3ADA6EC5620FF9C279C"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "38B077D9A2448A2103CEA6F273C7F3720296A9A1814D0B71947D8AC83D00A86F", "836E462F675F2C9FCBF338F4F11494FF3A1BCA5221F6914B8219C5B189D77D40", "869A3BD110A8D32B6BFD8EF14B914C58276462EFF9CF8CE08279DF8BDAD24593" + "E34709964F528A1F0DFC112CAA2C3D26FE51E875CB6A495B57DCAB6876193511"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "FBD4EC7D96CB1F88BCBFEAF6FB7DDEE0898A3E4246C60FD688784B0F3C86444B", "8C5762E2019C91F24C80F1B4B7382912B573B3E92A8B9BDE3FCF4F902D84874C", "C2A63FE9E15D19D5ED6232A5641C225B7E0F06B4D4F0C53750E7BD889DAE0B36" + "50C13CFD562D104DEFD08C3CB208A4EFDF2EA405795E61D37162BF374E1F9CFF"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "76598BC70790E15BD717E9044BCDBD1B02EE09B9A7359CB77DFD1BC324C6AC54", "0CA72F2D1207B08162535A2C57282FB9B73C842818BB14378DB2F0C202F44BDA", "058A67F66CFFB0C7F14A5F8D98B068264E02DF7D372B0A1658308D6694F3E2D8" + "3B1014276872CD2ED9D19D3CE03AA0AE87F86FF1AC643D2179947552F363FA31"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "AAFEBB955B36B528034142464309C23C2F252F1A1BA97AB34D54FBD35899D896", "6A64A71C9BA0B2C5AD94F490CD76682B47C5EA7EE3B3B43208ADBB855DA9629E", "75541ADBACFE1483A27B2C261FFAD609BD38BDC9FE2C951B1B1A53C0929973C9" + "AC5B33E168B832CD2B65E1A164BBBB45939F26696367461A41EBA76984FD70A9"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "A19FDD9C1A161DC1B272E9484FD60B80374765D89C60928230BA51C671986262", "7B82469A8B8D1E9A12756869E255B70DB0404DB187565D88DFD78618077826F3", "6E5221F9AB9634644B3447C56504BE4B2C6DEC1024DC5E486F0D11E8ABFF7266" + "7096BD1F7FC33C5E1F7AAD7DF06C43FAF8B7A05F312ADFABF586D516B988E880"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "D463F98114D5EFBF206441C3BCB07B5D0358B9ABCD7212700D1E85A3B59B4B14", "7507E3E1CD0CAF7E951B8F46C7A52717203AA6922F5B3AA4B813AE05B3BED616", "8CEE361B3E0FB92B24CBC9E239E5D80DA558354E0108715286EFEFDEF55275B0" + "A68CAFB8E5C8499EE3895F24C007AA9A43E708B8A2959F43A8A9F8C14E4B2B8C"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "F15B442705E64A36688564BB3E5DC9ED8469AC73CE1794E549D31C34A8CF7367", "2C755FB91D25C48F0340519A54DF0026F7F6DC06B8D9DB3BC50BBF6A82344CCA", "45E262112967F578ABC595C6D12A887D60BCEB91FEA1F83EE6488F89159451ED" + "944891E90094B663718799A3729D0423FA95D7D327E480BE1556DE1F9D8C29DB"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "27261595EF702F48336F47DD2317461C06157C0868BD0E18A27BFA393551E5EE", "3DA9A1F356C519B7E4B7ACD05A648D4BEE8539ACF4B60D291E68D76B357D308B", "019C854E1D900122F706721816DB3895C6772B9EE254F39B326895D299910AF6" + "F58A6281C7DECCD1104094E1D84A5C182D549B55F834DB610F7CA0B5CD74A718"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "FF553D981379C5046D1927B50DB2B8D24A0274C09F7F4FBDDF100C59398DCC0E", "6470BE1A8EA8E9328B5F5F83B64677F4E346AEFCFCE71D9725E062998E0DCF42", "CE38C701700CBFA7442BB4E51C0C6F22FCCE1F39D4B22ADF5D5A910CD8E22CDD" + "55DC9688ED2F2ABFCEEB40C8FD217F274F9C369C8ADEF703AF7772C967C06F84"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "F38B04C155684AF2C717223DCC91EBC828B2D5B09EE807AE45C131693EC63637", "A8A1BEF67F7A3847DB2A57F3724467EDCC6454D29CA0E399F2A492898E69E497", "3F95D1916590BC74B6FDC4F3E412ED29E040358F17DFDD209C0F4AE04C9E94EA" + "D8281CCD545F57D80EA420CFDE5F81E350333BED9A39E116F72B17635AB57A92"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "C97757D41207BECB21EC0B4EB4AF7450F06124F43701C0260A46734F7C3D67B0", "D585B47F24BB9BC50A555A7FF2E706140404BCE393B2ADBBD927D3B4608294E9", "66BD8B3E23E11BE273AFA3257E9EF2D979A957E5C6B97A7966CFF11B4B581E67" + "EECA4295F554E20DB9F59793130595AAD73641C813AA15028190130592D21E95"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "2B58BCED7852B0F4198A0802CA0887DFA819BD73AE54E8EEE55FA4C76B28BE29", "638E732221DF5962F9ABD1FC69375058D20215F3ED226F6CCEED2C6F9D91B56B", "8AE5EFDF614C21FD637A3B26BB5655E4922F2598826A10DE2218B8BF4B7328F2" + "611C67385E260B9DD75C59623A003ECAD7F73811BE8BC7F015574ECFEBE3A9DD"}, - {"304502210088BE0644191B935DB1CD786B43FF27798006578D8C908906B49E89", "0371B3651E7ABC533801290E1C7E1D91D9AEB000ECF44FD0500773699A1C95C7", "6B7439B47606111ABBDE3429B6BD2938F0CEE87E7507A265655BAEFE25B48A16", "F3353583290AF1CC35AD4929633A0044EE4E7422E260AF341F597D240257C51D" + "F2813DA1E04C64A03FBBD57834897D6DEC8D441D1DECF80746502081355BAA3C"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "FFFFFFFFFF03000000FCFFFFFFFFFFFFFF030000000000007CE0FFFFFFFFFFFF", "E0FFFFFFFF1F000000E0FFFFFFFFFFFFFFFFFFFFFFFFFFFF1F00E0FFFFFFFFFF", "D1637C2FFDBAF642250F8B54FEE34A98CB7DE641BA1E9EFA9A20EA874A5FDCFA" + "F0A7B370F9458C0562C0AEF18BBBB84D50BAA6533E05F2C11DDEFC1E4BB1A6C5"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "0CF8FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFF070000F8FF3F0000", "FFFFFFFFFF07000000000000C001000000E0FF3F00F0FFFFFFFFFFFFFF1F0000", "C0DB1A31A4E93F49E53C48CC1766CCC51B9A214400CC6A784090E7E0409D49BE" + "A0CAE6C3073B305E89A810F64558CC636F1F59049D00D4D7824A8BC1CB0FBEC4"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "E1FFFFFFFFFFFF00F07F0000000000000000E0FFFFFF3F0000FEFF0FF8FFFFFF", "000000000000000000000000F0FFFFFF1F3000E0FF7FF8FFFFFFFFFF0F000000", "AE12E3F8D79D596E023A250D9DDDB150ED35509F6F4B80488551CD46F1CA9D8A" + "78ED5DB488348DA811E1E9A192AF4E250F1EE3DC46C2A035E19D39D8FEAF9FEB"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "9FFFFFFFFFFFFFFFFFFFFFFFDF00FCC1FFFFFFFFFFFFFFFFFFFFFFFFFFFF0F00", "FFFFFFFFFFFFFFFFFFFF1F0000000000000000F8FFFF0F000000E0FFFFFFFFFF", "FE984A34D9D7B673DFCA1BAADC1F39C546BAA222E253E66726CA3045CCCC948B" + "A1DF6CBA13DD65FDBAAD8017A5C1C95331DEE2C07FFCDFE204ACD3E70028CA11"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "000000C03FFCFFFF03000000FFFF7FF8FFFF1F000000FFFFFFFF0F0000FC1F00", "FEFFFFFFFF1F00000000000000000000000000FFFF3F00E0070000FCFFFFFF03", "4BF5AD0E0C37DCE99BC56CD2D3AB0FDDF1321AE371E4F7D5E113D1D26793C780" + "DF0E1E0B5D69D151DD08639E25171A73C0CEA6F983F6B93ABCD5CD187A1853D8"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "FFFFFCFFFFDF010000000000F0FFFF3F000000FC1F007800FEFFFFFFFFFF0700", "00000000C0FFFFFFFFFFFFFFFFFFFFFF00FEFF03000000000080007E00000000", "3CCCCA01404CF09A1E906A00F61C1559FC3C8F1D29516D24D6BBD94A51664E0D" + "44B9CBA23BEC4D7DDA36DEA03F8D6077057C01ED9E33105629A9CC776DBE8985"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "00E0FFFFFFFFFFFFFFFF03FE3F000000000000000000FF1F0000000000000000", "FF3F00000000FEFFFFFF3F0000F8FFFFFF0F00C0FFFFFFFFFFFF0700000000C0", "2E4B97107F07E264BB3E7EBA6E019DE8B5FF11F2E2F42C92EFEB50DE38E9EC5D" + "2B3912BE0B0035FC5C8EC889312E4B47AAF460AD4A16752CE5266F395622D8BD"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "000000F8FFFFFFFFFF010000000000300000000000F8FF00000080FFFFFFFFFF", "FFFFFF07C0FF07000000980FE0FFFFFF0100000000000FE0FF0F0000FCFFFFFF", "52CC053205817B8727F8AEB8508345B77FC22F3C5CBC0A473D5AF2AD27F6C155" + "1DA91F27C36FED4DD90F61DD36457014F335C0773A0FBF423416294AE78E43FB"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "FFFFFFFFFFFFFFFFFFFFFCFFFFFFE3FFFFFFFFFFFF0F00E0FFFFFF0000F0FF1F", "FFFFFFFFFF3F0000C0FFFFFFFFFFFFFF0F0000F0FF7F1E00000080FFFFFF07FC", "95F2E4ACECBF9603303FDB868FD3F9DCB1D4DFD6C311FE00EA26E65B740C2B9E" + "BD6038044DBE6EF5791991EE1E968BF9D25402EAD2497C212EC526EF4C6EEF3A"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "0F0080FFFFFFFF0F00000000000000C0FFFFFFFFFFFFFF07000000C0FFFFFFFF", "FFFFFFFFFFFF01E0FFFFFFFFFFFFFFFF03F8FF7F00F0FFFF0700000000000000", "D163552127BF351D7918F66741435865FC04694090A4A9B3FDB2BAC13462A05C" + "8457E0464AEE6B27036C39066F0E1DF3DF952DF258FED6A42B9450F0FF27D9EB"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "003C803F00FFFFFFFFFFFFFFFF7F0000000000FE0700000000000000000000FF", "FF01000000C0FFFFFFFFFF3F00E00300003C000000E0FFFFFFFFFFFFFFFFFFFF", "00846EE6532D8B30C8912117FCBEF293EE79E212BA4507F33C8B90AF8DE35C01" + "8450F88A1B0F7EBCCBC155C30A68D51E60FFF9DC769B36E47C1AE34EDE9FA37B"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "FFFFFFFFFFFFFFFFFFFFFFC1FFFFFFFFFF010000000080FFFFFFFF1F00C0FFFF", "FFFFFFFFFFFFFFFF010000C0FF81FF81FF100000000000000000000F0000F00F", "0F4C75E1A7EBA72A2D0F014F477FCC765E6EC36350F92EF75F08EEB4C1C3195F" + "18368C0E7B4510534443B8279C741D3F2D1B01766B051B452C3D0698D8E8D08D"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "FFFFFF0100FCFFFF7F0000000000003F0000000000F0FFFFFFFF7FE0FFFFFFFF", "FFFFFFFFFF7FFFFFFFFFFF070000000000000000E0FFFFFFFFFF030000FCFFC3", "C05CFF7CE3C072431F05213A27ECD81288C83CBE48C39C43633B54B9AC0E6890" + "BC580EC26EFDEB276062CFE6B978F55430F757438183AA63B5F4B5226AAF675F"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "FFFF000000FFFFFFFFE1FFFFFFFFFFFFFF030000000000000000F0FFFF00FFFF", "FFFF0700000000C0FFFFFFFFFFFFFFFFFF1F00C0FFFFFFFF0700FFFF03000000", "8CE4A5F3CD68B81548A2F7D59CB610FAE94AC52FA07ED40A769F08552E5C5BE0" + "54C46CAE9374DC4A10F8B6D36A1A9D7C4B5AB09415DDF7D229193D9349D511D1"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "0000000000FFFFFFFFFFFF030000000000000000F81FE0FF3F00FEFF0F0000FE", "000000C0FFFF7F0000F8FFFFFFFFFF07000000F0FFFFFFFFFFFFFFFFFFFFFF0F", "A338C9A7F05E31D8D6870232B88E57B5EDD92A85423A9C256BE52B0DA92579E5" + "6467E2D50FAA93D2A56150ABC03D9DF69590E3AD72C4CC7D0C2FAC5AFEFE9085"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "0000000000000000E0FFFF0700F8FFFFFFFF1F00000000000000000000000000", "FFFF0F00E0FF1F00000000000000F0FFFFFFFFFFFF010000000080FFFFFFFFFF", "FFC45EC42040A6F58B402AEA3C18E40614842BA7EFA73FF843B896FB426CCFA7" + "AF9A01F69B5CC37977014A83BCB28C1E8847B897159B6069A6F988DE634CC2AB"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "07000000000000000000000000F8FF7F00FFFFFFFFFF00000000C0FFFFFFFFFF", "000000000000FC0F00000000000000000000000000FEFF0300C4FFFFFF3F80FF", "F25FD62A0081100E01A501FBF1EC42678C6B9BAE722ABD4F4979E99E8CC06E25" + "8FB87682E70ABC22E0EFE457C76D78BF293BCE128381AE5EDD03A4195CA8AD40"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "80FFF8FF3FFFFFFFFFFFFFFFFFFFFFFFFFFFF1FFFFFFFF1F0000FEFFFFFFFF3F", "F8FFFFFFFFFFFFFF0FFFFF3F00000000000000000000000000C0FF0700000000", "075A4EB0F330215AEECA9E9180F129BC6E2F0A53A49FFDE5A272C3F04DEDA081" + "8BEEBDC42915B1EE2106DB38D310E70B1CD1CCF228B0B3D3640B65289988DEDE"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "0100FEFF0100FFFFFFFF03000000FCFFFFFFFF3F0000E0FFFF01000000000000", "F8FF000000C0FFFF07000000000000000000FCFFFFFFFF03E001E0FFFFFFFFFF", "D1E8298DA8B147ABB128536F773BF456A3628719A237026BF5B458C8776F325B" + "85A448D3181B429C8AAC59343DD3E4DEBDBE01C44B8E6CE03C4F5FB4020DEBB9"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "00FEFFFFFF7F00FFFFFFFFFFFFFFFFFFFFFF0700FCFFFF00000000000080FF80", "0100000000000000000000000080FF1F0000C00300F0FFFF0700000000000000", "144B8536728044AEF88AF33D3087CCB1D1F50C41A5C972361469818A6FA498D4" + "9A536497E36544F704560801CE46DA59713B9B7287E100F77A69B9E88BE95B9F"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "00000000E0FFFFFFFF0100000000FFFFFF7F0000C0FFFFFF3F0080FFFFFFFFFF", "0000000000F0FFFF0FF8FF0300000000000000C0FFFFFFFF010000F8FFFF1F00", "ACAA7BE8ED867701F671DB71020483705480618CEF52BD96C0306ECED854702B" + "BF8CB65D50E21B0FAB21D6AD11DDAA0183CFE29F2FE348DF4A3E73A07111E313"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "000000000000000000C0FF0FFCFFFFFFFFFFFFFFFFFFFF1F0000000000000000", "0080FFFFFFFFFF000000C0FFFFFFFF1F00FCFFFFFFFFFF7F000000E0FFFF00E0", "F71708DB249A209F44771F98E3D659F5139823835B188982EE195A50D3D860B4" + "5226533153B14AA89D5F7958B9799BB893BFADC9528C871087AC795ADE224595"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "00000000E0FF7F0000000000000080FF1FF8FFFFC1FFFFFF3F00FFFF03000000", "01000000000000000080FFFFFFFFFFFF3F0000FEFFFFFFFFFF0F0000F8FF1F00", "54A25E83137863A94778D33F031BAC8DC10F39913A8B3FD792660F1034C70DBD" + "2B62E4B73DBFF01B97401ECD2F03DF81090FEC1A59FA161687A2BAAAEEE514DD"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "80FFFFFFFFFFFF0300F8FFFFFFFF1F00000000C0FF0300001C0080FF1F7F0000", "FF7FC0FFFFFFFFFFFFFFFFFF030000FCFF3F0000F0FFFFFFFFFFFF0F00060000", "75161FC21626DD84BD58778207FC7F58506E11204A95A603D5E8E6CA575CE2F1" + "F5984BFA2C970641936FACD9C9778AAE02EC89483AF879D0BC063FB516744E62"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "000000FCFFFF0100000000000000C0FFFFFFFFFFFFFFFFFFF7FFFFFF1F000000", "00FCFF3FC0FFFF0100000000000000004000000000FF7F00000000E0FFFF3F00", "971FA2BC49EBA95D1CCC10706D34C809ECB6B6521B4B028B3029E104404E7DE8" + "1833F25C71C6A100CDCACB2E154A1AA2B140671A79D001913F4AFDF830C255C2"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "FF030000E0FFFFFF3F80FFFF017E00FCFF0100FCFFFFFF010000F0FF07FCFFFF", "000000000080FFFFFFFF03FCFFFFFFFF0700000000E0FF0F0000000000F8FFF0", "7655EEC4926FEC2B7D0ABFB1A63333E9B9CB893A9366CC597090F55CD0D2602F" + "2827D561883C5D4924712D0EE305891E5869132F254F4AAD8E553E10A85975AE"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "000000FEFFFFFF7F0000008003000000000000000080FFFFFF07FEFFFFFF7F00", "FFFFFFFFFFFF3FF8FFFFFFFFFFFF0100000000FCFFFFFFFFFFFF0700E0FF0100", "EDE211DEE2487804585D84DAE822BF376C318CB44D6EF6EA9526BF1C26C6AB6A" + "5BF3BD71AA4A9D8990055BF9AA49AD82BF549B86D0E06B7D90F601E45C167F39"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "0700000000000000FCFFFFFFFFFFFF0084FFFF0000F8FFFFFF0700FEFFFFFFFF", "00001C00FFFF070000C0FF0100F0FF030000C0FFFFFFFF00FEFFFFFFFFFF0100", "2836BD0AD158AFA88ACAF13A0EC8DCE4414EEC0D282B2BA18820A712E252493B" + "E03F8FB67706EF558F2356B4385A25511613BB8D5132C91CD5084CAB5E56323B"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "0000000000FEFF0F0000000080FFFFFFFF0F000000FFFFFFFF0100F0FFFF0700", "000000000000000000FFFF03809FFFFFFFFFFFFF0F0000000000000000000000", "2A5837844FDEDC8C5FD40350737EB0412DFBEA43AF75736D2669D9E7A4341917" + "0EECFF456B3C3BA4AD1B74DC45C7FA0D77DDC52A60943687008C768839149E7C"}, - {"304402207C7BC9E2D115C4C5C3E50950E69B30A9810BD73946A6D23C4ACBFF2E", "FFFF01000000FEFFFFFFFFF3FFFFFFFFFFFF7F000000000000F07FF8FFFFFFFF", "FFFFFFFF80FFFF07FEFF7F00000000000000FC07FCFFFF0700000000E0FFFFFF", "93E083E71C14BA94479CBE92213A56FF2ECFF8F2B085B2B3AA5CC6E8FEFAEAC0" + "76444710354091BB4FE9A218E875885F81DD787241A766C4E0422C5C1D7AD271"}, -} + for _, test := range tests { + privKey := hexToBytes(test.key) + msg := hexToBytes(test.msg) + hash := hexToBytes(test.hash) + nonce := hexToBytes(test.nonce) + wantSig := hexToBytes(test.expected) -type SchnorrSigningTestVector struct { - msg []byte - nonce []byte - priv []byte - sig []byte -} - -func GetSigningTestVectors() []*SchnorrSigningTestVector { - tvs := make([]*SchnorrSigningTestVector, 0, len(schnorrSigningTestVectors)) - for _, v := range schnorrSigningTestVectors { - msg, _ := hex.DecodeString(v.msg) - nonce, _ := hex.DecodeString(v.nonce) - priv, _ := hex.DecodeString(v.priv) - sig, _ := hex.DecodeString(v.sig) - lv := SchnorrSigningTestVector{msg, nonce, priv, sig} - tvs = append(tvs, &lv) - } - - return tvs -} - -// Horribly broken hash function. Do not use for anything but tests. -func testSchnorrHash(msg []byte) []byte { - h32 := make([]byte, scalarSize) - - j := 32 - for i := 0; i < 32; i++ { - h32[i] = msg[i] ^ msg[j] - j++ - } - - return h32 -} - -func TestSchnorrSigning(t *testing.T) { - tRand := rand.New(rand.NewSource(54321)) - tvs := GetSigningTestVectors() - for _, tv := range tvs { - pubkey := secp256k1.PrivKeyFromBytes(tv.priv).PubKey() - - sig, err := schnorrSign(tv.msg, tv.priv, tv.nonce, testSchnorrHash) - if err != nil { - t.Fatalf("unexpected error %v", err) + // Ensure the test data is sane by comparing the provided hashed message + // and nonce, in the case rfc6979 was used, to their calculated values. + // These values could just be calculated instead of specified in the + // test data, but it's nice to have all of the calcuated values + // available in the test data for cross implementation testing and + // verification. + calcHash := chainhash.HashB(msg) + if !bytes.Equal(calcHash, hash) { + t.Errorf("%s: mismatched test hash -- expected: %x, given: %x", + test.name, calcHash, hash) + continue } - - cmp := bytes.Equal(sig.Serialize()[:], tv.sig[:]) - if !cmp { - t.Fatalf("expected %v, got %v", true, cmp) - } - - // Make sure they verify too while we're at it. - _, err = schnorrVerify(sig.Serialize(), pubkey, tv.msg, - testSchnorrHash) - if err != nil { - t.Fatalf("unexpected error %v", err) - } - - // Screw up the signature at a random bit and make sure that breaks it. - sigBad := sig.Serialize() - pos := tRand.Intn(63) - bitPos := tRand.Intn(7) - sigBad[pos] ^= 1 << uint8(bitPos) - _, err = schnorrVerify(sigBad, pubkey, tv.msg, - testSchnorrHash) - if err == nil { - t.Fatalf("expected an error, got %v", err) - } - } -} - -type SignatureVerParams struct { - pubkey *secp256k1.PublicKey - msg []byte - sig *Signature -} - -func randSigList(i int) []*SignatureVerParams { - r := rand.New(rand.NewSource(54321)) - - privKeyList := make([]*secp256k1.PrivateKey, i) - for j := 0; j < i; j++ { - for { - bIn := new([32]byte) - for k := 0; k < scalarSize; k++ { - randByte := r.Intn(255) - bIn[k] = uint8(randByte) - } - - pks := secp256k1.PrivKeyFromBytes(bIn[:]) - if pks == nil { + if test.rfc6979 { + calcNonce := secp256k1.NonceRFC6979(privKey, hash, nil, nil, 0) + calcNonceBytes := calcNonce.Bytes() + if !bytes.Equal(calcNonceBytes[:], nonce) { + t.Errorf("%s: mismatched test nonce -- expected: %x, given: %x", + test.name, calcNonceBytes, nonce) continue } - privKeyList[j] = pks - r.Seed(int64(j) + 54321) - break } - } - msgList := make([][]byte, i) - for j := 0; j < i; j++ { - m := make([]byte, 32) - for k := 0; k < scalarSize; k++ { - randByte := r.Intn(255) - m[k] = uint8(randByte) - } - msgList[j] = m - r.Seed(int64(j) + 54321) - } - - sigsList := make([]*Signature, i) - for j := 0; j < i; j++ { - r, s, err := Sign(privKeyList[j], msgList[j]) + // Sign the hash of the message with the given private key and nonce. + gotSig, err := schnorrSign(hash, privKey, nonce, chainhash.HashB) if err != nil { - panic("sign failure") + t.Errorf("%s: unexpected error when signing: %v", test.name, err) + continue } - sig := &Signature{r, s} - sigsList[j] = sig - } - sigStructList := make([]*SignatureVerParams, i) - for j := 0; j < i; j++ { - ss := new(SignatureVerParams) - ss.pubkey = privKeyList[j].PubKey() - ss.msg = msgList[j] - ss.sig = sigsList[j] - sigStructList[j] = ss - } + // Ensure the generated signature is the expected value. + gotSigBytes := gotSig.Serialize() + if !bytes.Equal(gotSigBytes, wantSig) { + t.Errorf("%s: unexpected signature -- got %x, want %x", test.name, + gotSigBytes, wantSig) + continue + } - return sigStructList -} - -// Use our actual hashing algorithm here. -func TestSignatures(t *testing.T) { - r := rand.New(rand.NewSource(54321)) - - numSigs := 128 - sigList := randSigList(numSigs) - - for _, tv := range sigList { - pubkey := tv.pubkey - sig := tv.sig - - // Make sure we can verify the original signature. - _, err := schnorrVerify(sig.Serialize(), pubkey, tv.msg, - chainhash.HashB) + // Ensure the produced signature verifies as well. + pubKey := secp256k1.NewPrivateKey(hexToModNScalar(test.key)).PubKey() + ok, err := schnorrVerify(gotSigBytes, pubKey, hash, chainhash.HashB) if err != nil { - t.Fatalf("expected an error, got %v", err) + t.Errorf("%s: signature failed to verify with error: %v", test.name, + err) + continue } - - ok := sig.Verify(tv.msg, pubkey) if !ok { - t.Fatalf("expected %v, got %v", true, ok) - } - - // Screw up the signature at some random bits and make sure - // that breaks it. - numBadBits := r.Intn(2) - sigBad := sig.Serialize() - // (numBadBits*2)+1 --> always odd so at least one bit is different - for i := 0; i < (numBadBits*2)+1; i++ { - pos := r.Intn(63) - bitPos := r.Intn(7) - sigBad[pos] ^= 1 << uint8(bitPos) - } - _, err = schnorrVerify(sigBad, pubkey, tv.msg, - chainhash.HashB) - if err == nil { - t.Fatalf("expected an error, got %v", err) + t.Errorf("%s: signature failed to verify", test.name) + continue + } + } +} + +// TestSchnorrSignAndVerifyRandom ensures the Schnorr signing and verification +// work as expected for randomly-generated private keys and messages. It also +// ensures invalid signatures are not improperly verified by mutating the valid +// signature and changing the message the signature covers. +func TestSchnorrSignAndVerifyRandom(t *testing.T) { + // Use a unique random seed each test instance and log it if the tests fail. + seed := time.Now().Unix() + rng := rand.New(rand.NewSource(seed)) + defer func(t *testing.T, seed int64) { + if t.Failed() { + t.Logf("random seed: %d", seed) + } + }(t, seed) + + for i := 0; i < 100; i++ { + // Generate a random private key. + var buf [32]byte + if _, err := rng.Read(buf[:]); err != nil { + t.Fatalf("failed to read random private key: %v", err) + } + var privKeyScalar secp256k1.ModNScalar + privKeyScalar.SetBytes(&buf) + privKey := secp256k1.NewPrivateKey(&privKeyScalar) + + // Generate a random hash to sign. + var hash [32]byte + if _, err := rng.Read(hash[:]); err != nil { + t.Fatalf("failed to read random hash: %v", err) + } + + // Sign the hash with the private key and then ensure the produced + // signature is valid for the hash and public key associated with the + // private key. + sigR, sigS, err := Sign(privKey, hash[:]) + if err != nil { + t.Fatalf("failed to sign\nprivate key: %x\nhash: %x", + privKey.Serialize(), hash) + } + sig := NewSignature(sigR, sigS) + pubKey := privKey.PubKey() + if !sig.Verify(hash[:], pubKey) { + t.Fatalf("failed to verify signature\nsig: %x\nhash: %x\n"+ + "private key: %x\npublic key: %x", sig.Serialize(), hash, + privKey.Serialize(), pubKey.SerializeCompressed()) + } + + // Change a random bit in the signature and ensure the bad signature + // fails to verify the original message. + goodSigBytes := sig.Serialize() + badSigBytes := make([]byte, len(goodSigBytes)) + copy(badSigBytes, goodSigBytes) + randByte := rng.Intn(len(badSigBytes)) + randBit := rng.Intn(7) + badSigBytes[randByte] ^= 1 << randBit + badSig, err := ParseSignature(badSigBytes) + if err != nil { + t.Fatalf("failed to create bad signature: %v", err) + } + if badSig.Verify(hash[:], pubKey) { + t.Fatalf("verified bad signature\nsig: %x\nhash: %x\n"+ + "private key: %x\npublic key: %x", badSig.Serialize(), hash, + privKey.Serialize(), pubKey.SerializeCompressed()) + } + + // Change a random bit in the hash that was originally signed and ensure + // the original good signature fails to verify the new bad message. + badHash := make([]byte, len(hash)) + copy(badHash, hash[:]) + randByte = rng.Intn(len(badHash)) + randBit = rng.Intn(7) + badHash[randByte] ^= 1 << randBit + if sig.Verify(badHash[:], pubKey) { + t.Fatalf("verified signature for bad hash\nsig: %x\nhash: %x\n"+ + "pubkey: %x", sig.Serialize(), badHash, + pubKey.SerializeCompressed()) } } }