hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

rfc6979+test.ha (15618B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use bytes;
      5 use crypto::sha1;
      6 use crypto::sha256;
      7 use crypto::sha512;
      8 use encoding::hex;
      9 use hash;
     10 use io;
     11 use strings;
     12 use test;
     13 
     14 const p256q: [_]u8 = [
     15 	0x04, 0x60, 0xfe, 0xd4, 0xba, 0x25, 0x5a, 0x9d, 0x31, 0xc9, 0x61, 0xeb,
     16 	0x74, 0xc6, 0x35, 0x6d, 0x68, 0xc0, 0x49, 0xb8, 0x92, 0x3b, 0x61, 0xfa,
     17 	0x6c, 0xe6, 0x69, 0x62, 0x2e, 0x60, 0xf2, 0x9f, 0xb6, 0x79, 0x03, 0xfe,
     18 	0x10, 0x08, 0xb8, 0xbc, 0x99, 0xa4, 0x1a, 0xe9, 0xe9, 0x56, 0x28, 0xbc,
     19 	0x64, 0xf2, 0xf1, 0xb2, 0x0c, 0x2d, 0x7e, 0x9f, 0x51, 0x77, 0xa3, 0xc2,
     20 	0x94, 0xd4, 0x46, 0x22, 0x99
     21 ];
     22 
     23 const p256x: [_]u8 = [
     24 	0xc9, 0xaf, 0xa9, 0xd8, 0x45, 0xba, 0x75, 0x16, 0x6b, 0x5c, 0x21, 0x57,
     25 	0x67, 0xb1, 0xd6, 0x93, 0x4e, 0x50, 0xc3, 0xdb, 0x36, 0xe8, 0x9b, 0x12,
     26 	0x7b, 0x8a, 0x62, 0x2b, 0x12, 0x0f, 0x67, 0x21
     27 ];
     28 
     29 const p384q: [_]u8 = [
     30 	0x04, 0xec, 0x3a, 0x4e, 0x41, 0x5b, 0x4e, 0x19, 0xa4, 0x56, 0x86, 0x18,
     31 	0x02, 0x9f, 0x42, 0x7f, 0xa5, 0xda, 0x9a, 0x8b, 0xc4, 0xae, 0x92, 0xe0,
     32 	0x2e, 0x06, 0xaa, 0xe5, 0x28, 0x6b, 0x30, 0x0c, 0x64, 0xde, 0xf8, 0xf0,
     33 	0xea, 0x90, 0x55, 0x86, 0x60, 0x64, 0xa2, 0x54, 0x51, 0x54, 0x80, 0xbc,
     34 	0x13, 0x80, 0x15, 0xd9, 0xb7, 0x2d, 0x7d, 0x57, 0x24, 0x4e, 0xa8, 0xef,
     35 	0x9a, 0xc0, 0xc6, 0x21, 0x89, 0x67, 0x08, 0xa5, 0x93, 0x67, 0xf9, 0xdf,
     36 	0xb9, 0xf5, 0x4c, 0xa8, 0x4b, 0x3f, 0x1c, 0x9d, 0xb1, 0x28, 0x8b, 0x23,
     37 	0x1c, 0x3a, 0xe0, 0xd4, 0xfe, 0x73, 0x44, 0xfd, 0x25, 0x33, 0x26, 0x47,
     38 	0x20
     39 ];
     40 
     41 const p384x: [_]u8 = [
     42 	0x6b, 0x9d, 0x3d, 0xad, 0x2e, 0x1b, 0x8c, 0x1c, 0x05, 0xb1, 0x98, 0x75,
     43 	0xb6, 0x65, 0x9f, 0x4d, 0xe2, 0x3c, 0x3b, 0x66, 0x7b, 0xf2, 0x97, 0xba,
     44 	0x9a, 0xa4, 0x77, 0x40, 0x78, 0x71, 0x37, 0xd8, 0x96, 0xd5, 0x72, 0x4e,
     45 	0x4c, 0x70, 0xa8, 0x25, 0xf8, 0x72, 0xc9, 0xea, 0x60, 0xd2, 0xed, 0xf5
     46 ];
     47 
     48 const p521q: [_]u8 = [
     49 	0x04, 0x01, 0x89, 0x45, 0x50, 0xd0, 0x78, 0x59, 0x32, 0xe0, 0x0e, 0xaa,
     50 	0x23, 0xb6, 0x94, 0xf2, 0x13, 0xf8, 0xc3, 0x12, 0x1f, 0x86, 0xdc, 0x97,
     51 	0xa0, 0x4e, 0x5a, 0x71, 0x67, 0xdb, 0x4e, 0x5b, 0xcd, 0x37, 0x11, 0x23,
     52 	0xd4, 0x6e, 0x45, 0xdb, 0x6b, 0x5d, 0x53, 0x70, 0xa7, 0xf2, 0x0f, 0xb6,
     53 	0x33, 0x15, 0x5d, 0x38, 0xff, 0xa1, 0x6d, 0x2b, 0xd7, 0x61, 0xdc, 0xac,
     54 	0x47, 0x4b, 0x9a, 0x2f, 0x50, 0x23, 0xa4, 0x00, 0x49, 0x31, 0x01, 0xc9,
     55 	0x62, 0xcd, 0x4d, 0x2f, 0xdd, 0xf7, 0x82, 0x28, 0x5e, 0x64, 0x58, 0x41,
     56 	0x39, 0xc2, 0xf9, 0x1b, 0x47, 0xf8, 0x7f, 0xf8, 0x23, 0x54, 0xd6, 0x63,
     57 	0x0f, 0x74, 0x6a, 0x28, 0xa0, 0xdb, 0x25, 0x74, 0x1b, 0x5b, 0x34, 0xa8,
     58 	0x28, 0x00, 0x8b, 0x22, 0xac, 0xc2, 0x3f, 0x92, 0x4f, 0xaa, 0xfb, 0xd4,
     59 	0xd3, 0x3f, 0x81, 0xea, 0x66, 0x95, 0x6d, 0xfe, 0xaa, 0x2b, 0xfd, 0xfc,
     60 	0xf5
     61 ];
     62 
     63 const p521x: [_]u8 = [
     64 	0x00, 0xfa, 0xd0, 0x6d, 0xaa, 0x62, 0xba, 0x3b, 0x25, 0xd2, 0xfb, 0x40,
     65 	0x13, 0x3d, 0xa7, 0x57, 0x20, 0x5d, 0xe6, 0x7f, 0x5b, 0xb0, 0x01, 0x8f,
     66 	0xee, 0x8c, 0x86, 0xe1, 0xb6, 0x8c, 0x7e, 0x75, 0xca, 0xa8, 0x96, 0xeb,
     67 	0x32, 0xf1, 0xf4, 0x7c, 0x70, 0x85, 0x58, 0x36, 0xa6, 0xd1, 0x6f, 0xcc,
     68 	0x14, 0x66, 0xf6, 0xd8, 0xfb, 0xec, 0x67, 0xdb, 0x89, 0xec, 0x0c, 0x08,
     69 	0xb0, 0xe9, 0x96, 0xb8, 0x35, 0x38
     70 ];
     71 
     72 type hashf = enum {
     73 	SHA1,
     74 	SHA224,
     75 	SHA256,
     76 	SHA384,
     77 	SHA512,
     78 };
     79 
     80 type tcurveid = enum {
     81 	P256,
     82 	P384,
     83 	P521,
     84 };
     85 
     86 type testcase = struct {
     87 	curve: tcurveid,
     88 	qpoint: []u8,
     89 	x: []u8,
     90 	hashf: hashf,
     91 	msg: str,
     92 	k: str,
     93 	sig: str,
     94 };
     95 
     96 // XXX: alloc is used to circumvent not initialisable during compiletime error.
     97 fn rfc6979_cases() []testcase = alloc([
     98 
     99 	// Test vectors for P-256, from RFC 6979
    100 	testcase {
    101 		curve = tcurveid::P256,
    102 		qpoint = p256q,
    103 		x = p256x,
    104 		hashf = hashf::SHA1,
    105 		msg = "sample",
    106 		k = "882905f1227fd620fbf2abf21244f0ba83d0dc3a9103dbbee43a1fb858109db4",
    107 		sig = "61340c88c3aaebeb4f6d667f672ca9759a6ccaa9fa8811313039ee4a35471d32"
    108 			"6d7f147dac089441bb2e2fe8f7a3fa264b9c475098fdcf6e00d7c996e1b8b7eb",
    109 	},
    110 	testcase {
    111 		curve = tcurveid::P256,
    112 		qpoint = p256q,
    113 		x = p256x,
    114 		hashf = hashf::SHA256,
    115 		msg = "sample",
    116 		k = "a6e3c57dd01abe90086538398355dd4c3b17aa873382b0f24d6129493d8aad60",
    117 		sig = "efd48b2aacb6a8fd1140dd9cd45e81d69d2c877b56aaf991c34d0ea84eaf3716f7cb1c942d657c41d436c7a1b6e29f65f3e900dbb9aff4064dc4ab2f843acda8",
    118 	},
    119 	testcase {
    120 		curve = tcurveid::P256,
    121 		qpoint = p256q,
    122 		x = p256x,
    123 		hashf = hashf::SHA256,
    124 		msg = "sample",
    125 		k = "a6e3c57dd01abe90086538398355dd4c3b17aa873382b0f24d6129493d8aad60",
    126 		sig = "efd48b2aacb6a8fd1140dd9cd45e81d69d2c877b56aaf991c34d0ea84eaf3716f7cb1c942d657c41d436c7a1b6e29f65f3e900dbb9aff4064dc4ab2f843acda8",
    127 	},
    128 	testcase {
    129 		curve = tcurveid::P256,
    130 		qpoint = p256q,
    131 		x = p256x,
    132 		hashf = hashf::SHA384,
    133 		msg = "sample",
    134 		k = "09f634b188cefd98e7ec88b1aa9852d734d0bc272f7d2a47decc6ebeb375aad4",
    135 		sig = "0eafea039b20e9b42309fb1d89e213057cbf973dc0cfc8f129edddc800ef77194861f0491e6998b9455193e34e7b0d284ddd7149a74b95b9261f13abde940954",
    136 	},
    137 	testcase {
    138 		curve = tcurveid::P256,
    139 		qpoint = p256q,
    140 		x = p256x,
    141 		hashf = hashf::SHA512,
    142 		msg = "sample",
    143 		k = "5fa81c63109badb88c1f367b47da606da28cad69aa22c4fe6ad7df73a7173aa5",
    144 		sig = "8496a60b5e9b47c825488827e0495b0e3fa109ec4568fd3f8d1097678eb97f002362ab1adbe2b8adf9cb9edab740ea6049c028114f2460f96554f61fae3302fe",
    145 	},
    146 	testcase {
    147 		curve = tcurveid::P256,
    148 		qpoint = p256q,
    149 		x = p256x,
    150 		hashf = hashf::SHA1,
    151 		msg = "test",
    152 		k = "8c9520267c55d6b980df741e56b4adee114d84fbfa2e62137954164028632a2e",
    153 		sig = "0cbcc86fd6abd1d99e703e1ec50069ee5c0b4ba4b9ac60e409e8ec5910d81a8901b9d7b73dfaa60d5651ec4591a0136f87653e0fd780c3b1bc872ffdeae479b1",
    154 	},
    155 	testcase {
    156 		curve = tcurveid::P256,
    157 		qpoint = p256q,
    158 		x = p256x,
    159 		hashf = hashf::SHA256,
    160 		msg = "test",
    161 		k = "d16b6ae827f17175e040871a1c7ec3500192c4c92677336ec2537acaee0008e0",
    162 		sig = "f1abb023518351cd71d881567b1ea663ed3efcf6c5132b354f28d3b0b7d38367019f4113742a2b14bd25926b49c649155f267e60d3814b4c0cc84250e46f0083",
    163 	},
    164 	testcase {
    165 		curve = tcurveid::P256,
    166 		qpoint = p256q,
    167 		x = p256x,
    168 		hashf = hashf::SHA384,
    169 		msg = "test",
    170 		k = "16aeffa357260b04b1dd199693960740066c1a8f3e8edd79070aa914d361b3b8",
    171 		sig = "83910e8b48bb0c74244ebdf7f07a1c5413d61472bd941ef3920e623fbccebeb68ddbec54cf8cd5874883841d712142a56a8d0f218f5003cb0296b6b509619f2c",
    172 	},
    173 	testcase {
    174 		curve = tcurveid::P256,
    175 		qpoint = p256q,
    176 		x = p256x,
    177 		hashf = hashf::SHA512,
    178 		msg = "test",
    179 		k = "6915d11632aca3c40d5d51c08daf9c555933819548784480e93499000d9f0b7f",
    180 		sig = "461d93f31b6540894788fd206c07cfa0cc35f46fa3c91816fff1040ad1581a0439af9f15de0db8d97e72719c74820d304ce5226e32dedae67519e840d1194e55",
    181 	},
    182 
    183 	// Test vectors for P-384, from RFC 6979.
    184 	testcase {
    185 		curve = tcurveid::P384,
    186 		qpoint = p384q,
    187 		x = p384x,
    188 		hashf = hashf::SHA1,
    189 		msg = "sample",
    190 		k = "4471ef7518bb2c7c20f62eae1c387ad0c5e8e470995db4acf694466e6ab096630f29e5938d25106c3c340045a2db01a7",
    191 		sig = "ec748d839243d6fbef4fc5c4859a7dffd7f3abddf72014540c16d73309834fa37b9ba002899f6fda3a4a9386790d4eb2a3bcfa947beef4732bf247ac17f71676cb31a847b9ff0cbc9c9ed4c1a5b3facf26f49ca031d4857570ccb5ca4424a443",
    192 	},
    193 
    194 	testcase {
    195 		curve = tcurveid::P384,
    196 		qpoint = p384q,
    197 		x = p384x,
    198 		hashf = hashf::SHA256,
    199 		msg = "sample",
    200 		k = "180ae9f9aec5438a44bc159a1fcb277c7be54fa20e7cf404b490650a8acc414e375572342863c899f9f2edf9747a9b60",
    201 		sig = "21b13d1e013c7fa1392d03c5f99af8b30c570c6f98d4ea8e354b63a21d3daa33bde1e888e63355d92fa2b3c36d8fb2cdf3aa443fb107745bf4bd77cb3891674632068a10ca67e3d45db2266fa7d1feebefdc63eccd1ac42ec0cb8668a4fa0ab0",
    202 	},
    203 	testcase {
    204 		curve = tcurveid::P384,
    205 		qpoint = p384q,
    206 		x = p384x,
    207 		hashf = hashf::SHA384,
    208 		msg = "sample",
    209 		k = "94ed910d1a099dad3254e9242ae85abde4ba15168eaf0ca87a555fd56d10fbca2907e3e83ba95368623b8c4686915cf9",
    210 		sig = "94edbb92a5ecb8aad4736e56c691916b3f88140666ce9fa73d64c4ea95ad133c81a648152e44acf96e36dd1e80fabe4699ef4aeb15f178cea1fe40db2603138f130e740a19624526203b6351d0a3a94fa329c145786e679e7b82c71a38628ac8",
    211 	},
    212 	testcase {
    213 		curve = tcurveid::P384,
    214 		qpoint = p384q,
    215 		x = p384x,
    216 		hashf = hashf::SHA512,
    217 		msg = "sample",
    218 		k = "92fc3c7183a883e24216d1141f1a8976c5b0dd797dfa597e3d7b32198bd35331a4e966532593a52980d0e3aaa5e10ec3",
    219 		sig = "ed0959d5880ab2d869ae7f6c2915c6d60f96507f9cb3e047c0046861da4a799cfe30f35cc900056d7c99cd7882433709512c8cceee3890a84058ce1e22dbc2198f42323ce8aca9135329f03c068e5112dc7cc3ef3446defceb01a45c2667fdd5",
    220 	},
    221 	testcase {
    222 		curve = tcurveid::P384,
    223 		qpoint = p384q,
    224 		x = p384x,
    225 		hashf = hashf::SHA1,
    226 		msg = "test",
    227 		k = "66cc2c8f4d303fc962e5ff6a27bd79f84ec812ddae58cf5243b64a4ad8094d47ec3727f3a3c186c15054492e30698497",
    228 		sig = "4bc35d3a50ef4e30576f58cd96ce6bf638025ee624004a1f7789a8b8e43d0678acd9d29876daf46638645f7f404b11c7d5a6326c494ed3ff614703878961c0fde7b2c278f9a65fd8c4b7186201a2991695ba1c84541327e966fa7b50f7382282",
    229 	},
    230 	testcase {
    231 		curve = tcurveid::P384,
    232 		qpoint = p384q,
    233 		x = p384x,
    234 		hashf = hashf::SHA256,
    235 		msg = "test",
    236 		k = "0cfac37587532347dc3389fdc98286bba8c73807285b184c83e62e26c401c0faa48dd070ba79921a3457abff2d630ad7",
    237 		sig = "6d6defac9ab64dabafe36c6bf510352a4cc27001263638e5b16d9bb51d451559f918eedaf2293be5b475cc8f0188636b2d46f3becbcc523d5f1a1256bf0c9b024d879ba9e838144c8ba6baeb4b53b47d51ab373f9845c0514eefb14024787265",
    238 	},
    239 	testcase {
    240 		curve = tcurveid::P384,
    241 		qpoint = p384q,
    242 		x = p384x,
    243 		hashf = hashf::SHA384,
    244 		msg = "test",
    245 		k = "015ee46a5bf88773ed9123a5ab0807962d193719503c527b031b4c2d225092ada71f4a459bc0da98adb95837db8312ea",
    246 		sig = "8203b63d3c853e8d77227fb377bcf7b7b772e97892a80f36ab775d509d7a5feb0542a7f0812998da8f1dd3ca3cf023dbddd0760448d42d8a43af45af836fce4de8be06b485e9b61b827c2f13173923e06a739f040649a667bf3b828246baa5a5",
    247 	},
    248 	testcase {
    249 		curve = tcurveid::P384,
    250 		qpoint = p384q,
    251 		x = p384x,
    252 		hashf = hashf::SHA512,
    253 		msg = "test",
    254 		k = "3780c4f67cb15518b6acae34c9f83568d2e12e47deab6c50a4e4ee5319d1e8ce0e2cc8a136036dc4b9c00e6888f66b6c",
    255 		sig = "a0d5d090c9980faf3c2ce57b7ae951d31977dd11c775d314af55f76c676447d06fb6495cd21b4b6e340fc236584fb277976984e59b4c77b0e8e4460dca3d9f20e07b9bb1f63beefaf576f6b2e8b224634a2092cd3792e0159ad9cee37659c736",
    256 	},
    257 	// Test vectors for P-521, from RFC 6979. */
    258 	testcase {
    259 		curve = tcurveid::P521,
    260 		qpoint = p521q,
    261 		x = p521x,
    262 		hashf = hashf::SHA1,
    263 		msg = "sample",
    264 		k = "0089c071b419e1c2820962321787258469511958e80582e95d8378e0c2ccdb3cb42bede42f50e3fa3c71f5a76724281d31d9c89f0f91fc1be4918db1c03a5838d0f9",
    265 		sig = "00343b6ec45728975ea5cba6659bbb6062a5ff89eea58be3c80b619f322c87910fe092f7d45bb0f8eee01ed3f20babec079d202ae677b243ab40b5431d497c55d75d00e7b0e675a9b24413d448b8cc119d2bf7b2d2df032741c096634d6d65d0dbe3d5694625fb9e8104d3b842c1b0e2d0b98bea19341e8676aef66ae4eba3d5475d5d16",
    266 	},
    267 	testcase {
    268 		curve = tcurveid::P521,
    269 		qpoint = p521q,
    270 		x = p521x,
    271 		hashf = hashf::SHA256,
    272 		msg = "sample",
    273 		k = "00edf38afcaaecab4383358b34d67c9f2216c8382aaea44a3dad5fdc9c32575761793fef24eb0fc276dfc4f6e3ec476752f043cf01415387470bcbd8678ed2c7e1a0",
    274 		sig = "01511bb4d675114fe266fc4372b87682baecc01d3cc62cf2303c92b3526012659d16876e25c7c1e57648f23b73564d67f61c6f14d527d54972810421e7d87589e1a7004a171143a83163d6df460aaf61522695f207a58b95c0644d87e52aa1a347916e4f7a72930b1bc06dbe22ce3f58264afd23704cbb63b29b931f7de6c9d949a7ecfc",
    275 	},
    276 	testcase {
    277 		curve = tcurveid::P521,
    278 		qpoint = p521q,
    279 		x = p521x,
    280 		hashf = hashf::SHA384,
    281 		msg = "sample",
    282 		k = "01546a108bc23a15d6f21872f7ded661fa8431ddbd922d0dcdb77cc878c8553ffad064c95a920a750ac9137e527390d2d92f153e66196966ea554d9adfcb109c4211",
    283 		sig = "01ea842a0e17d2de4f92c15315c63ddf72685c18195c2bb95e572b9c5136ca4b4b576ad712a52be9730627d16054ba40cc0b8d3ff035b12ae75168397f5d50c6745101f21a3cee066e1961025fb048bd5fe2b7924d0cd797babe0a83b66f1e35eeaf5fde143fa85dc394a7dee766523393784484bdf3e00114a1c857cde1aa203db65d61",
    284 	},
    285 	testcase {
    286 		curve = tcurveid::P521,
    287 		qpoint = p521q,
    288 		x = p521x,
    289 		hashf = hashf::SHA512,
    290 		msg = "sample",
    291 		k = "01dae2ea071f8110dc26882d4d5eae0621a3256fc8847fb9022e2b7d28e6f10198b1574fdd03a9053c08a1854a168aa5a57470ec97dd5ce090124ef52a2f7ecbffd3",
    292 		sig = "00c328fafcbd79dd77850370c46325d987cb525569fb63c5d3bc53950e6d4c5f174e25a1ee9017b5d450606add152b534931d7d4e8455cc91f9b15bf05ec36e377fa00617cce7cf5064806c467f678d3b4080d6f1cc50af26ca209417308281b68af282623eaa63e5b5c0723d8b8c37ff0777b1a20f8ccb1dccc43997f1ee0e44da4a67a",
    293 	},
    294 	testcase {
    295 		curve = tcurveid::P521,
    296 		qpoint = p521q,
    297 		x = p521x,
    298 		hashf = hashf::SHA1,
    299 		msg = "test",
    300 		k = "00bb9f2bf4fe1038ccf4dabd7139a56f6fd8bb1386561bd3c6a4fc818b20df5ddba80795a947107a1ab9d12daa615b1ade4f7a9dc05e8e6311150f47f5c57ce8b222",
    301 		sig = "013bad9f29abe20de37ebeb823c252ca0f63361284015a3bf430a46aaa80b87b0693f0694bd88afe4e661fc33b094cd3b7963bed5a727ed8bd6a3a202abe009d036701e9bb81ff7944ca409ad138dbbee228e1afcc0c890fc78ec8604639cb0dbdc90f717a99ead9d272855d00162ee9527567dd6a92cbd629805c0445282bbc916797ff",
    302 	},
    303 	testcase {
    304 		curve = tcurveid::P521,
    305 		qpoint = p521q,
    306 		x = p521x,
    307 		hashf = hashf::SHA256,
    308 		msg = "test",
    309 		k = "001de74955efaabc4c4f17f8e84d881d1310b5392d7700275f82f145c61e843841af09035bf7a6210f5a431a6a9e81c9323354a9e69135d44ebd2fcaa7731b909258",
    310 		sig = "000e871c4a14f993c6c7369501900c4bc1e9c7b0b4ba44e04868b30b41d8071042eb28c4c250411d0ce08cd197e4188ea4876f279f90b3d8d74a3c76e6f1e4656aa800cd52dbaa33b063c3a6cd8058a1fb0a46a4754b034fcc644766ca14da8ca5ca9fde00e88c1ad60ccba759025299079d7a427ec3cc5b619bfbc828e7769bcd694e86",
    311 	},
    312 	testcase {
    313 		curve = tcurveid::P521,
    314 		qpoint = p521q,
    315 		x = p521x,
    316 		hashf = hashf::SHA384,
    317 		msg = "test",
    318 		k = "01f1fc4a349a7da9a9e116bfdd055dc08e78252ff8e23ac276ac88b1770ae0b5dceb1ed14a4916b769a523ce1e90ba22846af11df8b300c38818f713dadd85de0c88",
    319 		sig = "014bee21a18b6d8b3c93fab08d43e739707953244fdbe924fa926d76669e7ac8c89df62ed8975c2d8397a65a49dcc09f6b0ac62272741924d479354d74ff6075578c0133330865c067a0eaf72362a65e2d7bc4e461e8c8995c3b6226a21bd1aa78f0ed94fe536a0dca35534f0cd1510c41525d163fe9d74d134881e35141ed5e8e95b979",
    320 	},
    321 	testcase {
    322 		curve = tcurveid::P521,
    323 		qpoint = p521q,
    324 		x = p521x,
    325 		hashf = hashf::SHA512,
    326 		msg = "test",
    327 		k = "016200813020ec986863bedfc1b121f605c1215645018aea1a7b215a564de9eb1b38a67aa1128b80ce391c4fb71187654aaa3431027bfc7f395766ca988c964dc56d",
    328 		sig = "013e99020abf5cee7525d16b69b229652ab6bdf2affcaef38773b4b7d08725f10cdb93482fdcc54edcee91eca4166b2a7c6265ef0ce2bd7051b7cef945babd47ee6d01fbd0013c674aa79cb39849527916ce301c66ea7ce8b80682786ad60f98f7e78a19ca69eff5c57400e3b3a0ad66ce0978214d13baf4e9ac60752f7b155e2de4dce3",
    329 	},
    330 ])!;
    331 
    332 @test fn ecdsa_rfc6979() void = {
    333 	test::require("slow");
    334 
    335 	let sigbuf: [MAX_SIGSZ]u8 = [0...];
    336 	let sumbuf: [sha512::SZ]u8 = [0...];
    337 	let hashbuf: [sha512::SZ * 2 + sha512::BLOCKSZ]u8 = [0...];
    338 	let cases = rfc6979_cases();
    339 	defer free(cases);
    340 
    341 	for (let tc &.. cases) {
    342 		let h: *hash::hash = switch (tc.hashf) {
    343 		case hashf::SHA1 =>
    344 			yield &sha1::sha1();
    345 		case hashf::SHA224 =>
    346 			abort("not implemented");
    347 		case hashf::SHA256 =>
    348 			yield &sha256::sha256();
    349 		case hashf::SHA384 =>
    350 			yield &sha512::sha384();
    351 		case hashf::SHA512 =>
    352 			yield &sha512::sha512();
    353 		case =>
    354 			abort();
    355 		};
    356 
    357 		let pub: *pubkey = switch (tc.curve) {
    358 		case tcurveid::P256 =>
    359 			yield &p256pub();
    360 		case tcurveid::P384 =>
    361 			yield &p384pub();
    362 		case tcurveid::P521 =>
    363 			yield &p521pub();
    364 		case =>
    365 			abort();
    366 		};
    367 
    368 		pubkey_buf(pub)[..] = tc.qpoint[..];
    369 
    370 		let sum = sumbuf[..hash::sz(h)];
    371 		io::writeall(h, strings::toutf8(tc.msg))!;
    372 		hash::sum(h, sum);
    373 
    374 		let sig = hex::decodestr(tc.sig)!;
    375 		defer free(sig);
    376 
    377 		sigbuf[..len(sig)] = sig[..];
    378 
    379 		verify(pub, sum, sigbuf[..len(sig)])!;
    380 		let priv: *privkey = switch (tc.curve) {
    381 		case tcurveid::P256 =>
    382 			yield &p256priv();
    383 		case tcurveid::P384 =>
    384 			yield &p384priv();
    385 		case tcurveid::P521 =>
    386 			yield &p521priv();
    387 		case =>
    388 			abort();
    389 		};
    390 
    391 		privkey_buf(priv)[..] = tc.x[..];
    392 
    393 		const n = sign(priv, sum, h, hashbuf, sigbuf)!;
    394 		assert(n == sigsz(pub));
    395 		assert(bytes::equal(sigbuf[..n], sig));
    396 	};
    397 };