hare

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

curves+test.ha (40404B)


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