hare

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

curves+test.ha (40376B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use bytes;
      5 
      6 
      7 // Testcases have been generated with help of pycryptdome.
      8 
      9 type multc = struct {
     10 	a: []u8,
     11 	b: []u8,
     12 	x: []u8,
     13 	y: []u8,
     14 	result: u32,
     15 	expected: []u8,
     16 };
     17 
     18 fn tmuladd(c: *curve, tcs: []multc) void = {
     19 	for (let i = 0z; i < len(tcs); i += 1) {
     20 		let t = tcs[i];
     21 		assert(c.muladd(t.a, t.b, t.x, t.y) == t.result);
     22 		if (t.result == 1) {
     23 			assert(bytes::equal(t.a, t.expected));
     24 		};
     25 	};
     26 };
     27 
     28 @test fn p256_mulgen() void = {
     29 	const c = p256;
     30 	// multiply by 1
     31 	let m1: [P256_SCALARSZ]u8 = [0...];
     32 	m1[len(m1) - 1] = 1;
     33 
     34 	let g = alloc(P256_G);
     35 	defer free(g);
     36 	assert(c.mul(g, m1) == 1);
     37 	assert(bytes::equal(g, P256_G));
     38 
     39 	assert(c.mulgen(g, m1) == 65);
     40 	assert(bytes::equal(g, P256_G));
     41 
     42 	// multiply by order - 1
     43 	let o = alloc(P256_N);
     44 	defer free(o);
     45 	o[len(o) - 1] -= 1;
     46 
     47 	const expected: [_]u8 = [
     48 		0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8,
     49 		0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d,
     50 		0x81, 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8,
     51 		0x98, 0xc2, 0x96, 0xb0, 0x1c, 0xbd, 0x1c, 0x01, 0xe5, 0x80,
     52 		0x65, 0x71, 0x18, 0x14, 0xb5, 0x83, 0xf0, 0x61, 0xe9, 0xd4,
     53 		0x31, 0xcc, 0xa9, 0x94, 0xce, 0xa1, 0x31, 0x34, 0x49, 0xbf,
     54 		0x97, 0xc8, 0x40, 0xae, 0x0a,
     55 	];
     56 
     57 	assert(c.mul(g, o) == 1);
     58 	assert(bytes::equal(g, expected));
     59 
     60 	let g = alloc(P256_G);
     61 	defer free(g);
     62 	assert(c.mulgen(g, o) == 65);
     63 	assert(bytes::equal(g, expected));
     64 	let priv: [_]u8 = [
     65 		0xde, 0x5c, 0x88, 0x05, 0x42, 0xa0, 0x71, 0xe2, 0xf6, 0xfe,
     66 		0xd0, 0xdc, 0x80, 0x07, 0x37, 0xc4, 0x35, 0xa6, 0x29, 0x48,
     67 		0x85, 0x70, 0x4f, 0x54, 0x1c, 0x41, 0x89, 0xaf, 0xf6, 0xbc,
     68 		0xb5, 0x19,
     69 	];
     70 	const expected: [_]u8 = [
     71 		0x04, 0x8a, 0x0d, 0x13, 0x84, 0x8e, 0x4f, 0xdb, 0x05, 0x83,
     72 		0x8e, 0x76, 0x24, 0xf9, 0x8a, 0xb2, 0x83, 0x5a, 0x79, 0xb0,
     73 		0x65, 0x63, 0x9b, 0x4c, 0x30, 0xcf, 0x69, 0x31, 0x46, 0xf7,
     74 		0x10, 0x49, 0x13, 0x46, 0x0b, 0xb0, 0x4e, 0x3e, 0x44, 0x7f,
     75 		0xad, 0x96, 0xfa, 0xfb, 0xc5, 0x78, 0xc0, 0xee, 0xc6, 0xc4,
     76 		0x88, 0xa3, 0xe5, 0xc3, 0x10, 0x3c, 0x63, 0x24, 0xc1, 0x48,
     77 		0x43, 0x37, 0x13, 0xdf, 0xc9,
     78 	];
     79 
     80 	let g = alloc(P256_G);
     81 	assert(c.mul(g, priv) == 1);
     82 	assert(bytes::equal(g, expected));
     83 
     84 	let r: [65]u8 = [0...];
     85 	assert(c.mulgen(r, priv) == 65);
     86 	assert(bytes::equal(r, expected));
     87 };
     88 
     89 @test fn p256_muladd() void = {
     90 	let c = p256;
     91 
     92 	let tcs: [_]multc = [
     93 		multc {
     94 			a = [
     95 				0x04, 0xee, 0x19, 0x71, 0x69, 0xae, 0xbd, 0x94,
     96 				0xc7, 0x8d, 0x4e, 0x7f, 0x05, 0x06, 0xb4, 0xdf,
     97 				0x60, 0x43, 0x22, 0x2c, 0x50, 0x8d, 0x33, 0x8a,
     98 				0x5a, 0xd0, 0x02, 0x60, 0x95, 0x5e, 0xda, 0x31,
     99 				0x64, 0x4c, 0x7e, 0x63, 0xa9, 0xa0, 0xaf, 0x56,
    100 				0xbb, 0x7c, 0x03, 0x84, 0x8a, 0x44, 0x30, 0xfd,
    101 				0x39, 0x1d, 0xc0, 0x0f, 0x5c, 0x50, 0xcf, 0xda,
    102 				0xf1, 0x99, 0x69, 0x8e, 0x77, 0x62, 0x56, 0x34,
    103 				0xce,
    104 			],
    105 			b = [],
    106 			x = [
    107 				0xef, 0xcb, 0x7a, 0x72, 0x9c, 0xb4, 0x6a, 0xe6,
    108 				0xb4, 0x66, 0xa6, 0x8c, 0x1a, 0x18, 0x64, 0x5c,
    109 				0xd8, 0xdc, 0x9d, 0xa2, 0x5b, 0x48, 0x45, 0xcd,
    110 				0x68, 0x0c, 0x5f, 0x93, 0x1b, 0x74, 0x42, 0x0b,
    111 			],
    112 			y = [
    113 				0x7b, 0x6b, 0x8f, 0x14, 0x8b, 0x7a, 0x5d, 0xbe,
    114 				0xa5, 0xd0, 0x6b, 0x7a, 0x3c, 0xaa, 0x6f, 0x4b,
    115 				0x2a, 0xeb, 0x52, 0x7e, 0x80, 0xdb, 0xc5, 0x95,
    116 				0x73, 0x91, 0xab, 0x3d, 0x29, 0xbc, 0xbd, 0x74,
    117 			],
    118 			result = 1,
    119 			expected = [
    120 				0x04, 0x85, 0x93, 0xaf, 0x32, 0x68, 0x1c, 0xa8,
    121 				0xba, 0xf8, 0x64, 0x4e, 0xd3, 0xd8, 0xf3, 0x52,
    122 				0x88, 0xdf, 0x3b, 0x92, 0x5b, 0xb4, 0xbb, 0xf6,
    123 				0xd4, 0x2c, 0xce, 0x42, 0x8c, 0xa5, 0x9b, 0xd4,
    124 				0xb0, 0x87, 0xac, 0xfe, 0x83, 0xcc, 0x11, 0xd1,
    125 				0x98, 0x3e, 0x63, 0xc8, 0xba, 0xc1, 0x8e, 0x7e,
    126 				0xf2, 0xd1, 0xa7, 0x78, 0x93, 0xa8, 0x71, 0x9e,
    127 				0xee, 0xd2, 0xf9, 0xe3, 0xf3, 0x0a, 0xda, 0xf6,
    128 				0x26,
    129 			],
    130 		},
    131 		multc {
    132 			a = [
    133 				0x04, 0xee, 0x19, 0x71, 0x69, 0xae, 0xbd, 0x94,
    134 				0xc7, 0x8d, 0x4e, 0x7f, 0x05, 0x06, 0xb4, 0xdf,
    135 				0x60, 0x43, 0x22, 0x2c, 0x50, 0x8d, 0x33, 0x8a,
    136 				0x5a, 0xd0, 0x02, 0x60, 0x95, 0x5e, 0xda, 0x31,
    137 				0x64, 0x4c, 0x7e, 0x63, 0xa9, 0xa0, 0xaf, 0x56,
    138 				0xbb, 0x7c, 0x03, 0x84, 0x8a, 0x44, 0x30, 0xfd,
    139 				0x39, 0x1d, 0xc0, 0x0f, 0x5c, 0x50, 0xcf, 0xda,
    140 				0xf1, 0x99, 0x69, 0x8e, 0x77, 0x62, 0x56, 0x34,
    141 				0xce,
    142 			],
    143 			b = [
    144 				0x04, 0xbd, 0x52, 0x07, 0x83, 0x40, 0x88, 0x6a,
    145 				0xa5, 0x24, 0xd8, 0x22, 0x13, 0x4f, 0xc3, 0xf3,
    146 				0x03, 0xca, 0xe1, 0xd3, 0x5e, 0x01, 0x95, 0x82,
    147 				0x5f, 0xa9, 0x95, 0x9f, 0xc3, 0xc4, 0x92, 0x8f,
    148 				0xd2, 0x30, 0x18, 0x56, 0x29, 0x93, 0x74, 0x50,
    149 				0xbd, 0xa6, 0x8d, 0x88, 0xf6, 0x03, 0xd6, 0x16,
    150 				0xd9, 0x9d, 0x01, 0x82, 0xbe, 0x08, 0x13, 0xec,
    151 				0x9f, 0xb4, 0xb1, 0x18, 0xbc, 0x14, 0x09, 0x31,
    152 				0xad,
    153 			],
    154 			x = [
    155 				0xef, 0xcb, 0x7a, 0x72, 0x9c, 0xb4, 0x6a, 0xe6,
    156 				0xb4, 0x66, 0xa6, 0x8c, 0x1a, 0x18, 0x64, 0x5c,
    157 				0xd8, 0xdc, 0x9d, 0xa2, 0x5b, 0x48, 0x45, 0xcd,
    158 				0x68, 0x0c, 0x5f, 0x93, 0x1b, 0x74, 0x42, 0x0b,
    159 			],
    160 			y = [
    161 				0x7b, 0x6b, 0x8f, 0x14, 0x8b, 0x7a, 0x5d, 0xbe,
    162 				0xa5, 0xd0, 0x6b, 0x7a, 0x3c, 0xaa, 0x6f, 0x4b,
    163 				0x2a, 0xeb, 0x52, 0x7e, 0x80, 0xdb, 0xc5, 0x95,
    164 				0x73, 0x91, 0xab, 0x3d, 0x29, 0xbc, 0xbd, 0x74,
    165 			],
    166 			result = 1,
    167 			expected = [
    168 				0x04, 0x7f, 0x66, 0x4b, 0x8c, 0x3e, 0x64, 0x5b,
    169 				0xc1, 0x97, 0x60, 0xac, 0xa6, 0xc3, 0x0c, 0x17,
    170 				0x80, 0xff, 0xd0, 0x95, 0xcd, 0x4d, 0x5b, 0xf1,
    171 				0x35, 0x25, 0x53, 0x5a, 0xec, 0xff, 0xb1, 0xd9,
    172 				0xdb, 0xdd, 0x96, 0xe3, 0xfb, 0x84, 0x68, 0x2b,
    173 				0x53, 0x04, 0x4b, 0xcd, 0x7c, 0x4e, 0x10, 0xfa,
    174 				0x87, 0x4c, 0x14, 0x43, 0xf0, 0x1b, 0x57, 0x39,
    175 				0x02, 0x35, 0x44, 0xef, 0xa0, 0x38, 0xb5, 0x70,
    176 				0xb8,
    177 			],
    178 		},
    179 		// invalid a
    180 		multc {
    181 			a = [
    182 				0x04, 0xee, 0x19, 0x71, 0x69, 0xae, 0xbd, 0x94,
    183 				0xc7, 0x8d, 0x4e, 0x0f, 0x05, 0x06, 0xb4, 0xdf,
    184 				0x60, 0x43, 0x22, 0x0c, 0x50, 0x8d, 0x33, 0x8a,
    185 				0x5a, 0xd0, 0x02, 0x00, 0x95, 0x5e, 0xda, 0x31,
    186 				0x64, 0x4c, 0x7e, 0x03, 0xa9, 0xa0, 0xaf, 0x56,
    187 				0xbb, 0x7c, 0x03, 0x04, 0x8a, 0x44, 0x30, 0xfd,
    188 				0x39, 0x1d, 0xc0, 0x0f, 0x5c, 0x50, 0xcf, 0xda,
    189 				0xf1, 0x99, 0x69, 0x0e, 0x77, 0x62, 0x56, 0x34,
    190 				0xce,
    191 			],
    192 			b = [
    193 				0x04, 0xbd, 0x52, 0x07, 0x83, 0x40, 0x88, 0x6a,
    194 				0xa5, 0x24, 0xd8, 0x22, 0x13, 0x4f, 0xc3, 0xf3,
    195 				0x03, 0xca, 0xe1, 0xd3, 0x5e, 0x01, 0x95, 0x82,
    196 				0x5f, 0xa9, 0x95, 0x9f, 0xc3, 0xc4, 0x92, 0x8f,
    197 				0xd2, 0x30, 0x18, 0x56, 0x29, 0x93, 0x74, 0x50,
    198 				0xbd, 0xa6, 0x8d, 0x88, 0xf6, 0x03, 0xd6, 0x16,
    199 				0xd9, 0x9d, 0x01, 0x82, 0xbe, 0x08, 0x13, 0xec,
    200 				0x9f, 0xb4, 0xb1, 0x18, 0xbc, 0x14, 0x09, 0x31,
    201 				0xad,
    202 			],
    203 			x = [
    204 				0xef, 0xcb, 0x7a, 0x72, 0x9c, 0xb4, 0x6a, 0xe6,
    205 				0xb4, 0x66, 0xa6, 0x8c, 0x1a, 0x18, 0x64, 0x5c,
    206 				0xd8, 0xdc, 0x9d, 0xa2, 0x5b, 0x48, 0x45, 0xcd,
    207 				0x68, 0x0c, 0x5f, 0x93, 0x1b, 0x74, 0x42, 0x0b,
    208 			],
    209 			y = [
    210 				0x7b, 0x6b, 0x8f, 0x14, 0x8b, 0x7a, 0x5d, 0xbe,
    211 				0xa5, 0xd0, 0x6b, 0x7a, 0x3c, 0xaa, 0x6f, 0x4b,
    212 				0x2a, 0xeb, 0x52, 0x7e, 0x80, 0xdb, 0xc5, 0x95,
    213 				0x73, 0x91, 0xab, 0x3d, 0x29, 0xbc, 0xbd, 0x74,
    214 			],
    215 			result = 0,
    216 			expected = [],
    217 		},
    218 		// invalid b
    219 		multc {
    220 			a = [
    221 				0x04, 0xee, 0x19, 0x71, 0x69, 0xae, 0xbd, 0x94,
    222 				0xc7, 0x8d, 0x4e, 0x7f, 0x05, 0x06, 0xb4, 0xdf,
    223 				0x60, 0x43, 0x22, 0x2c, 0x50, 0x8d, 0x33, 0x8a,
    224 				0x5a, 0xd0, 0x02, 0x60, 0x95, 0x5e, 0xda, 0x31,
    225 				0x64, 0x4c, 0x7e, 0x63, 0xa9, 0xa0, 0xaf, 0x56,
    226 				0xbb, 0x7c, 0x03, 0x84, 0x8a, 0x44, 0x30, 0xfd,
    227 				0x39, 0x1d, 0xc0, 0x0f, 0x5c, 0x50, 0xcf, 0xda,
    228 				0xf1, 0x99, 0x69, 0x8e, 0x77, 0x62, 0x56, 0x34,
    229 				0xce,
    230 			],
    231 			b = [
    232 				0x04, 0xbd, 0x52, 0x07, 0x83, 0x40, 0x88, 0x6a,
    233 				0xf5, 0x24, 0xd8, 0x22, 0x13, 0x4f, 0xc3, 0xf3,
    234 				0xf3, 0xca, 0xe1, 0xd3, 0x5e, 0x01, 0x95, 0x82,
    235 				0x3f, 0xa9, 0x95, 0x9f, 0xc3, 0xc4, 0x92, 0x8f,
    236 				0x52, 0x30, 0x18, 0x56, 0x29, 0x93, 0x74, 0x50,
    237 				0x1d, 0xa6, 0x8d, 0x88, 0xf6, 0x03, 0xd6, 0x16,
    238 				0xd9, 0x9d, 0x01, 0x82, 0xbe, 0x08, 0x13, 0xec,
    239 				0x9f, 0xb4, 0xb1, 0x18, 0xbc, 0x14, 0x09, 0x31,
    240 				0xad,
    241 			],
    242 			x = [
    243 				0xef, 0xcb, 0x7a, 0x72, 0x9c, 0xb4, 0x6a, 0xe6,
    244 				0xb4, 0x66, 0xa6, 0x8c, 0x1a, 0x18, 0x64, 0x5c,
    245 				0xd8, 0xdc, 0x9d, 0xa2, 0x5b, 0x48, 0x45, 0xcd,
    246 				0x68, 0x0c, 0x5f, 0x93, 0x1b, 0x74, 0x42, 0x0b,
    247 			],
    248 			y = [
    249 				0x7b, 0x6b, 0x8f, 0x14, 0x8b, 0x7a, 0x5d, 0xbe,
    250 				0xa5, 0xd0, 0x6b, 0x7a, 0x3c, 0xaa, 0x6f, 0x4b,
    251 				0x2a, 0xeb, 0x52, 0x7e, 0x80, 0xdb, 0xc5, 0x95,
    252 				0x73, 0x91, 0xab, 0x3d, 0x29, 0xbc, 0xbd, 0x74,
    253 			],
    254 			result = 0,
    255 			expected = [],
    256 		},
    257 		// invalid a and b
    258 		multc {
    259 			a = [
    260 				0x04, 0xee, 0x19, 0x71, 0x69, 0xae, 0xbd, 0x94,
    261 				0xc7, 0x8d, 0x4e, 0x0f, 0x05, 0x06, 0xb4, 0xdf,
    262 				0x60, 0x43, 0x22, 0x0c, 0x50, 0x8d, 0x33, 0x8a,
    263 				0x5a, 0xd0, 0x02, 0x00, 0x95, 0x5e, 0xda, 0x31,
    264 				0x64, 0x4c, 0x7e, 0x03, 0xa9, 0xa0, 0xaf, 0x56,
    265 				0xbb, 0x7c, 0x03, 0x04, 0x8a, 0x44, 0x30, 0xfd,
    266 				0x39, 0x1d, 0xc0, 0x0f, 0x5c, 0x50, 0xcf, 0xda,
    267 				0xf1, 0x99, 0x69, 0x0e, 0x77, 0x62, 0x56, 0x34,
    268 				0xce,
    269 			],
    270 			b = [
    271 				0x04, 0xbd, 0x52, 0x07, 0x83, 0xf0, 0x88, 0x6a,
    272 				0xa5, 0x24, 0xd8, 0x22, 0x13, 0xff, 0xc3, 0xf3,
    273 				0x03, 0xca, 0xe1, 0xd3, 0x5e, 0xf1, 0x95, 0x82,
    274 				0x5f, 0xa9, 0x95, 0x9f, 0xc3, 0xf4, 0x92, 0x8f,
    275 				0xd2, 0x30, 0x18, 0x56, 0x29, 0xf3, 0x74, 0x50,
    276 				0xbd, 0xa6, 0x8d, 0x88, 0xf6, 0xf3, 0xd6, 0x16,
    277 				0xd9, 0x9d, 0x01, 0x82, 0xbe, 0xf8, 0x13, 0xec,
    278 				0x9f, 0xb4, 0xb1, 0x18, 0xbc, 0x14, 0x09, 0x31,
    279 				0xad,
    280 			],
    281 			x = [
    282 				0xef, 0xcb, 0x7a, 0x72, 0x9c, 0xb4, 0x6a, 0xe6,
    283 				0xb4, 0x66, 0xa6, 0x8c, 0x1a, 0x18, 0x64, 0x5c,
    284 				0xd8, 0xdc, 0x9d, 0xa2, 0x5b, 0x48, 0x45, 0xcd,
    285 				0x68, 0x0c, 0x5f, 0x93, 0x1b, 0x74, 0x42, 0x0b,
    286 			],
    287 			y = [
    288 				0x7b, 0x6b, 0x8f, 0x14, 0x8b, 0x7a, 0x5d, 0xbe,
    289 				0xa5, 0xd0, 0x6b, 0x7a, 0x3c, 0xaa, 0x6f, 0x4b,
    290 				0x2a, 0xeb, 0x52, 0x7e, 0x80, 0xdb, 0xc5, 0x95,
    291 				0x73, 0x91, 0xab, 0x3d, 0x29, 0xbc, 0xbd, 0x74,
    292 			],
    293 			result = 0,
    294 			expected = [],
    295 		}
    296 	];
    297 
    298 	tmuladd(p256, tcs);
    299 };
    300 
    301 @test fn p384_mulgen() void = {
    302 	let c = p384;
    303 
    304 	// multiply by 1
    305 	let m1: [P384_SCALARSZ]u8 = [0...];
    306 	m1[len(m1) - 1] = 1;
    307 
    308 	let g = alloc(P384_G);
    309 	defer free(g);
    310 	assert(c.mul(g, m1) == 1);
    311 	assert(bytes::equal(g, P384_G));
    312 
    313 	assert(c.mulgen(g, m1) == 97);
    314 	assert(bytes::equal(g, P384_G));
    315 
    316 	// multiply by order - 1
    317 	let o = alloc(P384_N);
    318 	defer free(o);
    319 	o[len(o) - 1] -= 1;
    320 
    321 	const expected: [_]u8 = [
    322 		0x04, 0xaa, 0x87, 0xca, 0x22, 0xbe, 0x8b, 0x05, 0x37, 0x8e,
    323 		0xb1, 0xc7, 0x1e, 0xf3, 0x20, 0xad, 0x74, 0x6e, 0x1d, 0x3b,
    324 		0x62, 0x8b, 0xa7, 0x9b, 0x98, 0x59, 0xf7, 0x41, 0xe0, 0x82,
    325 		0x54, 0x2a, 0x38, 0x55, 0x02, 0xf2, 0x5d, 0xbf, 0x55, 0x29,
    326 		0x6c, 0x3a, 0x54, 0x5e, 0x38, 0x72, 0x76, 0x0a, 0xb7, 0xc9,
    327 		0xe8, 0x21, 0xb5, 0x69, 0xd9, 0xd3, 0x90, 0xa2, 0x61, 0x67,
    328 		0x40, 0x6d, 0x6d, 0x23, 0xd6, 0x07, 0x0b, 0xe2, 0x42, 0xd7,
    329 		0x65, 0xeb, 0x83, 0x16, 0x25, 0xce, 0xec, 0x4a, 0x0f, 0x47,
    330 		0x3e, 0xf5, 0x9f, 0x4e, 0x30, 0xe2, 0x81, 0x7e, 0x62, 0x85,
    331 		0xbc, 0xe2, 0x84, 0x6f, 0x15, 0xf1, 0xa0,
    332 	];
    333 
    334 	assert(c.mul(g, o) == 1);
    335 	assert(bytes::equal(g, expected));
    336 
    337 	let g = alloc(P384_G);
    338 	defer free(g);
    339 	assert(c.mulgen(g, o) == 97);
    340 	assert(bytes::equal(g, expected));
    341 
    342 	// random example
    343 	let priv: [_]u8 = [
    344 		0xde, 0x5c, 0x88, 0x05, 0x42, 0xa0, 0x71, 0xe2, 0xf6, 0xfe,
    345 		0xd0, 0xdc, 0x80, 0x07, 0x37, 0xc4, 0x35, 0xa6, 0x29, 0x48,
    346 		0x85, 0x70, 0x4f, 0x54, 0x1c, 0x41, 0x89, 0xaf, 0xf6, 0xbc,
    347 		0xb5, 0x19, 0x85, 0x70, 0x4f, 0x54, 0x1c, 0x41, 0x89, 0xaf,
    348 		0xf6, 0xbc, 0xb5, 0x19, 0xb5, 0x19, 0xb5, 0x19,
    349 	];
    350 	const expected: [_]u8 = [
    351 		0x04, 0xb6, 0xb4, 0x77, 0x6e, 0x08, 0x86, 0x64, 0x55, 0x3a,
    352 		0x64, 0xe0, 0xa3, 0xb0, 0x56, 0x39, 0x18, 0x4c, 0x5b, 0x15,
    353 		0x3b, 0x19, 0xd0, 0x99, 0xc5, 0xd2, 0x7a, 0x4a, 0x23, 0xb9,
    354 		0xf7, 0x37, 0x95, 0x4b, 0xe0, 0x97, 0x4c, 0x72, 0x16, 0x34,
    355 		0x76, 0xf6, 0xce, 0x9e, 0xb7, 0x52, 0xc9, 0x33, 0xed, 0x26,
    356 		0x5b, 0x7c, 0xb0, 0xd8, 0xe8, 0x8f, 0xc1, 0xb2, 0xd4, 0xbe,
    357 		0xe3, 0x20, 0xc7, 0x82, 0xc7, 0x71, 0x3d, 0xaf, 0xad, 0xdb,
    358 		0xe8, 0x56, 0xba, 0xad, 0x29, 0x76, 0x4c, 0x12, 0x24, 0xe9,
    359 		0x59, 0xca, 0xef, 0x09, 0x48, 0x0d, 0x40, 0xb1, 0xce, 0x5f,
    360 		0xcf, 0x6b, 0x62, 0xfd, 0xe5, 0x4b, 0xcc,
    361 	];
    362 
    363 	let g = alloc(P384_G);
    364 	defer free(g);
    365 	assert(c.mul(g, priv) == 1);
    366 	assert(bytes::equal(g, expected));
    367 
    368 	let r: [97]u8 = [0...];
    369 	assert(c.mulgen(r, priv) == 97);
    370 	assert(bytes::equal(r, expected));
    371 };
    372 
    373 @test fn p384_muladd() void = {
    374 	let tcs = [
    375 		multc {
    376 			a = [
    377 				0x04, 0xe4, 0x4f, 0x26, 0xd9, 0xce, 0xa7, 0xf0,
    378 				0x69, 0xed, 0xa6, 0x1f, 0x01, 0xcb, 0xef, 0x53,
    379 				0xe8, 0x2b, 0xf8, 0xdc, 0x16, 0x56, 0x05, 0x64,
    380 				0x8a, 0x46, 0xf8, 0x54, 0x25, 0x8e, 0x3e, 0x6c,
    381 				0xe8, 0xc3, 0x88, 0x0b, 0x30, 0xba, 0x9c, 0x8b,
    382 				0xf7, 0xf8, 0x17, 0xbb, 0x34, 0x08, 0x4b, 0xc5,
    383 				0xa7, 0xa3, 0x1d, 0x46, 0x64, 0x4d, 0xd1, 0xe5,
    384 				0x68, 0x23, 0x49, 0x11, 0xbd, 0x4f, 0x21, 0x6f,
    385 				0xcd, 0x88, 0x4d, 0xeb, 0x22, 0xad, 0x36, 0x57,
    386 				0xf3, 0x94, 0x5b, 0x13, 0x3c, 0xf3, 0xf6, 0xc6,
    387 				0xc6, 0x3c, 0xa1, 0x8e, 0xb6, 0x8c, 0x39, 0x85,
    388 				0x01, 0x85, 0x22, 0x16, 0xe7, 0xba, 0x9a, 0xa1,
    389 				0xd1,
    390 			],
    391 			b = [],
    392 			x = [
    393 				0xda, 0x9c, 0x84, 0xcf, 0x2d, 0x77, 0x4c, 0xfa,
    394 				0xe5, 0xdc, 0x52, 0xc3, 0xb3, 0xda, 0x1c, 0xa0,
    395 				0x26, 0xb0, 0x53, 0x16, 0x66, 0x46, 0x5f, 0x60,
    396 				0xa6, 0xbe, 0x6e, 0xd1, 0x0a, 0x5f, 0x01, 0x50,
    397 				0x63, 0xe1, 0x47, 0x62, 0x68, 0xcf, 0x40, 0x3a,
    398 				0x2b, 0xf0, 0x96, 0x6c, 0x1e, 0x71, 0x24, 0x79,
    399 			],
    400 			y = [
    401 				0xd9, 0xa7, 0x84, 0xd0, 0x77, 0x9e, 0x07, 0x4d,
    402 				0x78, 0x09, 0x84, 0xef, 0x5b, 0x7d, 0x94, 0xd7,
    403 				0xd8, 0x1f, 0x94, 0x1e, 0xfc, 0x3d, 0x76, 0x6c,
    404 				0x0d, 0x4c, 0x87, 0x76, 0xdf, 0x52, 0xfc, 0xe0,
    405 				0x02, 0x17, 0x2c, 0x95, 0x5e, 0x4b, 0xb7, 0x1f,
    406 				0x84, 0xce, 0x2e, 0x54, 0xf2, 0x08, 0xf7, 0x6a,
    407 			],
    408 			result = 1,
    409 			expected = [
    410 				0x04, 0x69, 0xf9, 0xbb, 0x7a, 0x32, 0x63, 0xef,
    411 				0xf2, 0xce, 0x3f, 0x4f, 0xf2, 0x48, 0x86, 0xd8,
    412 				0xe4, 0xa1, 0x68, 0x1f, 0x7b, 0x6c, 0x24, 0xcf,
    413 				0xa2, 0x60, 0x03, 0x0c, 0x8b, 0x10, 0x24, 0x4c,
    414 				0xea, 0x6f, 0x47, 0xc3, 0x75, 0xb0, 0x04, 0x07,
    415 				0xe0, 0xd1, 0x32, 0x8d, 0x02, 0x42, 0x75, 0x8c,
    416 				0x67, 0x90, 0x19, 0x12, 0x26, 0xd3, 0xaf, 0x57,
    417 				0x67, 0xc9, 0x20, 0x17, 0xd5, 0x2e, 0x57, 0xbb,
    418 				0x78, 0x98, 0xe4, 0xb5, 0xd5, 0x65, 0x53, 0x78,
    419 				0x20, 0x99, 0x2b, 0x43, 0x17, 0x1d, 0x2f, 0xdb,
    420 				0x2c, 0xd5, 0xe5, 0x61, 0x22, 0x1f, 0xae, 0x22,
    421 				0xae, 0x71, 0x03, 0x25, 0x9a, 0x47, 0x28, 0x4a,
    422 				0x0f,
    423 			],
    424 		},
    425 		multc {
    426 			a = [
    427 				0x04, 0xe4, 0x4f, 0x26, 0xd9, 0xce, 0xa7, 0xf0,
    428 				0x69, 0xed, 0xa6, 0x1f, 0x01, 0xcb, 0xef, 0x53,
    429 				0xe8, 0x2b, 0xf8, 0xdc, 0x16, 0x56, 0x05, 0x64,
    430 				0x8a, 0x46, 0xf8, 0x54, 0x25, 0x8e, 0x3e, 0x6c,
    431 				0xe8, 0xc3, 0x88, 0x0b, 0x30, 0xba, 0x9c, 0x8b,
    432 				0xf7, 0xf8, 0x17, 0xbb, 0x34, 0x08, 0x4b, 0xc5,
    433 				0xa7, 0xa3, 0x1d, 0x46, 0x64, 0x4d, 0xd1, 0xe5,
    434 				0x68, 0x23, 0x49, 0x11, 0xbd, 0x4f, 0x21, 0x6f,
    435 				0xcd, 0x88, 0x4d, 0xeb, 0x22, 0xad, 0x36, 0x57,
    436 				0xf3, 0x94, 0x5b, 0x13, 0x3c, 0xf3, 0xf6, 0xc6,
    437 				0xc6, 0x3c, 0xa1, 0x8e, 0xb6, 0x8c, 0x39, 0x85,
    438 				0x01, 0x85, 0x22, 0x16, 0xe7, 0xba, 0x9a, 0xa1,
    439 				0xd1,
    440 			],
    441 			b = [
    442 				0x04, 0xe0, 0xb0, 0x1d, 0x37, 0xe0, 0x12, 0xba,
    443 				0x21, 0xcd, 0xc5, 0xc4, 0x18, 0xfd, 0x85, 0x0a,
    444 				0x21, 0x11, 0x32, 0x69, 0x73, 0xc0, 0xd4, 0x55,
    445 				0xf3, 0x2e, 0x9d, 0x25, 0x0c, 0x4a, 0xc8, 0x89,
    446 				0x4d, 0x7c, 0xbf, 0xca, 0x2d, 0x28, 0x6d, 0x20,
    447 				0x5b, 0xbf, 0x0d, 0x1b, 0x6e, 0x92, 0x97, 0xd6,
    448 				0xbb, 0xe2, 0x1b, 0x17, 0xac, 0xce, 0xd9, 0x7c,
    449 				0x7e, 0x54, 0xca, 0xfb, 0xaf, 0x53, 0xa8, 0xde,
    450 				0xba, 0x4c, 0x0a, 0x0f, 0x67, 0x03, 0xe7, 0x23,
    451 				0xcf, 0x19, 0x07, 0x31, 0x71, 0x9a, 0x49, 0x51,
    452 				0x7f, 0xbd, 0x5b, 0xa0, 0x34, 0x5f, 0x79, 0xba,
    453 				0x48, 0xf1, 0x41, 0x9d, 0xcc, 0x2d, 0xef, 0x80,
    454 				0xbb,
    455 			],
    456 			x = [
    457 				0xda, 0x9c, 0x84, 0xcf, 0x2d, 0x77, 0x4c, 0xfa,
    458 				0xe5, 0xdc, 0x52, 0xc3, 0xb3, 0xda, 0x1c, 0xa0,
    459 				0x26, 0xb0, 0x53, 0x16, 0x66, 0x46, 0x5f, 0x60,
    460 				0xa6, 0xbe, 0x6e, 0xd1, 0x0a, 0x5f, 0x01, 0x50,
    461 				0x63, 0xe1, 0x47, 0x62, 0x68, 0xcf, 0x40, 0x3a,
    462 				0x2b, 0xf0, 0x96, 0x6c, 0x1e, 0x71, 0x24, 0x79,
    463 			],
    464 			y = [
    465 				0xd9, 0xa7, 0x84, 0xd0, 0x77, 0x9e, 0x07, 0x4d,
    466 				0x78, 0x09, 0x84, 0xef, 0x5b, 0x7d, 0x94, 0xd7,
    467 				0xd8, 0x1f, 0x94, 0x1e, 0xfc, 0x3d, 0x76, 0x6c,
    468 				0x0d, 0x4c, 0x87, 0x76, 0xdf, 0x52, 0xfc, 0xe0,
    469 				0x02, 0x17, 0x2c, 0x95, 0x5e, 0x4b, 0xb7, 0x1f,
    470 				0x84, 0xce, 0x2e, 0x54, 0xf2, 0x08, 0xf7, 0x6a,
    471 			],
    472 			result = 1,
    473 			expected = [
    474 				0x04, 0xdc, 0x38, 0x1d, 0x38, 0x27, 0x1a, 0x83,
    475 				0x03, 0x46, 0x18, 0xa6, 0xa7, 0xa7, 0x3e, 0xeb,
    476 				0xa3, 0x3b, 0x9b, 0x05, 0x00, 0xe8, 0x09, 0xac,
    477 				0x1a, 0x77, 0x5f, 0x21, 0xec, 0x5d, 0xe4, 0x70,
    478 				0x3d, 0x18, 0x1f, 0x38, 0x5b, 0x5d, 0xaf, 0xed,
    479 				0xc3, 0xff, 0xe4, 0x8a, 0xdb, 0x4b, 0x35, 0xfd,
    480 				0x34, 0x2b, 0xfa, 0x29, 0x04, 0xe8, 0x55, 0x73,
    481 				0xcf, 0xce, 0x1e, 0x2c, 0x34, 0x24, 0x08, 0xca,
    482 				0x21, 0x71, 0xe1, 0xb4, 0x90, 0xd6, 0xe0, 0x60,
    483 				0xff, 0x3b, 0x40, 0x70, 0xcd, 0x47, 0x26, 0xd1,
    484 				0x5b, 0xc6, 0xbf, 0x30, 0x94, 0x40, 0x6f, 0x88,
    485 				0x09, 0x12, 0xe7, 0x3e, 0x22, 0x88, 0x7e, 0x6e,
    486 				0xc1,
    487 			],
    488 		},
    489 		// invalid a
    490 		multc {
    491 			a = [
    492 				0x04, 0xe4, 0x4f, 0x26, 0xd9, 0xce, 0xa7, 0xf0,
    493 				0x69, 0xed, 0xa6, 0x1f, 0x01, 0xcb, 0xef, 0x53,
    494 				0xe8, 0x2b, 0x08, 0xdc, 0x16, 0x56, 0x05, 0x64,
    495 				0x8a, 0x46, 0x08, 0x54, 0x25, 0x8e, 0x3e, 0x6c,
    496 				0xe8, 0xc3, 0xf8, 0x0b, 0x30, 0xba, 0x9c, 0x8b,
    497 				0xf7, 0xf8, 0xf7, 0xbb, 0x34, 0x08, 0x4b, 0xc5,
    498 				0xa7, 0xa3, 0xfd, 0x46, 0x64, 0x4d, 0xd1, 0xe5,
    499 				0x68, 0x23, 0x49, 0x11, 0xbd, 0x4f, 0x21, 0x6f,
    500 				0xcd, 0x88, 0x4d, 0xeb, 0x22, 0xad, 0x36, 0x57,
    501 				0xf3, 0x94, 0x00, 0x13, 0x3c, 0xf3, 0xf6, 0xc6,
    502 				0xc6, 0x3c, 0x00, 0x8e, 0xb6, 0x8c, 0x39, 0x85,
    503 				0x01, 0x85, 0x00, 0x16, 0xe7, 0xba, 0x9a, 0xa1,
    504 				0xd1,
    505 			],
    506 			b = [
    507 				0x04, 0xe0, 0xb0, 0x1d, 0x37, 0xe0, 0x12, 0xba,
    508 				0x21, 0xcd, 0xc5, 0xc4, 0x18, 0xfd, 0x85, 0x0a,
    509 				0x21, 0x11, 0x32, 0x69, 0x73, 0xc0, 0xd4, 0x55,
    510 				0xf3, 0x2e, 0x9d, 0x25, 0x0c, 0x4a, 0xc8, 0x89,
    511 				0x4d, 0x7c, 0xbf, 0xca, 0x2d, 0x28, 0x6d, 0x20,
    512 				0x5b, 0xbf, 0x0d, 0x1b, 0x6e, 0x92, 0x97, 0xd6,
    513 				0xbb, 0xe2, 0x1b, 0x17, 0xac, 0xce, 0xd9, 0x7c,
    514 				0x7e, 0x54, 0xca, 0xfb, 0xaf, 0x53, 0xa8, 0xde,
    515 				0xba, 0x4c, 0x0a, 0x0f, 0x67, 0x03, 0xe7, 0x23,
    516 				0xcf, 0x19, 0x07, 0x31, 0x71, 0x9a, 0x49, 0x51,
    517 				0x7f, 0xbd, 0x5b, 0xa0, 0x34, 0x5f, 0x79, 0xba,
    518 				0x48, 0xf1, 0x41, 0x9d, 0xcc, 0x2d, 0xef, 0x80,
    519 				0xbb,
    520 			],
    521 			x = [
    522 				0xda, 0x9c, 0x84, 0xcf, 0x2d, 0x77, 0x4c, 0xfa,
    523 				0xe5, 0xdc, 0x52, 0xc3, 0xb3, 0xda, 0x1c, 0xa0,
    524 				0x26, 0xb0, 0x53, 0x16, 0x66, 0x46, 0x5f, 0x60,
    525 				0xa6, 0xbe, 0x6e, 0xd1, 0x0a, 0x5f, 0x01, 0x50,
    526 				0x63, 0xe1, 0x47, 0x62, 0x68, 0xcf, 0x40, 0x3a,
    527 				0x2b, 0xf0, 0x96, 0x6c, 0x1e, 0x71, 0x24, 0x79,
    528 			],
    529 			y = [
    530 				0xd9, 0xa7, 0x84, 0xd0, 0x77, 0x9e, 0x07, 0x4d,
    531 				0x78, 0x09, 0x84, 0xef, 0x5b, 0x7d, 0x94, 0xd7,
    532 				0xd8, 0x1f, 0x94, 0x1e, 0xfc, 0x3d, 0x76, 0x6c,
    533 				0x0d, 0x4c, 0x87, 0x76, 0xdf, 0x52, 0xfc, 0xe0,
    534 				0x02, 0x17, 0x2c, 0x95, 0x5e, 0x4b, 0xb7, 0x1f,
    535 				0x84, 0xce, 0x2e, 0x54, 0xf2, 0x08, 0xf7, 0x6a,
    536 			],
    537 			result = 0,
    538 			expected = [],
    539 		},
    540 		// invalid b
    541 		multc {
    542 			a = [
    543 				0x04, 0xe4, 0x4f, 0x26, 0xd9, 0xce, 0xa7, 0xf0,
    544 				0x69, 0xed, 0xa6, 0x1f, 0x01, 0xcb, 0xef, 0x53,
    545 				0xe8, 0x2b, 0xf8, 0xdc, 0x16, 0x56, 0x05, 0x64,
    546 				0x8a, 0x46, 0xf8, 0x54, 0x25, 0x8e, 0x3e, 0x6c,
    547 				0xe8, 0xc3, 0x88, 0x0b, 0x30, 0xba, 0x9c, 0x8b,
    548 				0xf7, 0xf8, 0x17, 0xbb, 0x34, 0x08, 0x4b, 0xc5,
    549 				0xa7, 0xa3, 0x1d, 0x46, 0x64, 0x4d, 0xd1, 0xe5,
    550 				0x68, 0x23, 0x49, 0x11, 0xbd, 0x4f, 0x21, 0x6f,
    551 				0xcd, 0x88, 0x4d, 0xeb, 0x22, 0xad, 0x36, 0x57,
    552 				0xf3, 0x94, 0x5b, 0x13, 0x3c, 0xf3, 0xf6, 0xc6,
    553 				0xc6, 0x3c, 0xa1, 0x8e, 0xb6, 0x8c, 0x39, 0x85,
    554 				0x01, 0x85, 0x22, 0x16, 0xe7, 0xba, 0x9a, 0xa1,
    555 				0xd1,
    556 			],
    557 			b = [
    558 				0x04, 0xe0, 0xb0, 0x1d, 0x37, 0xe0, 0x12, 0xba,
    559 				0x21, 0xcd, 0xc5, 0xc4, 0x18, 0xfd, 0x85, 0x0a,
    560 				0x21, 0x11, 0x32, 0x69, 0x73, 0xc0, 0xd4, 0x55,
    561 				0xf3, 0x2e, 0x9d, 0x25, 0x0c, 0x4a, 0xc8, 0x89,
    562 				0x4d, 0x7c, 0xbf, 0xca, 0x2d, 0x28, 0x6d, 0x20,
    563 				0x5b, 0x0f, 0x0d, 0x1b, 0x6e, 0x92, 0x97, 0xd6,
    564 				0xbb, 0x0f, 0x1b, 0x17, 0xac, 0xce, 0xd9, 0x7c,
    565 				0x7e, 0x0f, 0xca, 0xfb, 0xaf, 0x53, 0xa8, 0xde,
    566 				0xba, 0x0f, 0x0a, 0x0f, 0x67, 0x03, 0xe7, 0x23,
    567 				0xcf, 0x0f, 0x07, 0x31, 0x71, 0x9a, 0x49, 0x51,
    568 				0x7f, 0x0f, 0x5b, 0xa0, 0x34, 0x5f, 0x79, 0xba,
    569 				0x48, 0xff, 0x41, 0x9d, 0xcc, 0x2d, 0xef, 0x80,
    570 				0xbb,
    571 			],
    572 			x = [
    573 				0xda, 0x9c, 0x84, 0xcf, 0x2d, 0x77, 0x4c, 0xfa,
    574 				0xe5, 0xdc, 0x52, 0xc3, 0xb3, 0xda, 0x1c, 0xa0,
    575 				0x26, 0xb0, 0x53, 0x16, 0x66, 0x46, 0x5f, 0x60,
    576 				0xa6, 0xbe, 0x6e, 0xd1, 0x0a, 0x5f, 0x01, 0x50,
    577 				0x63, 0xe1, 0x47, 0x62, 0x68, 0xcf, 0x40, 0x3a,
    578 				0x2b, 0xf0, 0x96, 0x6c, 0x1e, 0x71, 0x24, 0x79,
    579 			],
    580 			y = [
    581 				0xd9, 0xa7, 0x84, 0xd0, 0x77, 0x9e, 0x07, 0x4d,
    582 				0x78, 0x09, 0x84, 0xef, 0x5b, 0x7d, 0x94, 0xd7,
    583 				0xd8, 0x1f, 0x94, 0x1e, 0xfc, 0x3d, 0x76, 0x6c,
    584 				0x0d, 0x4c, 0x87, 0x76, 0xdf, 0x52, 0xfc, 0xe0,
    585 				0x02, 0x17, 0x2c, 0x95, 0x5e, 0x4b, 0xb7, 0x1f,
    586 				0x84, 0xce, 0x2e, 0x54, 0xf2, 0x08, 0xf7, 0x6a,
    587 			],
    588 			result = 0,
    589 			expected = [],
    590 		},
    591 		// invalid a and b
    592 		multc {
    593 			a = [
    594 				0x04, 0xe4, 0x4f, 0x26, 0xd9, 0xce, 0xa7, 0xf0,
    595 				0x69, 0xed, 0xf6, 0x1f, 0x01, 0xcb, 0xef, 0x53,
    596 				0xe8, 0x2b, 0xf8, 0xdc, 0x16, 0x56, 0x05, 0x64,
    597 				0x8a, 0x46, 0xf8, 0x54, 0x25, 0x8e, 0x3e, 0x6c,
    598 				0xe8, 0xc3, 0xf8, 0x0b, 0x30, 0xba, 0x9c, 0x8b,
    599 				0xf7, 0xf8, 0xf7, 0xbb, 0x34, 0x08, 0x4b, 0xc5,
    600 				0xa7, 0xa3, 0xfd, 0x46, 0x64, 0x4d, 0xd1, 0xe5,
    601 				0x68, 0x23, 0xf9, 0x11, 0xbd, 0x4f, 0x21, 0x6f,
    602 				0xcd, 0x88, 0xfd, 0xeb, 0x22, 0xad, 0x36, 0x57,
    603 				0xf3, 0x94, 0xfb, 0x13, 0x3c, 0xf3, 0xf6, 0xc6,
    604 				0xc6, 0x3c, 0xf1, 0x8e, 0xb6, 0x8c, 0x39, 0x85,
    605 				0x01, 0x85, 0xf2, 0x16, 0xe7, 0xba, 0x9a, 0xa1,
    606 				0xd1,
    607 			],
    608 			b = [
    609 				0x04, 0xe0, 0xb0, 0x1d, 0x37, 0xe0, 0x12, 0xba,
    610 				0x21, 0xcd, 0xc5, 0xc4, 0x18, 0xfd, 0x85, 0x0a,
    611 				0x21, 0x11, 0x32, 0x60, 0x73, 0xc0, 0xd4, 0x55,
    612 				0xf3, 0x2e, 0x9d, 0x20, 0x0c, 0x4a, 0xc8, 0x89,
    613 				0x4d, 0x7c, 0xbf, 0xc0, 0x2d, 0x28, 0x6d, 0x20,
    614 				0x5b, 0xbf, 0x0d, 0x10, 0x6e, 0x92, 0x97, 0xd6,
    615 				0xbb, 0xe2, 0x1b, 0x10, 0xac, 0xce, 0xd9, 0x7c,
    616 				0x7e, 0x54, 0xca, 0xf0, 0xaf, 0x53, 0xa8, 0xde,
    617 				0xba, 0x4c, 0x0a, 0x00, 0x67, 0x03, 0xe7, 0x23,
    618 				0xcf, 0x19, 0x07, 0x30, 0x71, 0x9a, 0x49, 0x51,
    619 				0x7f, 0xbd, 0x5b, 0xa0, 0x34, 0x5f, 0x79, 0xba,
    620 				0x48, 0xf1, 0x41, 0x90, 0xcc, 0x2d, 0xef, 0x80,
    621 				0xbb,
    622 			],
    623 			x = [
    624 				0xda, 0x9c, 0x84, 0xcf, 0x2d, 0x77, 0x4c, 0xfa,
    625 				0xe5, 0xdc, 0x52, 0xc3, 0xb3, 0xda, 0x1c, 0xa0,
    626 				0x26, 0xb0, 0x53, 0x16, 0x66, 0x46, 0x5f, 0x60,
    627 				0xa6, 0xbe, 0x6e, 0xd1, 0x0a, 0x5f, 0x01, 0x50,
    628 				0x63, 0xe1, 0x47, 0x62, 0x68, 0xcf, 0x40, 0x3a,
    629 				0x2b, 0xf0, 0x96, 0x6c, 0x1e, 0x71, 0x24, 0x79,
    630 			],
    631 			y = [
    632 				0xd9, 0xa7, 0x84, 0xd0, 0x77, 0x9e, 0x07, 0x4d,
    633 				0x78, 0x09, 0x84, 0xef, 0x5b, 0x7d, 0x94, 0xd7,
    634 				0xd8, 0x1f, 0x94, 0x1e, 0xfc, 0x3d, 0x76, 0x6c,
    635 				0x0d, 0x4c, 0x87, 0x76, 0xdf, 0x52, 0xfc, 0xe0,
    636 				0x02, 0x17, 0x2c, 0x95, 0x5e, 0x4b, 0xb7, 0x1f,
    637 				0x84, 0xce, 0x2e, 0x54, 0xf2, 0x08, 0xf7, 0x6a,
    638 			],
    639 			result = 0,
    640 			expected = [],
    641 		},
    642 	];
    643 
    644 	tmuladd(p384, tcs);
    645 };
    646 
    647 @test fn p521_mulgen() void = {
    648 	let c = p521;
    649 
    650 	// multiply by 1
    651 	let m1: [P521_SCALARSZ]u8 = [0...];
    652 	m1[len(m1) - 1] = 1;
    653 
    654 	let g = alloc(P521_G);
    655 	defer free(g);
    656 	assert(c.mul(g, m1) == 1);
    657 	assert(bytes::equal(g, P521_G));
    658 
    659 	assert(c.mulgen(g, m1) == 133);
    660 	assert(bytes::equal(g, P521_G));
    661 
    662 	// multiply by order - 1
    663 	let o = alloc(P521_N);
    664 	defer free(o);
    665 	o[len(o) - 1] -= 1;
    666 
    667 	const expected: [_]u8 = [
    668 		0x04, 0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9,
    669 		0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c,
    670 		0x64, 0x81, 0x39, 0x05, 0x3f, 0xb5, 0x21, 0xf8, 0x28, 0xaf,
    671 		0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef,
    672 		0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, 0xa8,
    673 		0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9,
    674 		0x7e, 0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x00, 0xe7, 0xc6,
    675 		0xd6, 0x95, 0x87, 0x65, 0xc4, 0x3f, 0xfb, 0xa3, 0x75, 0xa0,
    676 		0x4b, 0xd3, 0x82, 0xe4, 0x26, 0x67, 0x0a, 0xbb, 0xb6, 0xa8,
    677 		0x64, 0xbb, 0x97, 0xe8, 0x50, 0x42, 0xe8, 0xd8, 0xc1, 0x99,
    678 		0xd3, 0x68, 0x11, 0x8d, 0x66, 0xa1, 0x0b, 0xd9, 0xbf, 0x3a,
    679 		0xaf, 0x46, 0xfe, 0xc0, 0x52, 0xf8, 0x9e, 0xca, 0xc3, 0x8f,
    680 		0x79, 0x5d, 0x8d, 0x3d, 0xbf, 0x77, 0x41, 0x6b, 0x89, 0x60,
    681 		0x2e, 0x99, 0xaf,
    682 	];
    683 
    684 	assert(c.mul(g, o) == 1);
    685 	assert(bytes::equal(g, expected));
    686 
    687 	let g = alloc(P521_G);
    688 	defer free(g);
    689 	assert(c.mulgen(g, o) == 133);
    690 	assert(bytes::equal(g, expected));
    691 
    692 	// random example
    693 	let priv: [_]u8 = [
    694 		0x01, 0x1f, 0xd5, 0x29, 0xff, 0x28, 0x24, 0x93, 0x43, 0x23,
    695 		0x3c, 0x0f, 0xe4, 0x15, 0x6a, 0xea, 0x1c, 0x95, 0xe6, 0xf1,
    696 		0x5e, 0x19, 0x30, 0xfe, 0xb4, 0xea, 0x0d, 0x24, 0xb3, 0x67,
    697 		0xa0, 0xeb, 0xcf, 0xed, 0x5c, 0xcf, 0xcf, 0x9f, 0x9d, 0x48,
    698 		0x04, 0x8b, 0xb1, 0x56, 0x53, 0xba, 0xa4, 0x86, 0x01, 0x29,
    699 		0x61, 0x21, 0xca, 0xd7, 0x63, 0x84, 0x35, 0x45, 0xc3, 0x9b,
    700 		0x55, 0xff, 0x9a, 0x4f, 0x27, 0x03,
    701 	];
    702 	const expected: [_]u8 = [
    703 		0x04, 0x00, 0x9f, 0x72, 0x15, 0x21, 0x0c, 0xdd, 0x22, 0x24,
    704 		0x16, 0xbb, 0x18, 0xa6, 0x46, 0x21, 0xee, 0x4f, 0x73, 0x1e,
    705 		0x9e, 0x03, 0xaf, 0x79, 0xc7, 0x1f, 0xf0, 0x33, 0x1c, 0xa6,
    706 		0xa1, 0x13, 0x98, 0x95, 0x6e, 0x88, 0x44, 0x6b, 0xa4, 0xbd,
    707 		0x4d, 0x49, 0x9e, 0xcb, 0x96, 0x0e, 0xdf, 0x67, 0x89, 0xca,
    708 		0xd5, 0xc3, 0x9e, 0x99, 0xa8, 0xc9, 0x00, 0x4b, 0x2c, 0x49,
    709 		0x57, 0xd7, 0xee, 0xf4, 0x6e, 0x07, 0xbb, 0x01, 0x35, 0xe2,
    710 		0xa4, 0xd6, 0x60, 0x99, 0x2c, 0x62, 0xad, 0xab, 0x89, 0xb5,
    711 		0xe7, 0xb6, 0x4b, 0x44, 0x89, 0xcf, 0xb0, 0x19, 0x29, 0xf8,
    712 		0x54, 0x76, 0x07, 0x40, 0x3a, 0xee, 0x41, 0x0c, 0x64, 0xeb,
    713 		0xda, 0x1e, 0x22, 0x4a, 0xee, 0xdb, 0x16, 0xa0, 0x5d, 0xe1,
    714 		0x95, 0x2f, 0xe3, 0xbc, 0x53, 0xd3, 0xf4, 0x36, 0x76, 0x03,
    715 		0x1f, 0xd8, 0xc6, 0xf4, 0x23, 0x4f, 0x45, 0x4e, 0x11, 0xeb,
    716 		0xb2, 0xb1, 0x62,
    717 	];
    718 
    719 	let g = alloc(P521_G);
    720 	defer free(g);
    721 	assert(c.mul(g, priv) == 1);
    722 	assert(bytes::equal(g, expected));
    723 
    724 	let r: [133]u8 = [0...];
    725 	assert(c.mulgen(r, priv) == 133);
    726 	assert(bytes::equal(r, expected));
    727 };
    728 
    729 @test fn p521_muladd() void = {
    730 	let tcs = [
    731 		multc {
    732 			a = [
    733 				0x04, 0x01, 0xb1, 0x0a, 0x39, 0x7f, 0x94, 0xe9,
    734 				0x0b, 0x4f, 0x8f, 0xf1, 0xe8, 0x31, 0xca, 0x0a,
    735 				0xda, 0x8f, 0x1c, 0x80, 0x1e, 0x1a, 0x95, 0x65,
    736 				0xdb, 0x0f, 0x52, 0x7f, 0xaa, 0x14, 0x65, 0x6d,
    737 				0xe9, 0xe6, 0x5c, 0xa2, 0x34, 0xc8, 0xea, 0x11,
    738 				0x67, 0x4a, 0xc3, 0x5f, 0xce, 0x8b, 0xa8, 0xe8,
    739 				0xe4, 0x8b, 0x6c, 0x9e, 0x5c, 0x0d, 0x37, 0xf0,
    740 				0x4e, 0x33, 0xb8, 0xd1, 0x5f, 0xce, 0x90, 0x92,
    741 				0xa7, 0x14, 0x07, 0x01, 0x1e, 0xde, 0x56, 0x92,
    742 				0xcc, 0x39, 0xb6, 0xe9, 0xcf, 0xbe, 0xe0, 0xeb,
    743 				0x35, 0x30, 0xfc, 0xf2, 0x2b, 0xc6, 0xe4, 0xfa,
    744 				0x71, 0x2e, 0x2f, 0x87, 0x54, 0x83, 0xb1, 0x9c,
    745 				0x96, 0xe2, 0xbb, 0x72, 0xca, 0x51, 0xf2, 0x58,
    746 				0x25, 0x80, 0xf4, 0x47, 0xa3, 0xb6, 0x29, 0x45,
    747 				0x3c, 0x28, 0xa7, 0x65, 0x85, 0x40, 0xb7, 0x2b,
    748 				0x75, 0x38, 0x4a, 0x3e, 0x25, 0x0a, 0xb6, 0x58,
    749 				0xe3, 0x9a, 0x7c, 0xde, 0xd5,
    750 			],
    751 			b = [],
    752 			x = [
    753 				0x01, 0x74, 0xe2, 0x0e, 0x0c, 0xa6, 0xd0, 0x12,
    754 				0xb0, 0xc3, 0x86, 0xbc, 0xfc, 0x9a, 0xcb, 0x09,
    755 				0x7a, 0xf9, 0xca, 0xb7, 0xc8, 0x79, 0x39, 0x3e,
    756 				0xb6, 0x8e, 0x3e, 0x2f, 0x02, 0x6a, 0xfd, 0x07,
    757 				0x65, 0xe9, 0x97, 0xe1, 0xf5, 0xf0, 0x16, 0x9a,
    758 				0xa2, 0xe6, 0x03, 0x75, 0x1f, 0xa2, 0xf4, 0xe5,
    759 				0xcd, 0x54, 0x94, 0x60, 0xb2, 0xfd, 0xe7, 0x97,
    760 				0xea, 0x72, 0x02, 0xb9, 0x96, 0x48, 0xd3, 0x45,
    761 				0xc2, 0x26,
    762 			],
    763 			y = [
    764 				0x01, 0xae, 0xa0, 0x8f, 0x5b, 0x13, 0xe1, 0x85,
    765 				0x4f, 0xfe, 0xcf, 0x73, 0x6a, 0x18, 0xc3, 0xfa,
    766 				0xb7, 0xe6, 0xfc, 0xe5, 0xa9, 0x09, 0x8a, 0x68,
    767 				0x4f, 0x49, 0x93, 0x59, 0xeb, 0xfd, 0x91, 0xf9,
    768 				0x45, 0x1d, 0xcf, 0x51, 0x61, 0x39, 0x5c, 0x87,
    769 				0x6c, 0x70, 0x9d, 0xfa, 0x7a, 0x86, 0x30, 0x64,
    770 				0x3a, 0x4f, 0x48, 0x78, 0x3a, 0x2f, 0x9f, 0x84,
    771 				0x07, 0xc1, 0x94, 0x5a, 0xc7, 0x1a, 0xe2, 0x5d,
    772 				0x73, 0xb3,
    773 			],
    774 			result = 1,
    775 			expected = [
    776 				0x04, 0x00, 0x27, 0xd3, 0x90, 0xf4, 0xf7, 0xdc,
    777 				0x2a, 0x67, 0xa0, 0x2b, 0x8c, 0x31, 0x3b, 0xe3,
    778 				0x37, 0xb9, 0xf9, 0x08, 0x49, 0x46, 0x56, 0xa6,
    779 				0xa4, 0x3d, 0x7c, 0x0a, 0x74, 0x98, 0x72, 0x20,
    780 				0xbe, 0xa7, 0xf8, 0x67, 0x95, 0x7d, 0x1f, 0x6a,
    781 				0x38, 0x03, 0xc9, 0xf3, 0xac, 0x55, 0xb9, 0x5b,
    782 				0x5d, 0xeb, 0x01, 0xe0, 0xaf, 0xf1, 0x66, 0xcf,
    783 				0x90, 0xe3, 0x43, 0x5c, 0x25, 0xfb, 0xcd, 0x48,
    784 				0xd4, 0xf5, 0xbd, 0x01, 0xb5, 0xa5, 0xd4, 0xa1,
    785 				0xe4, 0x4f, 0xab, 0x94, 0x96, 0xdd, 0x32, 0x7f,
    786 				0x9e, 0x40, 0x1c, 0x25, 0x7d, 0xcb, 0xed, 0xa5,
    787 				0x53, 0xac, 0x4f, 0xa3, 0x72, 0x75, 0x56, 0xd8,
    788 				0x32, 0x2c, 0x76, 0xed, 0x0d, 0xe7, 0x5c, 0xbd,
    789 				0xbd, 0xe8, 0x09, 0x35, 0x0e, 0x57, 0xd4, 0x20,
    790 				0xe1, 0x46, 0x6c, 0x49, 0xe1, 0x49, 0xc6, 0x04,
    791 				0x6e, 0xf9, 0xc9, 0x87, 0x76, 0x0a, 0x9a, 0x3b,
    792 				0x2b, 0xa6, 0x43, 0xc2, 0x24,
    793 			],
    794 		},
    795 		multc {
    796 			a = [
    797 				0x04, 0x01, 0xb1, 0x0a, 0x39, 0x7f, 0x94, 0xe9,
    798 				0x0b, 0x4f, 0x8f, 0xf1, 0xe8, 0x31, 0xca, 0x0a,
    799 				0xda, 0x8f, 0x1c, 0x80, 0x1e, 0x1a, 0x95, 0x65,
    800 				0xdb, 0x0f, 0x52, 0x7f, 0xaa, 0x14, 0x65, 0x6d,
    801 				0xe9, 0xe6, 0x5c, 0xa2, 0x34, 0xc8, 0xea, 0x11,
    802 				0x67, 0x4a, 0xc3, 0x5f, 0xce, 0x8b, 0xa8, 0xe8,
    803 				0xe4, 0x8b, 0x6c, 0x9e, 0x5c, 0x0d, 0x37, 0xf0,
    804 				0x4e, 0x33, 0xb8, 0xd1, 0x5f, 0xce, 0x90, 0x92,
    805 				0xa7, 0x14, 0x07, 0x01, 0x1e, 0xde, 0x56, 0x92,
    806 				0xcc, 0x39, 0xb6, 0xe9, 0xcf, 0xbe, 0xe0, 0xeb,
    807 				0x35, 0x30, 0xfc, 0xf2, 0x2b, 0xc6, 0xe4, 0xfa,
    808 				0x71, 0x2e, 0x2f, 0x87, 0x54, 0x83, 0xb1, 0x9c,
    809 				0x96, 0xe2, 0xbb, 0x72, 0xca, 0x51, 0xf2, 0x58,
    810 				0x25, 0x80, 0xf4, 0x47, 0xa3, 0xb6, 0x29, 0x45,
    811 				0x3c, 0x28, 0xa7, 0x65, 0x85, 0x40, 0xb7, 0x2b,
    812 				0x75, 0x38, 0x4a, 0x3e, 0x25, 0x0a, 0xb6, 0x58,
    813 				0xe3, 0x9a, 0x7c, 0xde, 0xd5,
    814 			],
    815 			b = [
    816 				0x04, 0x01, 0x01, 0xbf, 0xd2, 0xa7, 0xed, 0xe7,
    817 				0x68, 0x5a, 0x86, 0x4b, 0xc8, 0x40, 0x42, 0x9d,
    818 				0xea, 0x5c, 0xe5, 0x3e, 0x3d, 0x3d, 0x48, 0xc6,
    819 				0x38, 0xb0, 0x7f, 0xd4, 0x35, 0x67, 0x67, 0xb2,
    820 				0x12, 0xa7, 0xba, 0xd4, 0xc3, 0x22, 0x3f, 0x7d,
    821 				0xff, 0xe2, 0x23, 0x8e, 0x72, 0x71, 0x2c, 0x24,
    822 				0xd5, 0x91, 0xdc, 0x9c, 0xb2, 0xc7, 0x2d, 0x5c,
    823 				0xe1, 0xf7, 0x17, 0x49, 0x09, 0xeb, 0xe4, 0x26,
    824 				0xab, 0xe6, 0x6d, 0x01, 0x26, 0xb1, 0x8e, 0x19,
    825 				0xb3, 0xe3, 0x72, 0xe9, 0xf4, 0x15, 0xe3, 0x52,
    826 				0x2a, 0xb3, 0xcb, 0xac, 0xf8, 0xe7, 0xc0, 0x14,
    827 				0x60, 0x97, 0x71, 0xa0, 0x54, 0x2b, 0x94, 0x4c,
    828 				0x13, 0x6e, 0xfb, 0x98, 0x11, 0x72, 0x60, 0x6a,
    829 				0x0e, 0xd5, 0xb4, 0xe8, 0x17, 0x6c, 0x09, 0x2a,
    830 				0xff, 0x89, 0xac, 0x88, 0xcd, 0x56, 0xe4, 0xcc,
    831 				0x66, 0x79, 0x8c, 0xb7, 0xd2, 0x44, 0x44, 0x60,
    832 				0xd8, 0x04, 0xa2, 0x50, 0x0f,
    833 			],
    834 			x = [
    835 				0x01, 0x74, 0xe2, 0x0e, 0x0c, 0xa6, 0xd0, 0x12,
    836 				0xb0, 0xc3, 0x86, 0xbc, 0xfc, 0x9a, 0xcb, 0x09,
    837 				0x7a, 0xf9, 0xca, 0xb7, 0xc8, 0x79, 0x39, 0x3e,
    838 				0xb6, 0x8e, 0x3e, 0x2f, 0x02, 0x6a, 0xfd, 0x07,
    839 				0x65, 0xe9, 0x97, 0xe1, 0xf5, 0xf0, 0x16, 0x9a,
    840 				0xa2, 0xe6, 0x03, 0x75, 0x1f, 0xa2, 0xf4, 0xe5,
    841 				0xcd, 0x54, 0x94, 0x60, 0xb2, 0xfd, 0xe7, 0x97,
    842 				0xea, 0x72, 0x02, 0xb9, 0x96, 0x48, 0xd3, 0x45,
    843 				0xc2, 0x26,
    844 			],
    845 			y = [
    846 				0x01, 0xae, 0xa0, 0x8f, 0x5b, 0x13, 0xe1, 0x85,
    847 				0x4f, 0xfe, 0xcf, 0x73, 0x6a, 0x18, 0xc3, 0xfa,
    848 				0xb7, 0xe6, 0xfc, 0xe5, 0xa9, 0x09, 0x8a, 0x68,
    849 				0x4f, 0x49, 0x93, 0x59, 0xeb, 0xfd, 0x91, 0xf9,
    850 				0x45, 0x1d, 0xcf, 0x51, 0x61, 0x39, 0x5c, 0x87,
    851 				0x6c, 0x70, 0x9d, 0xfa, 0x7a, 0x86, 0x30, 0x64,
    852 				0x3a, 0x4f, 0x48, 0x78, 0x3a, 0x2f, 0x9f, 0x84,
    853 				0x07, 0xc1, 0x94, 0x5a, 0xc7, 0x1a, 0xe2, 0x5d,
    854 				0x73, 0xb3,
    855 			],
    856 			result = 1,
    857 			expected = [
    858 				0x04, 0x01, 0x4b, 0x18, 0x4d, 0x28, 0xd0, 0x8f,
    859 				0x23, 0xfc, 0x27, 0x13, 0x7e, 0xc9, 0x9d, 0xb2,
    860 				0x39, 0xb5, 0x5b, 0x7a, 0x30, 0xcb, 0x35, 0x47,
    861 				0x1b, 0x04, 0x63, 0x8a, 0x50, 0x15, 0xb2, 0x79,
    862 				0x9d, 0x74, 0xf5, 0xbc, 0x21, 0x14, 0x5e, 0x9f,
    863 				0x3f, 0x88, 0xfe, 0x46, 0x9d, 0x7c, 0xb8, 0x1a,
    864 				0x1c, 0x5c, 0x86, 0x60, 0xf2, 0xbb, 0x04, 0xdc,
    865 				0x81, 0x9d, 0xf3, 0x35, 0x75, 0x5e, 0xa9, 0x58,
    866 				0x36, 0x17, 0x33, 0x01, 0x86, 0xd9, 0x16, 0xdb,
    867 				0x10, 0xae, 0x45, 0x0a, 0xb6, 0x75, 0x6d, 0x90,
    868 				0x85, 0x92, 0xde, 0x4c, 0x96, 0x3b, 0xfd, 0x31,
    869 				0xe6, 0x99, 0x7f, 0xe2, 0xb6, 0xfd, 0xbb, 0x76,
    870 				0xe4, 0x62, 0x8f, 0xb8, 0xba, 0x8c, 0x9d, 0xc9,
    871 				0xc4, 0x2f, 0x3e, 0x67, 0xd5, 0xaf, 0xbc, 0xf0,
    872 				0x60, 0x8c, 0xca, 0xec, 0xa9, 0x21, 0xd1, 0x8e,
    873 				0x29, 0xc9, 0x81, 0x76, 0xdb, 0x17, 0x17, 0xd8,
    874 				0x6b, 0x97, 0x58, 0x88, 0x78,
    875 			],
    876 		},
    877 		// invalid a
    878 		multc {
    879 			a = [
    880 				0x04, 0x01, 0xb1, 0x0a, 0x39, 0x7f, 0x94, 0xe9,
    881 				0x0b, 0x4f, 0x8f, 0xf1, 0xe8, 0x31, 0xca, 0x0a,
    882 				0xda, 0x8f, 0x1c, 0x80, 0x1e, 0x1a, 0x95, 0x65,
    883 				0xdb, 0x0f, 0x52, 0x7f, 0xaa, 0x14, 0x65, 0x6d,
    884 				0xe9, 0xef, 0x5c, 0xa2, 0x34, 0xc8, 0xea, 0x11,
    885 				0x67, 0x4f, 0xc3, 0x5f, 0xce, 0x8b, 0xa8, 0xe8,
    886 				0xe4, 0x8f, 0x6c, 0x9e, 0x5c, 0x0d, 0x37, 0xf0,
    887 				0x4e, 0x3f, 0xb8, 0xd1, 0x5f, 0xce, 0x90, 0x92,
    888 				0xa7, 0x1f, 0x07, 0x01, 0x1e, 0xde, 0x56, 0x92,
    889 				0xcc, 0x3f, 0xb6, 0xe9, 0xcf, 0xbe, 0xe0, 0xeb,
    890 				0x35, 0x3f, 0xfc, 0xf2, 0x2b, 0xc6, 0xe4, 0xfa,
    891 				0x71, 0x2f, 0x2f, 0x87, 0x54, 0x83, 0xb1, 0x9c,
    892 				0x96, 0xef, 0xbb, 0x72, 0xca, 0x51, 0xf2, 0x58,
    893 				0x25, 0x8f, 0xf4, 0x47, 0xa3, 0xb6, 0x29, 0x45,
    894 				0x3c, 0x2f, 0xa7, 0x65, 0x85, 0x40, 0xb7, 0x2b,
    895 				0x75, 0x38, 0x4a, 0x3e, 0x25, 0x0a, 0xb6, 0x58,
    896 				0xe3, 0x9a, 0x7c, 0xde, 0xd5,
    897 			],
    898 			b = [
    899 				0x04, 0x01, 0x01, 0xbf, 0xd2, 0xa7, 0xed, 0xe7,
    900 				0x68, 0x5a, 0x86, 0x4b, 0xc8, 0x40, 0x42, 0x9d,
    901 				0xea, 0x5c, 0xe5, 0x3e, 0x3d, 0x3d, 0x48, 0xc6,
    902 				0x38, 0xb0, 0x7f, 0xd4, 0x35, 0x67, 0x67, 0xb2,
    903 				0x12, 0xa7, 0xba, 0xd4, 0xc3, 0x22, 0x3f, 0x7d,
    904 				0xff, 0xe2, 0x23, 0x8e, 0x72, 0x71, 0x2c, 0x24,
    905 				0xd5, 0x91, 0xdc, 0x9c, 0xb2, 0xc7, 0x2d, 0x5c,
    906 				0xe1, 0xf7, 0x17, 0x49, 0x09, 0xeb, 0xe4, 0x26,
    907 				0xab, 0xe6, 0x6d, 0x01, 0x26, 0xb1, 0x8e, 0x19,
    908 				0xb3, 0xe3, 0x72, 0xe9, 0xf4, 0x15, 0xe3, 0x52,
    909 				0x2a, 0xb3, 0xcb, 0xac, 0xf8, 0xe7, 0xc0, 0x14,
    910 				0x60, 0x97, 0x71, 0xa0, 0x54, 0x2b, 0x94, 0x4c,
    911 				0x13, 0x6e, 0xfb, 0x98, 0x11, 0x72, 0x60, 0x6a,
    912 				0x0e, 0xd5, 0xb4, 0xe8, 0x17, 0x6c, 0x09, 0x2a,
    913 				0xff, 0x89, 0xac, 0x88, 0xcd, 0x56, 0xe4, 0xcc,
    914 				0x66, 0x79, 0x8c, 0xb7, 0xd2, 0x44, 0x44, 0x60,
    915 				0xd8, 0x04, 0xa2, 0x50, 0x0f,
    916 			],
    917 			x = [
    918 				0x01, 0x74, 0xe2, 0x0e, 0x0c, 0xa6, 0xd0, 0x12,
    919 				0xb0, 0xc3, 0x86, 0xbc, 0xfc, 0x9a, 0xcb, 0x09,
    920 				0x7a, 0xf9, 0xca, 0xb7, 0xc8, 0x79, 0x39, 0x3e,
    921 				0xb6, 0x8e, 0x3e, 0x2f, 0x02, 0x6a, 0xfd, 0x07,
    922 				0x65, 0xe9, 0x97, 0xe1, 0xf5, 0xf0, 0x16, 0x9a,
    923 				0xa2, 0xe6, 0x03, 0x75, 0x1f, 0xa2, 0xf4, 0xe5,
    924 				0xcd, 0x54, 0x94, 0x60, 0xb2, 0xfd, 0xe7, 0x97,
    925 				0xea, 0x72, 0x02, 0xb9, 0x96, 0x48, 0xd3, 0x45,
    926 				0xc2, 0x26,
    927 			],
    928 			y = [
    929 				0x01, 0xae, 0xa0, 0x8f, 0x5b, 0x13, 0xe1, 0x85,
    930 				0x4f, 0xfe, 0xcf, 0x73, 0x6a, 0x18, 0xc3, 0xfa,
    931 				0xb7, 0xe6, 0xfc, 0xe5, 0xa9, 0x09, 0x8a, 0x68,
    932 				0x4f, 0x49, 0x93, 0x59, 0xeb, 0xfd, 0x91, 0xf9,
    933 				0x45, 0x1d, 0xcf, 0x51, 0x61, 0x39, 0x5c, 0x87,
    934 				0x6c, 0x70, 0x9d, 0xfa, 0x7a, 0x86, 0x30, 0x64,
    935 				0x3a, 0x4f, 0x48, 0x78, 0x3a, 0x2f, 0x9f, 0x84,
    936 				0x07, 0xc1, 0x94, 0x5a, 0xc7, 0x1a, 0xe2, 0x5d,
    937 				0x73, 0xb3,
    938 			],
    939 			result = 0,
    940 			expected = [],
    941 		},
    942 		// invalid b
    943 		multc {
    944 			a = [
    945 				0x04, 0x01, 0xb1, 0x0a, 0x39, 0x7f, 0x94, 0xe9,
    946 				0x0b, 0x4f, 0x8f, 0xf1, 0xe8, 0x31, 0xca, 0x0a,
    947 				0xda, 0x8f, 0x1c, 0x80, 0x1e, 0x1a, 0x95, 0x65,
    948 				0xdb, 0x0f, 0x52, 0x7f, 0xaa, 0x14, 0x65, 0x6d,
    949 				0xe9, 0xe6, 0x5c, 0xa2, 0x34, 0xc8, 0xea, 0x11,
    950 				0x67, 0x4a, 0xc3, 0x5f, 0xce, 0x8b, 0xa8, 0xe8,
    951 				0xe4, 0x8b, 0x6c, 0x9e, 0x5c, 0x0d, 0x37, 0xf0,
    952 				0x4e, 0x33, 0xb8, 0xd1, 0x5f, 0xce, 0x90, 0x92,
    953 				0xa7, 0x14, 0x07, 0x01, 0x1e, 0xde, 0x56, 0x92,
    954 				0xcc, 0x39, 0xb6, 0xe9, 0xcf, 0xbe, 0xe0, 0xeb,
    955 				0x35, 0x30, 0xfc, 0xf2, 0x2b, 0xc6, 0xe4, 0xfa,
    956 				0x71, 0x2e, 0x2f, 0x87, 0x54, 0x83, 0xb1, 0x9c,
    957 				0x96, 0xe2, 0xbb, 0x72, 0xca, 0x51, 0xf2, 0x58,
    958 				0x25, 0x80, 0xf4, 0x47, 0xa3, 0xb6, 0x29, 0x45,
    959 				0x3c, 0x28, 0xa7, 0x65, 0x85, 0x40, 0xb7, 0x2b,
    960 				0x75, 0x38, 0x4a, 0x3e, 0x25, 0x0a, 0xb6, 0x58,
    961 				0xe3, 0x9a, 0x7c, 0xde, 0xd5,
    962 			],
    963 			b = [
    964 				0x04, 0x01, 0x01, 0xbf, 0xd2, 0xa7, 0xed, 0xe7,
    965 				0x68, 0x5a, 0x86, 0x4b, 0xc8, 0x40, 0x42, 0x9d,
    966 				0xea, 0x5c, 0xe5, 0x5e, 0x3d, 0x3d, 0x48, 0xc6,
    967 				0x38, 0xb0, 0x7f, 0x54, 0x35, 0x67, 0x67, 0xb2,
    968 				0x12, 0xa7, 0xba, 0x54, 0xc3, 0x22, 0x3f, 0x7d,
    969 				0xff, 0xe2, 0x23, 0x5e, 0x72, 0x71, 0x2c, 0x24,
    970 				0xd5, 0x91, 0xdc, 0x5c, 0xb2, 0xc7, 0x2d, 0x5c,
    971 				0xe1, 0xf7, 0x17, 0x59, 0x09, 0xeb, 0xe4, 0x26,
    972 				0xab, 0xe6, 0x6d, 0x51, 0x26, 0xb1, 0x8e, 0x19,
    973 				0xb3, 0xe3, 0x72, 0x59, 0xf4, 0x15, 0xe3, 0x52,
    974 				0x2a, 0xb3, 0xcb, 0x5c, 0xf8, 0xe7, 0xc0, 0x14,
    975 				0x60, 0x97, 0x71, 0x50, 0x54, 0x2b, 0x94, 0x4c,
    976 				0x13, 0x6e, 0xfb, 0x58, 0x11, 0x72, 0x60, 0x6a,
    977 				0x0e, 0xd5, 0xb4, 0x58, 0x17, 0x6c, 0x09, 0x2a,
    978 				0xff, 0x89, 0xac, 0x58, 0xcd, 0x56, 0xe4, 0xcc,
    979 				0x66, 0x79, 0x8c, 0xb7, 0xd2, 0x44, 0x44, 0x60,
    980 				0xd8, 0x04, 0xa2, 0x50, 0x0f,
    981 			],
    982 			x = [
    983 				0x01, 0x74, 0xe2, 0x0e, 0x0c, 0xa6, 0xd0, 0x12,
    984 				0xb0, 0xc3, 0x86, 0xbc, 0xfc, 0x9a, 0xcb, 0x09,
    985 				0x7a, 0xf9, 0xca, 0xb7, 0xc8, 0x79, 0x39, 0x3e,
    986 				0xb6, 0x8e, 0x3e, 0x2f, 0x02, 0x6a, 0xfd, 0x07,
    987 				0x65, 0xe9, 0x97, 0xe1, 0xf5, 0xf0, 0x16, 0x9a,
    988 				0xa2, 0xe6, 0x03, 0x75, 0x1f, 0xa2, 0xf4, 0xe5,
    989 				0xcd, 0x54, 0x94, 0x60, 0xb2, 0xfd, 0xe7, 0x97,
    990 				0xea, 0x72, 0x02, 0xb9, 0x96, 0x48, 0xd3, 0x45,
    991 				0xc2, 0x26,
    992 			],
    993 			y = [
    994 				0x01, 0xae, 0xa0, 0x8f, 0x5b, 0x13, 0xe1, 0x85,
    995 				0x4f, 0xfe, 0xcf, 0x73, 0x6a, 0x18, 0xc3, 0xfa,
    996 				0xb7, 0xe6, 0xfc, 0xe5, 0xa9, 0x09, 0x8a, 0x68,
    997 				0x4f, 0x49, 0x93, 0x59, 0xeb, 0xfd, 0x91, 0xf9,
    998 				0x45, 0x1d, 0xcf, 0x51, 0x61, 0x39, 0x5c, 0x87,
    999 				0x6c, 0x70, 0x9d, 0xfa, 0x7a, 0x86, 0x30, 0x64,
   1000 				0x3a, 0x4f, 0x48, 0x78, 0x3a, 0x2f, 0x9f, 0x84,
   1001 				0x07, 0xc1, 0x94, 0x5a, 0xc7, 0x1a, 0xe2, 0x5d,
   1002 				0x73, 0xb3,
   1003 			],
   1004 			result = 0,
   1005 			expected = [],
   1006 		},
   1007 		// invalid a and b
   1008 		multc {
   1009 			a = [
   1010 				0x04, 0x01, 0xb1, 0x0a, 0x39, 0x7f, 0x94, 0xe9,
   1011 				0x0b, 0x4f, 0x8f, 0xf1, 0xe8, 0x31, 0xca, 0x0a,
   1012 				0xda, 0x8f, 0xfc, 0x80, 0x1e, 0x1a, 0x95, 0x65,
   1013 				0xdb, 0x0f, 0xf2, 0x7f, 0xaa, 0x14, 0x65, 0x6d,
   1014 				0xe9, 0xe6, 0xfc, 0xa2, 0x34, 0xc8, 0xea, 0x11,
   1015 				0x67, 0x4a, 0xf3, 0x5f, 0xce, 0x8b, 0xa8, 0xe8,
   1016 				0xe4, 0x8b, 0xfc, 0x9e, 0x5c, 0x0d, 0x37, 0xf0,
   1017 				0x4e, 0x33, 0xf8, 0xd1, 0x5f, 0xce, 0x90, 0x92,
   1018 				0xa7, 0x14, 0xf7, 0x01, 0x1e, 0xde, 0x56, 0x92,
   1019 				0xcc, 0x39, 0xf6, 0xe9, 0xcf, 0xbe, 0xe0, 0xeb,
   1020 				0x35, 0x30, 0xfc, 0xf2, 0x2b, 0xc6, 0xe4, 0xfa,
   1021 				0x71, 0x2e, 0xff, 0x87, 0x54, 0x83, 0xb1, 0x9c,
   1022 				0x96, 0xe2, 0xfb, 0x72, 0xca, 0x51, 0xf2, 0x58,
   1023 				0x25, 0x80, 0xf4, 0x47, 0xa3, 0xb6, 0x29, 0x45,
   1024 				0x3c, 0x28, 0xf7, 0x65, 0x85, 0x40, 0xb7, 0x2b,
   1025 				0x75, 0x38, 0x4a, 0x3e, 0x25, 0x0a, 0xb6, 0x58,
   1026 				0xe3, 0x9a, 0x7c, 0xde, 0xd5,
   1027 			],
   1028 			b = [
   1029 				0x04, 0x01, 0x01, 0xbf, 0xd2, 0xa7, 0xed, 0xe7,
   1030 				0x68, 0x5a, 0x06, 0x4b, 0xc8, 0x40, 0x42, 0x9d,
   1031 				0xea, 0x5c, 0x05, 0x3e, 0x3d, 0x3d, 0x48, 0xc6,
   1032 				0x38, 0xb0, 0x0f, 0xd4, 0x35, 0x67, 0x67, 0xb2,
   1033 				0x12, 0xa7, 0x0a, 0xd4, 0xc3, 0x22, 0x3f, 0x7d,
   1034 				0xff, 0xe2, 0x03, 0x8e, 0x72, 0x71, 0x2c, 0x24,
   1035 				0xd5, 0x91, 0x0c, 0x9c, 0xb2, 0xc7, 0x2d, 0x5c,
   1036 				0xe1, 0xf7, 0x07, 0x49, 0x09, 0xeb, 0xe4, 0x26,
   1037 				0xab, 0xe6, 0x0d, 0x01, 0x26, 0xb1, 0x8e, 0x19,
   1038 				0xb3, 0xe3, 0x72, 0xe9, 0xf4, 0x15, 0xe3, 0x52,
   1039 				0x2a, 0xb3, 0xcb, 0xac, 0xf8, 0xe7, 0xc0, 0x14,
   1040 				0x60, 0x97, 0x71, 0xa0, 0x54, 0x2b, 0x94, 0x4c,
   1041 				0x13, 0x6e, 0xfb, 0x98, 0x11, 0x72, 0x60, 0x6a,
   1042 				0x0e, 0xd5, 0xb4, 0xe8, 0x17, 0x6c, 0x09, 0x2a,
   1043 				0xff, 0x89, 0xac, 0x88, 0xcd, 0x56, 0xe4, 0xcc,
   1044 				0x66, 0x79, 0x8c, 0xb7, 0xd2, 0x44, 0x44, 0x60,
   1045 				0xd8, 0x04, 0xa2, 0x50, 0x0f,
   1046 			],
   1047 			x = [
   1048 				0x01, 0x74, 0xe2, 0x0e, 0x0c, 0xa6, 0xd0, 0x12,
   1049 				0xb0, 0xc3, 0x86, 0xbc, 0xfc, 0x9a, 0xcb, 0x09,
   1050 				0x7a, 0xf9, 0xca, 0xb7, 0xc8, 0x79, 0x39, 0x3e,
   1051 				0xb6, 0x8e, 0x3e, 0x2f, 0x02, 0x6a, 0xfd, 0x07,
   1052 				0x65, 0xe9, 0x97, 0xe1, 0xf5, 0xf0, 0x16, 0x9a,
   1053 				0xa2, 0xe6, 0x03, 0x75, 0x1f, 0xa2, 0xf4, 0xe5,
   1054 				0xcd, 0x54, 0x94, 0x60, 0xb2, 0xfd, 0xe7, 0x97,
   1055 				0xea, 0x72, 0x02, 0xb9, 0x96, 0x48, 0xd3, 0x45,
   1056 				0xc2, 0x26,
   1057 			],
   1058 			y = [
   1059 				0x01, 0xae, 0xa0, 0x8f, 0x5b, 0x13, 0xe1, 0x85,
   1060 				0x4f, 0xfe, 0xcf, 0x73, 0x6a, 0x18, 0xc3, 0xfa,
   1061 				0xb7, 0xe6, 0xfc, 0xe5, 0xa9, 0x09, 0x8a, 0x68,
   1062 				0x4f, 0x49, 0x93, 0x59, 0xeb, 0xfd, 0x91, 0xf9,
   1063 				0x45, 0x1d, 0xcf, 0x51, 0x61, 0x39, 0x5c, 0x87,
   1064 				0x6c, 0x70, 0x9d, 0xfa, 0x7a, 0x86, 0x30, 0x64,
   1065 				0x3a, 0x4f, 0x48, 0x78, 0x3a, 0x2f, 0x9f, 0x84,
   1066 				0x07, 0xc1, 0x94, 0x5a, 0xc7, 0x1a, 0xe2, 0x5d,
   1067 				0x73, 0xb3,
   1068 			],
   1069 			result = 0,
   1070 			expected = [],
   1071 		},
   1072 	];
   1073 
   1074 	tmuladd(p521, tcs);
   1075 };