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