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
This commit is contained in:
parent
a8dc9d41f1
commit
97294f5b41
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user