schnorr: Use extra data for RFC6979 nonces.

This modifies the signing code to use extra data that specifically
identifies the custom schnorr signature scheme used when generating
RFC6979 nonces to ensure the same nonce is not generated for the same
message and key as for other signing algorithms such as ECDSA.

While nobody realistically should ever be signing the same message with
the same private key with both Schnorr and ECDSA at the same time, it's
safer to ensure that even if they do, the same nonce value isn't used
since that could lead to revealing the private key.

It also updates the relevant tests to use the new deterministic nonces
and signatures which have been independently verified with the Sage
computer algebra system.
This commit is contained in:
Dave Collins 2020-03-29 04:44:35 -05:00
parent 4fcea17b28
commit bcc1a227a6
No known key found for this signature in database
GPG Key ID: B8904D9D9C93D1F2
2 changed files with 59 additions and 44 deletions

View File

@ -31,6 +31,19 @@ const (
var (
// bigZero is the big representation of zero.
bigZero = new(big.Int).SetInt64(0)
// rfc6979ExtraDataV0 is the extra data to feed to RFC6979 when generating
// the deterministic nonce for the EC-Schnorr-DCRv0 scheme. This ensures
// the same nonce is not generated for the same message and key as for other
// signing algorithms such as ECDSA.
//
// It is equal to BLAKE-256([]byte("EC-Schnorr-DCRv0")).
rfc6979ExtraDataV0 = [32]byte{
0x0b, 0x75, 0xf9, 0x7b, 0x60, 0xe8, 0xa5, 0x76,
0x28, 0x76, 0xc0, 0x04, 0x82, 0x9e, 0xe9, 0xb9,
0x26, 0xfa, 0x6f, 0x0d, 0x2e, 0xea, 0xec, 0x3a,
0x4f, 0xd1, 0x44, 0x6a, 0x76, 0x83, 0x31, 0xcb,
}
)
// NewSignature instantiates a new signature given some R,S values.
@ -309,7 +322,8 @@ func Sign(priv *secp256k1.PrivateKey, hash []byte) (r, s *big.Int, err error) {
for iteration := uint32(0); ; iteration++ {
// Generate a 32-byte scalar to use as a nonce via RFC6979.
kB := nonceRFC6979(priv.Serialize(), hash, nil, nil, iteration)
kB := nonceRFC6979(priv.Serialize(), hash, rfc6979ExtraDataV0[:], nil,
iteration)
sig, err := schnorrSign(hash, pA[:], kB)
if err == nil {
r = sig.r

View File

@ -32,10 +32,10 @@ func TestSchnorrSignAndVerify(t *testing.T) {
key: "0000000000000000000000000000000000000000000000000000000000000001",
msg: "01020304",
hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7",
nonce: "4154324ecd4158938f1df8b5b659aeb639c7fbc36005934096e514af7d64bcc2",
nonce: "d4e18f08eb87073cb2a6707def02007315f7349c3c132590a0088fefece557ef",
rfc6979: true,
expected: "c6c4137b0e5fbfc88ae3f293d7e80c8566c43ae20340075d44f75b009c943d09" +
"fe359056a1f6090fe2599acbe6b315be1e2dc7a675545ec96bb8a12d1a144deb",
expected: "4c68976afe187ff0167919ad181cb30f187e2af1c8233b2cbebbbe0fc97fff61" +
"e9ae2d0e306497236d4e328dc1a34244045745e87da69d806859348bc2a74525",
}, {
name: "key 0x1, blake256(0x01020304), random nonce",
key: "0000000000000000000000000000000000000000000000000000000000000001",
@ -50,10 +50,10 @@ func TestSchnorrSignAndVerify(t *testing.T) {
key: "0000000000000000000000000000000000000000000000000000000000000002",
msg: "01020304",
hash: "c301ba9de5d6053caad9f5eb46523f007702add2c62fa39de03146a36b8026b7",
nonce: "55f96f24cf7531f527edfe3b9222eca12d575367c32a7f593a828dc3651acf49",
nonce: "341682d3064ec802646be9c4a0fd97f8480807fcac3179e97098b8597de909dc",
rfc6979: true,
expected: "e6f137b52377250760cc702e19b7aee3c63b0e7d95a91939b14ab3b5c4771e59" +
"57341a8bb99ea27ccebee775fe6ea24b560763bb499d03354e739c3cd32d6629",
expected: "c6deb3a26c08842612bfd4411a91c90f64cfea2206c758cd1352ff2b93cc3611" +
"c9ffe5dd240f52d3ee199e29373030a5d795b674cd4da991fd07f5edefc3817d",
}, {
name: "key 0x2, blake256(0x01020304), random nonce",
key: "0000000000000000000000000000000000000000000000000000000000000002",
@ -68,10 +68,10 @@ func TestSchnorrSignAndVerify(t *testing.T) {
key: "0000000000000000000000000000000000000000000000000000000000000001",
msg: "0102030405",
hash: "dc063eba3c8d52a159e725c1a161506f6cb6b53478ad5ef3f08d534efa871d9f",
nonce: "aa87a543c68f2568bb107c9946afa5233bf94fb6a7a063544505282621021629",
nonce: "cfbabebb15824ff3cfa5f4080a8608aaa9db891541851b27275c61db9d6d7e1c",
rfc6979: true,
expected: "dda8308cdbda2edf51ccf598b42b42b19597e102eb2ed4a04a16dd57084d3b40" +
"5798fd44eba62ca35aa7efb27677414b46b7adfe6c523ccc5b18019314acaa71",
expected: "461646005002d673c2e903f3c9ff2c2455e60810445ee486b9c36152287bc41a" +
"1b54733190ed128e466c5263a404f17344b73426d7faf00325c7a0af04be6cfe",
}, {
name: "key 0x1, blake256(0x0102030405), random nonce",
key: "0000000000000000000000000000000000000000000000000000000000000001",
@ -86,10 +86,10 @@ func TestSchnorrSignAndVerify(t *testing.T) {
key: "0000000000000000000000000000000000000000000000000000000000000002",
msg: "0102030405",
hash: "dc063eba3c8d52a159e725c1a161506f6cb6b53478ad5ef3f08d534efa871d9f",
nonce: "a13d652abd54b6e862548e5d12716df14dc192d93f3fa13536fdf4e56c54f233",
nonce: "f7a8f640df67ba21b619eb742a73cbfc58739153b8772d5b2f8781f33d45e554",
rfc6979: true,
expected: "122663fd29e41a132d3c8329cf05d61ebcca9351074cc277dcd868faba58d87d" +
"e2d0532d74bcff2c8b643d098546590262f42f01826c28b656cf67e89514e655",
expected: "f3632492a72eb8e175b93e1eb31ef382e49f3f3fe385892523beaef9171aa15d" +
"441e1a94ab9b1dafa93e0d48d08c26513d53449197e761c74bebb2fae97525c3",
}, {
name: "key 0x2, blake256(0x0102030405), random nonce",
key: "0000000000000000000000000000000000000000000000000000000000000002",
@ -104,91 +104,91 @@ func TestSchnorrSignAndVerify(t *testing.T) {
key: "a1becef2069444a9dc6331c3247e113c3ee142edda683db8643f9cb0af7cbe33",
msg: "01",
hash: "4a6c419a1e25c85327115c4ace586decddfe2990ed8f3d4d801871158338501d",
nonce: "edb3a01063a0c6ccfc0d77295077cbd322cf364bfa64b7eeea3b20305135d444",
nonce: "c23097718bd90c10ba2e99abff92f21c0eec71796712a772f0ce10f2b1bc6f5f",
rfc6979: true,
expected: "ef392791d87afca8256c4c9c68d981248ee34a09069f50fa8dfc19ae34cd92ce" +
"14f6553176e5ca434831720f02c4c0c6b6228338cfa00aaae4aa6da5b72aae05",
expected: "0b89d1fb10635e4a5da463c7339fd0f8d2e7d205a8288d4f973635beb8b59f7f" +
"e7c69c94ac665d14c105c2b4ba3b4c59a7819f8ecfe0d9f5f0c93a9f6d7ef447",
}, {
name: "random key 2, blake256(0x02), rfc6979 nonce",
key: "59930b76d4b15767ec0e8c8e5812aa2e57db30c6af7963e2a6295ba02af5416b",
msg: "02",
hash: "49af37ab5270015fe25276ea5a3bb159d852943df23919522a202205fb7d175c",
nonce: "af2a59085976494567ef0fc2ecede587b2d1d8e9898cc46e72d7f3e33156e057",
nonce: "342d8326464a0b5866091126e2aa29a960eba8e47dba7bef355b18b3f9011793",
rfc6979: true,
expected: "886c9cccb356b3e1deafef2c276a4f8717ab73c1244c3f673cfbff5897de0e06" +
"0ef8e0ed66405379d05cf34934ccb3a38a8d800d35d4f0577b96f3cc316fb09d",
expected: "533e99ee9c838af4cc0280b0223ab0560e7e2083694bd5b0cab3c0cb80bc2e1e" +
"cf4f777f046a18b7f8eb2c29325945025e6d5a145176b1a1de9aca7d882ca5d2",
}, {
name: "random key 3, blake256(0x03), rfc6979 nonce",
key: "c5b205c36bb7497d242e96ec19a2a4f086d8daa919135cf490d2b7c0230f0e91",
msg: "03",
hash: "b706d561742ad3671703c247eb927ee8a386369c79644131cdeb2c5c26bf6c5d",
nonce: "82d82b696a386d6d7a111c4cb943bfd39de8e5f6195e7eed9d3edb40fe1419fa",
nonce: "710a4f1a3bee3567b53bd4dd0c9c0e55d76981a5ed488223ca0583bf8a563951",
rfc6979: true,
expected: "6589d5950cec1fe2e7e20593b5ffa3556de20c176720a1796aa77a0cec1ec5a7" +
"194f86c06b44bde164fcaaac03452c55dde0ba51a27c6397363b54cb705d3afa",
expected: "95c966fd6435d505a492548370b29a3c40efc3fefa3e1d997b3e2788cc33836e" +
"84a19d1d32c98f266f57f12c4363c0d9d432ca76985c6b7cb21c9970e14c75d8",
}, {
name: "random key 4, blake256(0x04), rfc6979 nonce",
key: "65b46d4eb001c649a86309286aaf94b18386effe62c2e1586d9b1898ccf0099b",
msg: "04",
hash: "4c6eb9e38415034f4c93d3304d10bef38bf0ad420eefd0f72f940f11c5857786",
nonce: "7afd696a9e770961d2b2eaec77ab7c22c734886fa57bc4a50a9f1946168cd06f",
nonce: "cb4727000027551b8c2c3b717696dcff46f9ad088050571cb8634038003fc136",
rfc6979: true,
expected: "81db1d6dca08819ad936d3284a359091e57c036648d477b96af9d8326965a7d1" +
"b5f807b7b4b62ff9f946d802c896d3bdf4eccdfc364f983aa29aa99da68df390",
expected: "327f4e1dc74948df95dba34f26b63317568325316742fc8276be8cd2544a105c" +
"ecd401dcd37834c2c007bb3402130fcac0cca549326b81727097d4420e73268c",
}, {
name: "random key 5, blake256(0x05), rfc6979 nonce",
key: "915cb9ba4675de06a182088b182abcf79fa8ac989328212c6b866fa3ec2338f9",
msg: "05",
hash: "bdd15db13448905791a70b68137445e607cca06cc71c7a58b9b2e84a06c54d08",
nonce: "2a6ae70ea5cf1b932331901d640ece54551f5f33bf9484d5f95c676b5612b527",
nonce: "665a2ba74200aaee038de3248c1acb8d92ca9c0a89ff63d140755834e04d55e8",
rfc6979: true,
expected: "47fd51aecbc743477cb59aa29d18d11d75fb206ae1cdd044216e4f294e33d5b6" +
"58541d8273675ac15d6e2113d56756febdc85c977716422761d4332d508d0ebe",
expected: "b3ac51091150852794914e12f12b8db00ec517ca8eeca0175a20e62b1a413a5c" +
"f942de4435ff6016a3faf233100b82c66d2e6efa423b2df0f3f1ee115dfc39f5",
}, {
name: "random key 6, blake256(0x06), rfc6979 nonce",
key: "93e9d81d818f08ba1f850c6dfb82256b035b42f7d43c1fe090804fb009aca441",
msg: "06",
hash: "19b7506ad9c189a9f8b063d2aee15953d335f5c88480f8515d7d848e7771c4ae",
nonce: "0b847a0ae0cbe84dfca66621f04f04b0f2ec190dce10d43ba8c3915c0fcd90ed",
nonce: "b817c907f71b11359bc2857e39f0f13d3a2cbaaadb722665ea73d7edf38c4342",
rfc6979: true,
expected: "c99800bc7ac7ea11afe5d7a264f4c26edd63ae9c7ecd6d0d19992980bcda1d34" +
"02ac38658b8102e6ebb35707f550ab106d27e2ce7f20e7ed14f8227b1ca2c6ba",
expected: "01bfb35cf41d809d572d1d891eb474e2c0decf67ebb0f1432edce06b75d73fe0" +
"36a1015a13c6bcf50a94b87f5ef2725cf892c40e0e0fbaa5ca33e02dc6d3f19d",
}, {
name: "random key 7, blake256(0x07), rfc6979 nonce",
key: "c249bbd5f533672b7dcd514eb1256854783531c2b85fe60bf4ce6ea1f26afc2b",
msg: "07",
hash: "53d661e71e47a0a7e416591200175122d83f8af31be6a70af7417ad6f54d0038",
nonce: "0f8e20694fe766d7b79e5ac141e3542f2f3c3d2cc6d0f60e0ec263a46dbe6d49",
nonce: "7eaa64ba668b3c77b0586695645707236f165a76ed7a53a04c833048995f8bc7",
rfc6979: true,
expected: "7a57a5222fb7d615eaa0041193f682262cebfa9b448f9c519d3644d0a3348521" +
"c2d8d91ba147a3f59557f02465f3e4e29adcc0988cbda169ed4a0e6992b258b1",
expected: "cb5bd3805bdd0a2e4daf58b30aa26b48c81ca59421ca320ad983c1eef672ad52" +
"5be5b6de8c0c343830bb803e0384a3942404485e8797cb48ac9ea332831fb5ad",
}, {
name: "random key 8, blake256(0x08), rfc6979 nonce",
key: "ec0be92fcec66cf1f97b5c39f83dfd4ddcad0dad468d3685b5eec556c6290bcc",
msg: "08",
hash: "9bff7982eab6f7883322edf7bdc86a23c87ca1c07906fbb1584f57b197dc6253",
nonce: "ab7df49257d18f5f1b730cc7448f46bd82eb43e6e220f521fa7d23802310e24d",
nonce: "63e12aa7d19a413577fbf6a0896f13040befb5b675f9238a09b9db400d9f454a",
rfc6979: true,
expected: "64f90b09c8b1763a3eeefd156e5d312f80a98c24017811c0163b1c0b01323668" +
"6f918ac37ead03f06ee7cf0cbe0927a3598874f5cfae087567ff6fd0904609f2",
expected: "9fbd427ddaef7c7ab87e5555c1faca398695e423ce44e5fc648b9203e38b69a0" +
"47f0752e1d421e24b3eb8666c9a966b86fd49438dda1a4987cb77f3147b8fa6a",
}, {
name: "random key 9, blake256(0x09), rfc6979 nonce",
key: "6847b071a7cba6a85099b26a9c3e57a964e4990620e1e1c346fecc4472c4d834",
msg: "09",
hash: "4c2231813064f8500edae05b40195416bd543fd3e76c16d6efb10c816d92e8b6",
nonce: "48ea6c907e1cda596048d812439ccf416eece9a7de400c8a0e40bd48eb7e613a",
nonce: "95adf9b15f485dc961061053838dbd0fb1fa8663ac344d78f3833acb5fdbfdc6",
rfc6979: true,
expected: "81fc600775d3cdcaa14f8629537299b8226a0c8bfce9320ce64a8d14e3f95bae" +
"faf7d1cdc07134f72fde4f0e306ed09543344a8c9834a5f134226fb2a12971e5",
expected: "cd9e9100f0fc8b631b40c4d93437eaf608e25ab6ad295d8b6460289ce571fb1e" +
"a91d3c16da2fb15ce0090702df4d824dc167a205af5824579a3e587646bf4251",
}, {
name: "random key 10, blake256(0x0a), rfc6979 nonce",
key: "b7548540f52fe20c161a0d623097f827608c56023f50442cc00cc50ad674f6b5",
msg: "0a",
hash: "e81db4f0d76e02805155441f50c861a8f86374f3ae34c7a3ff4111d3a634ecb1",
nonce: "95c07e315cd5457e84270ca01019563c8eeaffb18ab4f23e88a44a0ff01c5f6f",
nonce: "014c6f95c371ba1dd62e759229b65a7ffced18680f34789a204e1044926722ff",
rfc6979: true,
expected: "0d4cbf2da84f7448b083fce9b9c4e1834b5e2e98defcec7ec87e87c739f5fe78" +
"032b07372963fb913d86e7c911f69aa96a7821191b15210e99b8ce33c2b205a3",
expected: "c379f1c2a35b2f9712a5573fb59c4c29dfdc54cef833dc211716248d5c7e28e1" +
"6e180f905cd4459551eed45b2f85b4222d21d66eb2374d9f340920b42ff9807e",
}}
for _, test := range tests {
@ -211,7 +211,8 @@ func TestSchnorrSignAndVerify(t *testing.T) {
continue
}
if test.rfc6979 {
calcNonce := secp256k1.NonceRFC6979(privKey, hash, nil, nil, 0)
calcNonce := secp256k1.NonceRFC6979(privKey, hash,
rfc6979ExtraDataV0[:], nil, 0)
calcNonceBytes := calcNonce.Bytes()
if !bytes.Equal(calcNonceBytes[:], nonce) {
t.Errorf("%s: mismatched test nonce -- expected: %x, given: %x",