diff --git a/curve25519-dalek/src/backend/mod.rs b/curve25519-dalek/src/backend/mod.rs index 5f1ae0487..086921122 100644 --- a/curve25519-dalek/src/backend/mod.rs +++ b/curve25519-dalek/src/backend/mod.rs @@ -263,5 +263,13 @@ pub(crate) fn scalar_mul_abglsv_pornin( b: &Scalar, C: &EdwardsPoint, ) -> EdwardsPoint { - serial::scalar_mul::abglsv_pornin::mul(a, A, b, C) + match get_selected_backend() { + #[cfg(curve25519_dalek_backend = "simd")] + BackendKind::Avx2 => vector::scalar_mul::abglsv_pornin::spec_avx2::mul(a, A, b, C), + #[cfg(all(curve25519_dalek_backend = "simd", nightly))] + BackendKind::Avx512 => { + vector::scalar_mul::abglsv_pornin::spec_avx512ifma_avx512vl::mul(a, A, b, C) + } + BackendKind::Serial => serial::scalar_mul::abglsv_pornin::mul(a, A, b, C), + } } diff --git a/curve25519-dalek/src/backend/vector/avx2/constants.rs b/curve25519-dalek/src/backend/vector/avx2/constants.rs index 25c7bde21..e59e6ca0f 100644 --- a/curve25519-dalek/src/backend/vector/avx2/constants.rs +++ b/curve25519-dalek/src/backend/vector/avx2/constants.rs @@ -1189,3 +1189,1096 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf ), ])), ]); + +/// Odd multiples of `[2^128]B`. +#[cfg(feature = "precomputed-tables")] +pub(crate) static B_SHL_128_ODD_LOOKUP_TABLE: NafLookupTable8 = NafLookupTable8([ + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 8755753, 4017573, 9393842, 29016651, 58091843, 29406677, 5911539, 15741713, + ), + u32x8::new_const( + 28008622, 17252661, 16904093, 27372673, 51551732, 24834475, 32472144, 15562166, + ), + u32x8::new_const( + 44955085, 62629206, 20146305, 6020893, 10905149, 55666581, 15761135, 4707923, + ), + u32x8::new_const( + 12313655, 23244076, 17718992, 6290780, 27683783, 23915447, 10355237, 2160578, + ), + u32x8::new_const( + 58133746, 47246368, 17728398, 18234296, 33263660, 16159006, 28426963, 13602649, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 15441657, 37070347, 2368810, 28607155, 29949731, 36586102, 19386397, 23489024, + ), + u32x8::new_const( + 11375507, 934067, 22260001, 9925752, 58225337, 12352497, 9982020, 20917987, + ), + u32x8::new_const( + 44339484, 34985432, 28806997, 32692083, 61560097, 2341112, 1850782, 14609693, + ), + u32x8::new_const( + 17431082, 60062038, 18755461, 454850, 39648888, 1736870, 13697884, 15568139, + ), + u32x8::new_const( + 21580378, 61127162, 32567731, 17610432, 51108340, 66730293, 4003092, 9372493, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 23254090, 38054892, 12796661, 30045396, 61975312, 7374399, 13497621, 31400378, + ), + u32x8::new_const( + 60088420, 8386974, 11246633, 669142, 67005332, 51412298, 31474172, 28821031, + ), + u32x8::new_const( + 15163323, 570656, 5261990, 21514246, 26375486, 64905457, 30080029, 24170794, + ), + u32x8::new_const( + 38196312, 19139124, 9764004, 25593554, 26606487, 61478914, 30618326, 17335637, + ), + u32x8::new_const( + 17160780, 54663900, 5920669, 1396797, 7803799, 35064938, 28013092, 12013109, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 50822376, 19176133, 33447833, 30328698, 25202163, 26750673, 26415876, 11473399, + ), + u32x8::new_const( + 37027635, 7461429, 6434366, 27290394, 49714469, 61689192, 2373507, 12388779, + ), + u32x8::new_const( + 53755368, 45751156, 24124424, 17839371, 22017398, 30078662, 20860451, 27557960, + ), + u32x8::new_const( + 12693358, 33349476, 20905058, 26086122, 11610346, 3567220, 31431283, 32351206, + ), + u32x8::new_const( + 34860813, 51090233, 17833870, 6127999, 15082162, 20522983, 23673990, 14883774, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 43648753, 2054072, 3860074, 17601843, 37532964, 15812292, 15632274, 30800825, + ), + u32x8::new_const( + 12716406, 37443229, 32253504, 27073418, 42917085, 65512224, 3770221, 27568492, + ), + u32x8::new_const( + 66741524, 53720596, 21203089, 13290571, 59988495, 11606052, 22883986, 3953546, + ), + u32x8::new_const( + 55338683, 59786266, 2904155, 4617604, 42960084, 53286372, 13290563, 9026733, + ), + u32x8::new_const( + 14716164, 60215549, 26742742, 2936764, 5640097, 12718896, 13245547, 1384618, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 30335917, 3126216, 26512949, 2400631, 45706067, 57880151, 24141344, 16026041, + ), + u32x8::new_const( + 3923408, 16811812, 12756545, 16135116, 22606341, 65357208, 3727341, 15894457, + ), + u32x8::new_const( + 14198409, 37341927, 8922703, 25116594, 57672042, 13624355, 4876492, 28704216, + ), + u32x8::new_const( + 3430726, 48115330, 4128746, 8295485, 10955107, 15579135, 22639084, 15905524, + ), + u32x8::new_const( + 44221697, 28649568, 24499120, 28768287, 18991660, 569031, 10964248, 26148443, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 32795185, 60767379, 28080643, 6516674, 14507931, 60930494, 24191731, 7623230, + ), + u32x8::new_const( + 36489954, 48718066, 2340540, 9913145, 40339855, 56229944, 6172327, 6632400, + ), + u32x8::new_const( + 55418710, 60717139, 30488046, 23514154, 17186160, 19007301, 14678760, 265678, + ), + u32x8::new_const( + 48808538, 1547273, 23238173, 6656616, 31037519, 51112387, 721197, 4555141, + ), + u32x8::new_const( + 29635704, 6133188, 351130, 11591138, 38189982, 42930793, 10894500, 15662264, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 26786843, 9083373, 20028047, 31774323, 49991923, 23856540, 12402006, 17055385, + ), + u32x8::new_const( + 40766144, 9771615, 14128529, 10618546, 7879342, 57232649, 15249370, 6590609, + ), + u32x8::new_const( + 18276894, 22283350, 8987962, 789578, 37343736, 10168434, 16260670, 15646491, + ), + u32x8::new_const( + 13522158, 17689900, 3896423, 31875581, 61097555, 62633162, 20790877, 16735922, + ), + u32x8::new_const( + 66893016, 45003621, 5450866, 33463219, 39123657, 23627014, 33463955, 16142873, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 25244096, 56193691, 13693647, 3797397, 16819723, 60565256, 29766302, 6604108, + ), + u32x8::new_const( + 26038558, 17938278, 15708948, 10822439, 39601538, 24042566, 685562, 29111347, + ), + u32x8::new_const( + 26115313, 30335668, 27412057, 16877593, 30751919, 13185632, 15141141, 1738446, + ), + u32x8::new_const( + 56921536, 56772483, 17240655, 30220752, 42578810, 14904081, 4603043, 3092920, + ), + u32x8::new_const( + 49979389, 52209146, 4152549, 19445604, 40332149, 45274937, 24283196, 16932808, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 44338826, 14223252, 20442277, 23321362, 40038214, 46488187, 5742732, 2204077, + ), + u32x8::new_const( + 39228271, 32559500, 20259691, 26586250, 26262515, 59052902, 23135056, 11649237, + ), + u32x8::new_const( + 16254623, 38316614, 25757766, 13265296, 23905159, 3233007, 18799650, 6998358, + ), + u32x8::new_const( + 45665649, 3572073, 31240604, 487653, 41865951, 37900663, 12233973, 7639370, + ), + u32x8::new_const( + 44302796, 36159129, 30800263, 15032516, 41151044, 55384941, 11824450, 22941974, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 31241893, 41347273, 22368076, 5407912, 51672623, 37396913, 21647049, 9390208, + ), + u32x8::new_const( + 61944519, 39691317, 7653057, 29028656, 18632402, 9078343, 21878755, 24361969, + ), + u32x8::new_const( + 52445504, 54785760, 7437699, 23763053, 24062805, 47329301, 5514195, 29773945, + ), + u32x8::new_const( + 22393789, 60407354, 487787, 13673965, 17846820, 52074530, 27083395, 24777544, + ), + u32x8::new_const( + 43875816, 59249419, 32957537, 10870942, 28399651, 58474146, 4663810, 10017592, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 51554679, 37819148, 19348940, 15651319, 37795936, 38205495, 7250993, 9000707, + ), + u32x8::new_const( + 50848457, 52535584, 29280791, 28262045, 20257638, 24675779, 15449272, 32701122, + ), + u32x8::new_const( + 59464605, 36418062, 16995955, 15616003, 22138848, 43158193, 20383500, 24180001, + ), + u32x8::new_const( + 29686554, 5406070, 16000678, 13114803, 52355796, 27989363, 3671425, 13051751, + ), + u32x8::new_const( + 19601180, 66156367, 1524936, 5400671, 9995525, 44730210, 16393085, 29090349, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 40037160, 35404470, 1101128, 17679456, 58736817, 38023616, 26914195, 8912839, + ), + u32x8::new_const( + 35968724, 13728970, 11754453, 23467360, 1841443, 42974350, 6474954, 24601505, + ), + u32x8::new_const( + 56280543, 31144893, 7843677, 19658138, 60736750, 34446122, 32264650, 3424565, + ), + u32x8::new_const( + 13513424, 11609295, 5750330, 26246916, 39242282, 36838735, 24621930, 22522583, + ), + u32x8::new_const( + 22131993, 4637141, 32427576, 12341602, 10497907, 64148821, 19579779, 14045469, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 54609950, 57496022, 18903216, 6036359, 20442952, 33240197, 6488354, 23817064, + ), + u32x8::new_const( + 49271527, 14519837, 10125086, 30274541, 45174176, 9368036, 24136772, 31352469, + ), + u32x8::new_const( + 38208389, 47916826, 33379533, 23863228, 51138323, 24486617, 1301915, 20880100, + ), + u32x8::new_const( + 65802744, 64274992, 25618147, 4394386, 50833888, 21278502, 16683162, 17000151, + ), + u32x8::new_const( + 36947518, 22816190, 22192056, 30211520, 64307611, 52265127, 27315755, 27490530, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 51321, 40830537, 8476102, 14235484, 24849391, 23743264, 14338418, 17031145, + ), + u32x8::new_const( + 66598164, 59786947, 2136460, 32995697, 36118750, 45439324, 19211993, 2708393, + ), + u32x8::new_const( + 37724691, 5509204, 20466289, 18913067, 15898423, 54260591, 12395710, 2576176, + ), + u32x8::new_const( + 61307258, 35930215, 23866997, 25574406, 21103226, 56184168, 3981030, 27022428, + ), + u32x8::new_const( + 62596380, 29044391, 23702736, 18470638, 30048349, 10300315, 24123763, 19313036, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 18748598, 25016920, 8498307, 32631601, 6384168, 11203184, 31160303, 19353876, + ), + u32x8::new_const( + 54599459, 8450733, 18101969, 21149236, 59936193, 40875464, 28532510, 30586721, + ), + u32x8::new_const( + 52650220, 52786957, 2451896, 25440079, 2888922, 7824446, 18182020, 21626339, + ), + u32x8::new_const( + 57897594, 17757748, 12419853, 6645340, 59586422, 26086502, 5504818, 27962875, + ), + u32x8::new_const( + 38718231, 5800561, 25067897, 8515418, 17108509, 55345697, 118442, 26105073, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 54268326, 16824749, 14934403, 27905139, 26436520, 65067438, 30302608, 2606227, + ), + u32x8::new_const( + 34360360, 19291869, 5107794, 25084154, 22214431, 33767370, 24870743, 9286834, + ), + u32x8::new_const( + 19403086, 6987282, 31904378, 21798967, 31579134, 4370878, 27381324, 12695073, + ), + u32x8::new_const( + 311209, 6708892, 25513573, 33531716, 50761602, 57269370, 12784123, 28411213, + ), + u32x8::new_const( + 43066990, 39055630, 4056404, 32958780, 46478217, 50817541, 20773170, 9637186, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 969758, 3317929, 31955050, 1231435, 61018716, 18530061, 2714629, 20872400, + ), + u32x8::new_const( + 20065853, 19586812, 1833680, 14258018, 5764800, 39312900, 23313458, 25604123, + ), + u32x8::new_const( + 14291811, 1397971, 28135441, 8915146, 27595340, 14843901, 29983436, 11289771, + ), + u32x8::new_const( + 18619116, 27539265, 20262150, 32779737, 51687545, 26779216, 171748, 13362494, + ), + u32x8::new_const( + 32656855, 22871249, 27651278, 31509559, 64852501, 19094586, 7657304, 9361286, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 862812, 24342462, 30800284, 18937241, 23520762, 34047247, 13302174, 33376538, + ), + u32x8::new_const( + 33193961, 41350355, 15226631, 11516350, 21363267, 30442451, 2628724, 1841108, + ), + u32x8::new_const( + 60673609, 27630545, 25746504, 3180279, 62161613, 32834726, 14001684, 6381050, + ), + u32x8::new_const( + 34872640, 16555217, 11482800, 22240267, 25717564, 22294886, 7167663, 17610022, + ), + u32x8::new_const( + 8342351, 51746312, 28070678, 24423545, 62868162, 20036474, 27562710, 6146180, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 45732855, 27625740, 15875308, 2722322, 55392147, 26688106, 23349767, 257384, + ), + u32x8::new_const( + 2437255, 32963482, 13303582, 11523156, 63701395, 40007196, 11912016, 23143328, + ), + u32x8::new_const( + 44807068, 21822021, 4350414, 10338246, 35683427, 9868863, 7282601, 12517117, + ), + u32x8::new_const( + 28436658, 42296748, 21641399, 13239271, 58300470, 17015152, 32821456, 21456135, + ), + u32x8::new_const( + 10004841, 17325772, 9167777, 11608193, 39792347, 14902317, 4667127, 21362377, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 55504990, 19114936, 6441788, 6383398, 14961795, 62173642, 12371137, 12500924, + ), + u32x8::new_const( + 19610263, 17096980, 30443940, 30179846, 56991075, 14873797, 30171035, 11953746, + ), + u32x8::new_const( + 43997449, 44131801, 17025201, 30549823, 22604259, 20908205, 18243353, 16523359, + ), + u32x8::new_const( + 23565833, 6027097, 3440720, 7430435, 37046294, 43181462, 881174, 26262932, + ), + u32x8::new_const( + 8042192, 12290045, 3330872, 13842619, 2951561, 64924761, 17486315, 430756, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 11501106, 29143041, 27779672, 7751186, 18098809, 42098667, 24906090, 16866297, + ), + u32x8::new_const( + 30187580, 38302523, 4695208, 13455490, 11490808, 27745037, 23859881, 10067982, + ), + u32x8::new_const( + 5673265, 57045283, 15643989, 27782463, 31934352, 17940834, 7828911, 20906808, + ), + u32x8::new_const( + 9695496, 8633214, 24817824, 25745189, 56617808, 23333710, 13316187, 7383670, + ), + u32x8::new_const( + 57310421, 5478590, 21053929, 26540827, 15922278, 4616536, 12881838, 16328752, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 34423677, 31423152, 25388174, 6283247, 12060270, 5502508, 7601132, 13240098, + ), + u32x8::new_const( + 62264628, 8742145, 9259535, 24291249, 65503854, 9022735, 5963900, 29431774, + ), + u32x8::new_const( + 55316017, 53754227, 18917946, 20611352, 12032168, 22800238, 13037510, 21356731, + ), + u32x8::new_const( + 30700780, 4787507, 30041208, 399265, 40570787, 40794096, 16227405, 26753996, + ), + u32x8::new_const( + 45626882, 38199905, 9770478, 15517028, 37314739, 43350080, 19735463, 29040150, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 15242501, 57555873, 21434161, 32795511, 23479352, 34949241, 7044570, 3654374, + ), + u32x8::new_const( + 46163262, 23253675, 20854951, 2518809, 20978952, 45940418, 28021867, 29193190, + ), + u32x8::new_const( + 22764937, 58377185, 4885680, 840113, 32182789, 5558189, 5397457, 32089951, + ), + u32x8::new_const( + 28712417, 64799227, 27739311, 16837072, 54439346, 46555738, 26997803, 5721706, + ), + u32x8::new_const( + 13148620, 9614663, 14652862, 1310985, 29738998, 55375973, 9890859, 11655785, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 5388186, 59459275, 29384804, 21276059, 53514182, 22015974, 14636729, 12580300, + ), + u32x8::new_const( + 59439080, 49547721, 23841689, 7877703, 12235718, 13919465, 31835175, 23891867, + ), + u32x8::new_const( + 25680083, 36981363, 26069646, 29537946, 40427423, 7901251, 31687267, 28985655, + ), + u32x8::new_const( + 14937029, 17638552, 24075855, 8443594, 66921061, 62274474, 25594611, 26517536, + ), + u32x8::new_const( + 34759571, 54584038, 31563512, 22022684, 33980235, 54282472, 27774154, 5727479, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 6363204, 15204474, 7049037, 4546209, 10293555, 60551022, 4977015, 4282133, + ), + u32x8::new_const( + 23556622, 64491554, 5841323, 14984421, 48797939, 58473821, 28481194, 5029575, + ), + u32x8::new_const( + 13886182, 48614238, 12495755, 6545327, 35836771, 43678527, 1641472, 9995382, + ), + u32x8::new_const( + 40850790, 22829915, 3291721, 22636416, 62071712, 30655586, 23771710, 14357742, + ), + u32x8::new_const( + 36356304, 32362551, 31441727, 30246820, 26574852, 367436, 29677180, 2665305, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 7290493, 63889578, 9284299, 15846600, 60390629, 59214731, 25958079, 5221093, + ), + u32x8::new_const( + 3305994, 41283967, 27208469, 14881605, 21907363, 65027050, 4580134, 28013696, + ), + u32x8::new_const( + 5252960, 2680363, 218321, 800147, 63733672, 55298046, 25192094, 29204345, + ), + u32x8::new_const( + 9007144, 1608675, 19946454, 25296279, 59660429, 46799660, 14892135, 4597105, + ), + u32x8::new_const( + 61623339, 18340618, 31877103, 28150228, 10868237, 9016784, 33419628, 26809477, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 15395452, 38542704, 27941891, 8963361, 38412095, 22538941, 30042336, 25866449, + ), + u32x8::new_const( + 49690920, 60582847, 32890508, 29581759, 63269774, 65518144, 29341844, 12570942, + ), + u32x8::new_const( + 48143408, 13965528, 24961739, 1776794, 47809414, 31616229, 27123994, 6277311, + ), + u32x8::new_const( + 16918630, 22630489, 2089825, 31945334, 54390022, 28445863, 3260810, 28214812, + ), + u32x8::new_const( + 6623332, 30499163, 30285581, 28586243, 28797, 52290738, 19821923, 3582966, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 10548445, 41762914, 23236632, 14452770, 8251555, 44816341, 29589074, 28621377, + ), + u32x8::new_const( + 49793005, 20564595, 24138892, 6572375, 40744983, 5763220, 17589237, 27305189, + ), + u32x8::new_const( + 47299366, 49831819, 2694002, 3549418, 22813341, 66810496, 5419226, 18106756, + ), + u32x8::new_const( + 41776909, 36811011, 18405267, 23488614, 7810708, 13317621, 10728926, 32440168, + ), + u32x8::new_const( + 30677921, 34739298, 1007385, 560004, 10115944, 66117110, 7129928, 26669929, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 29680385, 48722306, 30849793, 1042205, 17984928, 13008956, 12933724, 9961241, + ), + u32x8::new_const( + 51591050, 43741888, 9337419, 3373180, 16615365, 43862874, 24769847, 4800304, + ), + u32x8::new_const( + 52472794, 32888122, 921387, 7390446, 14153667, 31038531, 29306720, 26770770, + ), + u32x8::new_const( + 26515907, 45785568, 7328668, 9852282, 48606129, 33406336, 4154285, 864251, + ), + u32x8::new_const( + 30084393, 41042663, 17948409, 27807379, 13699092, 60906447, 14466873, 32481124, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 3208277, 20301825, 29638236, 2309232, 43837464, 26128520, 15297814, 6820199, + ), + u32x8::new_const( + 49149503, 4569436, 9515396, 4047623, 42072224, 52535019, 32854737, 7153574, + ), + u32x8::new_const( + 24934886, 38730063, 3388108, 5459127, 33183156, 29754811, 10836041, 10040579, + ), + u32x8::new_const( + 65024304, 47823230, 22444273, 6366541, 14414404, 16553764, 24355526, 30247515, + ), + u32x8::new_const( + 12248860, 45407973, 12400524, 17874120, 8303381, 65410200, 10618115, 15174392, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 39153155, 59554001, 11299234, 29837354, 64272253, 39095013, 7855375, 14061016, + ), + u32x8::new_const( + 57244709, 53022363, 21894984, 30429858, 48853294, 28304329, 11436775, 29075907, + ), + u32x8::new_const( + 14445358, 32157748, 28385899, 3923288, 23739946, 15335955, 8103706, 13337391, + ), + u32x8::new_const( + 19181199, 41840573, 15001166, 26745592, 21880468, 51412124, 16991901, 33520381, + ), + u32x8::new_const( + 46847020, 15246410, 6027458, 28807380, 32715369, 54074483, 6179955, 28292194, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 49609482, 36088031, 19666029, 32046373, 26111110, 32582196, 25242162, 25348665, + ), + u32x8::new_const( + 25078439, 31745290, 32248424, 6439836, 22444895, 66565207, 188368, 5576544, + ), + u32x8::new_const( + 18788305, 44087183, 3371647, 25739876, 3096602, 53760420, 1805508, 8484168, + ), + u32x8::new_const( + 3159087, 52786825, 27001360, 31687786, 30814079, 66667510, 2615219, 13934166, + ), + u32x8::new_const( + 25127006, 38539690, 24156897, 7499074, 21462132, 61324, 19099942, 12151091, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 4982081, 9383704, 26934371, 19251905, 20440947, 27502950, 6950019, 11709433, + ), + u32x8::new_const( + 35897970, 23577002, 7243044, 9458393, 42376344, 11568052, 11009018, 27469196, + ), + u32x8::new_const( + 29223468, 1362209, 13782412, 27262919, 10814338, 32588817, 23316861, 30932865, + ), + u32x8::new_const( + 3411796, 62202509, 24101721, 30039544, 64077838, 54215925, 8197521, 5943210, + ), + u32x8::new_const( + 5966600, 11882725, 29658916, 18635048, 11145591, 26345022, 18947133, 23224812, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 25005702, 10156585, 31649778, 18646436, 56003564, 55631235, 8935316, 24554706, + ), + u32x8::new_const( + 21788130, 21697391, 28437053, 28233245, 59546301, 37565850, 26761589, 8124264, + ), + u32x8::new_const( + 49024950, 53773562, 8119780, 19177058, 20191968, 50074106, 12123504, 23394045, + ), + u32x8::new_const( + 32932598, 10472672, 11873365, 6383778, 34337700, 761686, 18329199, 22261120, + ), + u32x8::new_const( + 22706577, 48063433, 15088710, 24394443, 45063597, 55113046, 26760707, 18074423, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 33127983, 33408208, 17654381, 21630114, 33228683, 52269225, 13873719, 23248628, + ), + u32x8::new_const( + 6631819, 60433716, 14471284, 28388903, 59619528, 5303397, 16124634, 1990326, + ), + u32x8::new_const( + 41842468, 58480707, 22695409, 29288706, 44692487, 18268371, 19727247, 433133, + ), + u32x8::new_const( + 21275927, 25507743, 3825859, 11230890, 33141001, 52019263, 16706067, 27417665, + ), + u32x8::new_const( + 35345831, 61853116, 2186113, 26537906, 48997573, 61145570, 13800889, 27066626, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 64223075, 62834433, 3477712, 14176350, 61316174, 20998131, 23364543, 11921329, + ), + u32x8::new_const( + 49686058, 5383256, 20566914, 33302912, 50831948, 35178870, 14543957, 12217961, + ), + u32x8::new_const( + 60607563, 56070762, 33299772, 18453613, 48873260, 13938167, 32816416, 20182208, + ), + u32x8::new_const( + 29109694, 208468, 18505916, 17026465, 33146696, 56509584, 22402970, 10548542, + ), + u32x8::new_const( + 47908551, 33103330, 26629137, 20118514, 32222622, 27122759, 15531937, 3331316, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 5413051, 55007125, 23588396, 9870355, 13843332, 29305215, 31850562, 22775015, + ), + u32x8::new_const( + 1467766, 33731483, 25673350, 16422329, 61048272, 66097915, 157279, 18156463, + ), + u32x8::new_const( + 48572162, 38522889, 13309468, 21534193, 20412685, 61180360, 5036817, 20806483, + ), + u32x8::new_const( + 33998763, 73280, 4488518, 13502429, 28074183, 49777714, 1138234, 11430038, + ), + u32x8::new_const( + 3167400, 57147022, 25613316, 23945989, 36629788, 50336205, 17498149, 28670605, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 22684554, 31130387, 32926278, 29586156, 47601961, 33998854, 11546477, 18505370, + ), + u32x8::new_const( + 9933094, 38311209, 7041254, 6986982, 8766556, 21592559, 20131610, 16666920, + ), + u32x8::new_const( + 28482660, 57603951, 2680357, 27465006, 982251, 31391284, 16625941, 33000701, + ), + u32x8::new_const( + 27575030, 66006918, 14343148, 22731514, 35666556, 59486460, 28714955, 32532426, + ), + u32x8::new_const( + 53351092, 17206773, 12489709, 16580887, 66822366, 55990042, 26511557, 25984014, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 18611927, 11394163, 31148832, 26220485, 29117406, 25035053, 22782369, 15679976, + ), + u32x8::new_const( + 22374256, 36838937, 21501307, 30389625, 66667899, 58417194, 30993831, 8744131, + ), + u32x8::new_const( + 51964645, 37721309, 6856429, 27924777, 34327519, 33471791, 5407899, 21414159, + ), + u32x8::new_const( + 14581790, 23032983, 19827323, 3763632, 33397105, 25297129, 18184486, 19628503, + ), + u32x8::new_const( + 48169086, 3151280, 30373756, 33355756, 20730584, 4268147, 2778334, 29566325, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 33961418, 10750164, 6875389, 10085621, 43400388, 39463563, 23103762, 30970866, + ), + u32x8::new_const( + 5700066, 59027758, 21400140, 6438205, 62593313, 2077383, 16504674, 29865332, + ), + u32x8::new_const( + 45453380, 38411946, 30726569, 28295358, 67022419, 55735820, 11137089, 37071, + ), + u32x8::new_const( + 31353825, 60708184, 16531813, 31372128, 53726621, 48767632, 19861407, 18058254, + ), + u32x8::new_const( + 27409527, 61098917, 20408039, 28320444, 30961001, 661660, 23562915, 20816045, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 29618201, 40570126, 6599304, 14215370, 39758707, 18734810, 23784990, 12868367, + ), + u32x8::new_const( + 14295055, 56799374, 6717074, 16323427, 46001347, 57798092, 25715810, 1990626, + ), + u32x8::new_const( + 22929931, 17387666, 15949389, 2884542, 63124742, 32694745, 20813154, 944327, + ), + u32x8::new_const( + 20333373, 60632531, 23742122, 28491190, 55441470, 25986654, 4127343, 31317643, + ), + u32x8::new_const( + 58278762, 15410163, 2051362, 11956412, 43995747, 5785063, 21898378, 28010842, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 33403363, 50791305, 4047616, 8591, 53892290, 20752436, 17089227, 9096970, + ), + u32x8::new_const( + 61134307, 8270834, 26124791, 23897905, 49700624, 33987812, 14122900, 26476210, + ), + u32x8::new_const( + 39334455, 47083570, 13066338, 30371716, 24804564, 22931766, 23065014, 3267900, + ), + u32x8::new_const( + 25587367, 46535176, 18973648, 17563779, 65938164, 27808755, 18204591, 32977160, + ), + u32x8::new_const( + 12352023, 49525012, 776527, 32824531, 44963336, 7872290, 23935775, 828772, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 15396487, 34033520, 12524412, 25903962, 57260790, 11917013, 25000818, 585110, + ), + u32x8::new_const( + 54059342, 37115985, 5482240, 5111837, 27155614, 36391787, 5131685, 22684921, + ), + u32x8::new_const( + 28514802, 3510152, 30252855, 21009625, 32899748, 10654421, 2721566, 11989601, + ), + u32x8::new_const( + 58416089, 14611475, 13893012, 8581683, 57329339, 41031431, 25111533, 22461965, + ), + u32x8::new_const( + 9823029, 59850874, 13418913, 10620898, 42157103, 17458632, 20907936, 2642548, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 19657647, 33546661, 19653729, 1543199, 7892903, 27907955, 14638957, 8226806, + ), + u32x8::new_const( + 22423896, 47150119, 15077034, 11169076, 51048701, 59522619, 28620550, 30912612, + ), + u32x8::new_const( + 40735691, 59229283, 13335985, 2402786, 484477, 39998566, 22205108, 15703314, + ), + u32x8::new_const( + 29027921, 10251409, 11764758, 33427857, 4869906, 20129064, 28608660, 14014140, + ), + u32x8::new_const( + 29441677, 396483, 1350123, 19284141, 5626464, 27264452, 31093759, 1255138, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 37104291, 55211165, 20151594, 29159097, 47536086, 56187122, 20852598, 18537192, + ), + u32x8::new_const( + 27198056, 357176, 30627907, 32651523, 33295747, 128424, 19763964, 33051399, + ), + u32x8::new_const( + 3194228, 27225187, 13710677, 15887848, 9008937, 64020925, 5422179, 7314829, + ), + u32x8::new_const( + 59341296, 31072356, 13871225, 16849912, 65460879, 38037060, 7212649, 4960935, + ), + u32x8::new_const( + 24814111, 37062430, 4824467, 16567180, 48589749, 58594363, 9831935, 31251331, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 43859006, 42879588, 12314855, 5105898, 31135877, 16527292, 17239282, 26712507, + ), + u32x8::new_const( + 6330335, 66052651, 29713052, 6304699, 21114843, 11296481, 247197, 13056712, + ), + u32x8::new_const( + 4609863, 28761132, 30836462, 11468693, 48299469, 24382786, 29248966, 5961138, + ), + u32x8::new_const( + 38699621, 32685614, 14120870, 20016156, 44080923, 2863054, 13275585, 21540392, + ), + u32x8::new_const( + 14798641, 35287186, 20738502, 6083402, 19232653, 43871193, 3565951, 27468655, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 10809934, 7248997, 4071954, 20612425, 55783061, 35988927, 16653318, 18296956, + ), + u32x8::new_const( + 12999664, 44826746, 11984605, 21319716, 50090682, 64182684, 21075905, 31035021, + ), + u32x8::new_const( + 31961126, 33263054, 8927761, 15964127, 31717593, 6883809, 8218809, 4153924, + ), + u32x8::new_const( + 7964445, 54323904, 13126300, 8020273, 32863011, 33568812, 16907388, 13795259, + ), + u32x8::new_const( + 5460550, 11123863, 312259, 20557518, 48946733, 20144181, 6355063, 15994509, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 56248343, 17528193, 27309462, 14876176, 737111, 33857575, 6234099, 634068, + ), + u32x8::new_const( + 11951911, 7442830, 14116748, 28141270, 16372970, 61997614, 30416221, 26643238, + ), + u32x8::new_const( + 25593159, 62458126, 32347410, 31710520, 63851347, 18289119, 21547102, 6482576, + ), + u32x8::new_const( + 57115879, 52569266, 27090442, 32686644, 54668813, 55709464, 1162903, 24343629, + ), + u32x8::new_const( + 66383400, 18872685, 5955501, 29170797, 9230049, 15739673, 26990139, 12885135, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 21315488, 65821594, 12200384, 22714746, 27037626, 35096485, 12589086, 31857692, + ), + u32x8::new_const( + 1928462, 27520786, 25881086, 6898401, 23470132, 66804586, 7869673, 19821344, + ), + u32x8::new_const( + 34085809, 18137778, 21548070, 6251044, 38230665, 45554740, 9881753, 3958244, + ), + u32x8::new_const( + 18491029, 32113522, 31589964, 17895594, 45840625, 64298738, 25289066, 10486166, + ), + u32x8::new_const( + 11106058, 20943965, 22876695, 2997798, 58876726, 36970190, 30672711, 7741788, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 7768193, 52585272, 33109378, 25024320, 17406499, 31495213, 13450553, 24357136, + ), + u32x8::new_const( + 49960883, 20912115, 26995925, 5168001, 26023517, 58237009, 27698140, 2905272, + ), + u32x8::new_const( + 32669303, 17287215, 27680891, 15354507, 6937100, 21211564, 10585252, 15665988, + ), + u32x8::new_const( + 40480743, 66599860, 8946350, 2772370, 15223283, 27256312, 2981961, 25932978, + ), + u32x8::new_const( + 532038, 14781897, 11425264, 336293, 42756500, 15651221, 22855121, 19747310, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 49514533, 28464022, 20126145, 1904780, 29601684, 65259549, 11091773, 1460734, + ), + u32x8::new_const( + 62383808, 5214120, 1714707, 6309732, 23988395, 53011210, 2450403, 3473318, + ), + u32x8::new_const( + 43298097, 42539394, 25052562, 29600899, 56799175, 61029900, 7185774, 14660254, + ), + u32x8::new_const( + 63211757, 24591006, 13263879, 30104100, 2842611, 7623012, 27410850, 28924976, + ), + u32x8::new_const( + 63337574, 20704498, 5993853, 24142318, 51818794, 59997527, 24501215, 20935367, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 42162589, 8973683, 14405364, 12912783, 44198928, 60495064, 7120053, 9873326, + ), + u32x8::new_const( + 32571621, 10628421, 15294659, 18861151, 16821860, 38856424, 8680410, 3434117, + ), + u32x8::new_const( + 41388761, 44883790, 737188, 5753766, 54816757, 28502853, 12048385, 6432179, + ), + u32x8::new_const( + 52218762, 27995381, 16753949, 3342023, 49155435, 34149607, 18912666, 14085012, + ), + u32x8::new_const( + 19397260, 59274444, 23622350, 15349070, 33711885, 59103682, 28649583, 21733290, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 31258743, 52890551, 23361705, 5950255, 37369918, 24225294, 22793873, 20225997, + ), + u32x8::new_const( + 32277405, 15049540, 938446, 33043029, 16062984, 51781532, 282470, 23009192, + ), + u32x8::new_const( + 38088031, 6392825, 6622227, 33508819, 31705350, 50860025, 29337642, 24718354, + ), + u32x8::new_const( + 22693400, 16825845, 11927714, 13669769, 35425154, 47556114, 3715274, 4350638, + ), + u32x8::new_const( + 23724995, 64674418, 28698430, 22166506, 59364241, 49485862, 13722961, 25788622, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 10104291, 30687711, 14575524, 9325906, 32811084, 8513313, 9725974, 21152907, + ), + u32x8::new_const( + 13918841, 12486485, 7634864, 23311315, 52041370, 23121612, 16135419, 29558492, + ), + u32x8::new_const( + 12844416, 26431235, 11341029, 1360985, 27012916, 2907603, 28156716, 6822747, + ), + u32x8::new_const( + 47163397, 20189169, 1712074, 17581177, 62497740, 41568600, 6539609, 30761268, + ), + u32x8::new_const( + 49787396, 11741764, 30054375, 6787713, 31533617, 16509958, 23805586, 6227298, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 51320426, 64090469, 30160342, 8321700, 31088218, 56745843, 13050215, 25083547, + ), + u32x8::new_const( + 54780823, 45005352, 26787210, 28129864, 1812182, 15805420, 25104026, 20589972, + ), + u32x8::new_const( + 4729762, 4018827, 815317, 18789054, 63966109, 14782652, 5741298, 13252482, + ), + u32x8::new_const( + 37154601, 61012765, 11251664, 11776866, 41692299, 47508800, 1422244, 21271022, + ), + u32x8::new_const( + 46631602, 18950389, 8304568, 19710312, 61494089, 58610549, 14319623, 6419750, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 15502953, 34152593, 10585299, 19097625, 9240847, 30699659, 7971493, 29133180, + ), + u32x8::new_const( + 16758000, 42275366, 11394613, 244847, 23065024, 58557948, 4429603, 31497159, + ), + u32x8::new_const( + 4870390, 37723999, 22204616, 20090223, 49338571, 26646297, 8385697, 24989177, + ), + u32x8::new_const( + 13801283, 38147294, 22227026, 2034746, 4363782, 50741636, 12375613, 19969430, + ), + u32x8::new_const( + 64323430, 15528560, 33095739, 4928165, 44683311, 29036787, 9332490, 22483833, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 35292872, 22809441, 8745188, 27369713, 24643316, 41557383, 33314137, 4585952, + ), + u32x8::new_const( + 2872401, 20339100, 17927608, 8225779, 55045245, 62785029, 29045406, 22352775, + ), + u32x8::new_const( + 14259314, 60923771, 1096720, 13154225, 12301820, 62180675, 7656354, 16448591, + ), + u32x8::new_const( + 17835102, 38014838, 12656610, 30069985, 25955188, 13536990, 21322184, 22671353, + ), + u32x8::new_const( + 39386815, 16743229, 13569191, 20841167, 66284283, 11968696, 19896379, 3447964, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 5845189, 19057331, 6960334, 25415058, 42508715, 22057630, 20845927, 28198565, + ), + u32x8::new_const( + 56978171, 65090711, 15086025, 28549438, 44001730, 49891935, 5865376, 8368397, + ), + u32x8::new_const( + 54600164, 45631393, 21607323, 19426127, 7198825, 42746172, 19218065, 15404249, + ), + u32x8::new_const( + 47961578, 60141850, 22660032, 32103640, 22123801, 65698950, 9046479, 19509828, + ), + u32x8::new_const( + 49854022, 2241305, 13222805, 19556066, 43711569, 49780116, 5426873, 31745192, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 40729487, 25672990, 30547632, 32404203, 4085160, 13004027, 28875146, 11811206, + ), + u32x8::new_const( + 20547991, 2541178, 2227969, 27519033, 39450312, 27074253, 13022763, 9928609, + ), + u32x8::new_const( + 20049556, 21281014, 33432762, 7567009, 20095942, 23313211, 26222737, 17507295, + ), + u32x8::new_const( + 28470325, 36628616, 11309441, 30209421, 4144939, 17055327, 2445714, 6524443, + ), + u32x8::new_const( + 59833086, 15186171, 10591299, 28905308, 17620200, 52316367, 27875277, 26496741, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 31707893, 57894729, 5534032, 32532065, 65133671, 60502578, 5140826, 16393768, + ), + u32x8::new_const( + 64897304, 40244178, 15430388, 8812489, 19994054, 2014709, 21633662, 23401827, + ), + u32x8::new_const( + 15557619, 18105691, 21187155, 28576404, 10145732, 28843464, 13393359, 13771647, + ), + u32x8::new_const( + 31588611, 17211554, 33531942, 21933737, 39867819, 34672265, 28624346, 1702752, + ), + u32x8::new_const( + 24558207, 30197944, 8960550, 4038811, 47589645, 40446193, 18731959, 1833312, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 54828491, 39777098, 22517423, 16455138, 50715123, 66102776, 9301084, 20093053, + ), + u32x8::new_const( + 55829554, 42022961, 5016059, 1686958, 24619325, 59659530, 18949098, 21952180, + ), + u32x8::new_const( + 42720345, 49482640, 19134402, 29790817, 18897879, 57795525, 8546440, 6356057, + ), + u32x8::new_const( + 2706916, 10425878, 14967679, 24895913, 31385605, 20266645, 24008557, 19488761, + ), + u32x8::new_const( + 2293237, 396609, 11324444, 6992461, 12559441, 3742320, 18185850, 18446913, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 60379129, 35905652, 21359074, 12829780, 65679613, 39428427, 9549511, 30358093, + ), + u32x8::new_const( + 66257896, 46135879, 26128323, 8638473, 21248071, 6241769, 30569436, 20816755, + ), + u32x8::new_const( + 55903095, 57646824, 9030473, 26164290, 65488227, 47656288, 15821381, 18707886, + ), + u32x8::new_const( + 21350194, 18260505, 20668675, 3654065, 21317830, 25751197, 26172075, 10294298, + ), + u32x8::new_const( + 46303977, 16430687, 24613251, 10708139, 5017591, 48650527, 26007111, 1360285, + ), + ])), + CachedPoint(FieldElement2625x4([ + u32x8::new_const( + 65346245, 63796044, 11028852, 17531649, 59718051, 15718057, 28685598, 18174598, + ), + u32x8::new_const( + 7386590, 52782678, 26373161, 27818129, 58684363, 17330195, 31830625, 6117175, + ), + u32x8::new_const( + 38212947, 62642659, 6301612, 10450073, 7795528, 43400013, 28993668, 27890759, + ), + u32x8::new_const( + 6852276, 1135049, 23135942, 26143463, 36007462, 21771226, 14345856, 8570865, + ), + u32x8::new_const( + 38470522, 8939694, 14379901, 7008195, 56885942, 53407982, 29813126, 33251563, + ), + ])), +]); diff --git a/curve25519-dalek/src/backend/vector/avx2/edwards.rs b/curve25519-dalek/src/backend/vector/avx2/edwards.rs index fd70d7d2f..a03d9e16c 100644 --- a/curve25519-dalek/src/backend/vector/avx2/edwards.rs +++ b/curve25519-dalek/src/backend/vector/avx2/edwards.rs @@ -567,4 +567,32 @@ mod test { assert_eq!(base_splits[3], b_splits[3]); } } + + #[test] + fn b_shl_128_odd_lookup_table_verify() { + use crate::backend::vector::avx2::constants::B_SHL_128_ODD_LOOKUP_TABLE; + use crate::constants; + use crate::scalar::Scalar; + + let b_shl_128_odd_table = NafLookupTable8::::from( + &(constants::ED25519_BASEPOINT_POINT + * Scalar::from_canonical_bytes([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ]) + .unwrap()), + ); + println!("b_shl_128_odd_lookup_table = {:?}", b_shl_128_odd_table); + + let table_B = &B_SHL_128_ODD_LOOKUP_TABLE; + for (b_vec, base_vec) in table_B.0.iter().zip(b_shl_128_odd_table.0.iter()) { + let b_splits = b_vec.0.split(); + let base_splits = base_vec.0.split(); + + assert_eq!(base_splits[0], b_splits[0]); + assert_eq!(base_splits[1], b_splits[1]); + assert_eq!(base_splits[2], b_splits[2]); + assert_eq!(base_splits[3], b_splits[3]); + } + } } diff --git a/curve25519-dalek/src/backend/vector/ifma/constants.rs b/curve25519-dalek/src/backend/vector/ifma/constants.rs index 66ace9643..65a4ffcb3 100644 --- a/curve25519-dalek/src/backend/vector/ifma/constants.rs +++ b/curve25519-dalek/src/backend/vector/ifma/constants.rs @@ -2062,3 +2062,2032 @@ pub(crate) static BASEPOINT_ODD_LOOKUP_TABLE: NafLookupTable8 = Naf ), ])), ]); + +/// Odd multiples of `[2^128]B`. +// TODO: generate real constants using test in `super::edwards`. +#[cfg(feature = "precomputed-tables")] +pub(crate) static B_SHL_128_ODD_LOOKUP_TABLE: NafLookupTable8 = NafLookupTable8([ + CachedPoint(F51x4Reduced([ + u64x4::new_const(1277522120965857, 73557767439946, 243332, 1943719795065404), + u64x4::new_const(108375142003455, 341984820733594, 0, 2097709862669256), + u64x4::new_const(150073485536043, 750646439938056, 0, 581130035634455), + u64x4::new_const(2149983732744869, 1903255931888577, 0, 646644904824193), + u64x4::new_const(291045673509296, 1060034214701851, 0, 325245010451737), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1970681836121889, + 1660307753655178, + 1077207637163462, + 1436413309977108, + ), + u64x4::new_const( + 158785710838757, + 919645875412951, + 174577133496574, + 2213787394009350, + ), + u64x4::new_const( + 1017606396438281, + 1240932851489554, + 918203302506967, + 1239827708070863, + ), + u64x4::new_const( + 1748989883612327, + 1745367742532782, + 1168385548387, + 1211387683826673, + ), + u64x4::new_const( + 799349980018733, + 1471088235739693, + 1505351346057417, + 2104975925096407, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 171437462972293, + 36016853025886, + 1184164975342640, + 1633525003912147, + ), + u64x4::new_const( + 2113383632509037, + 1946216474924125, + 1884174984466256, + 1373317790955847, + ), + u64x4::new_const( + 791293623466401, + 1796466048084189, + 444977763198796, + 629823271230872, + ), + u64x4::new_const( + 1093217720067380, + 2157024270666135, + 238122980108466, + 806820763806847, + ), + u64x4::new_const( + 793658959468458, + 368578641413741, + 11592529764159, + 2144017075993471, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1538027396670268, + 1588896993892061, + 675619548648376, + 788373514423313, + ), + u64x4::new_const( + 1987517656073805, + 1940987929951188, + 666993851697339, + 2040540928108427, + ), + u64x4::new_const( + 375514548584082, + 1726008037083790, + 1070069155000872, + 570111103756303, + ), + u64x4::new_const( + 772223645372213, + 2123395244967674, + 868238486911408, + 1846639042240362, + ), + u64x4::new_const( + 872865734460736, + 32277956842850, + 1701451131455402, + 773883376061880, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1845177363882902, + 275858237213625, + 1052127336883600, + 171072805852218, + ), + u64x4::new_const( + 139016783952609, + 462699304987089, + 430046471494974, + 410922720999257, + ), + u64x4::new_const( + 846403935976337, + 243817706931454, + 971825428236901, + 571800039596794, + ), + u64x4::new_const( + 807642685434918, + 1933536976438782, + 812324278898440, + 688391556487313, + ), + u64x4::new_const( + 76239450396192, + 629532732688863, + 1833302026979779, + 650067934544499, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1373931604989264, + 331159264656614, + 364391529321767, + 874765630865409, + ), + u64x4::new_const( + 2109908262150241, + 473400816504190, + 91544045127333, + 976307977609515, + ), + u64x4::new_const( + 330175435673491, + 2126511895885904, + 1022944071588421, + 2158480209801463, + ), + u64x4::new_const( + 1305666795527971, + 162063591028664, + 2193154870675382, + 1789166662611800, + ), + u64x4::new_const( + 817858592500508, + 1672743239440202, + 859976879916778, + 1167423340862516, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 274334925170164, + 565841102587251, + 603083835949120, + 607539210240861, + ), + u64x4::new_const( + 196754662972649, + 1339063476699167, + 1406077076979491, + 896902435668469, + ), + u64x4::new_const( + 397962210956733, + 174839587476217, + 1381082665748936, + 175195877334136, + ), + u64x4::new_const( + 717429432748391, + 1635309821746318, + 363374010274647, + 882908746261699, + ), + u64x4::new_const( + 600946602802781, + 1946596133370711, + 1532135183320341, + 690530671668253, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 2074443704000945, + 2163534804938345, + 425423840926528, + 1100826171404853, + ), + u64x4::new_const( + 111700142796101, + 1456893872751964, + 1186145518682968, + 2192182627706116, + ), + u64x4::new_const( + 1848722121856066, + 2123239575044749, + 1323870754599272, + 883211262889775, + ), + u64x4::new_const( + 938263017712916, + 689670293631396, + 183944529557576, + 501908638166580, + ), + u64x4::new_const( + 2170571907220631, + 36636756989655, + 1875035480138608, + 803703278398018, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1053429956874064, + 1636640618139765, + 1556890827801070, + 2142720579528828, + ), + u64x4::new_const( + 1814240918422814, + 692326274601777, + 1054896561802157, + 2025454041705534, + ), + u64x4::new_const( + 2109495823888757, + 1287497869997176, + 194170063200096, + 621116840113213, + ), + u64x4::new_const( + 2156505873679998, + 2197064359737385, + 1312887672223536, + 369862818895912, + ), + u64x4::new_const( + 977381163563657, + 1878897311974033, + 2144566861359744, + 1832960882773351, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1266492498289486, + 1301524759372145, + 324789537938521, + 442710471023019, + ), + u64x4::new_const( + 1232722320001345, + 1191193089162455, + 176474006074813, + 2158950213252857, + ), + u64x4::new_const( + 1901782191467749, + 494791441598902, + 1820415815322129, + 854954583485223, + ), + u64x4::new_const( + 1511383667649702, + 792536415032464, + 2027741263854728, + 1727944381044738, + ), + u64x4::new_const( + 606355788891204, + 1670687521471220, + 582824350365415, + 1509135066079912, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1079942762813598, + 2015830004785901, + 479916361323351, + 1907956590950158, + ), + u64x4::new_const( + 2053400302939156, + 1319799126867070, + 19493088767391, + 1908755581402373, + ), + u64x4::new_const( + 2235858054780980, + 885832711204321, + 810332865560178, + 103174191215441, + ), + u64x4::new_const( + 1843466881032833, + 355511728384038, + 693846715794114, + 186545012724117, + ), + u64x4::new_const( + 1661758432892509, + 1491022339899281, + 698941123765263, + 174945407208560, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1075933251927831, + 400263885306647, + 1308157532880528, + 347933379126665, + ), + u64x4::new_const( + 673811632329433, + 1584860147186478, + 271778891257244, + 498194055154207, + ), + u64x4::new_const( + 703783427747558, + 1051624728592032, + 1371463103351544, + 230351033002960, + ), + u64x4::new_const( + 860729466483372, + 421647596766583, + 1520613871336707, + 635298775280054, + ), + u64x4::new_const( + 1168352891728845, + 1691216293752089, + 1799491997061519, + 399728882318504, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 420156727446514, + 1483649215777128, + 165508610199900, + 1918121104840431, + ), + u64x4::new_const( + 2129902293682427, + 730952770435213, + 2184527544565390, + 1939880362232986, + ), + u64x4::new_const( + 1771978364905086, + 510975579746524, + 927564335219142, + 177574146260558, + ), + u64x4::new_const( + 2164104536437514, + 1532598873799015, + 406875369182421, + 1367005937406517, + ), + u64x4::new_const( + 35073200082587, + 1981124717036219, + 1854087014063833, + 122419694385217, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1963785875777739, + 411497142699119, + 1974557512687408, + 1268304422747183, + ), + u64x4::new_const( + 762752575978150, + 1443822019541748, + 1331556159904338, + 377726798263780, + ), + u64x4::new_const( + 825953972847841, + 353487068141356, + 1955697322427207, + 2048226560172078, + ), + u64x4::new_const( + 1482378558684434, + 657691905625918, + 923870001994493, + 1694132799397736, + ), + u64x4::new_const( + 1643904759603122, + 170495566698285, + 1218312703413378, + 784318735038131, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 939230507241903, + 2238763473105245, + 1827325199528162, + 1153939339775538, + ), + u64x4::new_const( + 38544505283339, + 258889431497015, + 351721979677947, + 1357907379592829, + ), + u64x4::new_const( + 1393974676373341, + 1131355528938676, + 473104915298872, + 978783482501776, + ), + u64x4::new_const( + 2131516168980501, + 2113911780991092, + 1477027502354261, + 542884524860340, + ), + u64x4::new_const( + 1029606261349423, + 64226378557628, + 1669131167474348, + 2212808057234874, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1423176501543193, + 163313632579593, + 2220495688893001, + 2220041045291870, + ), + u64x4::new_const( + 1111834224023697, + 1026815658023689, + 1404605100939775, + 1412149108248227, + ), + u64x4::new_const( + 1542537854906076, + 1270288391129127, + 991419278941933, + 1824939809581980, + ), + u64x4::new_const( + 1142003215657891, + 525980550896367, + 1508270666157963, + 917719462309053, + ), + u64x4::new_const( + 400851268057105, + 1620818232405188, + 1251478578139510, + 2162841805361886, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 2125383272208441, + 1368790097335984, + 11813369275978, + 639513785921674, + ), + u64x4::new_const( + 2200806265616284, + 1041996387620216, + 1275149397833084, + 1723371028064068, + ), + u64x4::new_const( + 603720163891275, + 2135593511176153, + 2049641644431548, + 1198460677818310, + ), + u64x4::new_const( + 1862491879401621, + 2008116580769441, + 626566325260235, + 1058308304975798, + ), + u64x4::new_const( + 628557314314858, + 1075323332046522, + 1631772244117095, + 1812174547405683, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1222773123817104, + 363276129291452, + 796237592807883, + 1914425291893078, + ), + u64x4::new_const( + 1721259057429088, + 734941709009373, + 1553365830564638, + 1492120931079419, + ), + u64x4::new_const( + 1009354843273686, + 293884504384873, + 1050281954944357, + 134132942667344, + ), + u64x4::new_const( + 23119363298711, + 1694754778833445, + 1725925193393496, + 1738396998222001, + ), + u64x4::new_const( + 1753692057254667, + 118428526447110, + 840961387840295, + 1227619055408558, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1004186117579547, + 508771992330056, + 1426571663072421, + 2238524171903259, + ), + u64x4::new_const( + 744764613007812, + 398885442368825, + 2047459490294949, + 2141797621077959, + ), + u64x4::new_const( + 4556204156489, + 1708213022802363, + 1071381560923933, + 393474529142567, + ), + u64x4::new_const( + 350116198213005, + 945907227204695, + 168267474358731, + 1801504420122711, + ), + u64x4::new_const( + 728788674520360, + 1262722049156121, + 455259596607008, + 1159442365834489, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 2226818917892677, + 185673745808179, + 2240952219732549, + 324137961621908, + ), + u64x4::new_const( + 1659527641857410, + 973964060249383, + 1349692151487730, + 1172743533370593, + ), + u64x4::new_const( + 310591478467746, + 2123977244137170, + 774562885265820, + 430035546191685, + ), + u64x4::new_const( + 2150863173197992, + 2101978317708856, + 193592648406011, + 1375328504508580, + ), + u64x4::new_const( + 1946235834250479, + 121741431658675, + 1004342690620100, + 2063466488599450, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 463079632200153, + 40415275714025, + 545935352782679, + 1458043501600908, + ), + u64x4::new_const( + 783771976559993, + 880839641726471, + 1782028201271831, + 41664413404590, + ), + u64x4::new_const( + 985129151724159, + 187728621410000, + 16620051933318, + 378011085567733, + ), + u64x4::new_const( + 1820372198168638, + 905710046480679, + 1912961774249737, + 1868135861067161, + ), + u64x4::new_const( + 474460473983187, + 1455684425673661, + 652771171116843, + 733511920760779, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1088886980746809, + 1660218575261626, + 527921875040240, + 915086639857889, + ), + u64x4::new_const( + 1814735788528175, + 1586698876186367, + 2040856637532862, + 405684812785624, + ), + u64x4::new_const( + 658578559700999, + 1751442070931114, + 1293623371490094, + 715026719042518, + ), + u64x4::new_const( + 382156225644820, + 897982285504960, + 577673183555858, + 1158728558309719, + ), + u64x4::new_const( + 1865791902475663, + 124491617513788, + 758484125168765, + 734065580770143, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 330985690350617, + 2214424721795630, + 973374650780848, + 1507267060932964, + ), + u64x4::new_const( + 1733823971011290, + 1730742552292995, + 669018866977489, + 604527664126146, + ), + u64x4::new_const( + 1082092498645474, + 1029182053935309, + 756799947765834, + 1764720030308351, + ), + u64x4::new_const( + 969912105693756, + 38116887248276, + 2148030115687613, + 995140534653865, + ), + u64x4::new_const( + 2154373397460354, + 298128883464656, + 479587543632539, + 1061127201140779, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 843064865526549, + 2019481782959016, + 1873125524281672, + 2013330239022371, + ), + u64x4::new_const( + 1192932403815186, + 1818108671859220, + 1247005102016258, + 1210577394628058, + ), + u64x4::new_const( + 132359273326717, + 795492788299178, + 1235924489372816, + 891705064411550, + ), + u64x4::new_const( + 1425833709104858, + 152114045731085, + 991347902581315, + 1387773338707683, + ), + u64x4::new_const( + 48024203807922, + 157005564892977, + 1474053161953744, + 727448023498345, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1076621484026788, + 1309917234320927, + 1786998180233659, + 1595497085944737, + ), + u64x4::new_const( + 1737334672694726, + 2038133716999447, + 1929061192400917, + 620544235219084, + ), + u64x4::new_const( + 1550527313469747, + 329096759623509, + 1585214659209474, + 693419841748324, + ), + u64x4::new_const( + 1450010875912315, + 2085047082180569, + 757421110771886, + 389367139787400, + ), + u64x4::new_const( + 781339490566117, + 132941783448971, + 258650459725225, + 2042274962585613, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 859638991542650, + 2249840007426442, + 1138753070862357, + 793751342318913, + ), + u64x4::new_const( + 2133476133447306, + 1027010646129239, + 436851910892865, + 866949948830344, + ), + u64x4::new_const( + 1936003572431223, + 531513680252193, + 1929877059408416, + 830585477662503, + ), + u64x4::new_const( + 1460760405777960, + 686673748420916, + 275475330051554, + 1581792376993692, + ), + u64x4::new_const( + 894482039456784, + 1801274480988632, + 16407898635278, + 1668497039215206, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 258585746227669, + 936490904651492, + 1826793887434108, + 1201219990633823, + ), + u64x4::new_const( + 979462791643635, + 461762372210187, + 218708929991480, + 1378150755760178, + ), + u64x4::new_const( + 642542170229970, + 787135445552820, + 371168855880557, + 182642566486693, + ), + u64x4::new_const( + 1152277399721904, + 1726910452705576, + 1452393215705343, + 2117799581546845, + ), + u64x4::new_const( + 1211265143925330, + 14373046151823, + 1745528818271507, + 1842106288572078, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 635154614562157, + 1956763034454109, + 509123035953043, + 445727657534780, + ), + u64x4::new_const( + 2072765509783252, + 1282639891593570, + 1075086397362049, + 722996110178195, + ), + u64x4::new_const( + 1385572918825603, + 1190035835509576, + 218317841176013, + 1047865370756924, + ), + u64x4::new_const( + 473991569426488, + 1910588123704592, + 1338270051770806, + 401676861680875, + ), + u64x4::new_const( + 992455353618436, + 126422733426929, + 1955248037756399, + 119233843022643, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1555272991526078, + 2214378187116349, + 366893798097444, + 1401502118355702, + ), + u64x4::new_const( + 1157229521930713, + 2144787187506262, + 1681597469697840, + 847499096518697, + ), + u64x4::new_const( + 1872802655800758, + 1027119609820793, + 1137278714788290, + 1664750301179485, + ), + u64x4::new_const( + 1091289858897030, + 910126419483563, + 1101920147235731, + 597083075893952, + ), + u64x4::new_const( + 1711011533670315, + 185206680336278, + 1620960612579784, + 1968598849170880, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 73077300235958, + 257216723095630, + 466947267713785, + 847105214181598, + ), + u64x4::new_const( + 1322905631406309, + 407458059314731, + 230045063190376, + 923800751267786, + ), + u64x4::new_const( + 1146027205000415, + 1541328763727623, + 768510249199119, + 1630223587589059, + ), + u64x4::new_const( + 1930368769879433, + 1376145403022159, + 1898149855343131, + 1709421930518180, + ), + u64x4::new_const( + 633944191571764, + 58314960742839, + 2050971151574988, + 757799756090059, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 361576929158539, + 1035682890165818, + 160945739362874, + 266975208626222, + ), + u64x4::new_const( + 1635371797076046, + 2106722851965197, + 451585919077206, + 6692426667180, + ), + u64x4::new_const( + 175820543533852, + 2057511393764025, + 1531846543720469, + 1648320903946519, + ), + u64x4::new_const( + 947461770620940, + 1107335044817620, + 1725565474111216, + 2182263619949220, + ), + u64x4::new_const( + 726444888601221, + 1379664085279206, + 1517215633290417, + 1763968936542507, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 686545355846512, + 1712283265573167, + 1743509592736302, + 1653906616429153, + ), + u64x4::new_const( + 985108805667149, + 2244347650874753, + 1304749057936860, + 321846134330589, + ), + u64x4::new_const( + 296321076156886, + 1717929256240029, + 450933772486425, + 2015536856431605, + ), + u64x4::new_const( + 1690393512821866, + 646913049470189, + 2198650647576397, + 1230646705710442, + ), + u64x4::new_const( + 601961913448442, + 878806578800541, + 620497587492381, + 330716414244629, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 631510982676132, + 1755753187697174, + 1596201246674299, + 2197888384902121, + ), + u64x4::new_const( + 626957678275745, + 1447583371478595, + 1375375216702128, + 1443613232818823, + ), + u64x4::new_const( + 1962997804660501, + 1051744123184519, + 1002558639300437, + 1237313314603385, + ), + u64x4::new_const( + 2118828335274995, + 226398203764759, + 889099617161107, + 1620967117678504, + ), + u64x4::new_const( + 227261019362935, + 2046897556746842, + 591524060355369, + 2178552047369691, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1375403119051662, + 222313965014452, + 539873444241395, + 213198095917915, + ), + u64x4::new_const( + 1436952871599114, + 1229749762725246, + 1174441562267670, + 265367077740349, + ), + u64x4::new_const( + 11107426165917, + 985954476039181, + 1147329112365579, + 1133931640328107, + ), + u64x4::new_const( + 585235055006843, + 699515259687482, + 299559608721134, + 2134819767146767, + ), + u64x4::new_const( + 1376401105588528, + 391412107507860, + 302743651807545, + 1362834426455518, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1802940904616205, + 1615132760193234, + 869321663313735, + 666494072545310, + ), + u64x4::new_const( + 1452849320020701, + 1472716813676364, + 472862999490802, + 359937983286145, + ), + u64x4::new_const( + 1221198323133843, + 491718521756528, + 1387135774113906, + 793779904904008, + ), + u64x4::new_const( + 1032129287829151, + 30730741946697, + 217603185195068, + 2118169309744162, + ), + u64x4::new_const( + 225899335574721, + 1767553399797342, + 881082465669982, + 1435383196392870, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1127093564374276, + 2245188499702906, + 1250041622887441, + 2179324911668149, + ), + u64x4::new_const( + 908019210866875, + 1879900391060964, + 1355047706206597, + 647218945377302, + ), + u64x4::new_const( + 1616265604422592, + 2134336781521657, + 1157711219915601, + 1227494173135033, + ), + u64x4::new_const( + 136450294813355, + 1984543542455033, + 1199486053011083, + 33687889941331, + ), + u64x4::new_const( + 1053447012707371, + 68239344331930, + 537448158443925, + 1829189783369646, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 996806463322563, + 2043104667851348, + 1110361398300309, + 1218740346887957, + ), + u64x4::new_const( + 399141907016839, + 1307691109658227, + 532535384961264, + 896201194398872, + ), + u64x4::new_const( + 111705272106160, + 1790972382466021, + 1159338112559144, + 303544352897203, + ), + u64x4::new_const( + 1036600573322969, + 1457119922663674, + 334117653665514, + 460023361701263, + ), + u64x4::new_const( + 1363773215189933, + 1915594049343802, + 1661249423378694, + 1744945551969247, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 3093919631215, + 574886478077610, + 1704446919728971, + 250093147254210, + ), + u64x4::new_const( + 1387413348737796, + 360142717826981, + 2116185073015983, + 474541388374100, + ), + u64x4::new_const( + 1632539630892580, + 1332404016215719, + 2145297637794728, + 1289783723173504, + ), + u64x4::new_const( + 1030244179060173, + 579782698595797, + 1062365251139982, + 677149839815546, + ), + u64x4::new_const( + 6671539419876, + 1426937459653775, + 406942403696343, + 675479224223817, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 271984148441782, + 1708099625818957, + 1499011822959235, + 516808451044836, + ), + u64x4::new_const( + 1124847751346323, + 2038336022958449, + 1721698491022600, + 705944403212572, + ), + u64x4::new_const( + 85459783780275, + 1715213099986669, + 1728445509034791, + 730657630359717, + ), + u64x4::new_const( + 1185034652652387, + 755472578204310, + 476118360897817, + 1800434542785310, + ), + u64x4::new_const( + 1815589628676941, + 491778500674079, + 1547664984392513, + 279891608681267, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 2036337168672113, + 1730787524684269, + 639134121311693, + 698060925015524, + ), + u64x4::new_const( + 315211075189491, + 1329055848835358, + 688621136402134, + 1271193060119448, + ), + u64x4::new_const( + 1697984374314012, + 459330773536457, + 305481314707918, + 61676911066002, + ), + u64x4::new_const( + 2166631826859191, + 2105217187401781, + 937587962768434, + 357397435365683, + ), + u64x4::new_const( + 1206757093145471, + 1287847622009294, + 1951336140421622, + 2233789834777410, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 82144190081093, + 1568417433687791, + 907555979158442, + 2037855062523867, + ), + u64x4::new_const( + 1225315484058853, + 315317868015613, + 1765025920288384, + 175223259828436, + ), + u64x4::new_const( + 1215010304871271, + 662713408454950, + 429517658575616, + 991062684008811, + ), + u64x4::new_const( + 993837615254894, + 1485561584889450, + 2001836754226476, + 1915943063896801, + ), + u64x4::new_const( + 818895101625673, + 1342479472068804, + 1380235330010671, + 23315169761453, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1500726307559118, + 956166860173424, + 512663951564436, + 1940180717699824, + ), + u64x4::new_const( + 1789521472720825, + 779456898652427, + 2035063615853504, + 863582140589407, + ), + u64x4::new_const( + 634508890793787, + 1748041666732214, + 259642099961634, + 1294936839797812, + ), + u64x4::new_const( + 2183334898697038, + 2197242820694806, + 2217225409073703, + 992633998226449, + ), + u64x4::new_const( + 2197077498155916, + 1562008797791883, + 1395088759904208, + 331715244679294, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 186854731652320, + 284389440026580, + 1252175415119400, + 1025377410100223, + ), + u64x4::new_const( + 1578732129417607, + 898645497852382, + 2237766074482974, + 1939197790303592, + ), + u64x4::new_const( + 1438830390640145, + 1682452015845597, + 1108441197232223, + 1984134492898664, + ), + u64x4::new_const( + 282668727301669, + 1609018289552856, + 390363439795705, + 1138459124667912, + ), + u64x4::new_const( + 18889015928490, + 532489638086725, + 324621535996080, + 2210046082697453, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 2041327051605378, + 2244037852176483, + 2116336876147147, + 9616672544864, + ), + u64x4::new_const( + 969847387559191, + 1059119127679639, + 1764630094670633, + 364568045311834, + ), + u64x4::new_const( + 505938893153679, + 2075421412172902, + 326984153045666, + 1959549727324704, + ), + u64x4::new_const( + 1088715617911260, + 13917085151028, + 950568481355929, + 23687195265771, + ), + u64x4::new_const( + 1798284568673198, + 808382292203333, + 2214698741961545, + 610817203275867, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1731488929623777, + 1158815615106413, + 1491090861948525, + 1428384712900962, + ), + u64x4::new_const( + 722237139522457, + 1514290328911535, + 1366197913116230, + 1519472657321210, + ), + u64x4::new_const( + 246028966932273, + 1888239319448405, + 423720022211163, + 455243905681470, + ), + u64x4::new_const( + 738323403716001, + 1758018973481179, + 1180718299482318, + 1008495946606708, + ), + u64x4::new_const( + 334959381596119, + 1704599537529481, + 2172191232106896, + 13502508918495, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 273393076768079, + 427388720298603, + 1071733376018227, + 1715429388968611, + ), + u64x4::new_const( + 751776629892313, + 1965239102856011, + 541955408230119, + 831043488876080, + ), + u64x4::new_const( + 643718536393104, + 390543998404644, + 2176730661486279, + 499459234889079, + ), + u64x4::new_const( + 1482404333915009, + 865527293526285, + 507957951411713, + 216456252558825, + ), + u64x4::new_const( + 2210281256300231, + 1519357818277551, + 1257866936775246, + 1689605217672864, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 2135395168187905, + 2214400157568614, + 2032983817870823, + 1124945109072647, + ), + u64x4::new_const( + 1602820011758145, + 906675633903289, + 782700735390986, + 2067218823525601, + ), + u64x4::new_const( + 786785748926382, + 1433583123655616, + 905839404290873, + 2249680349963778, + ), + u64x4::new_const( + 1940824582370584, + 1610961256326291, + 285307858781375, + 1755588655461194, + ), + u64x4::new_const( + 233682812055333, + 2146114223476434, + 41132209533476, + 535292431776371, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 600257696476418, + 18449221564824, + 1422209458591138, + 239571584769716, + ), + u64x4::new_const( + 2056372917056980, + 1155290566623531, + 1252473955568148, + 1276690716882081, + ), + u64x4::new_const( + 246974369025311, + 658117221519903, + 2000380937898441, + 1351183273924850, + ), + u64x4::new_const( + 1803747363753112, + 1736801515030186, + 2025633577199091, + 603378480769167, + ), + u64x4::new_const( + 57348749438551, + 1893551220299655, + 657926732731806, + 1522499384853705, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 591809128842736, + 284860517232591, + 27436696863545, + 886306697195798, + ), + u64x4::new_const( + 2113192175751749, + 1405882509906423, + 561316282804847, + 835573846576266, + ), + u64x4::new_const( + 94407289485409, + 1781534171669004, + 2098782516531528, + 598529921520053, + ), + u64x4::new_const( + 1860137004504786, + 2197323407480349, + 1516772733981532, + 961740253777086, + ), + u64x4::new_const( + 1484139612868217, + 1593557644636881, + 838834937143441, + 36382198263380, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1165898865828562, + 1153420815042389, + 1068625028915785, + 1945927229911090, + ), + u64x4::new_const( + 843454394017146, + 571029655293754, + 386282254545998, + 1804608237584150, + ), + u64x4::new_const( + 370552451091100, + 1279105656351124, + 1864742949668631, + 2093071521726981, + ), + u64x4::new_const( + 1872542389052198, + 1679083953574330, + 349872262454465, + 1470311090717925, + ), + u64x4::new_const( + 685345654160323, + 319718985807814, + 1359932285384164, + 1410900103316331, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 2083666668832889, + 314624387816655, + 1496694646480345, + 1946728950459189, + ), + u64x4::new_const( + 1579153761571203, + 508771185291380, + 1002249659402007, + 551517831173801, + ), + u64x4::new_const( + 2132371471626150, + 1988122278556533, + 1552195130653890, + 1327637750292755, + ), + u64x4::new_const( + 118937099181527, + 382610380973142, + 634951529106471, + 382740054041699, + ), + u64x4::new_const( + 801287519643470, + 87822941589258, + 1908825350108451, + 1404208826499115, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 330347226380261, + 672119116965146, + 1761510370768005, + 1959200302484704, + ), + u64x4::new_const( + 1631876583009250, + 1684917718484264, + 1027256947805920, + 2174612545251129, + ), + u64x4::new_const( + 636668855699872, + 625187713984839, + 265886954766790, + 167898557908504, + ), + u64x4::new_const( + 1210974548180860, + 2051308710365526, + 907620584086428, + 1081788677970850, + ), + u64x4::new_const( + 621792955460854, + 1450945504745382, + 1666728650687828, + 977937146451674, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 24725936182267, + 2226765032752574, + 2036560083102883, + 2002351185719584, + ), + u64x4::new_const( + 1620080779405308, + 1493220053370419, + 2245691691038916, + 1152182628629603, + ), + u64x4::new_const( + 317928527147500, + 1855194218440212, + 979380281964169, + 861442286685289, + ), + u64x4::new_const( + 393308472784625, + 486143087279967, + 1234071346236405, + 777748237119399, + ), + u64x4::new_const( + 43850412814718, + 1497656407486446, + 744128331046695, + 1618035787321792, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1670169946550211, + 1230951698726438, + 806586940221293, + 23159779184607, + ), + u64x4::new_const( + 634011340979302, + 764182085034744, + 731065727766955, + 1737985776442180, + ), + u64x4::new_const( + 240492712141842, + 73976435954441, + 162810587166835, + 697230894340912, + ), + u64x4::new_const( + 1299745598348388, + 1359436039694544, + 1856609816731554, + 25228008461513, + ), + u64x4::new_const( + 2180690501932381, + 2161211192848458, + 87069466793408, + 2003456332883860, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1106932458043379, + 1675181364231371, + 1681785724775243, + 131824742557210, + ), + u64x4::new_const( + 1671649414647169, + 1827849994880670, + 1097958057111899, + 701956891169434, + ), + u64x4::new_const( + 2095539283710881, + 591029812888096, + 1699571518315654, + 1297589045812566, + ), + u64x4::new_const( + 1345612272298537, + 2166754730876055, + 2047982622154948, + 1785222806258129, + ), + u64x4::new_const( + 2181915268829890, + 1895697064378670, + 1288412327355885, + 1561075738281368, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 741330264098392, + 357073519729966, + 1603572339180975, + 433572083688575, + ), + u64x4::new_const( + 699685108971208, + 1719650727634959, + 1941668009419214, + 870374958347891, + ), + u64x4::new_const( + 385971389331537, + 11655507719711, + 94814615497633, + 515572102810609, + ), + u64x4::new_const( + 1396688200590426, + 1518748475144123, + 162386454324368, + 2083303971579002, + ), + u64x4::new_const( + 1511688632419263, + 251584258592336, + 545345887993880, + 1229840230314160, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1298668855706029, + 2017860934939344, + 2224150456036391, + 1925926576297971, + ), + u64x4::new_const( + 259522963883544, + 1312469129541229, + 1647530465049600, + 1113737129047154, + ), + u64x4::new_const( + 733193298663145, + 2115712816303403, + 897628702762311, + 116440277571901, + ), + u64x4::new_const( + 1998719395229750, + 1662774553684237, + 194395608126452, + 98796702872301, + ), + u64x4::new_const( + 2226158244229144, + 91961728239158, + 526869903032152, + 849263805316773, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 472779569333556, + 854477760843410, + 2070906720349401, + 734613359834689, + ), + u64x4::new_const( + 1771897100487404, + 1604024196006064, + 319699348925383, + 437152129592623, + ), + u64x4::new_const( + 627618365135361, + 1768642666037955, + 588564169143939, + 35295037750744, + ), + u64x4::new_const( + 220241884231278, + 319104161410840, + 1048165719448798, + 1583931089774347, + ), + u64x4::new_const( + 166479451884333, + 1623611819962804, + 59990366193679, + 900727256046987, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 1944687327687331, + 1328410791053991, + 2083980670913902, + 609396833380574, + ), + u64x4::new_const( + 1907563845734496, + 1385619047697883, + 869817384774457, + 106642388505109, + ), + u64x4::new_const( + 1006516581737154, + 1561918369633937, + 1921172883211450, + 2216650451558824, + ), + u64x4::new_const( + 1780506017391778, + 233064930371847, + 1332962603425752, + 1380075261612354, + ), + u64x4::new_const( + 1907624789747741, + 1310065402098523, + 1838275780706825, + 884225500782782, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 198729830692545, + 100156148743413, + 2140568641558859, + 2220606475942394, + ), + u64x4::new_const( + 1108788217903741, + 1706330932366163, + 2050449866410661, + 684907598542847, + ), + u64x4::new_const( + 1101958322366646, + 659427843062405, + 253899933868173, + 896574852821269, + ), + u64x4::new_const( + 1157052140740658, + 440541103447032, + 2173354981480949, + 604768603561932, + ), + u64x4::new_const( + 961238337866054, + 830849154351308, + 1643852412409441, + 1436749321770368, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 784870637473285, + 1180234052037572, + 2086951602998715, + 419328169540373, + ), + u64x4::new_const( + 1966862397394559, + 788036164772123, + 2024355635709481, + 1471696676696146, + ), + u64x4::new_const( + 1468884300957205, + 1408016588131185, + 2229595828577885, + 240413942963547, + ), + u64x4::new_const( + 1481791691942441, + 970648959691160, + 1635500996148197, + 2236917233261585, + ), + u64x4::new_const( + 31660820731028, + 801794768903647, + 1069092619607344, + 282652554845923, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 911659428682786, + 762502588057038, + 1311399152500807, + 1966922911783311, + ), + u64x4::new_const( + 1229849228728540, + 258161307933217, + 2140796867375541, + 1569345075547911, + ), + u64x4::new_const( + 1487354676143742, + 1818317546165791, + 811033554173350, + 1768788663337616, + ), + u64x4::new_const( + 450017165913234, + 962535873747168, + 2099104262993585, + 503030952485785, + ), + u64x4::new_const( + 1259958681304518, + 479589250923541, + 1503904042161640, + 706283657294305, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 794562643024291, + 198670993088241, + 1678984629358943, + 273399517554618, + ), + u64x4::new_const( + 188458991574433, + 1389872130156447, + 1461868931574746, + 795140878721432, + ), + u64x4::new_const( + 624046647169653, + 630363741191019, + 911018499983500, + 1410140563046579, + ), + u64x4::new_const( + 1675056174405076, + 632544713589250, + 795454163559811, + 1535271563341780, + ), + u64x4::new_const( + 25504547444781, + 812510098987855, + 51290042016232, + 1992260991700127, + ), + ])), + CachedPoint(F51x4Reduced([ + u64x4::new_const( + 269968325452358, + 470932785179706, + 1684444304834150, + 1027482126748243, + ), + u64x4::new_const( + 457941065342419, + 2117377568137882, + 1209423706730905, + 2192403099717071, + ), + u64x4::new_const( + 1899046404863678, + 1359500336071762, + 1492389156724726, + 1455627081827750, + ), + u64x4::new_const( + 2016101061876546, + 1967000012916571, + 582539481696050, + 1197538178790094, + ), + u64x4::new_const( + 639684852217504, + 1799941252757449, + 1470016556327743, + 846111828965901, + ), + ])), +]); diff --git a/curve25519-dalek/src/backend/vector/ifma/edwards.rs b/curve25519-dalek/src/backend/vector/ifma/edwards.rs index f8605fe52..711433a1a 100644 --- a/curve25519-dalek/src/backend/vector/ifma/edwards.rs +++ b/curve25519-dalek/src/backend/vector/ifma/edwards.rs @@ -334,4 +334,53 @@ mod test { let P = constants::ED25519_BASEPOINT_TABLE * &Scalar::from(8475983829u64); doubling_test_helper(P); } + + #[test] + fn basepoint_odd_lookup_table_verify() { + use crate::backend::vector::ifma::constants::BASEPOINT_ODD_LOOKUP_TABLE; + use crate::constants; + + let basepoint_odd_table = + NafLookupTable8::::from(&constants::ED25519_BASEPOINT_POINT); + println!("basepoint_odd_lookup_table = {:?}", basepoint_odd_table); + + let table_B = &BASEPOINT_ODD_LOOKUP_TABLE; + for (b_vec, base_vec) in table_B.0.iter().zip(basepoint_odd_table.0.iter()) { + let b_splits = b_vec.0.split(); + let base_splits = base_vec.0.split(); + + assert_eq!(base_splits[0], b_splits[0]); + assert_eq!(base_splits[1], b_splits[1]); + assert_eq!(base_splits[2], b_splits[2]); + assert_eq!(base_splits[3], b_splits[3]); + } + } + + #[test] + fn b_shl_128_odd_lookup_table_verify() { + use crate::backend::vector::ifma::constants::B_SHL_128_ODD_LOOKUP_TABLE; + use crate::constants; + use crate::scalar::Scalar; + + let b_shl_128_odd_table = NafLookupTable8::::from( + &(constants::ED25519_BASEPOINT_POINT + * Scalar::from_canonical_bytes([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ]) + .unwrap()), + ); + println!("b_shl_128_odd_lookup_table = {:?}", b_shl_128_odd_table); + + let table_B = &B_SHL_128_ODD_LOOKUP_TABLE; + for (b_vec, base_vec) in table_B.0.iter().zip(b_shl_128_odd_table.0.iter()) { + let b_splits = b_vec.0.split(); + let base_splits = base_vec.0.split(); + + assert_eq!(base_splits[0], b_splits[0]); + assert_eq!(base_splits[1], b_splits[1]); + assert_eq!(base_splits[2], b_splits[2]); + assert_eq!(base_splits[3], b_splits[3]); + } + } } diff --git a/curve25519-dalek/src/backend/vector/scalar_mul/abglsv_pornin.rs b/curve25519-dalek/src/backend/vector/scalar_mul/abglsv_pornin.rs new file mode 100644 index 000000000..17bd1f1ae --- /dev/null +++ b/curve25519-dalek/src/backend/vector/scalar_mul/abglsv_pornin.rs @@ -0,0 +1,213 @@ +// -*- mode: rust; -*- +// +// This file is part of curve25519-dalek. +// Copyright (c) 2020-2024 Jack Grigg +// See LICENSE for licensing information. +// +// Author: +// Jack Grigg +#![allow(non_snake_case)] + +#[curve25519_dalek_derive::unsafe_target_feature_specialize( + "avx2", + conditional("avx512ifma,avx512vl", nightly) +)] +pub mod spec { + #[for_target_feature("avx2")] + use crate::backend::vector::avx2::{CachedPoint, ExtendedPoint}; + + #[for_target_feature("avx512ifma")] + use crate::backend::vector::ifma::{CachedPoint, ExtendedPoint}; + + #[cfg(feature = "precomputed-tables")] + #[for_target_feature("avx2")] + use crate::backend::vector::avx2::constants::{ + BASEPOINT_ODD_LOOKUP_TABLE, B_SHL_128_ODD_LOOKUP_TABLE, + }; + + #[cfg(feature = "precomputed-tables")] + #[for_target_feature("avx512ifma")] + use crate::backend::vector::ifma::constants::{ + BASEPOINT_ODD_LOOKUP_TABLE, B_SHL_128_ODD_LOOKUP_TABLE, + }; + + use core::cmp::Ordering; + + use crate::{ + edwards::EdwardsPoint, + scalar::{lattice_reduction::find_short_vector, Scalar}, + traits::Identity, + window::NafLookupTable5, + }; + + /// Computes \\([δa]A + [δb]B - [δ]C\\) in variable time. + /// + /// - \\(B\\) is the Ed25519 basepoint. + /// - \\(δ\\) is a value invertible \\( \mod \ell \\), which is selected internally to + /// this function. + /// + /// This corresponds to the signature verification optimisation presented in + /// [Antipa et al 2005](http://cacr.uwaterloo.ca/techreports/2005/cacr2005-28.pdf). + pub fn mul(a: &Scalar, A: &EdwardsPoint, b: &Scalar, C: &EdwardsPoint) -> EdwardsPoint { + // Starting with the target equation: + // + // [(δa mod l)]A + [(δb mod l)]B - [δ]C + // + // We can split δb mod l into two halves e_0 (128 bits) and e_1 (125 bits), and + // rewrite the equation as: + // + // [(δa mod l)]A + [e_0]B + [e_1 2^128]B - [δ]C + // + // B and [2^128]B are precomputed, and their resulting scalar multiplications each + // have half as many doublings. We therefore want to find a pair of signed integers + // + // (d_0, d_1) = (δa mod l, δ) + // + // that both have as few bits as possible, similarly reducing the number of doublings + // in the scalar multiplications [d_0]A and [d_1]C. This is equivalent to finding a + // short vector in a lattice of dimension 2. + + // Find a short vector. + let (d_0, d_1) = find_short_vector(a); + + // Move the signs of d_0 and d_1 into their corresponding bases and scalars. + let A = if d_0.is_negative() { -A } else { *A }; + let (b, negC) = if d_1.is_negative() { + (-b, *C) + } else { + (*b, -C) + }; + let d_0 = Scalar::from(d_0.unsigned_abs()); + let d_1 = Scalar::from(d_1.unsigned_abs()); + + // Calculate the remaining scalars. + let (e_0, e_1) = { + let db = b * d_1; + let mut e_0 = [0; 32]; + let mut e_1 = [0; 32]; + e_0[..16].copy_from_slice(&db.as_bytes()[..16]); + e_1[..16].copy_from_slice(&db.as_bytes()[16..]); + (Scalar { bytes: e_0 }, Scalar { bytes: e_1 }) + }; + + // Now we can compute the following using Straus's method: + // [d_0]A + [e_0]B + [e_1][2^128]B + [d_1][-C] + // + // We inline it here so we can use precomputed multiples of [2^128]B. + + let d_0_naf = d_0.non_adjacent_form(5); + + #[cfg(feature = "precomputed-tables")] + let e_0_naf = e_0.non_adjacent_form(8); + #[cfg(not(feature = "precomputed-tables"))] + let e_0_naf = e_0.non_adjacent_form(5); + + #[cfg(feature = "precomputed-tables")] + let e_1_naf = e_1.non_adjacent_form(8); + #[cfg(not(feature = "precomputed-tables"))] + let e_1_naf = e_1.non_adjacent_form(5); + + let d_1_naf = d_1.non_adjacent_form(5); + + // Find starting index + let mut i: usize = 255; + for j in (0..256).rev() { + i = j; + if d_0_naf[i] != 0 || e_0_naf[i] != 0 || e_1_naf[i] != 0 || d_1_naf[i] != 0 { + break; + } + } + + let table_A = NafLookupTable5::::from(&A); + + #[cfg(feature = "precomputed-tables")] + let table_B = &BASEPOINT_ODD_LOOKUP_TABLE; + #[cfg(not(feature = "precomputed-tables"))] + let table_B = + &NafLookupTable5::::from(&crate::constants::ED25519_BASEPOINT_POINT); + + #[cfg(feature = "precomputed-tables")] + let table_B_SHL_128 = &B_SHL_128_ODD_LOOKUP_TABLE; + #[cfg(not(feature = "precomputed-tables"))] + let table_B_SHL_128 = + &NafLookupTable5::::from(&crate::constants::ED25519_BASEPOINT_SHL_128); + + let table_negC = NafLookupTable5::::from(&negC); + + let mut Q = ExtendedPoint::identity(); + + loop { + Q = Q.double(); + + match d_0_naf[i].cmp(&0) { + Ordering::Greater => Q = &Q + &table_A.select(d_0_naf[i] as usize), + Ordering::Less => Q = &Q - &table_A.select(-d_0_naf[i] as usize), + Ordering::Equal => {} + } + + match e_0_naf[i].cmp(&0) { + Ordering::Greater => Q = &Q + &table_B.select(e_0_naf[i] as usize), + Ordering::Less => Q = &Q - &table_B.select(-e_0_naf[i] as usize), + Ordering::Equal => {} + } + + match e_1_naf[i].cmp(&0) { + Ordering::Greater => Q = &Q + &table_B_SHL_128.select(e_1_naf[i] as usize), + Ordering::Less => Q = &Q - &table_B_SHL_128.select(-e_1_naf[i] as usize), + Ordering::Equal => {} + } + + match d_1_naf[i].cmp(&0) { + Ordering::Greater => Q = &Q + &table_negC.select(d_1_naf[i] as usize), + Ordering::Less => Q = &Q - &table_negC.select(-d_1_naf[i] as usize), + Ordering::Equal => {} + } + + if i == 0 { + break; + } + i -= 1; + } + + Q.into() + } +} + +#[cfg(test)] +mod tests { + use crate::{ + backend::scalar_mul_abglsv_pornin as mul, constants::ED25519_BASEPOINT_POINT, + scalar::Scalar, traits::IsIdentity, + }; + + #[test] + fn test_mul() { + let a = Scalar::from(2u8); + let A = ED25519_BASEPOINT_POINT.double(); // [2]B + let b = Scalar::from(4u8); + let C = A.double().double(); // [8]B + + // The equation evaluates to the identity, so will be unaffected by δ. + assert_eq!( + mul(&a, &A, &b, &C), + (a * A) + (b * ED25519_BASEPOINT_POINT) - C + ); + + // Now test some random values. + let mut rng = rand::thread_rng(); + + for _ in 0..100 { + let a = Scalar::random(&mut rng); + let A = &Scalar::random(&mut rng) * ED25519_BASEPOINT_POINT; + let b = Scalar::random(&mut rng); + + // With a correctly-constructed C, we get the identity. + let C = (a * A) + (b * ED25519_BASEPOINT_POINT); + assert!(mul(&a, &A, &b, &C).is_identity()); + + // With a random C, with high probability we do not get the identity. + let C = &Scalar::random(&mut rng) * ED25519_BASEPOINT_POINT; + assert!(!mul(&a, &A, &b, &C).is_identity()); + } + } +} diff --git a/curve25519-dalek/src/backend/vector/scalar_mul/mod.rs b/curve25519-dalek/src/backend/vector/scalar_mul/mod.rs index fed3470e7..e33b5961b 100644 --- a/curve25519-dalek/src/backend/vector/scalar_mul/mod.rs +++ b/curve25519-dalek/src/backend/vector/scalar_mul/mod.rs @@ -11,6 +11,8 @@ //! Implementations of various multiplication algorithms for the SIMD backends. +pub mod abglsv_pornin; + #[allow(missing_docs)] pub mod variable_base;